#!/usr/bin/perl -w
#
# iTunes.pl - Control iTunes from X-Chat Aqua and show what music you like.
#
# Author : Tego <Sorry, no email = no spam>
# Date : 2003-07-29
# Last update : 2003-08-19
#
# Usage:
# - Just load it (Mac OS X X-Chat Aqua users: put in plugins folder)
# - Command is /iTunes followed by an instruction (show|next|prev)
# - 0.0.2 : added commands : status, play, stop, pause
# added 'me' trigger to make output go to user instead of channel for certain commands.
# - 0.0.3 : fixed volume setting when using integer values: it always changed to one less then asked
# added command to add/remove button from X-Chat Aqua interface
# - 0.0.4 : added ratings for 'show' - will give other text when rating is defined for track
# - 0.0.5 : changed the way buttons are added or removed (now uses internal commands), following the X-Chat Aqua author's advice
# put all ratings in a config file in ~/.xchat2/iTunes.pl.conf
# it is now possible to have multiple texts for the same rating
# added <length> variable
# changed way data is in config
# added 'set' command to change config settings
# fixed 'missing value' bug with radio streams
$debug = 0;
my $script_name = "iTunes.pl";
my $script_version = '0.0.5';
my $pkg = __PACKAGE__;
$bold = chr(2);
$plain = chr(15);
$backred = chr(3)."4,0";
my $get_track = qq(tell application "iTunes"
set this_name to the name of current track
set this_artist to the artist of current track
set this_album to the album of current track
set this_rating to the rating of current track
set this_length to the time of current track
end tell
return this_name & tab & this_artist & tab & this_rating & tab & this_length);
$get_track = join ("' -e '",$get_track);
IRC::register($script_name,$script_version, "", "");
IRC::print(chr(3)."1,14"."\cB$script_name\cB version".chr(3)."11,14 $script_version ".chr(3)."1,14"
. "by Tego loading...\n");
IRC::add_command_handler("iTunes", "${pkg}::iTunes");
&loadratings;
sub loadratings(){
@ratings = ("is hearing to <track> in iTunes, by <player>","thinks the song he is listening to (<track>) is really not good. Maybe <player> has made better ones!?","says he has listened to better songs than <track> from <player>","lets you know the song <track> is actually quite good (<player>)","thinks the song he is listening to (<player>\'s <track>) is really good","considers the song <track> to be wonderful","considers the song <track> above any rating");
$home = qx(osascript -e 'return system attribute "HOME"');
undef(%rating);
chomp($home);
if(-e "$home/.xchat2/iTunes.pl.conf"){
open(FILE,"$home/.xchat2/iTunes.pl.conf");
$temp = <FILE>;
if(!($temp =~ /^\$/)){
&update_config;
}
require("$home/.xchat2/iTunes.pl.conf");
foreach(@ratings){
if($_ eq ""){ next; }
($rank,$msg) = split(/\t/,$_);
chomp($msg);
push(@{$rating[$rank]},$msg);
}
close FILE;
}else{
open(FILE,">$home/.xchat2/iTunes.pl.conf");
print FILE "\$conf_version = 1;\n";
print FILE "\$operate_quiet = 0; # Work in quiet mode, displays less on screen\n";
print FILE "\@ratings = (";
for($i=0;$i<=$#ratings;$i++){
$ratings[$i] =~ s/\"/\\\"/g;
$ratings[$i] =~ s/\'/\\\'/g;
print FILE "\'$i\t$ratings[$i]\',\n";
push(@{$rating[$i]},$ratings[$i]);
}
print FILE "\"\")\;";
close FILE;
}
IRC::print($backred.$bold."iTunes.pl config file (re)loaded");
}
sub update_config(){
IRC::print($backred.$bold."UPDATING iTunes.pl.conf");
@temp = ();
while(<FILE>){
chomp;
$_ =~ s/\"/\\\"/g;
$_ =~ s/\'/\\\'/g;
push(@temp,$_);
}
open(FILE,">$home/.xchat2/iTunes.pl.conf");
print FILE "\$conf_version = 1;\n";
print FILE "\$operate_quiet = 0; # Work in quiet mode, displays less on screen\n";
print FILE "\@ratings = (\'";
print FILE join("\',\n\'",@temp);
print FILE "\')\;\n";
close FILE;
return 1;
}
sub output(){
($what,$where) = @_;
$what =~ s/\t/ \- /g;
if($where =~ /^me$/i){
IRC::print(chr(3)."1,8".$what.chr(15));
}else{
IRC::command("/me $what");
}
}
sub iTunes(){
$options = shift;
$options =~ s/\s+/ /g;
($todo,$where,$rest) = split(/\s/,$options);
if($todo =~ /^show$/i){
&get_track_name;
}elsif($todo =~ /^next$/i){
&next_track;
}elsif($todo =~ /^prev/i){
&prev_track;
}elsif($todo =~ /^status/i){
&status;
}elsif($todo =~ /^play$/i){
&play;
}elsif($todo =~ /^stop/i){
&stop;
}elsif($todo =~ /^pause/i){
&pause;
}elsif($todo =~ /^rewind/i){
&rewind;
}elsif($todo =~ /^volume/i){
&volume;
}elsif($todo =~ /^button/i){
&toggle_BTN;
}elsif($todo =~ /^set/i){
&toggle_variable;
}elsif($todo =~ /^reload/i){
&loadratings;
}elsif($todo =~ /^help/i){
&help;
}else{
IRC::print($backred.$bold."iTunes plugin didn't understand your command.");
IRC::print($backred.$plain."type '/iTunes help' for more info");
}
return 1;
}
sub volume{
if($where =~ /^up$/i){
$volume = "sound volume + 11";
}elsif($where =~ /^down$/i){
$volume = "sound volume - 9";
}elsif($where =~ /^\d+$/){
$volume = $where + 1;
}else{
IRC::print($backred."Sorry, bad volume value (you can use 'up', 'down' and a number between 0 and 100)");
return 1;
}
my $next_track = qq(tell application "iTunes"
set sound volume to $volume
return sound volume
end tell);
$next_track = join ("' -e '",$next_track);
$track = qx(osascript -e '$next_track');
$track =~ s/\n//g;
$where = $rest;
if($where =~ /me/i){
$track = "iTunes sound volume is on $track/100";
}else{
$track = "has iTunes sound volume on $track/100";
}
unless($operate_quiet){
&output($track,$where);
}
}
sub get_track_name {
$temp = qx(osascript -e '$get_track');
$temp =~ s/\n//g;
if($debug){
IRC::print($get_track);
IRC::print($track);
}
$temp =~ s/\tmissing value\t/\t\t/g;
$temp =~ s/\tmissing value$/\t/g;
($track,$player,$rate,$duration) = split(/\t/,$temp);
if($player eq ""){
@temp = ("some unknown musician","some undefined musician","someone");
$player = $temp[int(rand(@temp))];
}
if($track =~ /^\s*$/){
if($where =~ /me/i){
$track = "nothing at all";
}else{
$track = "is listening to nothing at all";
}
}else{
if($where =~ /me/i){
$track = $track." [by $player]";
}else{
$rate--;
$rate = ($rate+(20-$rate%20))/20;
@temp = @{$rating[$rate]};
$line = $temp[int(rand(@temp))];
$line =~ s/<track>/$track/gi;
$line =~ s/<player>/$player/gi;
$line =~ s/<length>/$duration/gi;
$track = $line;
}
}
&output($track,$where);
}
sub status {
my $next_track = qq(tell application "iTunes"
return player state
end tell);
$next_track = join ("' -e '",$next_track);
$track = qx(osascript -e '$next_track');
$track =~ s/\n//g;
if($where =~ /me/i){
$track = "iTunes is $track";
}else{
$track = "has iTunes $track";
}
&output($track,$where);
}
sub play {
my $next_track = qq(tell application "iTunes"
play
end tell);
$next_track = join ("' -e '",$next_track);
$track = qx(osascript -e '$next_track');
$track = qx(osascript -e '$get_track');
$track =~ s/\n//g;
unless($operate_quiet){
$track =~ s/\t/ \- /g;
IRC::print($track);
}
}
sub rewind {
my $next_track = qq(tell application "iTunes"
back track
end tell);
$next_track = join ("' -e '",$next_track);
$track = qx(osascript -e '$next_track');
unless($operate_quiet){
$track = qx(osascript -e '$get_track');
$track =~ s/\n//g;
$track =~ s/\t/ \- /g;
IRC::print($track);
}
}
sub stop {
my $next_track = qq(tell application "iTunes"
stop
end tell);
$next_track = join ("' -e '",$next_track);
$track = qx(osascript -e '$next_track');
unless($operate_quiet){
IRC::print("iTunes playing stopped");
}
}
sub pause {
my $next_track = qq(tell application "iTunes"
playpause
return player state
end tell);
$next_track = join ("' -e '",$next_track);
$track = qx(osascript -e '$next_track');
unless($operate_quiet){
IRC::print("iTunes $track");
}
}
sub next_track {
my $next_track = qq(tell application "iTunes"
next track
end tell);
$next_track = join ("' -e '",$next_track);
$track = qx(osascript -e '$next_track');
unless($operate_quiet){
$track = qx(osascript -e '$get_track');
$track =~ s/\n//g;
$track =~ s/\t/ \- /g;
IRC::print($track);
}
}
sub prev_track {
my $next_track = qq(tell application "iTunes"
previous track
end tell);
$next_track = join ("' -e '",$next_track);
$track = qx(osascript -e '$next_track');
unless($operate_quiet){
$track = qx(osascript -e '$get_track');
$track =~ s/\n//g;
$track =~ s/\t/ \- /g;
IRC::print($track);
}
}
sub toggle_BTN {
$home = qx(osascript -e 'return system attribute "HOME"');
chomp($home);
$btn_string = "\nNAME iTunes\nCMD iTunes show\n";
open(FILE,"$home/.xchat2/buttons.conf");
@files = <FILE>;
$file = join("",@files);
if(grep(/$btn_string/,$file)){
IRC::print($backred."iTunes button removed from interface");
IRC::command("/DELBUTTON iTunes");
}else{
IRC::command("/ADDBUTTON iTunes iTunes show");
IRC::print($backred."iTunes button added to interface - please restart X-Chat Aqua");
}
}
sub help {
IRC::print(chr(3)."1,8"."iTunes $script_version plugin commands ");
IRC::print(" /iTunes show : displays playing track *");
IRC::print(" /iTunes play : start playing track");
IRC::print(" /iTunes stop : stop playing track");
IRC::print(" /iTunes pause : toggle play/iTunes pause");
IRC::print(" /iTunes status : display iTunes playing status *");
IRC::print(" /iTunes next : move to next track");
IRC::print(" /iTunes prev : move to previous track");
IRC::print(" /iTunes rewind : go back to beginning of the current track");
IRC::print(" /iTunes volume : set & display sound volume in iTunes (not system volume) *");
IRC::print(" options : up, down or a number from 0 till 100");
IRC::print(" /iTunes button : adds or removes button from X-Chat interface to do /iTunes show");
IRC::print(" [Needs restart of X-Chat Aqua to appear]");
IRC::print(" /iTunes set : change variable values in config file (eg \'/iTunes set operate_quiet 0\')");
IRC::print(" /iTunes reload : reload config file");
IRC::print(" /iTunes help : shows this help text");
IRC::print("* : in these commands you can add ' me' in the end to have output only at own display");
IRC::print(chr(3)."1,8"." ");
}
sub toggle_variable {
$var = $where;
$value = $rest;
$set = 0;
if(($var eq "") or ($value eq "")){ IRC::print($backred."Syntax: /iTunes set <variable> <value>"); return; }
open(FILE,"$home/.xchat2/iTunes.pl.conf");
@lines = <FILE>;
close FILE;
open(FILE,">$home/.xchat2/iTunes.pl.conf");
foreach(@lines){
if($_ =~ /^\$($var)\s*=/i){
$set = 1;
print FILE "\$$1 = $value\;\n";
}else{
print FILE $_;
}
}
close FILE;
if($set){
IRC::print($backred."iTunes: $var set to $value");
${$var} = $value;
}else{
IRC::print($backred."iTunes: $var is not a known variable or can't be user-defined.");
}
}
1;
# end