# HG changeset patch # User Dan # Date 1218858540 14400 # Node ID 3b817b961984d4fef22539caf044cc20892f9d37 # Parent 3b4aef1efff6270a5144de1693174a5bb33789c3# Parent 48004643a8a52a747dea289f7279d56c426d7bb7 Merging changes from nighthawk; added support for dumb terminals diff -r 3b4aef1efff6 -r 3b817b961984 functions.php --- a/functions.php Fri Aug 15 23:31:37 2008 -0400 +++ b/functions.php Fri Aug 15 23:49:00 2008 -0400 @@ -24,23 +24,39 @@ function burnout($msg) { + global $use_colors; $h = @fopen('php://stderr', 'w'); - fwrite($h, "\x1B[31;1m[Greyhound] fatal: \x1B[37;1m"); - fwrite($h, "$msg\x1B[0m\n"); + if ( $use_colors ) + { + fwrite($h, "\x1B[31;1m[Greyhound] fatal: \x1B[37;1m"); + fwrite($h, "$msg\x1B[0m\n"); + } + else + { + fwrite($h, "[Greyhound] fatal: $msg\n"); + } fclose($h); exit(1); } /** - * Print a stylized status message, compatible with Linux consoles + * Print a stylized status message, compatible with Linux consoles. Falls back to no control characters if on unsupported terminal. * @param string Status message */ function status($msg) { + global $use_colors; $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"); + if ( $use_colors ) + { + fwrite($h, "\x1B[32;1m[$label] \x1B[32;0m$msg\x1B[0m\n"); + } + else + { + fwrite($h, "[$label] $msg\n"); + } fclose($h); } @@ -51,8 +67,16 @@ function warning($msg) { + global $use_colors; $h = @fopen('php://stderr', 'w'); - fwrite($h, "\x1B[33;1m[Greyhound] \x1B[0m\x1B[33mWarning:\x1B[0m $msg\n"); + if ( $use_colors ) + { + fwrite($h, "\x1B[33;1m[Greyhound] \x1B[0m\x1B[33mWarning:\x1B[0m $msg\n"); + } + else + { + fwrite($h, "[Greyhound] Warning: $msg\n"); + } fclose($h); } diff -r 3b4aef1efff6 -r 3b817b961984 greyhound.php --- a/greyhound.php Fri Aug 15 23:31:37 2008 -0400 +++ b/greyhound.php Fri Aug 15 23:49:00 2008 -0400 @@ -37,7 +37,7 @@ // set this to false, it will only display the playlist. $allowcontrol = true; // The default theme. This should be a name of a directory in ./themes. -$theme = 'funkymonkey'; +$theme = 'grey'; // Allow forking when an HTTP request is received. This has advantages // and disadvantages. If this experimental option is enabled, it will // result in faster responses and load times but more memory usage. @@ -64,6 +64,9 @@ // create directories @mkdir('./compiled'); +// what kind of terminal do we have? +$use_colors = ( @in_array(@$_SERVER['TERM'], array('linux', 'xterm', 'vt100')) ) ? true : false; + // start up... status('Starting Greyhound Web Control v0.1a3'); @@ -85,6 +88,18 @@ exit(0); } +status('doing PHP capabilities check'); +if ( !function_exists('pcntl_signal') ) +{ + warning('System does not support POSIX functions. Termination signals will result in unclean shutdown.'); +} + +if ( !function_exists('simplexml_load_file') ) +{ + warning('Can\'t find support for SimpleXML, which is needed to parse the Amarok playlist file.'); + burnout('SimpleXML required to continue. You may have an outdated version of PHP; most versions of PHP 5 have SimpleXML built-in. Check your distribution\'s documentation to find out how to enable PHP\'s SimpleXML support.'); +} + status('initializing playlist'); // init playlist object @@ -99,11 +114,6 @@ try { status('starting PhpHttpd'); - status('doing PHP capabilities check'); - if ( !function_exists('pcntl_signal') ) - { - warning('System does not support POSIX functions. Termination signals will result in unclean shutdown.'); - } $httpd = new WebServer($ip, $port); // setup handlers @@ -143,6 +153,10 @@ } catch( Exception $e ) { + if ( strstr(strval($e), "Could not bind") ) + { + burnout("Could not bind to the port $ip:$port. Is Greyhound already running? Sometimes browsers don't close off their connections until Greyhound has been dead for about a minute, so try starting Greyhound again in roughly 60 seconds. If that doesn't work, type \"killall -9 php\" at a terminal and try starting Greyhound again in 60 seconds."); + } burnout("Exception caught while running webserver:\n$e"); } diff -r 3b4aef1efff6 -r 3b817b961984 themes/grey/images/ajax.gif Binary file themes/grey/images/ajax.gif has changed diff -r 3b4aef1efff6 -r 3b817b961984 themes/grey/images/amarok.gif Binary file themes/grey/images/amarok.gif has changed diff -r 3b4aef1efff6 -r 3b817b961984 themes/grey/images/next.png Binary file themes/grey/images/next.png has changed diff -r 3b4aef1efff6 -r 3b817b961984 themes/grey/images/pause.png Binary file themes/grey/images/pause.png has changed diff -r 3b4aef1efff6 -r 3b817b961984 themes/grey/images/play.png Binary file themes/grey/images/play.png has changed diff -r 3b4aef1efff6 -r 3b817b961984 themes/grey/images/playbar-shadow.gif Binary file themes/grey/images/playbar-shadow.gif has changed diff -r 3b4aef1efff6 -r 3b817b961984 themes/grey/images/playbar.gif Binary file themes/grey/images/playbar.gif has changed diff -r 3b4aef1efff6 -r 3b817b961984 themes/grey/images/playhead.png Binary file themes/grey/images/playhead.png has changed diff -r 3b4aef1efff6 -r 3b817b961984 themes/grey/images/position-empty.png Binary file themes/grey/images/position-empty.png has changed diff -r 3b4aef1efff6 -r 3b817b961984 themes/grey/images/position-full.png Binary file themes/grey/images/position-full.png has changed diff -r 3b4aef1efff6 -r 3b817b961984 themes/grey/images/prev.png Binary file themes/grey/images/prev.png has changed diff -r 3b4aef1efff6 -r 3b817b961984 themes/grey/images/src/playbar-shadow.xcf Binary file themes/grey/images/src/playbar-shadow.xcf has changed diff -r 3b4aef1efff6 -r 3b817b961984 themes/grey/images/src/playbar.xcf Binary file themes/grey/images/src/playbar.xcf has changed diff -r 3b4aef1efff6 -r 3b817b961984 themes/grey/images/src/playhead.xcf Binary file themes/grey/images/src/playhead.xcf has changed diff -r 3b4aef1efff6 -r 3b817b961984 themes/grey/images/src/position-empty.xcf Binary file themes/grey/images/src/position-empty.xcf has changed diff -r 3b4aef1efff6 -r 3b817b961984 themes/grey/images/src/position-full.xcf Binary file themes/grey/images/src/position-full.xcf has changed diff -r 3b4aef1efff6 -r 3b817b961984 themes/grey/images/stop.png Binary file themes/grey/images/stop.png has changed diff -r 3b4aef1efff6 -r 3b817b961984 themes/grey/images/volume.png Binary file themes/grey/images/volume.png has changed diff -r 3b4aef1efff6 -r 3b817b961984 themes/grey/playlist.tpl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/themes/grey/playlist.tpl Fri Aug 15 23:49:00 2008 -0400 @@ -0,0 +1,92 @@ +{** + * Template file for default Funky Monkey theme + * Web control interface script for Amarok + * Written by Dan Fuhry - 2008 + * + * This script is in the public domain. Use it for good, not evil. + *} + + + + + AmaroK playlist + + + + + {foreach from=$scripts item=script} + + {/foreach} + + +
+
+
 
