#!/usr/bin/perl ############################################## ############################################## # Put here your GoEar's username and password: my $goear_user = "username"; my $goear_pass = "password"; ############################################## ############################################## # # playgoear.pl # A Perl Player for GoEar # (C) Alvaro Marin, , 24 Jun 2007 # # # Redistributable under the terms of the GPL - see # # # playgoear is a command line interface to access # to mp3 streams of goear.com without the flash player # of it's web. # With playgoear and using the username and password # of goear.com, you can listen the songs of your # favorite list on your machine without the web browser # and you can use the randomly playing mode, continuosly, # download them, use the radio...etc. # # CHANGELOG: # # v1.1 - 10 Feb 2010 - adapted to avoid restrictions calling .xml # The .xml call is now redirected to: http://www.goear.com/secure_es.mp3 # Instead of calling the .xml directly, we use http://www.goear.com/hellocalsec.php # # v1.0 - Adapted to the new Goear's web. # - Stable version released! # # v1.0_rc3 - 16 Jun 2009 - Delete songs from your list (rm). # Option to add songs from URL. # # v1.0_rc2 - 26 May 2009 - Local list...no need of GoEar.com, only to download/listen songs :) # There is not need of an username on GoEar.com, only if you want to import your favourite # song list. If you have an account, you can import your favourite list from GoEar.com and # then, use playgoear to search songs on the web, download them, listen... # # v1.0_rc1 - 29 Apr 2009 - Cache for songs. With this feature, the user can cache his songs, # so the reproduction will be faster (goear's website sometimes is so slowly...). # Added to the songs table, "localpath" field to store the path to the local song. # Previous playgoear's databases are obsolete, but they are in other path, so now worry ;) # # Use "-c" option to cache all your songs (this can take a long time). There are 2 modes: # # This option will download all your favourite list's songs to /home/split/.goear/data. # Then you'll listen songs more faster but now, this process can take a while... # Now, choose one option: # "a" to abort and exit. # "b" to download all songs in background without interaction and simultaneously. # "r" to download all songs one by one (slower but recomended). # Option: # # The background, "b", mode will open the same "wget"s that the songs that you have added! # The "r" mode will download songs one by one (slower but recommended option!) # # Now, when the "d" option is choosed in the menu, the song is downloaded to the # cache directory ($HOME/.goear/data/). # # Added "-i" option to show database's information. For example: # # [+] ID: 66 # Title: Inkomunikazioa - Fermin Muguruza # Goear's path: http://www.goear.com/files/sst4/78678b4a761962f14829c69f217ba4b5.mp3 # Local path: /home/split/.goear/data/Inkomunikazioa___Fermin_Muguruza.mp3 # # [+] ID: 178 # Title: nortasuna eraikitzen - berri txarrak # Goear's path: http://www.goear.com/files/mp3files/26102008/840e44d58f99a3d95b2654be621904fa.mp3 # Local path: Not Cached! run playgoear.pl with "-c" option or use "d" option of the menu! # # Added some checks, like that mplayer exists. # # Created a directory to save the songs database and the local cache: # $HOME/.goear/goear.db for the db # $HOME/.goear/data for the local cache # # v0.9 - 28 Apr 2009 - Goear's Radio support ("g" option). # The .xml just has some mp3 streams, so we reproduce them and then, # we get again the .xml. This is an infinite loop until Ctrl+C! :-/ # ToDo: capture keypresses! # The .xml seems to be generated dynamically so sometimes it doesn't exists. We've # to try several times. # # New mplayer options added to avoid noise... -nojoystic -nolirc # # v0.8 - 27 Apr 2009 - Removed the question about download again the favorite list. # # Added a new menu for the result of the searching option. This will allow: # - play randomly through results # - play continuosly through results # (thx to Raul Moreno for request it) # # v0.7 - 15 Mar 2009 - Support for new URL format # # v0.6 - 30 Jan 2009 - Searching on your favourite list feature added! # # v0.5 - 12 Jan 2009 - Support for the new locations of the .xml and .mp3 files # # v0.4 - 26 Mar 2008 - Added checks to see if required Perl modules are installed # # v0.3 - 16 Jul 2007 - Added to mplayer the buffer/cache option to # avoid interrupts when the song is played. # # Added "i" option to see the information of a song: # # Song number to listen or option: i 40 # # Title: Iron Lion Zion - Bob Marley # URL: http://www.goear.com/listen.php?v=f67de6b # MP3: http://www.goear.com/files/sst/ace162817a76f1701daca2a245e4b9ca.mp3 # # v0.2 - 27 Jun 2007 - Added support to download the mp3 file with # "d N" command where "N" is the number of the song. # For example: # # ... # 17: I Should Have Known Better - The Skatalites # r) Play Randomly # c) Play Continuosly # d) Download: "d 5" downloads the 5th song # "d ALL" downloads all the favorite list # e) Exit # Song number to listen or option: d 17 # Downloading "I Should Have Known Better - The Skatalites" in background... # # This option uses wget command to download it and stores # the mp3 file in the directory where playgoear.pl is executed. # # v0.1 - 24 Jun 2007 - First release :) # # use Switch; #use warnings; # Check if all necesary is installed eval 'use LWP::UserAgent'; if ($@) { print "ERROR: LWP::UserAgent Perl module is required!\n"; print "Install it executing: \n perl -MCPAN -e 'install LWP::UserAgent'\n"; exit; } eval 'use HTTP::Request'; if ($@) { print "ERROR: HTTP::Request Perl module is required!\n"; print "Install it executing: \n perl -MCPAN -e 'install HTTP::Request'\n"; exit; } eval 'use HTTP::Cookies'; if ($@) { print "ERROR: HTTP::Cookies Perl module is required!\n"; print "Install it executing: \n perl -MCPAN -e 'install HTTP::Cookies'\n"; exit; } eval 'use DBI'; if ($@) { print "ERROR: DBI Perl module is required!\n"; print "Install it executing: \n perl -MCPAN -e 'install DBI'\n"; exit; } eval 'use DBD::SQLite'; if ($@) { print "ERROR: DBD::SQLite Perl module is required!\n"; print "Install it executing: \n perl -MCPAN -e 'install DBD::SQLite'\n"; exit; } if ( (! -x "/usr/bin/mplayer") && (! -x "/usr/local/bin/mplayer") && (! -x "/usr/sbin/mplayer")){ print "ERROR: mplayer not found! Install this program to use playgoear, please.\n"; exit; } # Global vars my $mplayer="nice -20 mplayer -ao alsa -really-quiet -cache 1024 -cache-min 80 -nojoystick -nolirc "; my $download="0"; my $cache="0"; my $show="0"; # Directory for config & cache/data my $configdir =$ENV{HOME}."/.goear"; # We store the favorite list and the location of each song my $dbfile = "$configdir/goear.db"; # Cache directory my $cachedir = "$configdir/data"; my $dbh; my %songs; # Capture signals to close database $SIG{'INT' } = 'interrupt'; $SIG{'QUIT'} = 'interrupt'; $SIG{'HUP' } = 'interrupt'; $SIG{'TRAP'} = 'interrupt'; $SIG{'ABRT'} = 'interrupt'; $SIG{'STOP'} = 'interrupt'; ############################### Functions # Signal interrupts handle sub interrupt { my($signal)=@_; print "Ok, now exiting...\n"; $dbh->disconnect; print "Bye bye...\n"; exit(1); } ############################### foreach $argnum (0 .. $#ARGV) { switch ($ARGV[$argnum]) { case "-h" { print "\nplaygoear.pl - A Perl Player for goear.com - v1.1\n"; print " Alvaro Marin, , 10 Feb 2010\n\n"; print "Usage: ./playgoear.pl [-c|-d|-s]\n"; print " -c : enable song's cache. This'll download Goear's songs to your disk!\n"; print " -d : download the favorite list using user and password\n"; print " configured in the first lines of playgoear.pl.\n"; print " -s : show database's information.\n\n"; print "playgoear.pl uses mplayer to play the mp3 streams, so install it :)\n\n"; print "Edit this file and add your username and password for goear.com!\n\n"; exit; } case "-c" { $cache = "1"; } case "-d" { $download = "1"; } case "-s" { $show = "1"; } } } # Create directory if not exists if ((! -e $configdir) || (! -w $configdir)){ mkdir $configdir or die("ERROR creating $configdir...\n"); } if ((! -e $cachedir) || (! -w $cachedir)){ mkdir $cachedir or die("ERROR creating $cachedir...\n"); } # Is goear.db file created? if ( ! -f "$dbfile"){ print "Creating $dbfile...from v1.1 of playgoear the .db has another format and path!\n"; $dbh = DBI->connect("dbi:SQLite:dbname=$dbfile","","", {}) or die("ERROR creating goear.db file. Check permissions or disk space.\n"); $dbh->do("CREATE TABLE songs (id INTEGER PRIMARY KEY AUTOINCREMENT, goear_id VARCHAR(10), title VARCHAR(200), path varchar(200), localpath varchar(200))"); print "Good, $dbfile has been created. Connected.\n"; } else { $dbh = DBI->connect("dbi:SQLite:dbname=$dbfile","","", {}) or die("ERROR opening goear.db file. Check permissions or disk space.\n"); print "Good, $dbfile exists. Connected.\n"; } #################### Handle options from cmd #################### # DOWNLOAD OPTION # Connect to Goear.com and download title, path...from the favorite list if ($download) { print "\nWARNING! Your local list will be deleted!\n"; print "Are you sure (y/n)?: "; my $wait=; chomp($wait); if ("$wait" eq "n"){ &interrupt; } print "Connecting to GoEar.com with username \"".$goear_user."\" and downloading the favorite list...\n"; my $sth = $dbh->prepare("DELETE from songs where 1=1"); $sth->execute(); my $goear_url = "http://goear.com/loged.php"; my $ua = LWP::UserAgent->new; $ua->agent("Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.1.6) Gecko/20100202 Iceweasel/3.5.6 (like Firefox/3.5.6; Debian-3.5.6-2)"); $ua->default_header('Referer' => "http://www.goear.com"); $ua->default_header('Host' => 'www.goear.com'); my $referer = "http://goear.com/login.php"; $ua->cookie_jar( HTTP::Cookies->new( 'file' => '/tmp/cookies.lwp', 'autosave' => 1, )); my $req = HTTP::Request->new(POST => 'http://goear.com/loged.php'); $req->content_type('application/x-www-form-urlencoded'); $req->content("user=$goear_user&pwd=$goear_pass"); my $res = $ua->request($req); my $goear_favorites = "http://goear.com/members/myFavorites.php"; my $response = $ua->get( $goear_favorites ); if ($response->is_success) { my @lines = split ("\n",$response->content); # $sth = $dbh->prepare("INSERT INTO songs (id,goear_id,title,path,localpath) values (?,?,?,?,?)"); foreach (@lines){ if ( /listen/){ my @lines2=split("href",$_); foreach (@lines2){ if ( /listen\/([0-9a-zA-Z]{7})\/[0-9a-zA-Z\-]+\>(.*)\<\/a\>/){ my $first=substr($1,0,1); #$url_aux="http://goear.com/files/xmlfiles/$first/secm$1.xml"; $url_aux="http://www.goear.com/hellocalsec.php?f=".$goear_id; $response = $ua->get( "$url_aux"); @lines = split ("\n",$response->content); $goear_id=$1; $goear_title=$2; print "Adding song-> ID: $1 | TITLE: $2\n"; # sanity checks my $sanity_title=$2; $sanity_title=~ s/(\s|-|\/|\\|\$|%|')/_/g; foreach (@lines){ if ( /path="(.*)" bild=/ ){ #$path=$1; #$path=~/http:\/\/www.goear.com.*\/([a-zA-Z0-9]+\.mp3)/; #$sth->execute(NULL,"$goear_id","$goear_title","$1","$cachedir/$sanity_title.mp3"); $sth = $dbh->prepare("INSERT INTO songs (id,goear_id,title,path,localpath) values (NULL,\"$goear_id\",\"$goear_title\",\"$1\",\"$cachedir/$sanity_title.mp3\")"); $sth->execute; } } } } } } $sth->finish; } else { die $response->status_line; } } # CACHE OPTION # Download songs if ($cache){ print "\nThis option will download all your favourite list's songs to $cachedir.\n"; print "Then you'll listen songs more faster but now, this process can take a while...\n"; print "Now, choose one option:\n"; print " \"a\" to abort and exit.\n"; print " \"b\" to download all songs in background without interaction and simultaneously.\n"; print " \"r\" to download all songs one by one (slower but recomended).\n"; print "Option: "; my $wait=; chomp($wait); my $back=""; if ("$wait" eq "b") { $back="-b"; } elsif ("$wait" eq "r"){ $back=""; } else { $dbh->disconnect; exit; } my $sthc = $dbh->prepare("select * from songs"); $sthc->execute(); while ( my ($id,$g_id,$song_title,$song_path,$local_path) = $sthc->fetchrow_array()) { if (-e $local_path){ print "\"$song_title\" already downloaded: $local_path\n"; } else { print "Downloading \"$song_title\" into $local_path...\n"; system("wget $song_path $back -o /dev/null -O \"$local_path\""); } } $sthc->finish; $dbh->disconnect; exit; } # INFORMATION OPTION # Show database's information and exit if ($show){ my $sthi = $dbh->prepare("select * from songs"); $sthi->execute(); my $found_r=0; print "\nDatabase content:\n"; while(my ($id,$goear_id,$goear_title,$goear_path,$localpath) = $sthi->fetchrow) { print "[+] ID: $id \n"; print " Title: $goear_title\n"; print " Goear's path: $goear_path\n"; if (-e "$localpath") { print " Local path: $localpath\n"; }else { print " Local path: Not Cached! run playgoear.pl with \"-c\" option or use \"d\" option of the menu!\n"; } $found_r++; } print "\n\nTotal: $found_r songs\n"; $sthi->finish; $dbh->disconnect; exit; } #################### / Handle options from cmd #################### # Main LOOP while (1){ LOOP:; my $sth2 = $dbh->prepare("select * from songs"); $sth2->execute(); print "\n"; while(my ($id,$goear_id,$goear_title,$goear_path) = $sth2->fetchrow) { print "$id: ".$goear_title."\n"; if ( ! $songs{$goear_title} ) { $songs{$goear_title}=$goear_path; } } if (keys(%songs) == 0){ # print "\nThere are no songs in favorite list. Go to www.goear.com, \n"; # print "login with your user and password and add some songs to it.\n\n"; # print "Then, execute \"playgoear.pl -d\" to download it.\n"; print "\nThere are no songs in your local favorite list. Use the menu to search for your songs on goear.com.\n"; print "If you already have an account on goear.com with a favorite list you can import it, using the option \"-d\"\n\n"; # $dbh->disconnect; # exit; } $sth2->finish(); print "----\n"; print "r) Play Randomly\n"; print "c) Play Continuosly\n"; print "d) Download: \"d 5\" downloads the 5th song.\n \"d ALL\" downloads all the favorite list\n"; print "i) Show song information: \"i 5\"\n"; print "rm) Remove song from your list: \"rm 5\"\n"; print "sl) Search on your list:\n \"sl Berri Txarrak\" searchs for \"Berri Txarrak\" on your list\n"; print "sg) Search on goear.com for a song:\n \"sg Berri Txarrak\" searchs for \"Berri Txarrak\"\n"; print "a) Add a song from URL:\n \"a http://www.goear.com/listen/4a4bb1d/story-of-my-life-social-distorsion\"\n"; print "g) Goear's Radio player.\n"; print "e) Exit\n"; print "----\n"; print "Song number to listen or option: "; my $shell=; chomp($shell); switch ($shell){ case /^[Ee]$/ { print "\nBye bye...\n"; $dbh->disconnect; exit; } case /^[0-9]+$/ { $sth2 = $dbh->prepare("select title,path,localpath from songs where id=?"); $sth2->execute($shell); my ($song_title,$song_path,$localpath) = $sth2->fetchrow_array(); $sth2->finish; if (-e $localpath){ print "\n[+] Playing from cache (press \"q\" to skip): ".$shell." - ".$song_title."\n"; `$mplayer "$localpath"`; } else { print "\n[+] Playing from Goear.com (press \"q\" to skip): ".$shell." - ".$song_title."\n"; `$mplayer "$song_path"`; } } case /^[Rr]$/ { print "\nPlaying Randomly (press \"Ctrl+c\" to exit)...\n"; #foreach $song ( keys(%songs) ){ # print "SONG: $song -> ".$songs{$song}."\n"; #} my @keys = keys %songs; while (1){ $random=$keys[int(rand(keys(%songs)))]; $sth2 = $dbh->prepare("select path,localpath from songs where path=?"); $sth2->execute("$songs{$random}"); my ($song_path,$localpath) = $sth2->fetchrow_array(); $sth2->finish; if (-e $localpath){ print "[+] Playing from cache (press \"q\" to skip): ".$random."\n"; `$mplayer "$localpath"`; } else { print "[+] Playing from Goear.com (press \"q\" to skip): ".$random."\n"; `$mplayer "$songs{$random}"`; } } } case /^[Cc]$/ { print "\nPlay Continuosly (press \"Ctrl+c\" to exit)...\n"; while (1){ $sth2 = $dbh->prepare("select title,path,localpath from songs"); $sth2->execute(); while( ($goear_title,$goear_path,$localpath) = $sth2->fetchrow) { if (-e $localpath){ print "[+] Playing from cache (press \"q\" to skip): $song_title\n"; `$mplayer "$localpath"`; } else { print "[+] Playing from Goear.com (press \"q\" to skip): $song_title\n"; `$mplayer "$goear_path"`; } } $sth2->finish; } } case /^rm ([0-9]+)$/ { $shell =~ /^rm ([0-9]+)$/; my $aux=$1; if ($1=~/[0-9]+/){ $sth2 = $dbh->prepare("delete from songs where id=?"); $sth2->execute($aux); $sth2->finish; } } case /^[Dd] ([0-9]+|ALL)$/ { $shell =~ /^[Dd] (([0-9]+|ALL))$/; my $aux=$1; if ($1=~/[0-9]+/){ $sth2 = $dbh->prepare("select title,path,localpath from songs where id=?"); $sth2->execute($aux); my ($song_title,$song_path,$localpath) = $sth2->fetchrow_array(); print "\nDownloading \"$song_title\" in background to $localpath...\n\n"; `wget $song_path -b --quiet -o /dev/null -O \"$localpath\"`; $sth2->finish; print "Press ENTER to continue...\n"; my $wait=; } elsif ($1 eq "ALL"){ $sth2 = $dbh->prepare("select title,path,localpath from songs"); $sth2->execute(); print "\n"; while ( ($song_title,$song_path,$localpath) = $sth2->fetchrow_array()) { print "Downloading \"$song_title\" in background to $localpath...\n"; `wget $song_path -b --quiet -o /dev/null -O \"$localpath\"`; } print "\n"; print "Press ENTER to continue...\n"; my $wait=; $sth2->finish; } } case /^[iI] ([0-9]+)$/ { $shell =~ /^[iI] ([0-9]+)$/; $sth2 = $dbh->prepare("select goear_id,title,path,localpath from songs where id=?"); $sth2->execute($1); ($goear_id,$song_title,$song_path,$localpath) = $sth2->fetchrow_array(); print "\n\n Title: $song_title\n"; print " URL: http://goear.com/listen.php?v=$goear_id\n"; print " MP3: $song_path\n"; if (-e $localpath){ print " Local: $localpath\n"; } print "\nPress ENTER to continue...\n"; my $wait=; } case /^[gG]$/ { # Radio support http://www.goear.com/radio.php my $ua2 = LWP::UserAgent->new; $ua2->agent("Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.4)"); $ua2->default_header('Referer' => "http://www.goear.com"); $ua2->default_header('Host' => 'www.goear.com'); my $referer2 = "http://goear.com/login.php"; $ua2->cookie_jar( HTTP::Cookies->new( 'file' => '/tmp/cookies2.lwp', 'autosave' => 1, )); my $goear_radio="http://www.goear.com/radio.php"; my $response2 = $ua2->get( $goear_radio ); if ($response2->is_success) { print "\n"; @lines = split ("\n",$response2->content); foreach (@lines){ # if ( /