#!/usr/bin/perl use strict; use warnings; use XML::Parser; use Getopt::Lucid qw/:all/; use LWP::Simple; use Data::Dumper; use Heap::Simple; use POSIX qw/strftime/; my @friends; sub fparse_start { my $expat = shift; my $elt = shift; if ($elt eq 'user') { my %attr = @_; push @friends, $attr{username}; } } my @tracks; my $insertpoint = -1; sub tparse_start { my $expat = shift; my $elt = shift; my %attr = @_; if ($elt eq 'track') { push @tracks, []; } elsif ($elt eq 'artist') { $insertpoint = 0; } elsif ($elt eq 'name') { $insertpoint = 1; } elsif ($elt eq 'url') { $insertpoint = 2; } elsif ($elt eq 'date') { $tracks[$#tracks]->[3] = $attr{uts}; $insertpoint = 4; } } sub tparse_char { my $expat = shift; my $string = shift; if ($insertpoint > -1) { $tracks[$#tracks]->[$insertpoint] = $string; $insertpoint = -1; } } my @opts = ( Param('user|u')->required, Param('mode|m')->default('text') ); my $opt = Getopt::Lucid->getopt( \@opts ); my $user = $opt->get_user(); my $mode = $opt->get_mode(); my $xp = new XML::Parser(Handlers => {Start => \&fparse_start}); my $content = get("http://ws.audioscrobbler.com/1.0/user/${user}/friends.xml"); if ($content) { $xp->parse($content); my $alltracks = new Heap::Simple(elements => [Array => 4], order => '>'); foreach my $fr(@friends) { my $content = get("http://ws.audioscrobbler.com/1.0/user/${fr}/recenttracks.xml"); if ($content) { my $xp = new XML::Parser(Handlers => { Start => \&tparse_start, Char => \&tparse_char }); $xp->parse($content); foreach my $t(@tracks) { $alltracks->insert([ $fr, @$t ]); } @tracks = (); } else { print "error getting tracks for $fr\n"; } } if ($mode eq 'dump') { for (1..$alltracks->count()) { my $tr = $alltracks->extract_top(); print Dumper(\$tr); } } elsif ($mode eq 'text') { for (1..$alltracks->count()) { my $tr = $alltracks->extract_top(); print "User: $tr->[0]\n"; print "Track: $tr->[1] - $tr->[2]\nDate: $tr->[5]\n"; } } elsif ($mode eq 'rss') { print "\n"; print "\n"; print "\n"; print "en\n"; print "", scalar localtime, "\n"; print "10\n"; print "${user}'s Friends' Recent Tracks\n"; for (1..$alltracks->count()) { print "\n"; my $tr = $alltracks->extract_top(); my $title = "$tr->[0] - $tr->[1] - $tr->[2]"; my $date = strftime '%a, %d %b %Y %H:%M:%S %z', localtime $tr->[4]; print "$title\n"; print "$tr->[3]\n"; print "$date\n"; print "\n"; } print "\n"; print "\n"; } else { print "Undefined output mode $mode\n"; } } else { die "Badness!"; }