<?php /* # $Id: $ ############################################################################### # AmaroK_Info: Script for InfoPlug amarok plugin (like xmms-infopipe). # ############################################################################### # Author: Magnus Määttä <magnus@php.net> # ############################################################################### # License: PHP Version 3 # ############################################################################### # Custom String: # # # # %a Album # # %A Artist # # %b Bitrate (Kilo) # # %c Comment # # %f Filename # # %F Sampling Frequency # # %g Genre # # %G Rating (@@* style) # # %i Title (track) # # %p Play count # # %r Release Name # # %R Rating # # %s Status # # %S Score # # %t Current position in track # # %T Track length # # %v Volume # # %y Year # # # *#############################################################################*/ class AmaroK_Info extends PIF_Base { /** * @var array */ public $data = array(); /** * @var string */ public $ret_str = ''; /** * @var object */ public $parent; /** * Class constructor. */ public function __construct($parent) { $this->parent = $parent; irssi_settings_add_str('amarok', 'amarok_info_uri', 'udp://10.0.3.5:5353'); irssi_settings_add_str('amarok', 'amarok_show_method', 'msg'); irssi_settings_add_str('amarok', 'amarok_preset_format', 'short'); irssi_settings_add_str('amarok', 'amarok_custom_format', ''); irssi_settings_add_bool('amarok', 'amarok_print_if_stopped', false); irssi_command_bind("anp", array($this, 'amarok_np')); } /** * /np command - Print help or what you're listening to. * * @return bool */ public function amarok_np($text, $server, $witem) { // Reset array $this->data = array(); $text = trim($text); if ($text == "help") { echo"AmaroK_Info Help:\n============================================\n"; echo "amarok_preset_format values:\n"; echo " short, custom\n"; echo "amarok_show_method values:\n"; echo " msg or action\n"; echo "Custom Format:\n"; echo "%b Bitrate %c Channels\n"; echo "%f Filename %F Sampling Frquency\n"; echo "%g Genre (Req. id3) %i ID3 Title\n"; echo "%p Current playlist entry %P Playlist entries\n"; echo "%r Release Name (if any) %s Status\n"; echo "%t Position in song %T Song length\n"; return true; } // if ($witem && ($witem->type == "CHANNEL" || $witem->type == "QUERY")) { /* foreach(array('target', 'nick', 'name', 'query', 'type', 'window') as $foo) { if (isset($witem->$foo)) { echo "$foo was set (". $witem->$foo .")\n"; } } */ if ($witem) { if (!$this->_getInfo()) { echo "AmaroK_Info: You are not listening to anything right now.\n"; return false; } if (!irssi_settings_get_bool('amarok_print_if_stopped') && (!isset($this->data['Status']) || $this->data['Status'] != 'Playing')) { echo "AmaroK_Info: You are not listening to anything right now.\n"; return false; } if (!$this->_makeInfoString($text)) { echo "AmaroK_Info: You are not listening to anything right now.\n"; return false; } $method = irssi_settings_get_str('amarok_show_method'); if (strtolower($method) == 'msg') { $witem->command("MSG {$witem->name} {$this->ret_str}"); return true; } elseif (strtolower($method) == 'action') { $witem->command("ME {$this->ret_str}"); return true; } else { echo "AmaroK_Info: Unknown amarok_show_method type.\n"; return false; } } else { echo "AmaroK_Info: Not in a query or channel window!\n"; return false; } } /** * * */ protected function _getInfo() { $info_file = irssi_settings_get_str('amarok_info_uri'); $info = explode(':', $info_file); clearstatcache(); $tmp = explode('/', $info[2]); if ($info[0] == "file") { /* Get data from infopipe file. */ if (@file_exists($info[1])) { $file = @file($info[1]); foreach ($file as $line) { $tmp = explode(':', $line, 2); $this->data[$tmp[0]] = trim($tmp[1]); } } else { echo "AmaroK_Info: Couldn't open file $info_file.\n"; return false; } } elseif (($info[0] == 'udp' || $info[0] == 'tcp') && @is_numeric($tmp[0])) { $fp = fsockopen("{$info[0]}:{$info[1]}", $info[2], $errno, $errstr, 5); if (!$fp) { echo "AmaroK_Info: Couldn't connect to {$info[0]}:{$info[1]}:{$tmp[0]}.\n"; echo "AmaroK_Info: Errno $errno: $errstr\n"; return false; } else { stream_set_timeout($fp, 5); /* Send one byte and get data. */ fwrite($fp, "\n", 1); $data = fread($fp, 25000); $status = stream_get_meta_data($fp); if (!$status['timed_out']) { $buf = explode("\n", trim($data)); foreach ($buf as $line) { $tmp = explode(':', $line, 2); if (count($tmp) == 2) $this->data[$tmp[0]] = trim($tmp[1]); @fclose($fp); } } else { echo "AmaroK_Info: Timeout while reading data from socket.\n"; echo "AmaroK_Info: infoplug thread locked up ?\n"; @fclose($fp); return false; } } } else { echo "AmaroK_Info: Unknown method. Use udp://host:port or tcp://host:port or file:/path/file.foo\n"; echo "Info0: {$info[0]} tmp0: {$tmp[0]}\n"; return false; } return true; } /** * * */ protected function _makeInfoString($custom_text = null) { // Check that we have a valid array first. if (!isset($this->data['Artist'])) return false; $preset = irssi_settings_get_str('amarok_preset_format'); if (strlen($custom_text) > 3) $preset = $custom_text; /* Check which preset we should use. */ switch ($preset) { case 'short': $format = "np: %A - %i"; break; case 'medium': $format = "np: %A - %i [%t/%T]"; break; case 'long': $format = "np: %A - %i [%t/%T @ %bkbps]"; break; case 'vlong': $format = "♫ %A - %i [%t/%T ♫ %g ♫ %bkbps ♫ %G]"; break; case 'magnus1': $format = "♫ %A - %i ♫ %r [%t/%T ♫ %g ♫ %bkbps ♫ %G]"; break; case 'custom': $format = irssi_settings_get_str('amarok_custom_format'); break; case 'custom_text': $format = $custom_text; break; default: echo "Amarok_Info: Invalid preset format specified.\n"; return false; break; } /* Get filename */ $tmp = explode('/', $this->data['URL']); $filename = $tmp[count($tmp) - 1]; /* Find release name if any. */ $release = $this->_getReleaseName($tmp); /* Graphical version of rating */ $gfxRating = $this->_getGfxRating(); /* Replacements */ $replace = array('%a', '%A', '%b', '%c', '%f', '%F', '%g', '%G', '%i', '%p', '%r', '%R', '%s', '%S', '%t', '%T', '%v', '%y'); $with = array( @$this->data['Album'], @$this->data['Artist'], @$this->data['Bitrate'], @$this->data['Comment'], $filename, @($this->data['Sample Rate'] / 1000), @$this->data['Genre'], $gfxRating, @$this->data['Title'], @$this->data['Play Count'], $release, @$this->data['Rating'], @$this->data['Status'], @$this->data['Score'], @$this->data['Current Time'], @$this->data['Total Time'], @$this->data['Volume'], @$this->data['Year'], ); $this->ret_str = str_replace($replace, $with, $format); return true; } /** * * */ protected function _getReleaseName($file) { /* Get the name of the release. */ $count = count($file) - 1; $parts = array(); for ($i = 0; $i < $count; $i++) { $len = strlen($file[$i]); $parts[$i] = 0; for ($x = 0; $x < $len; $x++) { /* Correctly named releases should have _ and - instead of spaces. * Lower name "rating" if we find spaces. */ if ($file[$i]{$x} === '_' || $file[$i]{$x} === '-') $parts[$i]++; if ($file[$i]{$x} === ' ' && $parts[$i] > 0) $parts[$i]--; } } arsort($parts, SORT_NUMERIC); $ret = key($parts); /* Atleast 15 chars and 4 _ or - should be in the name. */ if (strlen($file[$ret]) < 15 || $parts[$ret] < 3) { return "NONE"; } else { return $file[$ret]; } } /** * Get graphical representation of rating * * @return string */ protected function _getGfxRating() { $r = @$this->data['Rating']; if (!is_numeric($r) || $r == 0) { return '-'; } // The GFX representation $g = ""; while($r) { if (!($r % 2)) { $g .="*"; $r -= 2; } else { $g .="+"; $r--; } } // String is reversed $g = strrev($g); return $g; } } $_module = 'AmaroK_Info';