#!/usr/bin/perl -wT

# JAmpg123 scrobbler wrapper - andy white 20080614
# you are free to print this out and use it in place of TP

$|=1;

use MP3::Info qw(get_mp3info get_mp3tag);
use Audio::Scrobbler;

my ($pid, $data, $last, %colours, $dataok);
my %keywordmap	= qw(length secs);
my @id_fields	= qw/album title length artist playtime/;
my @colours	= qw(red green yellow blue magenta cyan white);

for (0 .. $#colours) {
        $colour{$colours[$_]} = "\e[" . (31+$_) . 'm';
}

my $scrob = new Audio::Scrobbler(
	cfg=>{
		username => 'ilikebunnies',
		password => 'formydindins',
		progname=> 'roc',
		progver	=>'0.1'}
	);

while (1) {
	$pid = get_player_id();
	$data = get_media_file($pid);

	if (scalar keys %$data) {

		for (keys %$data) {
			$$data{lc($_)} = delete $$data{$_};
		}

		for (keys(%keywordmap)) {
			$$data{$_} = delete $$data{$keywordmap{$_}};
		}

		print "\n$colour{blue}Scrobbling$colour{white}... ";


		$$data{length} = int($$data{length});
		$$data{playtime} = gmtime();

		$data = { map { $_, $$data{$_} } @id_fields };

		$dataok = 1;
		for (@id_fields) {
			$dataok = 0 unless length($$data{$_}||'');
			$$data{$_}||='*** MISSING ***';
			print "'$colour{yellow}$_$colour{white}' =>" .
				" $colour{magenta}$$data{$_}$colour{white} ";
		}

		if ($dataok) {
			if ($scrob->handshake()) {
				if ($scrob->submit($data)) {
					print "$colour{green}Success$colour{white}!";
				} else { print "$colour{red}Scrobbling error? "  . $scrob->err() . $colour{white} }
			} else {
				print "$colour{red}Handshake failed, data not submitted: " . $scrob->err() . $colour{white};
			}
		} else {
			print "$colour{red}Missing metadata: not submitted$colour{white}";
		}
	}

	sleep(20);
}

sub get_player_id {
	my $pid =-1;

	opendir(D,'/proc');

	for (grep /^\d+$/, readdir(D)) {
		open(C,"/proc/$_/cmdline");
		$pid = $_ if ( ((split(/\0/,<C>))[0] || '') =~ /^mpg[13]2[13]$/);
		close(C);
	}

	closedir(D);

	return $pid;
}

sub get_media_file {
	my $pid = shift;
	my $file = undef;

	return if $pid == -1;

	opendir(D,"/proc/$pid/fd");
	for (grep /^\d+$/, readdir(D)) {
		next if $_ < 3;
		$file = $_ if (readlink "/proc/$pid/fd/$_") =~ /\.mp3/i;
	}

	closedir(D);
	$file = int($file||0) ? readlink "/proc/$pid/fd/$file" : '';

	return unless length $file;

	return unless track_change("$pid-$file");

	my %data = %{get_mp3info($file)};
	%data = (%data, %{get_mp3tag($file)});

	return \%data;
}

sub track_change {
	my $cur = shift;
	if ($cur ne ($last||'')) {
		$last = $cur;
		return 1;
	}

	return 0;
}
