1 <?php
require_once('./http_auth.php'); /*Delete this line to disable password protection*/ ?
>
2 <?php
$exec_time = round(microtime(true), 3); /*
4 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
6 * 0.3.6 - Now sorting also directories and have icon link support in css
7 * 0.3.5 - Fixed security bug - directory traversal in filelisting (upgrade recommended)
8 * 0.3.4 - Generating playlist for flashplayer, searching for bugs, cleaning code and preparing for new version release
9 * 0.3.3 - Shorter URLs for flashplayer (due to discussion at #skola ;o), nicer national characters handling
10 * 0.3.2 - Better support for national charsets, few small bugfixes, css improvements, modular search engines
11 * 0.3.1 - Buckfickses in m3u generation, better navigation, magic_quotes_gpc handled, css improvements
12 * 0.3 - Migrated to standalone WPAudioPlayer (better, nicer, with more functions)
13 * 0.2 - Few new functions (search playlist, random,...)
14 * 0.1.1 - Few little fixups, written help.html in Czech language ;o)
15 * 0.1 - All functions works - TODO: bugfix & replace ugly code
16 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
20 $title = 'Harvie\'s JuKe!Box'; //Title of jukebox
21 $music_dir = './music'; //Local path to directory with music
22 $music_dir_url = 'http://your-server.net/jukebox/music'; //URL path to the same directory
23 $cache_passwd = 'renew123'; //You need this passwd to refresh search cache
24 $sort = 3; //Sort? 0 = none, 1 = playlists, 2 = 1+listings; 3 = 2+search-EXPERIMENTAL! (sorting could eat lot of memory)
25 $access_limit = 40; //How many files could be accessed without using cache (while searching)
28 $charset = 'UTF-8'; //Charset for page
29 $national_characters = 1; //Support searching in filenames with national characters? 0 = no; 1 = yes; (may slowdown search a little)
32 $playlist_name = 'playlist.m3u'; //Name of downloaded pl
33 $m3u_exts = 'ogg|mp[0-9]|wma|wmv|wav'; //Allow only these files
34 $default_random_count = 30; //How many random songs by defaul?
37 $indexlist = array('index.html', 'index.txt'); //Search for this file in each directory
38 $bonus_dir = './jbx'; //Misc. files directory
40 $search_cache = $bonus_dir.'/cache.db'; //Database for searching music (php +rw) - .htaccess: Deny from all!!!
41 $css_file = $bonus_dir.'/themes/default/jukebox.css'; //CSS (Design)
42 $favicon_file = './favicon.png'; //favicon
43 $header_file = $bonus_dir.'/header.html'; //header file
44 $footer_file = $bonus_dir.'/footer.html'; //footer file
46 //Search engines extend search experience
47 $search_engines = array(
48 'Google.com' => 'http://google.com/search?q=',
49 'Images' => 'http://google.com/images?q=',
50 'Karaoke-Lyrics.net' => 'http://www.karaoke-lyrics.net/index.php?page=find&q=',
51 'Jyxo.cz multimedia' => 'http://jyxo.cz/s?d=mm&q=',
52 'Centrum.cz mp3' => 'http://search.centrum.cz/index.php?sec=mp3&q=',
53 'YOUTube.com' => 'http://youtube.com/results?search_query='
56 //Flash MusicPlayer (info about settings: http://wpaudioplayer.com/standalone)
57 $flash_player_swf = $bonus_dir.'/player.swf'; //path to musicplayer
58 $flash_player_frame = 'playframe-show'; //FlashPlayer Target (playframe-show|playframe-hide) - usefull for compatibility with old music player
59 $flash_player_options = '?bg=000099&loader=000000&tracker=AAAAFF&skip=FFFFFF' //.'&leftbg=000077&rightbg=000077&righticon=999999'
60 .'&autostart=yes&initialvolume=100&soundFile='; //& arguments (urlencoded song url will be added)
63 error_reporting(0); //This will disable error reporting, wich can pass sensitive data to users
65 //External configuration file (overrides index.php configuration)
66 @include
('./_config.php');
68 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
72 @ini_set
('magic_quotes_gpc' , 'off');
73 if(get_magic_quotes_gpc()) die("Error: magic_quotes_gpc needs to be disabled!\n");
76 $useflash = is_file($flash_player_swf);
78 //Little magic with directories ;o)
79 $current_dir = ereg_replace('/+', '/', '/'.$_GET['dir'].'/');
80 if(eregi('(/|\\\\)\\.\\.(/|\\\\)', $current_dir)) { //check for directory traversal ;)
81 header('Location: ?');
82 die('Error - directory not found!');
84 $dir = $music_dir.$current_dir;
85 $url = $music_dir_url.$current_dir;
86 $parent_dir = dirname($current_dir);
89 function serve_download($filename) {
90 header('Cache-Control: no-cache, no-store, max-age=0, must-revalidate');
91 header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
92 header('Pragma: no-cache');
94 //header('Content-Type: application/force-download');
95 header('Content-Type: audio/x-mpegurl');
96 header("Content-Disposition: attachment; filename={$filename}");
97 header('Content-Transfer-Encoding: binary');
99 header('X-PHP-Application: Harvie\'s JuKe!Box');
102 $nchars_f = array('Á','Ä','Č','Ç','Ď','É','Ě','Ë','Í','Ň','Ó','Ö','Ř','Š','Ť','Ú','Ů','Ü','Ý','Ž','á','ä','č','ç','ď','é','ě','ë','í','ň','ó','ö','ř','š','ť','ú','ů','ü','ý','ž');
103 $nchars_t = array('A','A','C','C','D','E','E','E','I','N','O','O','R','S','T','U','U','U','Y','Z','a','a','c','c','d','e','e','e','i','n','o','o','r','s','t','u','u','u','y','z');
105 function unational($text) {
106 if(!$GLOBALS['national_characters']) return $text;
107 return(str_replace($GLOBALS['nchars_f'], $GLOBALS['nchars_t'], $text));
110 function generate_m3u($dir, $prefix='', $recursive=0, $nl="\r\n", $doubleenc=0) {
112 if(isset($_GET['newline'])) $nl = $_GET['newline'];
113 if(!isset($_GET['search'])) {
115 while(($item = readdir($dd)) != false) {
116 if($item == '.' ||
$item == '..') continue;
117 if( is_file($dir.$item) && eregi(('\.('.$GLOBALS['m3u_exts'].')$'), $item) ) {
118 if($GLOBALS['sort'] > 0) {
121 $item=($prefix.'/'.str_replace('%2F', '/', (rawurlencode($dir.$item))).$nl);
122 if($doubleenc) $item = rawurlencode($item);
126 if($recursive && is_dir($dir.$item)) {
127 generate_m3u($dir.$item, $prefix, $recursive, $nl, $doubleenc);
131 if(!($searchfp = fopen($GLOBALS['search_cache'], 'r')))
132 die("Cannot read cache from $outfile<br />Refresh cache or set permissions properly!<br />\n");
133 while(!feof($searchfp)) {
134 $line = trim(fgets($searchfp));
135 if(@eregi
(str_replace(' ', '(.*)', unational($_GET['search'])), unational($line))) {
136 $line=(dirname($GLOBALS['music_dir_url']).'/'.str_replace('%2F', '/', (rawurlencode($line))).$nl);
137 if($doubleenc) $line = rawurlencode($line);
143 if($GLOBALS['sort'] > 0) {
145 foreach($temp as $item) {
146 $temp=($prefix.'/'.str_replace('%2F', '/', (rawurlencode($dir.$item))).$nl);
147 if($doubleenc) $temp = rawurlencode($temp);
153 function write_search_cache($dir, $outfp) {
156 while($item = readdir($dd)) {
157 if($item == '.' ||
$item == '..') continue;
158 if( is_file($dir.$item) && eregi(('\.('.$GLOBALS['m3u_exts'].')$'), $item) ) {
159 fwrite($outfp, $dir.$item."\n");
161 if(is_dir($dir.$item)) {
162 write_search_cache($dir.$item, $outfp);
167 function generate_search_cache($dir, $outfile) {
168 echo("Generating search cache. Please wait...<br />\n"); flush();
169 @chmod
($outfile, 0755); //At least i tryed ;D
170 if(!($outfp = fopen($outfile, 'w')))
171 die("Cannot write cache to $outfile<br />You probably haven't set the permissions properly!<br />\n");
172 write_search_cache($dir, $outfp);
174 $osize = filesize($outfile); clearstatcache();
175 if($GLOBALS['sort'] > 2) {
176 echo("Sorting search cache. Please wait...<br />\n"); flush();
178 $items = file($outfile); @sort
($items);
179 $total = ' ('.sizeof($items).' files)';
180 file_put_contents($outfile, @implode
('', $items));
182 if(abs(filesize($outfile)-$osize) > 2)
183 die('ERROR! Please disable sorting of search cache ($sort < 3)<br />'."\nSorted only ".
184 filesize($outfile).' of '.$osize.' bytes!!!\n');
186 echo('Total: '.filesize($outfile).' of '.$osize.' bytes'.$total.' <a href="?">DONE!</a>'.'<br /><META http-equiv="refresh" content="2;URL=?">'."\n");
189 function render_file_line($dir, $item, $dir_url, $index, $filesize, $parent = false) {
190 $parclass=($index%2?
'even':'odd'); $parcolor=($index%2?
'lightblue':'white');
191 $temp=str_replace('&', '%26', dirname($dir_url)).'/'.str_replace('%2F', '/', (rawurlencode($dir.$item)));
192 if(is_numeric($filesize)) $filesize = round($filesize/(1024*1024), 2);
193 echo("<tr class=\"$parclass\" bgcolor=\"$parcolor\">".'<td><a href="#up">'.$index.'</a></td><td class="btntd">');
194 echo('<a href="?download&song='.rawurlencode($temp).'" class="icon iplay">P</a>');
196 echo('/<a href="?dir='.
197 substr(str_replace(array('&','%2F'), array('%26','/'), (rawurlencode(dirname($dir.$item)))), strlen($GLOBALS['music_dir'])).
198 '" class="icon ifolder">D</a>');
200 if($GLOBALS['useflash'] && eregi(('\.('.$GLOBALS['m3u_exts'].')$'), $item)) {
201 echo('/<a href="?f&song='.rawurlencode($temp).
202 '" target="'.$GLOBALS['flash_player_frame'].'" class="icon ifplay">F</a>/'.
203 '<a href="?blank" target="'.$GLOBALS['flash_player_frame'].'" class="icon ifstop">S</a>');
205 echo(' </td><td class="maximize-width"><a href="'.$temp.'">'.unxss(str_replace('-',' - ',str_replace('_', ' ',
206 $item))).'</a></td><td>'.$filesize." MiB </td></tr>\n");
209 function render_dir_line($current_dir, $item, $i) {
210 $parclass=($i%2?
'even':'odd'); $parcolor=($i%2?
'lightblue':'white');
211 $temp=str_replace('%2F', '/', rawurlencode($current_dir)).rawurlencode($item);
212 echo("<tr class=\"$parclass directory\" bgcolor=\"$parcolor\">".
213 '<td><a href="#up">'.$i.'</a></td><td class="btntd"><a href="?download&playlist&dir='.$temp.'" class="icon iplay">P</a>/'.
214 '<a href="?download&recursive&playlist&dir='.$temp.'" class="icon irplay">R</a>');
215 if($GLOBALS['useflash']) echo('/<a href="?f&playlist&dir='.$temp.'" target="'.$GLOBALS['flash_player_frame'].'" class="icon ifplay">F</a>');
216 echo('</td><td colspan="100%" class="maximize-width"><span class="icon ifolder">[DIR] </span><a href="?dir='.$temp.'">'.unxss(str_replace('_', ' ', $item)).
220 function render_tr_playframe_show() {
221 if($GLOBALS['flash_player_frame'] == 'playframe-show' && $GLOBALS['useflash']) { ?
>
222 <tr id
="playframe-tr">
223 <td
><a href
="?blank" target
="playframe-show" title
="Stop playback" class="icon ifstop">S
</a
></td
>
227 name
="playframe-show"
231 transparentpagebg
="yes"
236 function render_footer() {
238 'This is NOT advertisments. This is just good text to think about... Remove it if you want!',
239 'Downloading without sharing and other forms of leeching equals STEALING! ;P',
240 'Do NOT support Microsoft!!! Use Linux! ;D',
241 'Don\'t steal! Steal and share!!! ;P',
242 'Linux is not matter of price, it\'s matter of freedom!',
243 'This software brought to you by <a href="http://blog.Harvie.cz">Harvie</a> free of charge! Of course...',
244 'Don\'t be looser, use GNU/Linux! ;P',
245 'Make love and not war!',
246 'Take your chance! Prove yourself!',
247 'This software is free of charge. If you wan\'t to donate, please send some money to children in Africa/etc...'
250 echo('<span id="quote" style="float: left;"><i><small>'.$quotes[rand(0,sizeof($quotes)-1)]."</small></i></span>\n");
251 echo('<span id="exectime" style="float: right;"><small>Page was generated in '.(round(microtime(true), 3) - $GLOBALS['exec_time']).'
252 seconds</small></span>');
253 @readfile
($GLOBALS['footer_file']);
254 echo('</body></html>');
257 function unxss($string) {
258 return htmlspecialchars($string);
261 function explode_path($dir) {
262 $dir = substr($dir, strlen($GLOBALS['music_dir'])+
1);
263 $temp = split('/', ereg_replace('/+', '/', $dir));
265 for($j=sizeof($temp)-1;$j>0;$j--) {
267 for($i=0;$i<(sizeof($temp)-$j);$i++
) {
270 $out.='<a href="?dir='.rawurlencode($dir).'">'.unxss($temp[$i-1]).'</a>/';
272 return('<a href="?">.</a>/'.$out);
275 function flash_mp3_player() {
277 <html
><head
><title
><?
=$GLOBALS['title']?
>: Flash Music Player Plugin
</title
>
278 <style
> * { margin
: 0; padding
: 0; border
: 0; } </style
></head
><body
>
279 <object width
="100%" height
="344">
281 echo($GLOBALS['flash_player_swf'].$GLOBALS['flash_player_options']);
282 if(isset($_GET['song'])) echo(rawurlencode($_GET['song']));
283 if(isset($_GET['playlist'])) generate_m3u($GLOBALS['dir'], dirname($GLOBALS['music_dir_url']), isset($_GET['recursive']), ',', true);
285 type
="application/x-shockwave-flash"
286 allowscriptaccess
="never"
287 allowfullscreen
="true"
288 transparentpagebg
="yes"
290 width
="100%" height
="24px"
291 >You need Adobe Flash enabled browser to play records directly in website
.</embed
>
292 </object></body
></html
>
297 if(isset($_GET['download'])) serve_download($playlist_name);
298 if(isset($_GET['f'])) flash_mp3_player();
299 if(isset($_GET['song'])) {
300 die($_GET['song']."\r\n");
305 if($_POST['cache-refresh'] == $cache_passwd) {
306 generate_search_cache($music_dir, $search_cache);
310 if(isset($_GET['playlist'])) {
311 generate_m3u($dir, dirname($music_dir_url), isset($_GET['recursive']));
315 if(isset($_GET['random'])) {
317 if(!($searchfp = fopen($search_cache, 'r')))
318 die("Cannot read cache from $outfile<br />Refresh cache or set permissions properly!<br />\n");
319 while(!feof($searchfp)) { fgets($searchfp); $flen++
; }
320 for($i=0; $i<$_GET['random']; $i++
) {
322 for($j=0; $j<rand(0, $flen-1); $j++
) fgets($searchfp);
323 echo(dirname($music_dir_url).'/'.str_replace('%2F', '/', (rawurlencode(trim(fgets($searchfp)))))."\r\n");
328 if(isset($_GET['blank'])) {
330 <link rel
="stylesheet" type
="text/css" href
="<?=$css_file?>" />
331 <body
class="blank"><div
class="blank"><b
>Music player
</b
> <small
><i
>(click
'F' link next to the song name to start
, 'S' to stop
...)</i
></small
></div
></body
>
336 <!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
337 <meta http
-equiv
="Content-Type" content
="text/html; charset=<?=$charset?>" />
340 <link rel
="stylesheet" type
="text/css" href
="<?=$css_file?>" />
341 <link rel
="shortcut icon" href
="<?=$favicon_file?>" />
342 <link href
="<?=$favicon_file?>" rel
="icon" type
="image/gif" />
346 <div align
="right" style
="position: absolute; top: 5px; right: 5px;">
348 <iframe src
="about:blank" name
="playframe-hide" width
="0" height
="0" style
="border: none;" class="hide"></iframe
><!-- -----------???
--------------- -->
349 <span
class="icon"><
;</span
> <a href
="javascript: history.go(-1)" class="icon iback">BACK
</a
>
350 |
<a href
="?"><span
class="icon ihome">HOME
</span
> (<?
=$music_dir?
>)</a
>
351 |
<a href
="?help" class="icon ihelp">ABOUT
/HELP
</a
>
352 |
<a href
="?logout" class="icon ilogout">LOGOUT
</a
>
356 if(isset($_GET['help'])) {
357 ?
><h1
>About
/Help
</h1
><?php
358 readfile($bonus_dir.'/help.html');
363 if(!isset($_GET['search'])) {
364 echo('<title>'.$title.': '.unxss($dir).'</title>');
365 echo('<a href="?" style="color: black;"><h1 style="float: left;">'.$title.'</h1></a><h2 style="clear: left; display: inline; float: left;">Index of: '.explode_path($dir).'</h2>');
367 echo('<title>'.$title.': '.unxss($_GET['search']).'</title>');
368 echo('<a href="?" style="color: black;"><h1 style="float: left;">'.$title.'</h1></a><h2 style="clear: left; display: inline; float: left;">Searching for: '.unxss($_GET['search']).'</h2>');
376 <span style
="float: right;">
377 <form action
="?" method
="GET" align
="right" style
="display: inline;">
378 <input type
="hidden" name
="download" value
="" />
379 <input type
="number" min
="1" name
="random" value
="<?=$default_random_count?>" style
="width:4em;" title
="how many randomly selected tracks should be in
382 <input type
="submit" value
="random" title
="Generate random music playlist..." />
384 <form action
="?" method
="GET" align
="right" style
="display: inline;">
385 <span
class="icon isearch"></span
><input type
="search" name
="search" autofocus placeholder
="search regexp..."
386 title
="Search in music/google/lyrics/mp3/youtube; Hint: You can use regular expressions in search query..."
387 value
="<?=unxss($_GET['search'])?>"
389 <input type
="submit" value
="search" title
="Search in this JuKe!Box..." />
393 if(!isset($_GET['search'])) {
394 echo('<br style="clear: both;" />');
398 <span style
="float: right;">
399 <form action
="?" method
="POST" align
="right">
400 <input type
="password" name
="cache-refresh" value
="" style
="width:5em;" title
="Password for refreshing - good for avoiding DoS Attacks!!!" />
401 <input type
="submit" value
="refresh cache" title
="You should refresh cache each time when you add new music or upgrade to newer version of JuKe!Box !!!" />
405 <div align
="right" style
="clear: right;" title
="Aditional search engines...">
409 foreach($search_engines as $search_desc => $search_link) {
410 if(!$search_prefix) {
411 echo(unxss($_GET['search'])." @\n");
414 echo('<a href="'.$search_link.rawurlencode($_GET['search']).'">'.$search_desc."</a>;\n");
417 </div
><br style
="clear: both;" />
419 echo('<small>Search DB size: '.(filesize($search_cache)/1024)." kB<br /></small>\n");
421 if(!($searchfp = fopen($search_cache, 'r')))
422 die("Cannot read cache from $outfile<br />Refresh cache or set permissions properly!<br />\n");
425 echo('<table border="1" width="100%">');
426 render_tr_playframe_show();
427 echo('<tr class="directory"><td>S</td><td><a href="?download&playlist&search='.unxss($_GET['search']).'" class="icon iplay">P</a>');
428 if($GLOBALS['useflash']) echo('/<a href="?f&playlist&search='.unxss($_GET['search']).'" target="'.$GLOBALS['flash_player_frame'].'" class="icon ifplay">F</a>');
429 echo('</td><td colspan="100%">Search: '.unxss($_GET['search']).'</td></tr>');
431 while(!feof($searchfp)) {
432 $line = trim(fgets($searchfp));
433 $parclass=($i%2?
'even':'odd'); $parcolor=($i%2?
'lightblue':'white');
434 if(@eregi
(str_replace(' ', '(.*)', unational($_GET['search'])), unational($line))) {
436 $filesize = 0; if($i <= $access_limit) $filesize = filesize($line); else $filesize = 'n/a';
437 render_file_line('', $line, $music_dir_url, $i, $filesize, true);
440 echo('<tr><td colspan="100%">Total: '.$i.' results...</td></tr></table>');
441 render_footer(); die();
444 @readfile
($header_file);
445 foreach($indexlist as $index) @readfile
($dir.$index);
448 <table border
="1" width
="100%">
449 <?php
render_tr_playframe_show(); ?
>
451 <tr
class="directory"><td
>>
;</td
>
452 <td
><a href
="?download&playlist&dir=<?=str_replace('%2F', '/', rawurlencode($current_dir))?>" class="icon iplay">P
</a
>/<a
453 href
="?download&recursive&playlist&dir=<?=str_replace('%2F', '/', rawurlencode($current_dir))?>" class="icon irplay">R
</a
><?php
454 if($GLOBALS['useflash']) echo('/<a href="?f&playlist&dir='.str_replace('%2F', '/', rawurlencode($current_dir)).'" target="'.$GLOBALS['flash_player_frame'].'"
455 class="icon ifplay">F</a>'); ?
>
457 <td colspan
="100%"><?
=unxss($dir)?
></td
></tr
>
458 <tr
><td
>^
</td
><td
> 
;</td
><td colspan
="100%" class="directory"><span
class="icon ifolder">[DIR
] </span
><a href
="?dir=<?=rawurlencode($parent_dir)?>">..
459 (<?
=$parent_dir?
>)</a
></td
></tr
>
464 for($s=2;$s;$s--) { while(($item = readdir($dd)) != false) {
465 if($item == '.' ||
$item == '..') continue;
466 if(($s==2 && is_file($dir.$item)) ||
($s!=2 && is_dir($dir.$item))) continue;
468 //$parclass=($i%2?'even':'odd'); $parcolor=($i%2?'lightblue':'white');
470 if(is_file($dir.$item)) {
474 if(is_dir($dir.$item)) {
479 if(is_file($dir.$item)) {
480 render_file_line($dir, $item, $music_dir_url, $i, filesize($dir.$item));
482 if(is_dir($dir.$item)) {
483 render_dir_line($current_dir, $item, $i);
491 foreach($itemsd as $item) {
493 render_dir_line($current_dir, $item, $i);
495 foreach($itemsf as $item) {
497 render_file_line($dir, $item, $music_dir_url, $i, filesize($dir.$item));