PDA

View Full Version : Public Radio Program Playlist Creator



Ben Klaas
2004-12-16, 16:05
hola slim community--

I'm fairly new to the forum (and to the glory that is the squeezebox),
and wanted to try to contribute something of value to establish good
will to all, peace on earth, and all of that.

I am a fan of a few particular shows on public radio. On my local public
radio station, they either a) aren't available or b) aren't on at a
convenient time. There is an excellent website called
http://publicradiofan.com that catalogs when shows are on various
internet streams.

To make a program's chronological/station listings easily accessible via
playlist(s), I wrote a perl script that scrapes the info for a given
public radio program and creates a set of .pls files that have titles
indiciative of the time slot and what radio station it is (the reason I
didn't use just one .pls is that I believe I uncovered a sorting bug in
slimserver; workaround is to use multiple pls files within a subdir).
The timezone is set by a cookie that is configurable in my script.

So, the end result, for example:
on Saturday at 4pm, I want to listen to "Wait Wait Don't Tell Me". I go
to my squeezebox remote or slimserver browser, and it's
Browse Playlists--> Wait Wait --> (scroll to) Sa 1600-1700 (KIPO) -->
<play>.

the script is attached. use/edit/play with/wrap it as you see fit-- I
wrote it in Linux, but I don't think there is anything in the script
that should be platform-specific...should work in OSX or a perl-capable
Windows machine.

comments welcome.

cheers,
#!/ben
JAPH

p.s., this is the bug I opened about playlist titles--
http://bugs.slimdevices.com/show_bug.cgi?id=735

#!/usr/bin/perl

use strict;

# look through the timezones at the bottom of this script for the one that matches yours
my $timezone = "Central";

#############################
# prfan_playlist.pl
#
# this script is designed to scrape information from
# dynamically generated program listings on publicradiofan.com
# and create <playlist title>/Dy HHHH-hhhh.pls files of mp3 stream URLs
#
# currently requires the user to know the program id, grabbed from the URL of the program
# listing page on publicradiofan.com
#
# the title format of each stream in the playlists is "Dy HHHH-hhhh (ABCD)"
# where
# Dy is a two letter abbreviation for day
# HHHH is the start time for the show
# hhhh is the end time for the show
# and (ABCD) is the call letters for the radio station
#
# v1.0 12.16.04 bklaas
#
#############################

$|=1;

die "usage: prfan_playlist.pl <playlist title> <programid>\n\nExample: ./prfan_playlist.pl waitwaitdonttellme 46\n" unless $ARGV[1];
my $playlist_title = shift;
my $programid = shift;

use LWP::UserAgent;
use HTTP::Cookies;
use HTML::TokeParser;

my $timezone_value = translate_timezones($timezone);
my $ua = LWP::UserAgent->new();
my $resp;

set_cookie();
get_html();
my $playlist = parse_html();
write_playlist($playlist);
clean_up();

sub set_cookie {
print "setting timezone cookie with publicradiofan.com...";
#$ua->cookie_jar(HTTP::Cookies->new({ file => "/tmp/cookietest" }, autosave => 1,));
$ua->cookie_jar({});
$resp = $ua->post("http://www.publicradiofan.com/cgi-bin/settings.pl",
{
"timezone" => "$timezone_value",
"timefmt" => "24",
"submit" => "submit choices"}
);
print "DONE\n";
}

sub get_html {
print "getting html page from publicradiofan.com...";
$resp = $ua->get("http://www.publicradiofan.com/cgi-bin/program.pl?programid=$programid");
my $content = $resp->content();
open(HTML,">$playlist_title.html") or die "couldn't write to $playlist_title.html: $!";
print HTML $content;
close(HTML);
print "DONE\n";
}

sub parse_html {
print "parsing html...";
my $p = HTML::TokeParser->new("$playlist_title.html");
my $time; my $day; my $station; my @playlist;
while (my $token = $p->get_tag("a", "nobr", "td")) {
my $text = $p->get_trimmed_text("/a", "/td");
my $url = $token->[1]{href} || "-";
if ($token->[1]{class} eq "C1") {
$station = $text;
} elsif ($token->[1]{class} eq "bct") {
if ($text =~ /\d\d\d*\-\d\d\d*/) {
$time = $text;
} elsif ($text =~ /^[A-Z][a-z]$/) {
$day = $text;
}
} elsif ($text =~ /\[MP3\]/) {
$url =~ s/http:\/\/www\.publicradiofan\.com.*?(http:\/\/.*)/$1/g;
my %temp = ();
$temp{'title'} = $day . " " . "$time" . "($station)";
$temp{'url'} = $url;
#print "$station\n";
push @playlist, \%temp;
}
}
print "DONE\n";
return \@playlist;
}

sub write_playlist {
mkdir ($playlist_title, 0777);
print "Writing playlist to $playlist_title.pls...";
my $list = shift;
for my $ref (@$list) {
open(PLAYLIST,">$playlist_title/$ref->{'title'}.pls") or die "couldn't write to $playlist_title.pls: $!";
my $size = 1;
print PLAYLIST "[playlist]
NumberOfEntries=$size
";

my $i = 1;
print PLAYLIST "File$i=$ref->{'url'}\n";
print PLAYLIST "Title$i=$ref->{'title'}\n";
print PLAYLIST "Length$i=-1\n";
#print STDOUT "$ref->{'title'}\n";
$i++;

print PLAYLIST "Version=2\n";
close(PLAYLIST);
}

print "DONE\n";
}

