author | Dan |
Fri, 25 Apr 2008 12:42:26 -0400 | |
changeset 18 | 69af47034212 |
parent 16 | 23d4cf2f183b |
child 32 | 86140ed9087d |
permissions | -rw-r--r-- |
<?php /** * Utility functions * * Greyhound - real web management for Amarok * Copyright (C) 2008 Dan Fuhry * * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. */ /** * Utility/reporting functions */ /** * Report a fatal error and exit * @param string Error message */ function burnout($msg) { $h = @fopen('php://stderr', 'w'); fwrite($h, "\x1B[31;1m[Greyhound] fatal: \x1B[37;1m"); fwrite($h, "$msg\x1B[0m\n"); fclose($h); exit(1); } /** * Print a stylized status message, compatible with Linux consoles * @param string Status message */ function status($msg) { $h = @fopen('php://stderr', 'w'); $label = ( defined('HTTPD_WS_CHILD') ) ? 'Child ' . substr(strval(getmypid()), -3) : 'Greyhound'; fwrite($h, "\x1B[32;1m[$label] \x1B[32;0m$msg\x1B[0m\n"); fclose($h); } /** * Print a stylized warning message, compatible with Linux consoles * @param string message message */ function warning($msg) { $h = @fopen('php://stderr', 'w'); fwrite($h, "\x1B[33;1m[Greyhound] \x1B[0m\x1B[33mWarning:\x1B[0m $msg\n"); fclose($h); } /** * Performs an action with DCOP. * @param string DCOP component, e.g. player, playlist, playlistbrowser, ... * @param string Action to perform, e.g. stop, play, ... * @param string additional parameters... (NOT IMPLEMENTED) * @return mixed output of DCOP command */ function dcop_action($component, $action) { $tmpfile = tempnam('amaweb', ''); if ( !$tmpfile ) burnout('tempnam() failed us'); system("dcop amarok $component $action > $tmpfile"); $output = @file_get_contents($tmpfile); @unlink($tmpfile); $output = trim($output); // detect type of output if ( $output == 'true' ) return true; else if ( $output == 'false' ) return false; else if ( preg_match('/^-?[0-9]+/', $output) ) return intval($output); else return $output; } /** * Rebuilds the copy of the playlist in RAM */ $playlist_last_md5 = ''; function rebuild_playlist() { // import what we need global $homedir, $playlist; // sync and load the playlist file $playlist_file = dcop_action('playlist', 'saveCurrentPlaylist'); // check MD5 - if it's not changed, exit to save CPU cycles global $playlist_last_md5; $effective_md5 = md5_playlist_file($playlist_file); if ( $playlist_last_md5 == $effective_md5 ) { return true; } status('Rebuilding playlist cache'); $playlist_last_md5 = $effective_md5; // start XML parser try { $xml = simplexml_load_file($playlist_file); } catch ( Exception $e ) { burnout("Caught exception trying to load playlist file:\n$e"); } $attribs = $xml->attributes(); if ( @$attribs['product'] != 'Amarok' ) { burnout('Playlist is not in Amarok format'); } $playlist = array(); foreach ( $xml->children() as $child ) { $attribs = $child->attributes(); $item = array( 'uri' => $attribs['uri'], 'title' => strval($child->Title), 'artist' => strval($child->Artist), 'album' => strval($child->Album), 'length' => seconds_to_str(intval($child->Length)), 'length_int' => intval($child->Length) ); $playlist[] = $item; } } /** * Builds the correct MD5 check for the specified playlist XML file. This is designed to base on the list of actual tracks, disregarding * the rest of the text in the XML file. * @param string Path to playlist * @return string hash */ function md5_playlist_file($file) { $contents = @file_get_contents($file); if ( empty($contents) ) return false; $count = preg_match_all('/uniqueid="([a-fA-F0-9]+?)"/', $contents, $matches); $matches = implode("", $matches[1]); if ( empty($matches) ) { // sometimes current.xml has blank unique IDs $count = preg_match_all('/url="([^"]+?)"/', $contents, $matches); $matches = implode("", $matches[1]); } return md5($matches); } /** * Converts a number to minute:second format * @param int Seconds * @return string format: mm:ss */ function seconds_to_str($secs) { $seconds = $secs % 60; $minutes = ( $secs - $seconds ) / 60; $seconds = strval($seconds); $minutes = strval($minutes); if ( strlen($seconds) < 2 ) $seconds = "0$seconds"; if ( strlen($minutes) < 2 ) $minutes = "0$minutes"; return "$minutes:$seconds"; } /** * Loads the specified theme into Smarty * @param string Theme ID * @return object Smarty object */ function load_theme($theme_id) { global $httpd; static $smarty = array(); if ( !isset($smarty[$theme_id]) ) { $smarty[$theme_id] = new Smarty(); $smarty[$theme_id]->template_dir = GREY_ROOT . "/themes/$theme_id"; if ( !is_dir("./compiled/$theme_id") ) @mkdir("./compiled/$theme_id"); $smarty[$theme_id]->compile_dir = "./compiled/$theme_id"; $smarty[$theme_id]->config_dir = "./config"; $httpd->add_handler("themes/$theme_id", 'dir', GREY_ROOT . "/themes/$theme_id"); } return $smarty[$theme_id]; }