+
 
+ + AmaroK web control + {if $allow_control} + « PrevTrk + Play + Stop + NextTrk » + {/if} +   + --:--/--:-- + {if $allow_control} +   + Volume: +             + + {/if} +
+
+
+ + + + + + + + + {foreach key=tid item=track from=$playlist} + {strip} + + + + + + + + {/strip} + {/foreach} +
TrackNoTrackArtistAlbumLength
{$tid+1} + + {$track.title|escape} + + {$track.artist|escape}{$track.album|escape}{$track.length|escape}
+
+
+ Powered by Greyhound +
+ + + diff -r 3b4aef1efff6 -r 3b817b961984 themes/grey/style.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/themes/grey/style.css Fri Aug 15 23:49:00 2008 -0400 @@ -0,0 +1,146 @@ +/** + * Based upon the AmaroK WebControl interface by: + * Jonas Christian Drewsen ( kde at xspect dot dk ) + * André Kelpe ( fs111 at web dot de ) + * Peter C. Ndikuwera ( pndiku at gmail dot com ) + */ + +body { + font-family: sans-serif; + background-color: #262626; + color: #ffffff; + padding: 0 8px; + background-image: url(images/playbar-shadow.gif); + background-repeat: repeat-x; +} + +div.tblholder { + padding: 1px; + background-color: #b0b0b0; + border: 1px solid #000000; +} + +div.tblholder table { + background-color: #606060; +} + +tr th { + background-color: #505050; +} + +tr.row1 td { + background-color: #383838; +} + +tr.row2 td { + background-color: #424242; +} + +tr.current td { + background-color: #303030; + color: #ffff00; +} + +div#playbar { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 32px; + padding: 0; + margin: 0; + background-image: url(images/playbar.gif); + background-repeat: repeat-x; + background-color: #383f61; + border-bottom: 1px solid #000000; +} + +div.playbar-inner { + padding: 5px; + line-height: 22px; +} + +a img { + border-width: 0; +} + +div#playlist { + margin-top: 48px; +} + +a.tracklink { + text-decoration: none; + color: white; +} + +div#playlist tr.current a.tracklink { + color: #ffff00; +} + +span#playmeter, span#volume_wrap { + position: relative; + top: -7px; +} + +a.volume_button { + padding-right: 10px; + margin-right: 1px; + background-color: #262626; + border: 1px solid #909090; + text-decoration: none; +} + +a.volume_button_active { + background-color: #404040; + border-color: #d0d0d0; +} + +/* Position slider (playhead) */ + +div#playhead { + background-image: url(images/position-empty.png); + width: 250px; + background-repeat: no-repeat; + background-position: center center; + float: right; + margin-left: 10px; +} + +div#playhead-filler { + background-image: url(images/position-full.png); + width: 150px; + background-repeat: no-repeat; + background-position: left center; +} + +div#playhead-button { + background-image: url(images/playhead.png); + width: 16px; + height: 16px; + font-size: 1px; + position: absolute; + background-repeat: no-repeat; + background-position: center center; +} + +/* The list of colors that will be cycled through as playback takes place */ +tr.pulsar0 td { background-color: #303030; } +tr.pulsar1 td { background-color: #333333; } +tr.pulsar2 td { background-color: #363636; } +tr.pulsar3 td { background-color: #393939; } +tr.pulsar4 td { background-color: #3c3c3c; } +tr.pulsar5 td { background-color: #3f3f3f; } +tr.pulsar6 td { background-color: #424242; } +tr.pulsar7 td { background-color: #454545; } +tr.pulsar8 td { background-color: #484848; } +tr.pulsar9 td { background-color: #4b4b4b; } + +div.poweredby { + font-size: smaller; + text-align: center; + margin: 10px 0; +} + +div.poweredby a { + color: #57608a; +} diff -r 3b4aef1efff6 -r 3b817b961984 webserver.php --- a/webserver.php Fri Aug 15 23:31:37 2008 -0400 +++ b/webserver.php Fri Aug 15 23:49:00 2008 -0400 @@ -18,7 +18,7 @@ * @const string */ -define('HTTPD_VERSION', '0.1b1'); +define('HTTPD_VERSION', '0.1b4'); /** * Length of keep-alive connections @@ -33,7 +33,7 @@ define('HTTPD_ICON_SCRIPT', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGSSURBVCjPVVFNSwJhEF78Ad79Cf6PvXQRsotUlzKICosuRYmR2RJR0KE6lBFFZVEbpFBSqKu2rum6llFS9HHI4iUhT153n6ZtIWMOM+/MM88z7wwH7s9Ub16SJcnbmrNcxVm2q7Z8/QPvEOtntpj92NkCqITLepEpjix7xQtiLOoQ2b6+E7YAN/5nfOEJ2WbKqOIOJ4bYVMEQx4LfBBQDsvFMhUcCVU1/CxVXmDBGA5ZETrhDCQVcYAPbyEJBhvrnBVPiSpNr6cYDNCQwo4zzU/ySckkgDYuNuVpI42T9k4gLKGMPs/xPzzovQiY2hQYe0jlJfyNNhTqiWDYBq/wBMcSRpnyPzu1oS7WtxjVBSthU1vgVksiQ3Dn6Gp5ah2YOKQo5GiuHPA6xT1EKpxQNCNYejgIR457KKio0S56YckjSa9jo//3mrj+BV0QQagqGTOo+Y7gZIf1puP3WHoLhEb2PjTlCTCWGXtbp8DCX3hZuOdaIc9A+aQvWk4ihq95p67a7nP+u+Ws+r0dql9z/zv0NCYhdCPKZ7oYAAAAASUVORK5CYII='); define('HTTPD_ICON_FOLDER', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGrSURBVDjLxZO7ihRBFIa/6u0ZW7GHBUV0UQQTZzd3QdhMQxOfwMRXEANBMNQX0MzAzFAwEzHwARbNFDdwEd31Mj3X7a6uOr9BtzNjYjKBJ6nicP7v3KqcJFaxhBVtZUAK8OHlld2st7Xl3DJPVONP+zEUV4HqL5UDYHr5xvuQAjgl/Qs7TzvOOVAjxjlC+ePSwe6DfbVegLVuT4r14eTr6zvA8xSAoBLzx6pvj4l+DZIezuVkG9fY2H7YRQIMZIBwycmzH1/s3F8AapfIPNF3kQk7+kw9PWBy+IZOdg5Ug3mkAATy/t0usovzGeCUWTjCz0B+Sj0ekfdvkZ3abBv+U4GaCtJ1iEm6ANQJ6fEzrG/engcKw/wXQvEKxSEKQxRGKE7Izt+DSiwBJMUSm71rguMYhQKrBygOIRStf4TiFFRBvbRGKiQLWP29yRSHKBTtfdBmHs0BUpgvtgF4yRFR+NUKi0XZcYjCeCG2smkzLAHkbRBmP0/Uk26O5YnUActBp1GsAI+S5nRJJJal5K1aAMrq0d6Tm9uI6zjyf75dAe6tx/SsWeD//o2/Ab6IH3/h25pOAAAAAElFTkSuQmCC'); -define('HTTPD_ICON_FILE', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAINSURBVBgZBcG/r55zGAfg6/4+z3va01NHlYgzEfE7MdCIGISFgS4Gk8ViYyM2Mdlsko4GSf8Do0FLRCIkghhYJA3aVBtEz3nP89wf11VJvPDepdd390+8Nso5nESBQoq0pfvXm9fzWf19453LF85vASqJlz748vInb517dIw6EyYBIIG49u+xi9/c9MdvR//99MPPZ7+4cP4IZhhTPbwzT2d+vGoaVRRp1rRliVvHq+cfvM3TD82+7mun0o/ceO7NT+/4/KOXjwZU1ekk0840bAZzMQ2mooqh0A72d5x/6sB9D5zYnff3PoYBoWBgFKPKqDKqjCpjKr//dcu9p489dra88cydps30KswACfNEKanSaxhlntjJ8Mv12Paie+vZ+0+oeSwwQ0Iw1xAR1CiFNJkGO4wu3ZMY1AAzBI0qSgmCNJsJUEOtJSMaCTBDLyQ0CknAGOgyTyFFiLI2awMzdEcSQgSAAKVUmAeNkxvWJWCGtVlDmgYQ0GFtgg4pNtOwbBcwQy/Rife/2yrRRVI0qYCEBly8Z+P4qMEMy7JaVw72N568e+iwhrXoECQkfH91kY7jwwXMsBx1L93ZruqrK6uuiAIdSnTIKKPLPFcvay8ww/Hh+ufeznTXu49v95IMoQG3784gYXdTqvRmqn/Wpa/ADFX58MW3L71SVU9ETgEIQQQIOOzub+fhIvwPRDgeVjWDahIAAAAASUVORK5CYII='); +define('HTTPD_ICON_FILE', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAINSURBVBgZBcG/r55zGAfg6/4+z3va01NHlYgzEfE7MdCIGISFgS4Gk8ViYyM2Mdlsko4GSf8Do0FLRCIkghhYJA3aVBtEz3nP89wf11VJvPDepdd390+8Nso5nESBQoq0pfvXm9fzWf19453LF85vASqJlz748vInb517dIw6EyYBIIG49u+xi9/c9MdvR//99MPPZ7+4cP4IZhhTPbwzT2d+vGoaVRRp1rRliVvHq+cfvM3TD82+7mun0o/ceO7NT+/4/KOXjwZU1ekk0840bAZzMQ2mooqh0A72d5x/6sB9D5zYnff3PoYBoWBgFKPKqDKqjCpjKr//dcu9p489dra88cydps30KswACfNEKanSaxhlntjJ8Mv12Paie+vZ+0+oeSwwQ0Iw1xAR1CiFNJkGO4wu3ZMY1AAzBI0qSgmCNJsJUEOtJSMaCTBDLyQ0CknAGOgyTyFFiLI2awMzdEcSQgSAAKVUmAeNkxvWJWCGtVlDmgYQ0GFtgg4pNtOwbBcwQy/Rife/2yrRRVI0qYCEBly8Z+P4qMEMy7JaVw72N568e+iwhrXoECQkfH91kY7jwwXMsBx1L93ZruqrK6uuiAIdSnTIKKPLPFcvay8ww/Hh+ufeznTXu49v95IMoQG3784gYXdTqvRmqn/Wpa/ADFX58MW3L71SVU9ETgEIQQQIOOzub+fhIvwPRDgeVjWDahIAAAAASUVORK5CYII='); /** * Simple but full-featured embedded web server written in PHP. @@ -404,6 +404,13 @@ // parse request $client_headers = trim($client_headers); + + if ( isset($last_finish_time) && empty($client_headers) && defined('HTTPD_WS_CHILD') && $last_finish_time + HTTPD_KEEP_ALIVE_TIMEOUT < microtime(true) ) + { + status('[debug] keep-alive connection timed out (checkpoint 2)'); + continue; // will jump back to the start of the loop and kill the child process + } + $client_headers = explode("\n", $client_headers); // first line @@ -697,7 +704,7 @@ // if ( defined('HTTPD_WS_CHILD') ) // status('Continuing connection'); // @socket_write($remote, "\r\n\r\n"); - $last_finish_time = time(); + $last_finish_time = microtime(true); } else {