sub clean_up {
print "Removing temporary files...";
#remove the html file
unlink("$playlist_title.html");
print "DONE\n";
}
sub translate_timezones {

my $myzone = shift;
my %timezones = (
"Hawaii" => "-10,HST,-10,HST,Hawaii",
"Alaska" => "-9,AST,-8,ADT,Alaska",
"Pacific" => "-8,PST,-7,PDT,Pacific",
"Arizona" => "-7,MST,-7,MST,Arizona",
"Mountain" => "-7,MST,-6,MDT,Mountain",
"Saskatchewan" => "-6,CST,-6,CST,Saskatchewan",
"Central" => "-6,CST,-5,CDT,Central",
"Indiana" => "-5,EST,-5,EST,Indiana",
"Eastern" => "-5,EST,-4,EDT,Eastern",
"Atlantic" => "-4,AST,-3,ADT,Atlantic",
"UTC or GMT" => "0,UTC,0,UTC,UTC",
"Britain" => "0,GMT,1,BST,Britain",
"Central Europe" => "1,CET,2,CEST,Central Europe",
"UTC-12" => "-12,(UTC-12),-12,(UTC-12),(UTC-12)",
"UTC-11" => "-11,(UTC-11),-11,(UTC-11),(UTC-11)",
"UTC-10" => "-10,(UTC-10),-10,(UTC-10),(UTC-10)",
"UTC-9" => "-9,(UTC-9),-9,(UTC-9),(UTC-9)",
"UTC-8" => "-8,(UTC-8),-8,(UTC-8),(UTC-8)",
"UTC-7" => "-7,(UTC-7),-7,(UTC-7),(UTC-7)",
"UTC-6" => "-6,(UTC-6),-6,(UTC-6),(UTC-6)",
"UTC-5" => "-5,(UTC-5),-5,(UTC-5),(UTC-5)",
"UTC-4" => "-4,(UTC-4),-4,(UTC-4),(UTC-4)",
"UTC-3" => "-3,(UTC-3),-3,(UTC-3),(UTC-3)",
"UTC-2" => "-2,(UTC-2),-2,(UTC-2),(UTC-2)",
"UTC-1" => "-1,(UTC-1),-1,(UTC-1),(UTC-1)",
"UTC" => "0,UTC,0,UTC,UTC",
"UTC+1" => "1,(UTC+1),1,(UTC+1),(UTC+1)",
"UTC+2" => "2,(UTC+2),2,(UTC+2),(UTC+2)",
"UTC+3" => "3,(UTC+3),3,(UTC+3),(UTC+3)",
"UTC+4" => "4,(UTC+4),4,(UTC+4),(UTC+4)",
"UTC+5" => "5,(UTC+5),5,(UTC+5),(UTC+5)",
"UTC+6" => "6,(UTC+6),6,(UTC+6),(UTC+6)",
"UTC+7" => "7,(UTC+7),7,(UTC+7),(UTC+7)",
"UTC+8" => "8,(UTC+8),8,(UTC+8),(UTC+8)",
"UTC+9" => "9,(UTC+9),9,(UTC+9),(UTC+9)",
"UTC+10" => "10,(UTC+10),10,(UTC+10),(UTC+10)",
"UTC+11" => "11,(UTC+11),11,(UTC+11),(UTC+11)",
"UTC+12" => "12,(UTC+12),12,(UTC+12),(UTC+12)",
"UTC+13" => "13,(UTC+13),13,(UTC+13),(UTC+13)"
);
return $timezones{$myzone};

}

Victor Brilon
2004-12-16, 18:02
Ben,

Great idea, thanks for coming up with this.

FYI, to save you the headache of doing all the timezone stuff manually,
there's a module called Time::Zone which will automagically determine
the system's local time zone and return the GMT offset in seconds via
its tz_local_offse() method. Didn't know if you knew about it, thought
it'd be worth mentioning just in case.

