# Scrobble Swipper is a program to rip a user's last.fm scrobbles. # Copyright (C) 2008 Brian West # # This program (Scrobble Swipper) is free software: you can redistribute it and/or # modify it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # Brian West (Ostien) Contact info - OstienCF@gmail.com # also Ostien on Freenode IRC and most other servers I bum around on. #!/usr/bin/perl -w use warnings; use LWP::UserAgent; my($USR); my($NUMBER); my($max); ## this is no longer needed as a temp folder is unnecesary but for now it will stay #use Cwd; #my($pwd) = cwd; #mkdir($pwd."/temp", 0777) unless (-d $pwd."/temp"); print "\n"; print "**DO NOT** scrobble to last.fm while running Scrobble Swipper!\n\n"; print "Enter Last.fm Username: "; chomp($USR = <>); print "Grabbing user data...for $USR\n"; my($ua) = LWP::UserAgent->new; $ua->agent("ScrobbleSwipper/Beta"); # Create a request my $req = HTTP::Request->new(POST => "http://www.last.fm/user/$USR/tracks/?page=1"); # Pass request to the user agent and get a response back my $res = $ua->request($req); # Check the outcome of the response if ($res->is_success) { $_=$res->content; } else { print $res->status_line, "\n"; exit 0; } if (m|("lastpage">\s*.*?<)|g) { $max = $1; } $max =~ s/\D//g; print "How many pages of data?(total $max): "; chomp($NUMBER = <>); if ($NUMBER!~ /\d/) { print "Defaulting to $max\n"; $NUMBER=$max; } elsif ($NUMBER > $max) { print "You have chosen $NUMBER, more then the maximum amount of pages... **DEFAULTING** to $max\n"; $NUMBER=$max; } else { print "You have chosen to grab $NUMBER page(s) of data\n"; } open FILE, ">", "Chart-$USR.txt" or die $!; #create a brand new file close (FILE); #close that file open FILE, ">>", "Chart-$USR.txt" or die $!; #reopen in append mode my($end)=$NUMBER; # where to start the progress $a=$end; # set our counter variable my($current)=1; # where does progress end print "**NOTICE** This may take several minutes depending on your history...\n"; my $columns = &getTerminalSize()->[1]; $| = 1; while ($a >= $current) { my $retry = 0; while($retry!=-1) { if ($retry==2) { print "Died at page $current out of $NUMBER after $retry tries Exiting...\n"; exit 0; } # Create a request my $req = HTTP::Request->new(POST => "http://www.last.fm/user/$USR/tracks/?page=$current"); # Pass request to the user agent and get a response back my $res = $ua->request($req); # Check the outcome of the response if ($res->is_success) { $_=$res->content; $retry=-1; } else { print $res->status_line, " at page $current out of $NUMBER Retrying...\n"; #Breaks up progress bar on error (will create a separate error report later) $retry++; } } s/.*//gs; #crop s/<\/tbody>.*<\/html>//gs; # crop s/–/\n/g; s/<[^>]*>//g; #remove HTML tags s/^\s+//mg; #remove all lines starting with a space #s/^\n//mg; s/ *$//mg; #remove all space after lines s/\s$//g; #removing ending newline print FILE $_; print FILE "\n"; #Eliminates problem of when a new page is read it starts at the end of the last line of the previous page. Thanks nameless wiki guy! $current++; # Progress Bar my $percent = int((($current-1)/$a*100)); my $pbwidth = $columns-10; my $numhashes = (($current-1)/$a*$pbwidth); printf("\r% -${pbwidth}s% 10s", '#' x $numhashes, "[ " . $percent . "% ]"); sleep 1; } sub getTerminalSize { use Term::ReadKey; my ($w, $h) = GetTerminalSize(STDOUT); if (!defined $w || !defined $h) { die "Cannot determine terminal size!"; } return [$h, $w]; } close (FILE); print "\nChart-$USR.txt now contains specified chart list\n";