#!/usr/local/bin/perl -w use strict; use WWW::TV qw(); use DateTime::Format::ISO8601; use File::Slurp; use XML::Atom::Feed; use XML::Atom::Entry; my $DEBUG = 0; =head1 NAME tv2feed - create an Atom feed of upcoming TV shows =head1 USAGE tv2feed [option[s]] [program list] =head1 OPTIONS =over 4 =item -d =item --debug Print status to STDERR =item program list One program name per line. If you don't supply one it will look for ~/.tv2feed =back =cut while (@ARGV) { last unless $ARGV[0] =~ s!^-+!!; my $arg = shift; if ($arg eq "d" || $arg eq "debug") { $DEBUG = 1; } } my $conf = shift || "$ENV{HOME}/.tv2feed"; my @shows = map { chomp; $_ } read_file($conf); my $now = DateTime->now; my @episodes; foreach my $show (@shows) { print STDERR "$show ... " if $DEBUG; my $episode = fetch_next_episode($show); if ($episode) { print STDERR "OK\n" if $DEBUG; } else { print STDERR "FAIL\n" if $DEBUG; next; } $episode->{_show_name} = $show; push @episodes, $episode; } my $atom = XML::Atom::Feed->new( Version => "1.0" ) ; $atom->title("Simon's TV"); $atom->link("http://thegestalt.org/simon"); $atom->subtitle("My TV programs"); $atom->id('http://thegestalt.org/simon/tv.atom'); $atom->updated($now->ymd('-') . 'T' . $now->hms(':') . "Z"); my $link = XML::Atom::Link->new( Namespace => 'http://www.w3.org/2005/Atom' ); $link->type('application/atom+xml'); $link->rel('self'); $link->href("http://thegestalt.org/simon"); $atom->add_link("http://thegestalt.org/simon"); foreach my $episode (sort { $a->first_aired cmp $b->first_aired } @episodes) { my $entry = XML::Atom::Entry->new( Version => "1.0" ); $entry->id($episode->url); $entry->title($episode->{_show_name}." - ".$episode->name." (".$episode->first_aired.")"); $entry->content($episode->summary); my $elink = XML::Atom::Link->new( Namespace => 'http://www.w3.org/2005/Atom' ); $elink->type('text/html'); $elink->href($episode->url); $entry->link($elink); $entry->updated($episode->first_aired); $atom->add_entry($entry); } print $atom->as_xml; sub fetch_next_episode { my $name = shift; my $series = eval { WWW::TV::Series->new( name => $name ) }; return undef if $@; return undef unless $series; my @episodes = sort { $a->first_aired cmp $b->first_aired } $series->episodes; foreach my $episode (@episodes) { my $date = eval { DateTime::Format::ISO8601->parse_datetime($episode->first_aired) }; next if $@; next if ( $date->year < $now->year || $date->month < $now->month || ($date->month == $now->month && $date->day < $now->day) ); return $episode; } return undef; } =head1 WARNING This can take quite a long time to run - especially if you have a large list of programs. =head1 AUTHOR Simon Wistow =head1 COPYRIGHT Copyright, 2007 - Simon Wistow Licenced under the same terms as Perl itself. =cut