Victor
Ben Klaas wrote:
> hola slim community--
>
> I'm fairly new to the forum (and to the glory that is the squeezebox),
> and wanted to try to contribute something of value to establish good
> will to all, peace on earth, and all of that.
>
> I am a fan of a few particular shows on public radio. On my local public
> radio station, they either a) aren't available or b) aren't on at a
> convenient time. There is an excellent website called
> http://publicradiofan.com that catalogs when shows are on various
> internet streams.
>
> To make a program's chronological/station listings easily accessible via
> playlist(s), I wrote a perl script that scrapes the info for a given
> public radio program and creates a set of .pls files that have titles
> indiciative of the time slot and what radio station it is (the reason I
> didn't use just one .pls is that I believe I uncovered a sorting bug in
> slimserver; workaround is to use multiple pls files within a subdir).
> The timezone is set by a cookie that is configurable in my script.
>
> So, the end result, for example:
> on Saturday at 4pm, I want to listen to "Wait Wait Don't Tell Me". I go
> to my squeezebox remote or slimserver browser, and it's
> Browse Playlists--> Wait Wait --> (scroll to) Sa 1600-1700 (KIPO) -->
> <play>.
>
> the script is attached. use/edit/play with/wrap it as you see fit-- I
> wrote it in Linux, but I don't think there is anything in the script
> that should be platform-specific...should work in OSX or a perl-capable
> Windows machine.
>
> comments welcome.
>
> cheers,
> #!/ben
> JAPH
>
> p.s., this is the bug I opened about playlist titles--
> http://bugs.slimdevices.com/show_bug.cgi?id=735
>
>
> ------------------------------------------------------------------------
>
> #!/usr/bin/perl
>
> use strict;
>
> # look through the timezones at the bottom of this script for the one that matches yours
> my $timezone = "Central";
>
> #############################
> # prfan_playlist.pl
> #
> # this script is designed to scrape information from
> # dynamically generated program listings on publicradiofan.com
> # and create <playlist title>/Dy HHHH-hhhh.pls files of mp3 stream URLs
> #
> # currently requires the user to know the program id, grabbed from the URL of the program
> # listing page on publicradiofan.com
> #
> # the title format of each stream in the playlists is "Dy HHHH-hhhh (ABCD)"
> # where
> # Dy is a two letter abbreviation for day
> # HHHH is the start time for the show
> # hhhh is the end time for the show
> # and (ABCD) is the call letters for the radio station
> #
> # v1.0 12.16.04 bklaas
> #
> #############################
>
> $|=1;
>
> die "usage: prfan_playlist.pl <playlist title> <programid>\n\nExample: ./prfan_playlist.pl waitwaitdonttellme 46\n" unless $ARGV[1];
> my $playlist_title = shift;
> my $programid = shift;
>
> use LWP::UserAgent;
> use HTTP::Cookies;
> use HTML::TokeParser;
>
> my $timezone_value = translate_timezones($timezone);
> my $ua = LWP::UserAgent->new();
> my $resp;
>
> set_cookie();
> get_html();
> my $playlist = parse_html();
> write_playlist($playlist);
> clean_up();
>
> sub set_cookie {
> print "setting timezone cookie with publicradiofan.com...";
> #$ua->cookie_jar(HTTP::Cookies->new({ file => "/tmp/cookietest" }, autosave => 1,));
> $ua->cookie_jar({});
> $resp = $ua->post("http://www.publicradiofan.com/cgi-bin/settings.pl",
> {
> "timezone" => "$timezone_value",
> "timefmt" => "24",
> "submit" => "submit choices"}
> );
> print "DONE\n";
> }
>
> sub get_html {
> print "getting html page from publicradiofan.com...";
> $resp = $ua->get("http://www.publicradiofan.com/cgi-bin/program.pl?programid=$programid");
> my $content = $resp->content();
> open(HTML,">$playlist_title.html") or die "couldn't write to $playlist_title.html: $!";
> print HTML $content;
> close(HTML);
> print "DONE\n";
> }
>
> sub parse_html {
> print "parsing html...";
> my $p = HTML::TokeParser->new("$playlist_title.html");
> my $time; my $day; my $station; my @playlist;
> while (my $token = $p->get_tag("a", "nobr", "td")) {
> my $text = $p->get_trimmed_text("/a", "/td");
> my $url = $token->[1]{href} || "-";
> if ($token->[1]{class} eq "C1") {
> $station = $text;
> } elsif ($token->[1]{class} eq "bct") {
> if ($text =~ /\d\d\d*\-\d\d\d*/) {
> $time = $text;
> } elsif ($text =~ /^[A-Z][a-z]$/) {
> $day = $text;
> }
> } elsif ($text =~ /\[MP3\]/) {
> $url =~ s/http:\/\/www\.publicradiofan\.com.*?(http:\/\/.*)/$1/g;
> my %temp = ();
> $temp{'title'} = $day . " " . "$time" . "($station)";
> $temp{'url'} = $url;
> #print "$station\n";
> push @playlist, \%temp;
> }
> }
> print "DONE\n";
> return \@playlist;
> }
>
> sub write_playlist {
> mkdir ($playlist_title, 0777);
> print "Writing playlist to $playlist_title.pls...";
> my $list = shift;
> for my $ref (@$list) {
> open(PLAYLIST,">$playlist_title/$ref->{'title'}.pls") or die "couldn't write to $playlist_title.pls: $!";
> my $size = 1;
> print PLAYLIST "[playlist]
> NumberOfEntries=$size
> ";
>
> my $i = 1;
> print PLAYLIST "File$i=$ref->{'url'}\n";
> print PLAYLIST "Title$i=$ref->{'title'}\n";
> print PLAYLIST "Length$i=-1\n";
> #print STDOUT "$ref->{'title'}\n";
> $i++;
>
> print PLAYLIST "Version=2\n";
> close(PLAYLIST);
> }
>
> print "DONE\n";
> }
>
> sub clean_up {
> print "Removing temporary files...";
> #remove the html file
> unlink("$playlist_title.html");
> print "DONE\n";
> }
> sub translate_timezones {
>
> my $myzone = shift;
> my %timezones = (
> "Hawaii" => "-10,HST,-10,HST,Hawaii",
> "Alaska" => "-9,AST,-8,ADT,Alaska",
> "Pacific" => "-8,PST,-7,PDT,Pacific",
> "Arizona" => "-7,MST,-7,MST,Arizona",
> "Mountain" => "-7,MST,-6,MDT,Mountain",
> "Saskatchewan" => "-6,CST,-6,CST,Saskatchewan",
> "Central" => "-6,CST,-5,CDT,Central",
> "Indiana" => "-5,EST,-5,EST,Indiana",
> "Eastern" => "-5,EST,-4,EDT,Eastern",
> "Atlantic" => "-4,AST,-3,ADT,Atlantic",
> "UTC or GMT" => "0,UTC,0,UTC,UTC",
> "Britain" => "0,GMT,1,BST,Britain",
> "Central Europe" => "1,CET,2,CEST,Central Europe",
> "UTC-12" => "-12,(UTC-12),-12,(UTC-12),(UTC-12)",
> "UTC-11" => "-11,(UTC-11),-11,(UTC-11),(UTC-11)",
> "UTC-10" => "-10,(UTC-10),-10,(UTC-10),(UTC-10)",
> "UTC-9" => "-9,(UTC-9),-9,(UTC-9),(UTC-9)",
> "UTC-8" => "-8,(UTC-8),-8,(UTC-8),(UTC-8)",
> "UTC-7" => "-7,(UTC-7),-7,(UTC-7),(UTC-7)",
> "UTC-6" => "-6,(UTC-6),-6,(UTC-6),(UTC-6)",
> "UTC-5" => "-5,(UTC-5),-5,(UTC-5),(UTC-5)",
> "UTC-4" => "-4,(UTC-4),-4,(UTC-4),(UTC-4)",
> "UTC-3" => "-3,(UTC-3),-3,(UTC-3),(UTC-3)",
> "UTC-2" => "-2,(UTC-2),-2,(UTC-2),(UTC-2)",
> "UTC-1" => "-1,(UTC-1),-1,(UTC-1),(UTC-1)",
> "UTC" => "0,UTC,0,UTC,UTC",
> "UTC+1" => "1,(UTC+1),1,(UTC+1),(UTC+1)",
> "UTC+2" => "2,(UTC+2),2,(UTC+2),(UTC+2)",
> "UTC+3" => "3,(UTC+3),3,(UTC+3),(UTC+3)",
> "UTC+4" => "4,(UTC+4),4,(UTC+4),(UTC+4)",
> "UTC+5" => "5,(UTC+5),5,(UTC+5),(UTC+5)",
> "UTC+6" => "6,(UTC+6),6,(UTC+6),(UTC+6)",
> "UTC+7" => "7,(UTC+7),7,(UTC+7),(UTC+7)",
> "UTC+8" => "8,(UTC+8),8,(UTC+8),(UTC+8)",
> "UTC+9" => "9,(UTC+9),9,(UTC+9),(UTC+9)",
> "UTC+10" => "10,(UTC+10),10,(UTC+10),(UTC+10)",
> "UTC+11" => "11,(UTC+11),11,(UTC+11),(UTC+11)",
> "UTC+12" => "12,(UTC+12),12,(UTC+12),(UTC+12)",
> "UTC+13" => "13,(UTC+13),13,(UTC+13),(UTC+13)"
> );
> return $timezones{$myzone};
>
> }
>
>
> ------------------------------------------------------------------------
>
>

