# This 'now playing' script for Irssi will display the last song
# scrobbled to your last.fm account in any channel or query window.
# This script is triggered by using the /np command inside Irssi channel
# or query windows.
#
# This script depends on the WWW::Curl and XML::Simple Perl modules, which can be
# installed with CPAN.
#
# =-=-=-= Installation/Usage Instructions: =-=-=-=
#
# 1) Run this script, either by placing it in ~/.irssi/scripts and
# typing '/run lastfm' in Irssi, or by placing it in ~/.irssi/scripts/autorun
# and simply starting Irssi.
#
# 2) Set up the script for use inside Irssi.
#
#	To set your last.fm username:
#		/set lastfm_username your_username
#
#	To customize the text that appears between your nick and the song information
#   (default is "is now playing"):
#
# 		/set lastfm_prefix is grooving to
#
# 3) Use /np inside Irssi channel or query windows.
#
# =-=-=-= Changelog: =-=-=-=
#
# Version 0.3 (1/11/2009):
#		Initial public release. Updated to use version 2.0 of the last.fm API. Now
#		uses WWW::Curl instead of wget, and XML::Simple instead of sed.
# Version 0.2 (7/26/2008):
#		Private development release. Updated parsing-related code to reflect changes
#		in the last.fm API.
# Version 0.1 (Date Unknown):
#		Initial private development release. Uses version 1.0 of the last.fm API. Uses
#		wget to retreive plain text files containing last songs played, and sed to
#		isolate song information.

use Irssi;
use Irssi::Irc;
use WWW::Curl::Easy;
use XML::Simple;
use vars qw($VERSION %IRSSI);
$VERSION = "0.3";
%IRSSI = (
	authors		=> "Josh Dick",
	contact		=> "josh@joshdick.net",
	name		=> "lastfm",
	description	=> "Displays the last song scrobbled to your last.fm account in the active channel or query window.",
	license		=> "GNU GPL v3 or later",
	url         => "http://joshdick.net/index.php?section=programs&subsection=plugins",
	changed		=> "Sunday, January 11, 2009"
	);

	my $lastfm_username_placeholder = '%%_UNSET_%%';

	sub main {
		my ($data, $server, $witem) = @_;
		my $prefix = Irssi::settings_get_str('lastfm_prefix');
		my $lastfm_username = Irssi::settings_get_str('lastfm_username');

		# If the script was invoked in a valid context...
		if ($witem && ($witem->{type} eq 'CHANNEL' || $witem->{type} eq 'QUERY'))
		{
			# Make sure the user has actually set their last.fm username.
			if ($lastfm_username eq $lastfm_username_placeholder)
			{
				$witem->print("To use the lastfm now playing script, please set your lastfm username by typing '/set lastfm_username your_username'.");
			}
			else
			{
				# Get ready to attempt to fetch XML using the last.fm API.
				my $curl = new WWW::Curl::Easy;

				$curl->setopt(CURLOPT_HEADER, 0);
				$curl->setopt(CURLOPT_FOLLOWLOCATION, 1);
				$curl->setopt(CURLOPT_URL, 'http://ws.audioscrobbler.com/2.0/user/' . $lastfm_username . '/recenttracks.xml');
				my $response_body;

				open (my $fileb, ">", \$response_body);
				$curl->setopt(CURLOPT_WRITEDATA,$fileb);

				# Perform the HTTP request.
				my $retcode = $curl->perform;

				# Make sure the request completed successfully.
				if ($retcode == 0)
				{
					# Now that we know the request completed successfully, make sure the response was valid.
					my $response_code = $curl->getinfo(CURLINFO_HTTP_CODE);

					# If the response was valid, parse the received XML and output the song information to the current window as a /me action.
					if ($response_code == 200)
					{
						# Parse the XML.
						my $xs = XML::Simple->new(ForceArray => 1);
						my $xml_ref = $xs->XMLin($response_body);
						my $artist = $xml_ref->{track}[0]->{artist}[0]->{content};
						my $title = $xml_ref->{track}[0]->{name}[0];

						# Construct a /me command containing the song information and execute it in the current window.
						my $npcommand = "me ". $prefix . " " . $artist . " - " . $title;
						$witem->command($npcommand);
					}
					# The response was invalid. Let the user know.
					else
					{
						$witem->print('ERROR: The last.fm API returned an HTTP response code of ' . $response_code . '.');
						$witem->print("Is your specified username '" . $lastfm_username . "' valid?");
						$witem->print("If not, please set your lastfm username by typing '/set lastfm_username your_username'.");
					}
				}
				# The request didn't complete successfully. Let the user know.
				else 
				{
					$witem->print("ERROR: Can't connect to last.fm! [" . $curl->strerror($retcode)." ($retcode)]");
				}
			}
		}
	}

	Irssi::settings_add_str($IRSSI{name}, 'lastfm_prefix', 'is now playing');
	Irssi::settings_add_str($IRSSI{name}, 'lastfm_username', $lastfm_username_placeholder);
	Irssi::command_bind('np', 'main');
