public function add_file($full_file, $options) { // Ensure that we've got our cache $this->_create_filecache(); /* First thing first, check if file is already in catalog. * This check is very quick, so it should be performed before any other checks to save time */ if (isset($this->_filecache[strtolower($full_file)])) { return false; } // Incase this is the second time through clear this variable // if it was set the day before unset($failed_check); if (AmpConfig::get('no_symlinks')) { if (is_link($full_file)) { debug_event('read', "Skipping symbolic link {$full_file}", 5); return false; } } /* If it's a dir run this function again! */ if (is_dir($full_file)) { $this->add_files($full_file, $options); /* Change the dir so is_dir works correctly */ if (!chdir($full_file)) { debug_event('read', "Unable to chdir to {$path}", 2); AmpError::add('catalog_add', sprintf(T_('Error: Unable to change to directory %s'), $path)); } /* Skip to the next file */ return true; } //it's a directory $is_audio_file = Catalog::is_audio_file($full_file); if (AmpConfig::get('catalog_video_pattern')) { $is_video_file = Catalog::is_video_file($full_file); } if ($options['parse_playlist'] && AmpConfig::get('catalog_playlist_pattern')) { $is_playlist = Catalog::is_playlist_file($full_file); } /* see if this is a valid audio file or playlist file */ if ($is_audio_file || $is_video_file || $is_playlist) { /* Now that we're sure its a file get filesize */ $file_size = Core::get_filesize($full_file); if (!$file_size) { debug_event('read', "Unable to get filesize for {$full_file}", 2); /* HINT: FullFile */ AmpError::add('catalog_add', sprintf(T_('Error: Unable to get filesize for %s'), $full_file)); } // file_size check if (!Core::is_readable($full_file)) { // not readable, warn user debug_event('read', "{$full_file} is not readable by ampache", 2); /* HINT: FullFile */ AmpError::add('catalog_add', sprintf(T_('%s is not readable by ampache'), $full_file)); return false; } // Check to make sure the filename is of the expected charset if (function_exists('iconv')) { $convok = false; $site_charset = AmpConfig::get('site_charset'); $lc_charset = $site_charset; if (AmpConfig::get('lc_charset')) { $lc_charset = AmpConfig::get('lc_charset'); } $enc_full_file = iconv($lc_charset, $site_charset, $full_file); if ($lc_charset != $site_charset) { $convok = strcmp($full_file, iconv($site_charset, $lc_charset, $enc_full_file)) == 0; } else { $convok = strcmp($enc_full_file, $full_file) == 0; } if (!$convok) { debug_event('read', $full_file . ' has non-' . $site_charset . ' characters and can not be indexed, converted filename:' . $enc_full_file, '1'); /* HINT: FullFile */ AmpError::add('catalog_add', sprintf(T_('%s does not match site charset'), $full_file)); return false; } $full_file = $enc_full_file; // Check again with good encoding if (isset($this->_filecache[strtolower($full_file)])) { return false; } } // end if iconv if ($is_playlist) { debug_event('read', 'Found playlist file to import: ' . $full_file, '5'); $this->_playlists[] = $full_file; } else { if (count($this->get_gather_types('music')) > 0) { if ($is_audio_file) { $this->insert_local_song($full_file, $options); } else { debug_event('read', $full_file . " ignored, bad media type for this music catalog.", 5); } } else { if (count($this->get_gather_types('video')) > 0) { if ($is_video_file) { $this->insert_local_video($full_file, $options); } else { debug_event('read', $full_file . " ignored, bad media type for this video catalog.", 5); } } } $this->count++; $file = str_replace(array('(', ')', '\''), '', $full_file); if (UI::check_ticker()) { UI::update_text('add_count_' . $this->id, $this->count); UI::update_text('add_dir_' . $this->id, scrub_out($file)); } // update our current state } // if it's not an m3u } else { debug_event('read', "{$full_file} ignored, non-audio file or 0 bytes", 5); } // else not an audio file }
/** * add_files * * Recurses through $this->path and pulls out all mp3s and returns the * full path in an array. Passes gather_type to determine if we need to * check id3 information against the db. */ public function add_files($path, $options) { // Profile the memory a bit debug_event('Memory', UI::format_bytes(memory_get_usage(true)), 5); // See if we want a non-root path for the add if (isset($options['subdirectory'])) { $path = $options['subdirectory']; unset($options['subdirectory']); } // Correctly detect the slash we need to use here if (strpos($path, '/') !== false) { $slash_type = '/'; } else { $slash_type = '\\'; } /* Open up the directory */ $handle = opendir($path); if (!is_resource($handle)) { debug_event('read', "Unable to open {$path}", 5); Error::add('catalog_add', sprintf(T_('Error: Unable to open %s'), $path)); return false; } /* Change the dir so is_dir works correctly */ if (!chdir($path)) { debug_event('read', "Unable to chdir to {$path}", 2); Error::add('catalog_add', sprintf(T_('Error: Unable to change to directory %s'), $path)); return false; } // Ensure that we've got our cache $this->_create_filecache(); debug_event('Memory', UI::format_bytes(memory_get_usage(true)), 5); /* Recurse through this dir and create the files array */ while (false !== ($file = readdir($handle))) { /* Skip to next if we've got . or .. */ if (substr($file, 0, 1) == '.') { continue; } debug_event('read', "Starting work on {$file} inside {$path}", 5); debug_event('Memory', UI::format_bytes(memory_get_usage(true)), 5); /* Create the new path */ $full_file = $path . $slash_type . $file; /* First thing first, check if file is already in catalog. * This check is very quick, so it should be performed before any other checks to save time */ if (isset($this->_filecache[strtolower($full_file)])) { continue; } // Incase this is the second time through clear this variable // if it was set the day before unset($failed_check); if (AmpConfig::get('no_symlinks')) { if (is_link($full_file)) { debug_event('read', "Skipping symbolic link {$path}", 5); continue; } } /* If it's a dir run this function again! */ if (is_dir($full_file)) { $this->add_files($full_file, $options); /* Change the dir so is_dir works correctly */ if (!chdir($path)) { debug_event('read', "Unable to chdir to {$path}", 2); Error::add('catalog_add', sprintf(T_('Error: Unable to change to directory %s'), $path)); } /* Skip to the next file */ continue; } //it's a directory $is_audio_file = Catalog::is_audio_file($file); if (AmpConfig::get('catalog_video_pattern')) { $is_video_file = Catalog::is_video_file($file); } if ($options['parse_playlist'] && AmpConfig::get('catalog_playlist_pattern')) { $is_playlist = Catalog::is_playlist_file($file); } /* see if this is a valid audio file or playlist file */ if ($is_audio_file or $is_video_file or $is_playlist) { /* Now that we're sure its a file get filesize */ $file_size = filesize($full_file); if (!$file_size) { debug_event('read', "Unable to get filesize for {$full_file}", 2); /* HINT: FullFile */ Error::add('catalog_add', sprintf(T_('Error: Unable to get filesize for %s'), $full_file)); } // file_size check if (!Core::is_readable($full_file)) { // not readable, warn user debug_event('read', "{$full_file} is not readable by ampache", 2); /* HINT: FullFile */ Error::add('catalog_add', sprintf(T_('%s is not readable by ampache'), $full_file)); continue; } // Check to make sure the filename is of the expected charset if (function_exists('iconv')) { $convok = false; $site_charset = AmpConfig::get('site_charset'); $lc_charset = $site_charset; if (AmpConfig::get('lc_charset')) { $lc_charset = AmpConfig::get('lc_charset'); } $enc_full_file = iconv($lc_charset, $site_charset, $full_file); if ($lc_charset != $site_charset) { $convok = strcmp($full_file, iconv($site_charset, $lc_charset, $enc_full_file)) == 0; } else { $convok = strcmp($enc_full_file, $full_file) == 0; } if (!$convok) { debug_event('read', $full_file . ' has non-' . $site_charset . ' characters and can not be indexed, converted filename:' . $enc_full_file, '1'); /* HINT: FullFile */ Error::add('catalog_add', sprintf(T_('%s does not match site charset'), $full_file)); continue; } $full_file = $enc_full_file; } // end if iconv if ($is_playlist) { debug_event('read', 'Found playlist file to import: ' . $file, '5'); $this->_playlists[] = $full_file; } else { if ($is_audio_file) { $this->_insert_local_song($full_file, $file_size); } else { $this->insert_local_video($full_file, $file_size); } $this->count++; $file = str_replace(array('(', ')', '\''), '', $full_file); if (UI::check_ticker()) { UI::update_text('add_count_' . $this->id, $this->count); UI::update_text('add_dir_' . $this->id, scrub_out($file)); } // update our current state } // if it's not an m3u } else { debug_event('read', "{$full_file} ignored, non-audio file or 0 bytes", 5); } // else not an audio file } // end while reading directory debug_event('closedir', "Finished reading {$path} , closing handle", 5); // This should only happen on the last run if ($path == $this->path) { UI::update_text('add_count_' . $this->id, $this->count); UI::update_text('add_dir_' . $this->id, scrub_out($file)); } /* Close the dir handle */ @closedir($handle); }