2004-12-16, 19:06
I will give this a try and let you know how it goes.

I have been using the PublicRadioFan.com Plugin for a while now, and love
it. I really wish that was in active development, other then kdf updating
it to work with the 5.0 release, it seems to have been abandoned. I'd say
it works 99% of the time without much trouble, but that 1% generally
brings down the slimserver. One feature that I would like to see added to
the plugin is to have it report the bitrate for the station when showing
the station call letters.

I am working on my Perl skills as we speak, but I still think that
reworking and trouble shooting a established web based plugin is beyond me
for the time being. If you would like I could post the plugin for you to
look at and and maybe together we could get it back in to development.

Let me know

Tom

> hola slim community--
>
> I'm fairly new to the forum (and to the glory that is the squeezebox),
> and wanted to try to contribute something of value to establish good
> will to all, peace on earth, and all of that.
>
> I am a fan of a few particular shows on public radio. On my local public
> radio station, they either a) aren't available or b) aren't on at a
> convenient time. There is an excellent website called
> http://publicradiofan.com that catalogs when shows are on various
> internet streams.
>
> To make a program's chronological/station listings easily accessible via
> playlist(s), I wrote a perl script that scrapes the info for a given
> public radio program and creates a set of .pls files that have titles
> indiciative of the time slot and what radio station it is (the reason I
> didn't use just one .pls is that I believe I uncovered a sorting bug in
> slimserver; workaround is to use multiple pls files within a subdir).
> The timezone is set by a cookie that is configurable in my script.
>
> So, the end result, for example:
> on Saturday at 4pm, I want to listen to "Wait Wait Don't Tell Me". I go
> to my squeezebox remote or slimserver browser, and it's
> Browse Playlists--> Wait Wait --> (scroll to) Sa 1600-1700 (KIPO) -->
> <play>.
>
> the script is attached. use/edit/play with/wrap it as you see fit-- I
> wrote it in Linux, but I don't think there is anything in the script
> that should be platform-specific...should work in OSX or a perl-capable
> Windows machine.
>
> comments welcome.
>
> cheers,
> #!/ben
> JAPH
>
> p.s., this is the bug I opened about playlist titles--
> http://bugs.slimdevices.com/show_bug.cgi?id=735

kdf
2004-12-17, 01:50
There was a NPRRadioFan plugin posted here a long time ago, by a user. It
simply logged in and listed current streams. I still have a copy lying around
which may or may not still work. If there is interest, I can mail it to
anyone, or post online for a while.

-kdf

Quoting Victor Brilon <victor (AT) victorland (DOT) com>:

