/** * Recursive directory scanner * * param path - str: the path to scan with no trailing slash * param allowed_filetypes arr: mp3, ogg etc * param media_scanner str: the media scanner object */ function scan_directory($path, $allowed_filetypes, $media_scanner, $id3_scanner) { $dp = opendir($path); while ($filename = readdir($dp)) { //create the full pathname and streeme pathname $full_file_path = $path . '/' . $filename; //skip hidden files/folders if ($filename[0] === '.') { continue; } //it's a directory, recurse from this level if (is_dir($full_file_path)) { scan_directory($full_file_path, $allowed_filetypes, $media_scanner, $id3_scanner); continue; } //Stat the file $file_stat = stat($full_file_path); //is it a usable file? if ($file_stat['size'] === 0 || !in_array(strtolower(substr($filename, -3)), $allowed_filetypes)) { continue; } $streeme_path_name = iconv(sfConfig::get('app_filesystem_encoding', 'ISO-8859-1'), 'UTF-8//TRANSLIT', $full_file_path); //has it been scanned before? if ($media_scanner->is_scanned($streeme_path_name, $file_stat['mtime'])) { continue; } echo "Scanning " . $filename . "\n"; //get the file information from pathinfo in case we need a substitute song name $pinfo = pathinfo($full_file_path); /** * Pure ugliness - there's 3 possible containers for scraps of ID3 data - they're in order of preference and data integrity * Tempted to move this to its own container * high high medium none * apex -> id3v2 -> id3v1 -> null * getID3 is a bit of a tricky lib to work with, but it has great features */ $value = $id3_scanner->analyze($full_file_path); $tags = $value['tags']; //track number is a nuisance - regress to find the tags if (isset($tags['id3v1']['track'][0]) && is_int($tags['id3v1']['track'][0])) { //could be an int $tracknumber = $tags['id3v1']['track'][0]; } else { if (isset($tags['id3v2']['track_number'][0]) && !empty($tags['id3v2']['track_number'][0])) { //or it could be 5/12 $temp = explode('/', $tags['id3v2']['track_number'][0]); $tracknumber = $temp[0]; } else { if (isset($tags['ape']['track_number'][0]) && !empty($tags['ape']['track_number'][0])) { //or it could be 5/12 APEX $temp = explode('/', $tags['ape']['track_number'][0]); $tracknumber = $temp[0]; } else { //or it's missing $tracknumber = 0; } } } $song_array = array(); $song_array['artist_name'] = StreemeUtil::xmlize_utf8_string(@$tags['ape']['artist'][0] ? @$tags['ape']['artist'][0] : ($tags['id3v2']['artist'][0] ? $tags['id3v2']['artist'][0] : ($tags['id3v1']['artist'][0] ? $tags['id3v1']['artist'][0] : null))); $song_array['album_name'] = StreemeUtil::xmlize_utf8_string(@$tags['ape']['album'][0] ? @$tags['ape']['album'][0] : ($tags['id3v2']['album'][0] ? $tags['id3v2']['album'][0] : ($tags['id3v1']['album'][0] ? $tags['id3v1']['album'][0] : null))); $song_array['song_name'] = StreemeUtil::xmlize_utf8_string(@@$tags['ape']['title'][0] ? @$tags['ape']['title'][0] : ($tags['id3v2']['title'][0] ? $tags['id3v2']['title'][0] : ($tags['id3v1']['title'][0] ? $tags['id3v1']['title'][0] : $pinfo['filename']))); $song_array['song_length'] = $value['playtime_string']; $song_array['accurate_length'] = floor((double) $value['playtime_seconds'] * 1000); $song_array['genre_name'] = @$tags['ape']['genre'][0] ? @$tags['ape']['genre'][0] : ($tags['id3v2']['genre'] ? $tags['id3v2']['genre'][0] : ($tags['id3v1']['genre'][0] ? $tags['id3v1']['genre'][0] : null)); $song_array['filesize'] = $file_stat['size']; $song_array['bitrate'] = floor((int) $value['audio']['bitrate'] / 1000); $song_array['yearpublished'] = @$tags['ape']['year'][0] ? @$tags['ape']['year'][0] : ($tags['id3v2']['year'][0] ? $tags['id3v2']['year'][0] : ($tags['id3v1']['year'][0] ? $tags['id3v1']['year'][0] : null)); $song_array['tracknumber'] = $tracknumber; $song_array['label'] = StreemeUtil::xmlize_utf8_string(@$tags['ape']['label'][0] ? @$tags['ape']['label'][0] : ($tags['id3v2']['label'][0] ? $tags['id3v2']['label'][0] : null)); //not available in V1 $song_array['mtime'] = $file_stat['mtime']; $song_array['atime'] = $file_stat['atime']; $song_array['filename'] = $streeme_path_name; unset($value, $tags, $file_stat, $temp); //free the RAM used by the temp containters /* End Ugliness */ $media_scanner->add_song($song_array); } closedir($dp); }
<?php include dirname(__FILE__) . '/../bootstrap/doctrine.php'; include dirname(__FILE__) . '/../../apps/client/lib/StreemeUtil.class.php'; // Initialize the test object $t = new lime_test(10, new lime_output_color()); $t->comment('->itunes_format_decode()'); $t->is(StreemeUtil::itunes_format_decode('file://localhost/Z:/music/music.mp3', true), 'Z:/music/music.mp3', 'Decoded an itunes path with mapped drive replacements'); $mapped_drive_locations = array('file://localhost/Z:' => '\\mediabox'); $t->is(StreemeUtil::itunes_format_decode('file://localhost/Z:/music/music.mp3', true, array('file://localhost/Z:' => '\\mediabox')), '\\mediabox/music/music.mp3', 'Decoded an iTunes path with mapped drive replacements'); $t->is(StreemeUtil::itunes_format_decode('file://localhost/home/foo/bar%20man', false), '/home/foo/bar man', 'Decoded an itunes formatted path'); $t->comment('->slugify()'); $t->is(StreemeUtil::slugify('stuff & thing fox\'s Name'), 'stuff-thing-fox-s-name', 'Processed sting pattern into valid url'); $t->comment('->xmlize_uf8_string()'); $t->is(StreemeUtil::xmlize_utf8_string(join(range(chr(0), chr(127)))), join(range(chr(1), chr(127))), 'passes printable US-ascii chars'); $t->is(StreemeUtil::xmlize_utf8_string(' 小低胡' . chr(0)), '小低胡', 'passes printable UTF-8 chars'); $t->is(StreemeUtil::xmlize_utf8_string('äöüæøy'), 'äöüæøy', 'passes printable UTF-8 tremas'); $t->is(StreemeUtil::xmlize_utf8_string('m̥mn̥nɲ̊ɲŋ̊ŋðóíáþ'), 'm̥mn̥nɲ̊ɲŋ̊ŋðóíáþ', 'passes printable UTF-8 icelandic chars'); $t->is(StreemeUtil::xmlize_utf8_string('YÿþAÿþ#ÿþÿþ'), '', 'removes id3 signalling leak'); $t->comment('->replace_url_nonfs_chars()'); $t->is(StreemeUtil::replace_url_nonfs_chars('%E2%80%93' . '%E2%80%A6' . '%E2%80%BA'), '%96' . '%85' . '%9B', 'change mb_strings to single byte latin');
/** * Get a combined file from the cache dir * * @param type string css or js * @param namespace string the combined file namespace (eg. module+action names) * @return string filesystem path to combined file */ public function getFileName($type, $namespace) { $type = $type === 'css' ? 'css' : 'js'; $namespace = StreemeUtil::slugify($namespace); return sprintf('%s/combine/%s/%s.%s', sfConfig::get('sf_cache_dir'), $type, $namespace, $type); }
* @package streeme * @author Richard Hoar * @version SVN: $Id: Builder.php 7490 2010-03-29 19:53:27Z jwage $ */ $itunes_music_library = sfConfig::get('app_itunes_xml_location'); $mapped_drive_locations = sfConfig::get('app_mdl_mapped_drive_locations'); $allowed_filetypes = array_map('strtolower', sfConfig::get('app_aft_allowed_file_types')); $media_scanner = new MediaScan(); $itunes_parser = new StreemeItunesTrackParser($itunes_music_library); while ($value = $itunes_parser->getTrack()) { //if it's not a valid filetype, ignore if (!in_array(strtolower(substr($value['Location'], -3)), $allowed_filetypes)) { continue; } //decode the itunes file scheme for checking is_readable $location = StreemeUtil::itunes_format_decode($value['Location'], StreemeUtil::is_windows(), $mapped_drive_locations); //convert it from user's filesystem value to UTF-8 for the database $value['Location'] = iconv(sfConfig::get(app_filesystem_encoding, 'ISO-8859-1'), 'UTF-8//TRANSLIT', $location); //if this file's scanned already and nothing about the file has been modified, ignore if ($media_scanner->is_scanned($value['Location'], strtotime($value['Date Modified']))) { continue; } //smooth times from itunes format to minutes:seconds $minutes = floor($value['Total Time'] / 1000 / 60); $seconds = str_replace('.', '0', substr(($value['Total Time'] - floor($value['Total Time'] / 1000 / 60) * 60 * 1000) / 1000, 0, 2)); if ($seconds > 60) { $seconds = '00'; } //create an array of song information $song_array = array(); $song_array['artist_name'] = @$value['Artist'];
function mapItunes($collection) { return array('filename' => iconv(sfConfig::get(app_filesystem_encoding, 'ISO-8859-1'), 'UTF-8//TRANSLIT', StreemeUtil::itunes_format_decode($collection['filename'], StreemeUtil::is_windows(), sfConfig::get('app_mdl_mapped_drive_locations')))); }