/** * Execute the console command. * * @return mixed */ public function handle() { if ($this->option('tracks') === 'all') { // Get all cacheable track files $trackFiles = TrackFile::where('is_cacheable', true)->with('track.album')->get(); } else { // Get all expired track files $trackFiles = TrackFile::where('is_cacheable', true)->where('expires_at', '<=', Carbon::now())->with('track.album')->get(); } // Delete above track files if (count($trackFiles) === 0) { $this->info('No tracks found. Exiting.'); } else { if ($this->option('force') || $this->confirm(count($trackFiles) . ' cacheable track files found. Proceed to delete their files if they exist? [y|N]', false)) { $count = 0; foreach ($trackFiles as $trackFile) { // Set expiration to null (so can be re-cached upon request) $trackFile->expires_at = null; $trackFile->update(); // Delete file if exists if (File::exists($trackFile->getFile())) { $count++; File::delete($trackFile->getFile()); $this->info('Deleted ' . $trackFile->getFile()); } // Remove the cached file size for the album Cache::forget($trackFile->track->album->getCacheKey('filesize-' . $trackFile->format)); } $this->info($count . ' files deleted. Deletion complete. Exiting.'); } else { $this->info('Deletion cancelled. Exiting.'); } } }
/** * Execute the console command. * * @return mixed */ public function handle() { $this->info('***'); $this->info('If this is your first time running this command, it is *highly* recommended that you ensure the file sizes for all track files have been populated.'); $this->info('***'); if ($this->option('force') || $this->confirm('Are you sure you want to delete all to-be-cached track files and encode missing non-cached track files?', false)) { //========================================================================================================== // Delete previously cached track files //========================================================================================================== $this->output->newLine(1); $this->info('========== Step 1/4 - Deleting previously cached track files. =========='); $count = 0; // Chunk track files which are cacheable and NOT master TrackFile::where('is_cacheable', true)->where('is_master', false)->chunk(200, function ($trackFiles) use(&$count) { // Delete chunked track files foreach ($trackFiles as $trackFile) { // Clear expiration so will be re-cached on next request $trackFile->expires_at = null; $trackFile->update(); // Delete files if (File::exists($trackFile->getFile())) { $count++; File::delete($trackFile->getFile()); $this->info('Deleted ' . $trackFile->getFile()); } } $this->info($count . ' track files deleted. Deletion complete. Continuing.'); }); //========================================================================================================== // Update the database entries for cacheable track files - non-cacheable to cacheable //========================================================================================================== $this->output->newLine(3); $this->info('========== Step 2/4 - Updating is_cacheable entries in database. =========='); $trackFileCount = 0; $formats = []; // Find track files which are meant to be cacheable and NOT master, but currently not cacheable TrackFile::where('is_cacheable', false)->whereIn('format', Track::$CacheableFormats)->where('is_master', false)->chunk(200, function ($trackFiles) use(&$trackFileCount, &$formats) { $this->output->newLine(1); $this->info('---------- Start Chunk ----------'); // Set above files to cacheable in the database foreach ($trackFiles as $trackFile) { $trackFileCount++; // Let user know which formats, previously not cached, were made cacheable $formats[] = $trackFile->format; $trackFile->expires_at = null; $trackFile->is_cacheable = true; $trackFile->update(); } $this->info('----------- End Chunk -----------'); $this->output->newLine(1); }); $this->info('Format(s) set from non-cacheable to cacheable: ' . implode(' ', array_unique($formats))); $this->info($trackFileCount . ' non-cacheable track files set to cacheable.'); $this->output->newLine(2); //========================================================================================================== // Update the database entries for cacheable track files - cacheable to non-cacheable //========================================================================================================== $trackFileCount = 0; $formats = []; // Chunk track files which are NOT meant to be cacheable, but currently cacheable TrackFile::where('is_cacheable', true)->whereNotIn('format', Track::$CacheableFormats)->chunk(200, function ($trackFiles) use(&$trackFileCount, &$formats) { $this->output->newLine(1); $this->info('---------- Start Chunk ----------'); // Set chunked track files to non-cacheable in the database foreach ($trackFiles as $trackFile) { $trackFileCount++; // Let user know which formats, previously not cached, were made cacheable $formats[] = $trackFile->format; $trackFile->expires_at = null; $trackFile->is_cacheable = false; $trackFile->update(); } $this->info('----------- End Chunk -----------'); $this->output->newLine(1); $this->output->newLine(1); }); $this->info('Format(s) set from cacheable to non-cacheable: ' . implode(' ', array_unique($formats))); $this->info($trackFileCount . ' cacheable track files set to non-cacheable.'); //========================================================================================================== // Delete track files which have now been marked as cacheable //========================================================================================================== $this->output->newLine(3); $this->info('========== Step 3/4 - Deleting now-cacheable track files. =========='); $count = 0; $trackFileCount = 0; // Find track files which are cacheable and NOT master TrackFile::whereIn('format', Track::$CacheableFormats)->where('is_master', false)->chunk(200, function ($trackFiles) use(&$count, &$trackFileCount) { $this->output->newLine(1); $this->info('---------- Start Chunk ----------'); foreach ($trackFiles as $trackFile) { $trackFileCount++; // Delete track files if track files exist; double-check that they are NOT master files if (File::exists($trackFile->getFile()) && $trackFile->is_master == false) { $count++; File::delete($trackFile->getFile()); $this->info('Deleted ' . $trackFile->getFile()); } } $this->info('----------- End Chunk -----------'); $this->output->newLine(1); }); $this->info(sprintf('%d track files deleted out of %d track files. Continuing.', $count, $trackFileCount)); //========================================================================================================== // Encode missing (i.e., now non-cacheable) track files //========================================================================================================== $this->output->newLine(3); $this->info('========== Step 4/4 - Encoding missing track files. =========='); $count = 0; // Chunk non-cacheable track files TrackFile::where('is_cacheable', false)->where('is_master', false)->chunk(200, function ($trackFiles) use(&$count) { $this->output->newLine(1); $this->info('---------- Start Chunk ----------'); // Record the track files which do not exist (i.e., have not been encoded yet) $emptyTrackFiles = []; foreach ($trackFiles as $trackFile) { if (!File::exists($trackFile->getFile())) { $count++; $emptyTrackFiles[] = $trackFile; } } // Encode recorded track files foreach ($emptyTrackFiles as $emptyTrackFile) { $this->info("Started encoding track file ID {$emptyTrackFile->id}"); $this->dispatch(new EncodeTrackFile($emptyTrackFile, false)); } $this->info('----------- End Chunk -----------'); $this->output->newLine(1); }); $this->info($count . ' track files encoded.'); $this->output->newLine(1); $this->info('Rebuild complete. Exiting.'); } else { $this->info('Rebuild cancelled. Exiting.'); } }
/** * Execute the job. * * @return void */ public function handle() { // Sanity-check: was this file just generated, or is it already being processed? if ($this->trackFile->status === TrackFile::STATUS_PROCESSING) { Log::warning('Track file #' . $this->trackFile->id . ' (track #' . $this->trackFile->track_id . ') is already being processed!'); return; } elseif (!$this->trackFile->is_expired) { Log::warning('Track file #' . $this->trackFile->id . ' (track #' . $this->trackFile->track_id . ') is still valid! No need to re-encode it.'); return; } // Start the job $this->trackFile->status = TrackFile::STATUS_PROCESSING; $this->trackFile->save(); // Use the track's master file as the source if ($this->isForUpload) { $source = $this->trackFile->track->getTemporarySourceFile(); } else { $source = TrackFile::where('track_id', $this->trackFile->track_id)->where('is_master', true)->first()->getFile(); } // Assign the target $this->trackFile->track->ensureDirectoryExists(); $target = $this->trackFile->getFile(); // Prepare the command $format = Track::$Formats[$this->trackFile->format]; $command = $format['command']; $command = str_replace('{$source}', '"' . $source . '"', $command); $command = str_replace('{$target}', '"' . $target . '"', $command); Log::info('Encoding track file ' . $this->trackFile->id . ' into ' . $target); // Start a synchronous process to encode the file $process = new Process($command); try { $process->mustRun(); } catch (ProcessFailedException $e) { Log::error('An exception occured in the encoding process for track file ' . $this->trackFile->id . ' - ' . $e->getMessage()); Log::info($process->getOutput()); // Ensure queue fails throw $e; } // Update the tags of the track $this->trackFile->track->updateTags($this->trackFile->format); // Insert the expiration time for cached tracks if ($this->isExpirable && $this->trackFile->is_cacheable) { $this->trackFile->expires_at = Carbon::now()->addMinutes(Config::get('ponyfm.track_file_cache_duration')); $this->trackFile->save(); } // Update file size $this->trackFile->updateFilesize(); // Complete the job $this->trackFile->status = TrackFile::STATUS_NOT_BEING_PROCESSED; $this->trackFile->save(); if ($this->isForUpload) { if (!$this->trackFile->is_master && $this->trackFile->is_cacheable) { File::delete($this->trackFile->getFile()); } // This was the final TrackFile for this track! if ($this->trackFile->track->status === Track::STATUS_COMPLETE) { if ($this->autoPublishWhenComplete) { $this->trackFile->track->published_at = Carbon::now(); DB::table('tracks')->whereUserId($this->trackFile->track->user_id)->update(['is_latest' => false]); $this->trackFile->track->is_latest = true; $this->trackFile->track->save(); } File::delete($this->trackFile->track->getTemporarySourceFile()); } } }