> Ben,
>
> Great idea, thanks for coming up with this.
>
> FYI, to save you the headache of doing all the timezone stuff manually,
> there's a module called Time::Zone which will automagically determine
> the system's local time zone and return the GMT offset in seconds via
> its tz_local_offse() method. Didn't know if you knew about it, thought
> it'd be worth mentioning just in case.
>
> Victor
> Ben Klaas wrote:
> > hola slim community--
> >
> > I'm fairly new to the forum (and to the glory that is the squeezebox),
> > and wanted to try to contribute something of value to establish good
> > will to all, peace on earth, and all of that.
> >
> > I am a fan of a few particular shows on public radio. On my local public
> > radio station, they either a) aren't available or b) aren't on at a
> > convenient time. There is an excellent website called
> > http://publicradiofan.com that catalogs when shows are on various
> > internet streams.
> >
> > To make a program's chronological/station listings easily accessible via
> > playlist(s), I wrote a perl script that scrapes the info for a given
> > public radio program and creates a set of .pls files that have titles
> > indiciative of the time slot and what radio station it is (the reason I
> > didn't use just one .pls is that I believe I uncovered a sorting bug in
> > slimserver; workaround is to use multiple pls files within a subdir).
> > The timezone is set by a cookie that is configurable in my script.
> >
> > So, the end result, for example:
> > on Saturday at 4pm, I want to listen to "Wait Wait Don't Tell Me". I go
> > to my squeezebox remote or slimserver browser, and it's
> > Browse Playlists--> Wait Wait --> (scroll to) Sa 1600-1700 (KIPO) -->
> > <play>.
> >
> > the script is attached. use/edit/play with/wrap it as you see fit-- I
> > wrote it in Linux, but I don't think there is anything in the script
> > that should be platform-specific...should work in OSX or a perl-capable
> > Windows machine.
> >
> > comments welcome.
> >
> > cheers,
> > #!/ben
> > JAPH
> >
> > p.s., this is the bug I opened about playlist titles--
> > http://bugs.slimdevices.com/show_bug.cgi?id=735
> >
> >
> > ------------------------------------------------------------------------
> >
> > #!/usr/bin/perl
> >
> > use strict;
> >
> > # look through the timezones at the bottom of this script for the one that
> matches yours
> > my $timezone = "Central";
> >
> > #############################
> > # prfan_playlist.pl
> > #
> > # this script is designed to scrape information from
> > # dynamically generated program listings on publicradiofan.com
> > # and create <playlist title>/Dy HHHH-hhhh.pls files of mp3 stream URLs
> > #
> > # currently requires the user to know the program id, grabbed from the URL
> of the program
> > # listing page on publicradiofan.com
> > #
> > # the title format of each stream in the playlists is "Dy HHHH-hhhh (ABCD)"
> > # where
> > # Dy is a two letter abbreviation for day
> > # HHHH is the start time for the show
> > # hhhh is the end time for the show
> > # and (ABCD) is the call letters for the radio station
> > #
> > # v1.0 12.16.04 bklaas
> > #
> > #############################
> >
> > $|=1;
> >
> > die "usage: prfan_playlist.pl <playlist title> <programid>\n\nExample:
> ./prfan_playlist.pl waitwaitdonttellme 46\n" unless $ARGV[1];
> > my $playlist_title = shift;
> > my $programid = shift;
> >
> > use LWP::UserAgent;
> > use HTTP::Cookies;
> > use HTML::TokeParser;
> >
> > my $timezone_value = translate_timezones($timezone);
> > my $ua = LWP::UserAgent->new();
> > my $resp;
> >
> > set_cookie();
> > get_html();
> > my $playlist = parse_html();
> > write_playlist($playlist);
> > clean_up();
> >
> > sub set_cookie {
> > print "setting timezone cookie with publicradiofan.com...";
> > #$ua->cookie_jar(HTTP::Cookies->new({ file => "/tmp/cookietest" },
> autosave => 1,));
> > $ua->cookie_jar({});
> > $resp = $ua->post("http://www.publicradiofan.com/cgi-bin/settings.pl",
> > {
> > "timezone" => "$timezone_value",
> > "timefmt" => "24",
> > "submit" => "submit choices"}
> > );
> > print "DONE\n";
> > }
> >
> > sub get_html {
> > print "getting html page from publicradiofan.com...";
> > $resp =
>
$ua->get("http://www.publicradiofan.com/cgi-bin/program.pl?programid=$programid");
> > my $content = $resp->content();
> > open(HTML,">$playlist_title.html") or die "couldn't write to
> $playlist_title.html: $!";
> > print HTML $content;
> > close(HTML);
> > print "DONE\n";
> > }
> >
> > sub parse_html {
> > print "parsing html...";
> > my $p = HTML::TokeParser->new("$playlist_title.html");
> > my $time; my $day; my $station; my @playlist;
> > while (my $token = $p->get_tag("a", "nobr", "td")) {
> > my $text = $p->get_trimmed_text("/a", "/td");
> > my $url = $token->[1]{href} || "-";
> > if ($token->[1]{class} eq "C1") {
> > $station = $text;
> > } elsif ($token->[1]{class} eq "bct") {
> > if ($text =~ /\d\d\d*\-\d\d\d*/) {
> > $time = $text;
> > } elsif ($text =~ /^[A-Z][a-z]$/) {
> > $day = $text;
> > }
> > } elsif ($text =~ /\[MP3\]/) {
> > $url =~ s/http:\/\/www\.publicradiofan\.com.*?(http:\/\/.*)/$1/g;
> > my %temp = ();
> > $temp{'title'} = $day . " " . "$time" . "($station)";
> > $temp{'url'} = $url;
> > #print "$station\n";
> > push @playlist, \%temp;
> > }
> > }
> > print "DONE\n";
> > return \@playlist;
> > }
> >
> > sub write_playlist {
> > mkdir ($playlist_title, 0777);
> > print "Writing playlist to $playlist_title.pls...";
> > my $list = shift;
> > for my $ref (@$list) {
> > open(PLAYLIST,">$playlist_title/$ref->{'title'}.pls") or die "couldn't
> write to $playlist_title.pls: $!";
> > my $size = 1;
> > print PLAYLIST "[playlist]
> > NumberOfEntries=$size
> > ";
> >
> > my $i = 1;
> > print PLAYLIST "File$i=$ref->{'url'}\n";
> > print PLAYLIST "Title$i=$ref->{'title'}\n";
> > print PLAYLIST "Length$i=-1\n";
> > #print STDOUT "$ref->{'title'}\n";
> > $i++;
> >
> > print PLAYLIST "Version=2\n";
> > close(PLAYLIST);
> > }
> >
> > print "DONE\n";
> > }
> >
> > sub clean_up {
> > print "Removing temporary files...";
> > #remove the html file
> > unlink("$playlist_title.html");
> > print "DONE\n";
> > }
> > sub translate_timezones {
> >
> > my $myzone = shift;
> > my %timezones = (
> > "Hawaii" => "-10,HST,-10,HST,Hawaii",
> > "Alaska" => "-9,AST,-8,ADT,Alaska",
> > "Pacific" => "-8,PST,-7,PDT,Pacific",
> > "Arizona" => "-7,MST,-7,MST,Arizona",
> > "Mountain" => "-7,MST,-6,MDT,Mountain",
> > "Saskatchewan" => "-6,CST,-6,CST,Saskatchewan",
> > "Central" => "-6,CST,-5,CDT,Central",
> > "Indiana" => "-5,EST,-5,EST,Indiana",
> > "Eastern" => "-5,EST,-4,EDT,Eastern",
> > "Atlantic" => "-4,AST,-3,ADT,Atlantic",
> > "UTC or GMT" => "0,UTC,0,UTC,UTC",
> > "Britain" => "0,GMT,1,BST,Britain",
> > "Central Europe" => "1,CET,2,CEST,Central
> Europe",
> > "UTC-12" =>
> "-12,(UTC-12),-12,(UTC-12),(UTC-12)",
> > "UTC-11" =>
> "-11,(UTC-11),-11,(UTC-11),(UTC-11)",
> > "UTC-10" =>
> "-10,(UTC-10),-10,(UTC-10),(UTC-10)",
> > "UTC-9" => "-9,(UTC-9),-9,(UTC-9),(UTC-9)",
> > "UTC-8" => "-8,(UTC-8),-8,(UTC-8),(UTC-8)",
> > "UTC-7" => "-7,(UTC-7),-7,(UTC-7),(UTC-7)",
> > "UTC-6" => "-6,(UTC-6),-6,(UTC-6),(UTC-6)",
> > "UTC-5" => "-5,(UTC-5),-5,(UTC-5),(UTC-5)",
> > "UTC-4" => "-4,(UTC-4),-4,(UTC-4),(UTC-4)",
> > "UTC-3" => "-3,(UTC-3),-3,(UTC-3),(UTC-3)",
> > "UTC-2" => "-2,(UTC-2),-2,(UTC-2),(UTC-2)",
> > "UTC-1" => "-1,(UTC-1),-1,(UTC-1),(UTC-1)",
> > "UTC" => "0,UTC,0,UTC,UTC",
> > "UTC+1" => "1,(UTC+1),1,(UTC+1),(UTC+1)",
> > "UTC+2" => "2,(UTC+2),2,(UTC+2),(UTC+2)",
> > "UTC+3" => "3,(UTC+3),3,(UTC+3),(UTC+3)",
> > "UTC+4" => "4,(UTC+4),4,(UTC+4),(UTC+4)",
> > "UTC+5" => "5,(UTC+5),5,(UTC+5),(UTC+5)",
> > "UTC+6" => "6,(UTC+6),6,(UTC+6),(UTC+6)",
> > "UTC+7" => "7,(UTC+7),7,(UTC+7),(UTC+7)",
> > "UTC+8" => "8,(UTC+8),8,(UTC+8),(UTC+8)",
> > "UTC+9" => "9,(UTC+9),9,(UTC+9),(UTC+9)",
> > "UTC+10" => "10,(UTC+10),10,(UTC+10),(UTC+10)",
> > "UTC+11" => "11,(UTC+11),11,(UTC+11),(UTC+11)",
> > "UTC+12" => "12,(UTC+12),12,(UTC+12),(UTC+12)",
> > "UTC+13" => "13,(UTC+13),13,(UTC+13),(UTC+13)"
> > );
> > return $timezones{$myzone};
> >
> > }
> >
> >
> > ------------------------------------------------------------------------
> >
> >

