public function import() { $path = $this->args[0]; $recursive = $this->param('recursive'); //$verbose = $this->param('verbose'); if (Cache::read('import')) { $this->out("<warning>[WARN]</warning> The import process is already running via another client or the CLI"); exit(0); } $found = array(); if (is_dir($path)) { $path = new Folder($path); $this->out("<info>[INFO]</info> Scan {$path->path}..."); if ($recursive) { $found = $path->findRecursive('^.*\\.(mp3|ogg|flac|aac)$'); } else { $found = $path->find('^.*\\.(mp3|ogg|flac|aac)$'); // The Folder::find() method does not return the absolute path of each file, we need to add it: $found = preg_filter('/^/', $path->path, $found); } } elseif (file_exists($path)) { $found = array($path); } else { $this->error('Invalid path'); } $already_imported = $this->Song->find('list', array('fields' => array('Song.id', 'Song.source_path'))); $to_import = array_merge(array_diff($found, $already_imported)); $to_import_count = count($to_import); $found_count = count($found); if ($to_import_count == 1) { $selection = $this->in("[INFO] You asked to import {$to_import['0']}. Continue?", array('yes', 'no'), 'yes'); } elseif ($to_import_count > 1) { $diff = $found_count - $to_import_count; $selection = $this->in("[INFO] Found {$to_import_count} audio files ({$diff} already in the database). Continue?", array('yes', 'no'), 'yes'); } elseif ($found_count > 0 && $to_import_count == 0) { $this->out("<info>[INFO]</info> {$found_count} file(s) found, but already in the database."); exit(0); } else { $this->out('<info>[INFO]</info> Nothing to do.'); exit(0); } if ($selection == 'no') { $this->out('<info>[INFO]</info> Ok, bye.'); exit(0); } $this->out('<info>[INFO]</info> Run import', 0); // Write lock to avoid multiple import processes in the same time if (Cache::read('import')) { $this->out("<warning>[WARN]</warning> The import process is already running via another client or the CLI"); exit(0); } else { Cache::write('import', true); // Catch SIGINT pcntl_signal(SIGINT, function () { Cache::delete('import'); $this->refreshSyncToken(); exit; }); $i = 1; foreach ($to_import as $file) { pcntl_signal_dispatch(); $song_manager = new SongManager($file); $parse_result = $song_manager->parseMetadata(); if ($parse_result['status'] != 'OK') { if ($parse_result['status'] == 'WARN') { $this->overwrite("<warning>[WARN]</warning>[{$file}] - " . $parse_result['message']); } elseif ($parse_result['status'] == 'ERR') { $this->overwrite("<error>[ERR]</error>[{$file}] - " . $parse_result['message']); } } $this->Song->create(); if (!$this->Song->save($parse_result['data'])) { $this->overwrite("<error>[ERR]</error>[{$file}] - Unable to save the song metadata to the database"); } // Progressbar $percent_done = 100 * $i / $to_import_count; $hashtags_quantity = round(45 * $percent_done / 100); $remaining_spaces = 45 - $hashtags_quantity; if ($i < $to_import_count) { $this->overwrite('<info>[INFO]</info> Run import: [' . round($percent_done) . '%] [' . str_repeat('#', $hashtags_quantity) . str_repeat(' ', $remaining_spaces) . ']', 0); } else { $this->overwrite('<info>[INFO]</info> Run import: [' . round($percent_done) . '%] [' . str_repeat('#', $hashtags_quantity) . str_repeat(' ', $remaining_spaces) . ']'); } $i++; } // Delete lock Cache::delete('import'); $this->refreshSyncToken(); } }
/** * The import view function. * The function does the following action: * - Check the root path, * - Search every media files (mp3, ogg, flac, aac) to load them in an array * - Compare this array with the list of existing songs to keep only new tracks * - Pass this array to the view. * * @see SongsController::_importSong */ public function import() { App::uses('Folder', 'Utility'); App::uses('SongManager', 'SongManager'); $this->loadModel('Setting'); $this->Setting->contain('Rootpath'); $settings = $this->Setting->find('first'); if ($this->request->is('get')) { if ($settings) { $paths = $settings['Rootpath']; } else { $this->Flash->error(__('Please define a root path.')); $this->redirect(array('controller' => 'settings', 'action' => 'index')); } // The files found via Folder->findRecursive() $found = array(); foreach ($paths as $path) { $dir = new Folder($path['rootpath']); $found = array_merge($found, $dir->findRecursive('^.*\\.(mp3|ogg|flac|aac)$')); } // The files already imported $already_imported = $this->Song->find('list', array('fields' => array('Song.id', 'Song.source_path'))); // The difference between $found and $already_imported $to_import = array_merge(array_diff($found, $already_imported)); $to_import_count = count($to_import); $found_count = count($found); $diff_count = $found_count - $to_import_count; $this->Session->write('to_import', $to_import); $this->set(compact('to_import_count', 'diff_count')); } elseif ($this->request->is('post')) { $this->viewClass = 'Json'; $import_result = array(); if (Cache::read('import')) { // Read lock to avoid multiple import processes in the same time $import_result[0]['status'] = 'ERR'; $import_result[0]['message'] = __('The import process is already running via another client or the CLI.'); $this->set(compact('import_result')); $this->set('_serialize', array('import_result')); } else { // Write lock Cache::write('import', true); $to_import = $this->Session->read('to_import'); $imported = array(); $i = 0; foreach ($to_import as $file) { $song_manager = new SongManager($file); $parse_result = $song_manager->parseMetadata(); $this->Song->create(); if (!$this->Song->save($parse_result['data'])) { $import_result[$file]['status'] = 'ERR'; $import_result[$file]['message'] = __('Unable to save the song metadata to the database'); } else { unset($parse_result['data']); $import_result[$i]['file'] = $file; $import_result[$i]['status'] = $parse_result['status']; $import_result[$i]['message'] = $parse_result['message']; } if ($i >= 100) { break; } $imported[] = $file; $i++; } if ($i) { $settings['Setting']['sync_token'] = time(); $this->Setting->save($settings); } // Delete lock Cache::delete('import'); $sync_token = $settings['Setting']['sync_token']; $diff = array_diff($to_import, $imported); $this->Session->write('to_import', $diff); $this->set(compact('sync_token', 'import_result')); $this->set('_serialize', array('sync_token', 'import_result')); } } }