1#!/usr/bin/perl 2use strict; 3use Music::Audioscrobbler::MPD; 4use Getopt::Long; 5use Proc::Daemon; 6use Pod::Usage; 7our $VERSION = 0.08; 8our %cloptions = (); 9our $clopts = [ 10 [ "daemonize" => \$cloptions{daemonize}, 11 "Run as a daemon" 12 ], 13 [ "pidfile=s" => \$cloptions{pidfile}, 14 "Specify a pid file for daemon mode" 15 ], 16 [ "logfile=s" => \$cloptions{logfile}, 17 "Specify a log file. Set to STDERR for terminal output" 18 ], 19 [ "monitor" => \$cloptions{monitor}, 20 "print program status while running" 21 ], 22 [ "verbose=i" => \$cloptions{verbose}, 23 "Set program verbosity level" 24 ], 25 [ "config=s" => \$cloptions{optionfile}, 26 "Set config file location" 27 ], 28 [ "help" => \&help, 29 "Your lookin' at it." 30 ], 31 [ "longhelp" => \&longhelp, 32 "Help file with more BS." 33 ], 34 [ "version" => sub { print "musicmpdscrobble version: $VERSION\nMusic::Audioscsrobbler::MPD version: ", $Music::Audioscrobbler::MPD::VERSION, "\n"; exit 254 }, 35 "Print version number and exit." 36 ], 37 [ "kill" => \$cloptions{kill}, 38 "Kill a running daemon" 39 ], 40 ]; 41 42Getopt::Long::GetOptions( map { $_->[0] => $_->[1] } @{$clopts} ); 43 44# Need to ignore undefind options. 45our %options = (); 46while ( my ( $k, $v ) = each %cloptions ) { 47 if ( defined $v ) { 48 $options{$k} = $v; 49 } 50} 51 52#if ( $options{logfile} eq "STDERR" ) { 53# $options{logfile} = undef; 54#} 55 56my $mpds = Music::Audioscrobbler::MPD->new( \%options ); 57 58 59if ( $options{kill}) { 60 killdaemon(); 61} 62 63if ( $options{"daemonize"} ) { 64 print STDERR "Running as a daemon... (pid $$ > ", $mpds->options->{"pidfile"},")\n"; 65 Proc::Daemon::Init; 66 local *PIDFILE; 67 if ( open( PIDFILE, ">", $mpds->options->{"pidfile"} ) ) { 68 print PIDFILE $$; 69 close PIDFILE; 70 } 71} 72 73$SIG{INT} = sub { $mpds->status(0, "Process killed"); exit 1 }; 74 75$mpds->monitor_mpd(); 76exit; 77 78sub help { 79 foreach ( @{$clopts} ) { 80 printf "--%-15s %s\n", $_->[0], $_->[2]; 81 } 82 exit 1; 83} 84 85sub longhelp { 86 pod2usage( -verbose => 2 ); 87} 88 89sub killdaemon { 90 local *PIDFILE; 91 open( PIDFILE, "<", $mpds->options->{"pidfile"} ) or die "Couldn't open pid file: $!"; 92 my $pid = <PIDFILE>; 93 close(PIDFILE); 94 if ($pid) { 95 if ( kill 2, $pid ) { 96 unlink $mpds->options->{pidfile}; 97 exit; 98 } 99 } 100 print STDERR "Failed to kill anything\n"; 101 exit 1; 102} 103 104 105__END__ 106 107=head1 musicmpdscrobble 108 109musicmpdscrobble - Perl script to submit tracks to Last.FM from mpd 110 111=head1 SYNOPSIS 112 113 musicmpdscrobble --monitor --logfile=STDERR 114 115 This runs musicmpdscrobble in the foreground and prints a nifty little monitor summery. 116 117=head1 OPTIONS 118 119=over 4 120 121=item --daemonize 122 123Run as a daemon. You should set the logfile option if you use this! 124Note: There is no way to set this option in the config file. 125 126=item --kill 127 128Kill running process if daemonized. Should work, let me know if it doesn't. 129 130=item --pidfile 131 132Specify a pid file for daemon mode. 133 134=item --logfile="/path/to/log/file" 135 136Specify a log file. Set to STDERR or STDOUT for terminal output. 137 138=item --monitor 139 140Print program status while running. Don't use in daemon mode! 141 142=item --verbose=n 143 144Set verbosity level of the log (0 through 4) 145 146=item --config 147 148Set path to config file (default /etc/musicmpdscrobble.conf) 149 150=item --help 151 152Print summery of command options and quit. 153 154=item longhelp 155 156Print this. 157 158=back 159 160=head1 CONFIGURATION FILE 161 162The configuration file is a perl program. It is evaluated after the script runs, so it is a good idea to run perl -c /etc/musicmpdscrobble.conf 163after editing it. Here is an example config file: 164 165 #!/usr/bin/perl 166 # Example musicmpdscrobble.conf file 167 # 168 # This is a perl file. It must be a hash reference. This means a comma between 169 # key / value pairs. 170 # 171 # To check syntax run perl -c musicmpdscrobble.conf 172 # 173 174 { 175 # LastFM Username and Password 176 lastfm_username => "riemann42", 177 #lastfm_password => "secret", 178 lastfm_md5password => "md5 hash of password here", 179 180 # Specify mpd_server info. Default is MPD_HOST or localhost 181 # mpd_server => 'localhost', 182 183 # Specify mpd_port. Default is MPD_PORT or 6600 184 # mpd_port => 6600, 185 186 # If you have installed the Music::Tag module, set to 1. 187 musictag => 0, 188 189 # If you want information from musictag to overwrite info from mpd (not recommended) set to 1 190 musictag_overwrite => 0, 191 192 # Specify the music_directory path for MPD. 193 music_directory => "/mnt/media/music/MP3s", 194 195 # Set the verbosity level. 1 through 4. 3 is a good medium 196 verbose => 3, 197 198 #Specify the logfile path 199 logfile => "/var/log/musicmpdscrobble.log", 200 201 #Specify the file to write the pid to. 202 pidfile => "/var/run/musicmpdscrobble.pid", 203 204 #Specify the file to store pending scrobbles in. 205 scrobble_queue => "/var/lib/musicmpdscrobble.queue", 206 207 #Automatically get missing mbid info: 208 # get_mbid_from_mb => 1, 209 210 # list of programs to run when a song start. Accepts the following variables: 211 # 212 # %f filename 213 # %a Artist 214 # %b Album 215 # %t Title 216 # %l Length of track in seconds 217 # %n Track number 218 # %m mbid of track 219 # 220 # runonstart => [], 221 222 # list of programs to run after song submit. 223 # runonsubmit => [], 224 }; 225 226=head1 About Music::Tag Module 227 228The music tag module is framework for reading tag files. It requires several modules be installed to work correctly. 229 230The major reason to install this is that it will read info from the filename and not just from the MPD database. You can, 231therefore, submit the MusicBrainz ID, if it is available via Music::Tag. You want to submit the MusicBrainz Track ID because 232at it (currently) makes you immune from last.fm spam protection and helps improve the last.fm database. 233 234=head1 CLIENT ID 235 236This is BETA code. It does, however, have an official last.fm client id of "MAM." It is not developed by the last.fm folks, and is not guaranteed to even work. 237 238=head1 SEE ALSO 239 240L<Music::Audioscrobbler::MPD>, L<Music::Tag> 241 242=head1 COPYRIGHT 243 244Copyright (c) 2007 Edward J. Allen III 245 246Some code and inspiration from L<Audio::MPD> Copyright (c) 2005 Tue Abrahamsen, Copyright (c) 2006 Nicholas J. Humfrey, Copyright (c) 2007 Jerome Quelin 247 248=head1 LICENSE 249 250This program is free software; you can redistribute it and/or modify 251it under the same terms as Perl itself, either: 252 253a) the GNU General Public License as published by the Free 254Software Foundation; either version 1, or (at your option) any 255later version, or 256 257b) the "Artistic License" which comes with Perl. 258 259This program is distributed in the hope that it will be useful, 260but WITHOUT ANY WARRANTY; without even the implied warranty of 261MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either 262the GNU General Public License or the Artistic License for more details. 263 264You should have received a copy of the Artistic License with this 265Kit, in the file named "Artistic". If not, I'll be glad to provide one. 266 267You should also have received a copy of the GNU General Public License 268along with this program in the file named "Copying". If not, write to the 269Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 270Boston, MA 02110-1301, USA or visit their web page on the Internet at 271http://www.gnu.org/copyleft/gpl.html. 272 273 274=cut 275