Latest News
It seems that a few of you are using or trying to use the XML::RSS::Podcast module I published on this blog. As was mentioned there, modern version of XML::RSS do not support the encode function required for generating well-formed XML documents.
That's all changed thanks to Rohan Carly. [Add your thanks to Rohan in the comments.]
I present the complete version of XML::RSS::Podcast below. If you find this module
useful, I'll attempt to create a CPAN module for it.
package XML::RSS::Podcast;
use XML::RSS;
use HTML::Entities qw[encode_entities_numeric encode_entities];
@XML::RSS::Podcast::ISA = qw[XML::RSS];
our $VERSION = q[1.1];
# encode by Rohan Carly
# Stolen from XML::RSS::Private::Output::Base;
sub encode {
my ($self,$text) = @_;
return unless defined($text);
my $encoded_text = '';
while ($text =~ s,(.*?)(<!\[CDATA\[.*?\]\]>),,s) {
# we use &named; entities here because it's HTML
$encoded_text .= encode_entities($1) . $2;
}
# we use numeric entities here because it's XML
$encoded_text .= encode_entities_numeric($text);
return $encoded_text;
};
sub as_string {
my $self = shift;
return $self->as_podcast_rss;
}
sub as_podcast_rss {
my $self = shift;
my $enc = $self->{encoding};
my $output = qq[<?xml version="1.0" encoding="$enc"?>
<rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
version="2.0">];
$output .= $self->podcast_start_channel;
for my $i (@{$self->{items}}) {
$output .= $self->podcast_item($i);
}
$output .= $self->podcast_end_channel;
return $output .= "\n</rss>\n";
}
sub podcast_start_channel {
my $self = shift;
my @fields = qw[ttl title description link language
pubDate lastBuildDate creator
webMaster copyright
];
my @image_fields = qw[title url description link
width height];
my @itunes_fields = qw[subtitle author summary
image explicit]; # Thanks Rohan
my $output = "<channel>\n";
for my $f (@fields) {
if (defined($self->{channel}->{$f})) {
my $s = $self->encode($self->{channel}->{$f});
$output .= "\t<$f>$s</$f>\n";
}
}
my $seen_image = 0;
for my $f (@image_fields) {
if (defined($self->{image}->{$f})) {
unless ($seen_image) {
$output .= "\t<image>\n";
$seen_image = 1;
}
my $s = $self->encode($self->{image}->{$f});
$output .= "\t\t<$f>$s</$f>\n";
}
}
if ($seen_image) {
$output .= "\t</image>\n";
}
# Owner name/email not handled
for my $f (@itunes_fields) {
if (defined($self->{channel}->{itunes}->{$f})) {
my $s=$self->encode($self->{channel}->{itunes}->{$f});
$output .= "\t<itunes:$f>$s</itunes:$f>\n";
}
}
# Rohan's sub-cat handling code
# Expects an array: [category, sub-category]
if (ref $self->{channel}->{itunes}->{category} eq 'ARRAY') {
my $major = $self->encode(${$self->{channel}->{itunes}->{category}}[0]);
my $minor = $self->encode(${$self->{channel}->{itunes}->{category}}[1]);
$output .= qq[\t<itunes:category text="$major">\n];
$output .= qq[\t\t<itunes:category text="$minor">\n];
$output .= qq[\t\t</itunes:category>\n];
$output .= qq[\t</itunes:category>\n];
}
return $output . "\n";
}
sub podcast_end_channel {
return "</channel>\n";
}
sub podcast_item {
my $self = shift;
my $item = shift;
my @fields = qw[title guid pubDate description link];
my @itunes_fields = qw[author subtitle summary
duration keywords explicit];
my $output = "\t<item>\n";
for my $f (@fields) {
if (defined($item->{$f})) {
$s = $self->encode($item->{$f});
my $perma = "";
if ($f eq "guid") {
$perma = qq[isPermaLink="false"];
}
$output .= "\t\t<$f$perma>$s</$f>\n";
}
}
if (ref $item->{enclosure}) {
$output .= "<enclosure";
for my $f (qw[url length type]) {
if (defined $item->{enclosure}->{$f}) {
$output .= sprintf("$f=%s", $self->encode($item->{enclosure}->{$f}));
}
}
$output .= "/>";
}
for my $f (@itunes_fields) {
if (defined $item->{itunes}->{$f}) {
$s = $self->encode($item->{itunes}->{$f});
$output .= "\t\t<itunes:$f>$s</itunes:$f>\n";
}
}
return $output .= "\t</item>\n";
}
1;
For an example of usage, please see the previous post cited above. Report bugs in the comments or through email. Thanks.
I supply guids and I had to something similar to insert a space before permalink="false":
Also, when I try to supply a image, I get a HASH ref in the rss feed in the tag. I tried all sorts of combinations but couldn't get it to work.
I posted a working version at https://thesmithden.com/Podcast.txt with comments where I modified it. The resulting feed is at https://thesmithden.com/NC.xml
Again, great job! Thanks, Dave
About this blog
The taskboy blog is a exploration of computer technology by Joe Johnston. Topics of posts include practical examples Perl, PHP, Python and Java as well as book reviews, industry insights and miscellaneous good stuff.
Latest Feedbag
- This Week In Design: Chair Inspired By A Mussel, Transparent Racecar, Uncorked Wine Timer
- Google Hopeful Of 2010 Launch For iTunes Rival Despite Lack Of Signed Label Deals
- Getting to know the 'Catfish'
- Project Dance Party: Facebooks Secret Twitter-Like Follow Feature
- Three Stations
- TI reveals new teensy projector chip
- Important: Gmail Priority Inbox Should Now Be Available To All
- YC-Funded Cloudant Launches Its NoSQL Cloud Database Platform
- A Singularity in English Spelling
- New Calculations May Lead To a Test For String Theory
Generated: 06:30 on 03/Sep/2010
Recent posts
- Very quick git primer for basic functionality
- Tips for spammers: don't insult me
- CakePHP vs. Symfony: a quick note
- Creating events for Yahoo and Google calendars
- SANs on a budget: iSCSI under Ubuntu
- iPad, iTouch and Kindle: Which is the better mousetrap?
- Rise of the Ad-Hocracy, Part II
- Rise of the Ad-Hocracy, Part I
- Small Hiatus