Thomas B. Malsbury
2004-12-17, 05:53
I would love to take a look at it and see if it is still functional.
You can email it to me off list, or just let me know where you can post it.

Tom

ps: You must have the most complete plugin collection, and the a great
ability to recall them all.

kdf wrote:

>There was a NPRRadioFan plugin posted here a long time ago, by a user. It
>simply logged in and listed current streams. I still have a copy lying around
>which may or may not still work. If there is interest, I can mail it to
>anyone, or post online for a while.
>
>-kdf
>
>

Ben Klaas
2004-12-17, 14:10
hi Victor-

thanks for the tip-- I looked into the timezone module, and I can't see
how it could reasonably fit into this script...I'm using the timezone
information to set a cookie for publicradiofan.com, and it expects data
like "-6,CST,-5,CDT,Central" for time zone information. I setup the hash
at the end of the script to make it easier, but considering I'm still
requiring the user to look up the program id for a given show, the
manual entry (once) of the user's time zone seemed okay to me...

#!/ben

Victor Brilon wrote:
> Ben,
>
> Great idea, thanks for coming up with this.
>
> FYI, to save you the headache of doing all the timezone stuff manually,
> there's a module called Time::Zone which will automagically determine
> the system's local time zone and return the GMT offset in seconds via
> its tz_local_offse() method. Didn't know if you knew about it, thought
> it'd be worth mentioning just in case.
>
> Victor
> Ben Klaas wrote:
>
>> hola slim community--
>>
>> I'm fairly new to the forum (and to the glory that is the squeezebox),
>> and wanted to try to contribute something of value to establish good
>> will to all, peace on earth, and all of that.
>>
>> I am a fan of a few particular shows on public radio. On my local
>> public radio station, they either a) aren't available or b) aren't on
>> at a convenient time. There is an excellent website called
>> http://publicradiofan.com that catalogs when shows are on various
>> internet streams.
>>
>> To make a program's chronological/station listings easily accessible
>> via playlist(s), I wrote a perl script that scrapes the info for a
>> given public radio program and creates a set of .pls files that have
>> titles indiciative of the time slot and what radio station it is (the
>> reason I didn't use just one .pls is that I believe I uncovered a
>> sorting bug in slimserver; workaround is to use multiple pls files
>> within a subdir). The timezone is set by a cookie that is configurable
>> in my script.
>>
>> So, the end result, for example:
>> on Saturday at 4pm, I want to listen to "Wait Wait Don't Tell Me". I
>> go to my squeezebox remote or slimserver browser, and it's
>> Browse Playlists--> Wait Wait --> (scroll to) Sa 1600-1700 (KIPO) -->
>> <play>.
>>
>> the script is attached. use/edit/play with/wrap it as you see fit-- I
>> wrote it in Linux, but I don't think there is anything in the script
>> that should be platform-specific...should work in OSX or a
>> perl-capable Windows machine.
>>
>> comments welcome.
>>
>> cheers,
>> #!/ben
>> JAPH
>>
>> p.s., this is the bug I opened about playlist titles--
>> http://bugs.slimdevices.com/show_bug.cgi?id=735
>>
>>
>> ------------------------------------------------------------------------
>>
>> #!/usr/bin/perl
>>
>> use strict;
>>
>> # look through the timezones at the bottom of this script for the one
>> that matches yours
>> my $timezone = "Central";
>> #############################
>> # prfan_playlist.pl
>> #
>> # this script is designed to scrape information from
>> # dynamically generated program listings on publicradiofan.com
>> # and create <playlist title>/Dy HHHH-hhhh.pls files of mp3 stream URLs
>> # # currently requires the user to know the program id, grabbed from
>> the URL of the program
>> # listing page on publicradiofan.com
>> #
>> # the title format of each stream in the playlists is "Dy HHHH-hhhh
>> (ABCD)"
>> # where
>> # Dy is a two letter abbreviation for day
>> # HHHH is the start time for the show
>> # hhhh is the end time for the show
>> # and (ABCD) is the call letters for the radio station
>> #
>> # v1.0 12.16.04 bklaas
>> #
>> #############################
>>
>> $|=1;
>>
>> die "usage: prfan_playlist.pl <playlist title> <programid>\n\nExample:
>> ./prfan_playlist.pl waitwaitdonttellme 46\n" unless $ARGV[1];
>> my $playlist_title = shift;
>> my $programid = shift;
>>
>> use LWP::UserAgent;
>> use HTTP::Cookies;
>> use HTML::TokeParser;
>>
>> my $timezone_value = translate_timezones($timezone);
>> my $ua = LWP::UserAgent->new();
>> my $resp;
>>
>> set_cookie();
>> get_html();
>> my $playlist = parse_html();
>> write_playlist($playlist);
>> clean_up();
>>
>> sub set_cookie {
>> print "setting timezone cookie with publicradiofan.com...";
>> #$ua->cookie_jar(HTTP::Cookies->new({ file => "/tmp/cookietest"
>> }, autosave => 1,));
>> $ua->cookie_jar({});
>> $resp =
>> $ua->post("http://www.publicradiofan.com/cgi-bin/settings.pl",
>> {
>> "timezone" => "$timezone_value",
>> "timefmt" => "24",
>> "submit" => "submit choices"}
>> );
>> print "DONE\n";
>> }
>>
>> sub get_html {
>> print "getting html page from publicradiofan.com...";
>> $resp =
>> $ua->get("http://www.publicradiofan.com/cgi-bin/program.pl?programid=$programid");
>>
>> my $content = $resp->content();
>> open(HTML,">$playlist_title.html") or die "couldn't write to
>> $playlist_title.html: $!";
>> print HTML $content;
>> close(HTML);
>> print "DONE\n";
>> }
>>
>> sub parse_html {
>> print "parsing html...";
>> my $p = HTML::TokeParser->new("$playlist_title.html");
>> my $time; my $day; my $station; my @playlist;
>> while (my $token = $p->get_tag("a", "nobr", "td")) {
>> my $text = $p->get_trimmed_text("/a", "/td");
>> my $url = $token->[1]{href} || "-";
>> if ($token->[1]{class} eq "C1") {
>> $station = $text;
>> } elsif ($token->[1]{class} eq "bct") {
>> if ($text =~ /\d\d\d*\-\d\d\d*/) {
>> $time = $text;
>> } elsif ($text =~ /^[A-Z][a-z]$/) {
>> $day = $text;
>> }
>> } elsif ($text =~ /\[MP3\]/) {
>> $url =~
>> s/http:\/\/www\.publicradiofan\.com.*?(http:\/\/.*)/$1/g;
>> my %temp = ();
>> $temp{'title'} = $day . " " . "$time" . "($station)";
>> $temp{'url'} = $url;
>> #print "$station\n";
>> push @playlist, \%temp;
>> }
>> }
>> print "DONE\n";
>> return \@playlist;
>> }
>>
>> sub write_playlist {
>> mkdir ($playlist_title, 0777);
>> print "Writing playlist to $playlist_title.pls...";
>> my $list = shift;
>> for my $ref (@$list) {
>> open(PLAYLIST,">$playlist_title/$ref->{'title'}.pls") or die
>> "couldn't write to $playlist_title.pls: $!";
>> my $size = 1;
>> print PLAYLIST "[playlist]
>> NumberOfEntries=$size
>> ";
>>
>> my $i = 1;
>> print PLAYLIST "File$i=$ref->{'url'}\n";
>> print PLAYLIST "Title$i=$ref->{'title'}\n";
>> print PLAYLIST "Length$i=-1\n";
>> #print STDOUT "$ref->{'title'}\n";
>> $i++;
>>
>> print PLAYLIST "Version=2\n";
>> close(PLAYLIST);
>> }
>>
>> print "DONE\n";
>> }
>>
>> sub clean_up {
>> print "Removing temporary files...";
>> #remove the html file
>> unlink("$playlist_title.html");
>> print "DONE\n";
>> }
>> sub translate_timezones {
>>
>> my $myzone = shift;
>> my %timezones = (
>> "Hawaii" => "-10,HST,-10,HST,Hawaii",
>> "Alaska" => "-9,AST,-8,ADT,Alaska",
>> "Pacific" => "-8,PST,-7,PDT,Pacific",
>> "Arizona" => "-7,MST,-7,MST,Arizona",
>> "Mountain" => "-7,MST,-6,MDT,Mountain",
>> "Saskatchewan" => "-6,CST,-6,CST,Saskatchewan",
>> "Central" => "-6,CST,-5,CDT,Central",
>> "Indiana" => "-5,EST,-5,EST,Indiana",
>> "Eastern" => "-5,EST,-4,EDT,Eastern",
>> "Atlantic" => "-4,AST,-3,ADT,Atlantic",
>> "UTC or GMT" => "0,UTC,0,UTC,UTC",
>> "Britain" => "0,GMT,1,BST,Britain",
>> "Central Europe" => "1,CET,2,CEST,Central
>> Europe",
>> "UTC-12" =>
>> "-12,(UTC-12),-12,(UTC-12),(UTC-12)",
>> "UTC-11" =>
>> "-11,(UTC-11),-11,(UTC-11),(UTC-11)",
>> "UTC-10" =>
>> "-10,(UTC-10),-10,(UTC-10),(UTC-10)",
>> "UTC-9" => "-9,(UTC-9),-9,(UTC-9),(UTC-9)",
>> "UTC-8" => "-8,(UTC-8),-8,(UTC-8),(UTC-8)",
>> "UTC-7" => "-7,(UTC-7),-7,(UTC-7),(UTC-7)",
>> "UTC-6" => "-6,(UTC-6),-6,(UTC-6),(UTC-6)",
>> "UTC-5" => "-5,(UTC-5),-5,(UTC-5),(UTC-5)",
>> "UTC-4" => "-4,(UTC-4),-4,(UTC-4),(UTC-4)",
>> "UTC-3" => "-3,(UTC-3),-3,(UTC-3),(UTC-3)",
>> "UTC-2" => "-2,(UTC-2),-2,(UTC-2),(UTC-2)",
>> "UTC-1" => "-1,(UTC-1),-1,(UTC-1),(UTC-1)",
>> "UTC" => "0,UTC,0,UTC,UTC",
>> "UTC+1" => "1,(UTC+1),1,(UTC+1),(UTC+1)",
>> "UTC+2" => "2,(UTC+2),2,(UTC+2),(UTC+2)",
>> "UTC+3" => "3,(UTC+3),3,(UTC+3),(UTC+3)",
>> "UTC+4" => "4,(UTC+4),4,(UTC+4),(UTC+4)",
>> "UTC+5" => "5,(UTC+5),5,(UTC+5),(UTC+5)",
>> "UTC+6" => "6,(UTC+6),6,(UTC+6),(UTC+6)",
>> "UTC+7" => "7,(UTC+7),7,(UTC+7),(UTC+7)",
>> "UTC+8" => "8,(UTC+8),8,(UTC+8),(UTC+8)",
>> "UTC+9" => "9,(UTC+9),9,(UTC+9),(UTC+9)",
>> "UTC+10" =>
>> "10,(UTC+10),10,(UTC+10),(UTC+10)",
>> "UTC+11" =>
>> "11,(UTC+11),11,(UTC+11),(UTC+11)",
>> "UTC+12" =>
>> "12,(UTC+12),12,(UTC+12),(UTC+12)",
>> "UTC+13" =>
>> "13,(UTC+13),13,(UTC+13),(UTC+13)"
>> );
>> return $timezones{$myzone};
>>
>> }
>>
>>
>> ------------------------------------------------------------------------
>>
>>