2015-10-26 20:47:42 +01:00
< ? php
/**
* Pony . fm - A community for pony fan music .
2021-02-14 03:39:15 +01:00
* Copyright ( C ) 2015 Kelvin Zhang .
2015-10-26 20:47:42 +01:00
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU Affero General Public License for more details .
*
* You should have received a copy of the GNU Affero General Public License
* along with this program . If not , see < http :// www . gnu . org / licenses />.
*/
2021-02-14 03:34:58 +01:00
namespace App\Console\Commands ;
2015-10-26 20:47:42 +01:00
2021-02-14 03:34:58 +01:00
use App\Jobs\EncodeTrackFile ;
use App\Models\Track ;
use App\Models\TrackFile ;
2021-02-14 03:39:15 +01:00
use File ;
use Illuminate\Console\Command ;
use Illuminate\Foundation\Bus\DispatchesJobs ;
2015-10-26 20:47:42 +01:00
class RebuildTrackCache extends Command
{
2015-10-27 18:29:51 +01:00
use DispatchesJobs ;
2015-10-26 20:47:42 +01:00
/**
* The name and signature of the console command .
*
* @ var string
*/
2015-10-31 13:19:12 +01:00
protected $signature = ' rebuild : track - cache
2015-10-27 18:29:51 +01:00
{ -- force : Skip all prompts . } ' ;
2015-10-26 20:47:42 +01:00
/**
* 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 ()
{
2015-10-29 17:00:16 +01:00
$this -> info ( '***' );
2015-11-01 17:49:28 +01:00
$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.' );
2015-10-29 17:00:16 +01:00
$this -> info ( '***' );
2015-10-26 20:47:42 +01:00
2016-09-30 00:26:31 +02:00
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
)
2015-10-26 20:47:42 +01:00
) {
//==========================================================================================================
2015-11-01 17:49:28 +01:00
// Delete previously cached track files
2015-10-26 20:47:42 +01:00
//==========================================================================================================
2015-11-01 17:49:28 +01:00
$this -> output -> newLine ( 1 );
$this -> info ( '========== Step 1/4 - Deleting previously cached track files. ==========' );
2015-10-26 20:47:42 +01:00
2015-11-01 17:49:28 +01:00
$count = 0 ;
2015-10-26 20:47:42 +01:00
2015-11-01 17:49:28 +01:00
// Chunk track files which are cacheable and NOT master
TrackFile :: where ( 'is_cacheable' , true )
-> where ( 'is_master' , false )
2016-09-30 00:26:31 +02:00
-> chunk ( 200 , function ( $trackFiles ) use ( & $count ) {
2015-11-01 17:49:28 +01:00
// 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 ());
2016-06-06 08:29:37 +02:00
$this -> info ( 'Deleted ' . $trackFile -> getFile ());
2015-11-01 17:49:28 +01:00
}
2015-10-26 20:47:42 +01:00
}
2016-06-06 08:29:37 +02:00
$this -> info ( $count . ' track files deleted. Deletion complete. Continuing.' );
2015-11-01 17:49:28 +01:00
});
2015-10-26 20:47:42 +01:00
//==========================================================================================================
2015-11-01 17:49:28 +01:00
// Update the database entries for cacheable track files - non-cacheable to cacheable
2015-10-26 20:47:42 +01:00
//==========================================================================================================
2015-11-01 17:49:28 +01:00
$this -> output -> newLine ( 3 );
$this -> info ( '========== Step 2/4 - Updating is_cacheable entries in database. ==========' );
$trackFileCount = 0 ;
$formats = [];
2015-10-26 20:47:42 +01:00
2015-11-01 17:49:28 +01:00
// 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 )
2015-10-26 20:47:42 +01:00
-> where ( 'is_master' , false )
2016-09-30 00:26:31 +02:00
-> chunk ( 200 , function ( $trackFiles ) use ( & $trackFileCount , & $formats ) {
2015-11-01 17:49:28 +01:00
$this -> output -> newLine ( 1 );
$this -> info ( '---------- Start Chunk ----------' );
2015-10-26 20:47:42 +01:00
2015-11-01 17:49:28 +01:00
// 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 ;
2015-10-26 20:47:42 +01:00
2015-11-01 17:49:28 +01:00
$trackFile -> expires_at = null ;
$trackFile -> is_cacheable = true ;
$trackFile -> update ();
}
2015-10-26 20:47:42 +01:00
2015-11-01 17:49:28 +01:00
$this -> info ( '----------- End Chunk -----------' );
$this -> output -> newLine ( 1 );
});
2015-10-26 20:47:42 +01:00
2016-06-06 08:29:37 +02:00
$this -> info ( 'Format(s) set from non-cacheable to cacheable: ' . implode ( ' ' , array_unique ( $formats )));
$this -> info ( $trackFileCount . ' non-cacheable track files set to cacheable.' );
2015-11-01 17:49:28 +01:00
$this -> output -> newLine ( 2 );
2015-10-26 20:47:42 +01:00
//==========================================================================================================
2015-11-01 17:49:28 +01:00
// Update the database entries for cacheable track files - cacheable to non-cacheable
2015-10-26 20:47:42 +01:00
//==========================================================================================================
2015-11-01 17:49:28 +01:00
$trackFileCount = 0 ;
2015-10-26 20:47:42 +01:00
$formats = [];
2015-11-01 17:49:28 +01:00
// Chunk track files which are NOT meant to be cacheable, but currently cacheable
TrackFile :: where ( 'is_cacheable' , true )
-> whereNotIn ( 'format' , Track :: $CacheableFormats )
2016-09-30 00:26:31 +02:00
-> chunk ( 200 , function ( $trackFiles ) use ( & $trackFileCount , & $formats ) {
2015-11-01 17:49:28 +01:00
$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 );
});
2015-10-26 20:47:42 +01:00
2016-06-06 08:29:37 +02:00
$this -> info ( 'Format(s) set from cacheable to non-cacheable: ' . implode ( ' ' , array_unique ( $formats )));
$this -> info ( $trackFileCount . ' cacheable track files set to non-cacheable.' );
2015-10-26 20:47:42 +01:00
//==========================================================================================================
2015-11-01 17:49:28 +01:00
// Delete track files which have now been marked as cacheable
2015-10-26 20:47:42 +01:00
//==========================================================================================================
2015-11-01 17:49:28 +01:00
$this -> output -> newLine ( 3 );
$this -> info ( '========== Step 3/4 - Deleting now-cacheable track files. ==========' );
2015-10-26 20:47:42 +01:00
2015-11-01 17:49:28 +01:00
$count = 0 ;
$trackFileCount = 0 ;
// Find track files which are cacheable and NOT master
TrackFile :: whereIn ( 'format' , Track :: $CacheableFormats )
2015-10-26 20:47:42 +01:00
-> where ( 'is_master' , false )
2016-09-30 00:26:31 +02:00
-> chunk ( 200 , function ( $trackFiles ) use ( & $count , & $trackFileCount ) {
2015-11-01 17:49:28 +01:00
$this -> output -> newLine ( 1 );
$this -> info ( '---------- Start Chunk ----------' );
2015-10-26 20:47:42 +01:00
2015-11-01 17:49:28 +01:00
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 ());
2016-06-06 08:29:37 +02:00
$this -> info ( 'Deleted ' . $trackFile -> getFile ());
2015-11-01 17:49:28 +01:00
}
2015-10-26 20:47:42 +01:00
}
2015-11-01 17:49:28 +01:00
$this -> info ( '----------- End Chunk -----------' );
$this -> output -> newLine ( 1 );
});
$this -> info ( sprintf ( '%d track files deleted out of %d track files. Continuing.' , $count , $trackFileCount ));
2015-10-26 20:47:42 +01:00
//==========================================================================================================
2015-11-01 17:49:28 +01:00
// Encode missing (i.e., now non-cacheable) track files
2015-10-26 20:47:42 +01:00
//==========================================================================================================
2015-11-01 17:49:28 +01:00
$this -> output -> newLine ( 3 );
$this -> info ( '========== Step 4/4 - Encoding missing track files. ==========' );
2015-10-26 20:47:42 +01:00
$count = 0 ;
2015-11-01 17:49:28 +01:00
// Chunk non-cacheable track files
2015-11-10 09:09:39 +01:00
TrackFile :: where ( 'is_cacheable' , false )
-> where ( 'is_master' , false )
2016-09-30 00:26:31 +02:00
-> chunk ( 200 , function ( $trackFiles ) use ( & $count ) {
$this -> output -> newLine ( 1 );
$this -> info ( '---------- Start Chunk ----------' );
2015-11-01 17:49:28 +01:00
2021-02-14 03:39:15 +01:00
// Record the track files which do not exist (i.e., have not been encoded yet)
2016-09-30 00:26:31 +02:00
$emptyTrackFiles = [];
2015-11-01 17:49:28 +01:00
2016-09-30 00:26:31 +02:00
foreach ( $trackFiles as $trackFile ) {
2021-02-14 03:39:15 +01:00
if ( ! File :: exists ( $trackFile -> getFile ())) {
2016-09-30 00:26:31 +02:00
$count ++ ;
$emptyTrackFiles [] = $trackFile ;
}
2015-11-01 17:49:28 +01:00
}
2015-10-26 20:47:42 +01:00
2021-02-14 03:39:15 +01:00
// Encode recorded track files
2016-09-30 00:26:31 +02:00
foreach ( $emptyTrackFiles as $emptyTrackFile ) {
$this -> info ( " Started encoding track file ID { $emptyTrackFile -> id } " );
$this -> dispatch ( new EncodeTrackFile ( $emptyTrackFile , false ));
}
2015-11-01 17:49:28 +01:00
2016-09-30 00:26:31 +02:00
$this -> info ( '----------- End Chunk -----------' );
$this -> output -> newLine ( 1 );
});
2015-11-01 17:49:28 +01:00
2016-06-06 08:29:37 +02:00
$this -> info ( $count . ' track files encoded.' );
2015-11-01 17:49:28 +01:00
$this -> output -> newLine ( 1 );
2015-10-26 20:47:42 +01:00
$this -> info ( 'Rebuild complete. Exiting.' );
} else {
$this -> info ( 'Rebuild cancelled. Exiting.' );
}
}
}