. */ namespace Poniverse\Ponyfm\Console\Commands; use Illuminate\Console\Command; use Poniverse\Ponyfm\Track; use Poniverse\Ponyfm\TrackFile; use Symfony\Component\HttpFoundation\File\File; class RebuildTrackCache extends Command { /** * The name and signature of the console command. * * @var string */ protected $signature = 'track-cache:rebuild [--force : Skip all prompts.]'; /** * The console command description. * * @var string */ protected $description = 'Rebuilds the track cache for when $CacheableFormats is changed. Deletes cacheable files and encodes missing files which are not cacheable.'; /** * Create a new command instance. * */ public function __construct() { parent::__construct(); } /** * Execute the console command. * * @return mixed */ public function handle() { $this->info('This will run \'php artisan down\' if you proceed and \'php artisan up\' when complete.'); if ($this->option('force') || $this->confirm('Are you sure you want to delete all to-be-cached files and encode missing non-cached files? [y|N]', false) ) { $this->call('down'); //========================================================================================================== // Delete previously cached tracks //========================================================================================================== // Find files which are cacheable and NOT master $trackFiles = TrackFile::where('is_cacheable', true) ->where('is_master', false) ->get(); // Delete above files if (count($trackFiles) == 0) { $this->info('No tracks found. Continuing.'); } else { $this->info(count($trackFiles) . ' tracks found.'); $count = 0; foreach ($trackFiles as $trackFile) { // Clear expiration so will be re-cached on next request $trackFile->expiration = null; $trackFile->update(); // Delete files if (File::exists($trackFile->getFile())) { $count++; File::delete($trackFile->getFile()); $this->info('Deleted ' . $trackFile->getFile()); } } $this->info($count . ' files deleted. Deletion complete. Continuing.'); } //========================================================================================================== // Update the database entries for cacheable files - non-cacheable to cacheable //========================================================================================================== $this->info('--- Step 2/4 - Updating is_cacheable entries in database. ---'); // Find files which are meant to be cacheable and NOT master, but currently not cacheable $trackFiles = TrackFile::where('is_cacheable', false) ->whereIn('format', array_keys(Track::$CacheableFormats)) ->where('is_master', false) ->get(); $formats = []; // Set above files to cacheable in the database foreach ($trackFiles as $trackFile) { // Let user know which formats, previously not cached, were made cacheable $formats[] = $trackFile->format; $trackFile->expiration = null; $trackFile->is_cacheable = true; $trackFile->update(); } $this->info('Format(s) set from non-cacheable to cacheable: ' . implode(' ', array_unique($formats))); $this->info(count($trackFiles) . ' non-cacheable tracks set to cacheable.'); //========================================================================================================== // Update the database entries for cacheable files - cacheable to non-cacheable //========================================================================================================== // Find files which are NOT meant to be cacheable, but currently cacheable $trackFiles = TrackFile::where('is_cacheable', true) ->whereNotIn('format', array_keys(Track::$CacheableFormats)) ->get(); $formats = []; // Set above files to non-cacheable in the database foreach ($trackFiles as $trackFile) { // Let user know which formats, previously not cached, were made cacheable $formats[] = $trackFile->format; $trackFile->expiration = null; $trackFile->is_cacheable = false; $trackFile->update(); } $this->info('Format(s) set from cacheable to non-cacheable: ' . implode(' ', array_unique($formats))); $this->info(count($trackFiles) . ' cacheable tracks set to non-cacheable.'); //========================================================================================================== // Delete files which have now been marked as cacheable //========================================================================================================== $this->info('--- Step 3/4 - Deleting now-cacheable files. ---'); // Find files which are cacheable and NOT master $trackFiles = TrackFile::whereIn('format', array_keys(Track::$CacheableFormats)) ->where('is_master', false) ->get(); // Delete above files if (count($trackFiles) == 0) { $this->info('No tracks to delete found. Continuing.'); } else { $count = 0; foreach ($trackFiles as $trackFile) { // Delete files if 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(sprintf('%d files deleted out of %d tracks. Continuing.', $count, count($trackFiles))); } //========================================================================================================== // Encode missing (i.e., now non-cacheable) files //========================================================================================================== $this->info('--- Step 4/4 - Encoding missing files. ---'); // Get non-cacheable files $trackFiles = TrackFile::where('is_cacheable', false)->get(); // Record the above files which do not exist (i.e., have not been encoded yet) $trackFileIds = []; $count = 0; foreach ($trackFiles as $trackFile) { if (!File::exists($trackFile->getFile())) { $count++; $trackFileIds[] = $trackFile->id; } } // Encode recorded files $encodeTrackFileCommand = new EncodeTrackFileCommand($trackFileIds); $encodeTrackFileCommand->execute(); $this->info($count . ' tracks encoded.'); $this->call('up'); $this->info('Rebuild complete. Exiting.'); } else { $this->info('Rebuild cancelled. Exiting.'); } } }