T357, T125: Added SIGINT handling and a skip feature to the import script, implemented importing of lossy files, made the import script actually import tracks now, and other improvements.

This commit is contained in:
Peter Deltchev 2015-09-07 07:02:25 -07:00
parent f17e824586
commit 15760a1040
4 changed files with 101 additions and 46 deletions

View file

@ -21,7 +21,14 @@ class ClassifyMLPMA extends Command {
* *
* @var string * @var string
*/ */
protected $description = 'Add Pony.fm-specific metadata to imported MLPMA tracks.'; protected $description = 'Adds Pony.fm-specific metadata to imported MLPMA tracks.';
/**
* A counter for the number of processed tracks.
*
* @var int
*/
protected $currentTrack = 0;
/** /**
* Create a new command instance. * Create a new command instance.
@ -42,11 +49,26 @@ class ClassifyMLPMA extends Command {
{ {
// Get the list of tracks that need classification // Get the list of tracks that need classification
$tracks = DB::table('mlpma_tracks') $tracks = DB::table('mlpma_tracks')
->orderBy('id') ->orderBy('mlpma_tracks.id')
->join('tracks', 'tracks.id', '=', 'mlpma_tracks.track_id')
->whereNull('tracks.published_at')
->get(); ->get();
$this->comment('Importing tracks...');
$totalTracks = sizeof($tracks);
$fileToStartAt = (int) $this->option('startAt') - 1;
$this->comment("Skipping $fileToStartAt files..." . PHP_EOL);
$tracks = array_slice($tracks, $fileToStartAt);
$this->currentTrack = $fileToStartAt;
foreach ($tracks as $track) { foreach ($tracks as $track) {
$parsedTags = json_decode($track->parsed_tags); $this->currentTrack++;
$this->comment('[' . $this->currentTrack . '/' . $totalTracks . '] Classifying track [' . $track->filename . ']...');
$parsedTags = json_decode($track->parsed_tags, true);
//========================================================================================================== //==========================================================================================================
@ -69,14 +91,14 @@ class ClassifyMLPMA extends Command {
// If it has "Ingram" in the name, it's definitely an official song remix. // If it has "Ingram" in the name, it's definitely an official song remix.
if (Str::contains(Str::lower($track->filename), 'ingram')) { if (Str::contains(Str::lower($track->filename), 'ingram')) {
$this->comment('This is an official song remix!'); $this->info('This is an official song remix!');
list($trackType, $linkedSongIds) = $this->classifyTrack($track->filename, $officialSongs, true); list($trackType, $linkedSongIds) = $this->classifyTrack($track->filename, $officialSongs, true);
// If it has "remix" in the name, it's definitely a remix. // If it has "remix" in the name, it's definitely a remix.
} else if (Str::contains(Str::lower($sanitizedTrackTitle), 'remix')) { } else if (Str::contains(Str::lower($sanitizedTrackTitle), 'remix')) {
$this->comment('This is some kind of remix!'); $this->info('This is some kind of remix!');
list($trackType, $linkedSongIds) = $this->classifyTrack($track->filename, $officialSongs); list($trackType, $linkedSongIds) = $this->classifyTrack($track->filename, $officialSongs);
} }
@ -96,6 +118,7 @@ class ClassifyMLPMA extends Command {
$track->showSongs()->attach($linkedSongIds); $track->showSongs()->attach($linkedSongIds);
} }
echo PHP_EOL;
} }
} }
@ -107,9 +130,7 @@ class ClassifyMLPMA extends Command {
*/ */
protected function getArguments() protected function getArguments()
{ {
return array( return array();
array('example', InputArgument::REQUIRED, 'An example argument.'),
);
} }
/** /**
@ -120,7 +141,7 @@ class ClassifyMLPMA extends Command {
protected function getOptions() protected function getOptions()
{ {
return array( return array(
array('example', null, InputOption::VALUE_OPTIONAL, 'An example option.', null), array('startAt', null, InputOption::VALUE_OPTIONAL, 'Track to start importing from. Useful for resuming an interrupted import.', 1),
); );
} }
@ -143,11 +164,12 @@ class ClassifyMLPMA extends Command {
$this->comment('=> Matched official song: [' . $song->id . '] ' . $song->title); $this->comment('=> Matched official song: [' . $song->id . '] ' . $song->title);
} }
if ($isRemixOfOfficialTrack && sizeof($officialSongs) === 1) { if ($isRemixOfOfficialTrack && sizeof($officialSongs) === 1) {
$linkedSongIds = [$officialSongs[0]->id]; $linkedSongIds = [$officialSongs[0]->id];
} else { } else {
if ($isRemixOfOfficialTrack) { if ($isRemixOfOfficialTrack && sizeof($officialSongs) > 1) {
$this->question('Multiple official songs matched! Please enter the ID of the correct one.'); $this->question('Multiple official songs matched! Please enter the ID of the correct one.');
} else if (sizeof($officialSongs) > 0) { } else if (sizeof($officialSongs) > 0) {

View file

@ -7,9 +7,7 @@ use Illuminate\Support\Facades\File;
use Entities\Album; use Entities\Album;
use Entities\Image; use Entities\Image;
use Entities\User; use Entities\User;
use Entities\ShowSong;
use Entities\Track; use Entities\Track;
use Entities\TrackType;
use Commands\UploadTrackCommand; use Commands\UploadTrackCommand;
use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\File\UploadedFile;
use Carbon\Carbon; use Carbon\Carbon;
@ -40,6 +38,20 @@ class ImportMLPMA extends Command {
*/ */
protected $ignoredExtensions = ['db', 'jpg', 'png']; protected $ignoredExtensions = ['db', 'jpg', 'png'];
/**
* Used to stop the import process when a SIGINT is received.
*
* @var bool
*/
protected $isInterrupted = false;
/**
* A counter for the number of processed tracks.
*
* @var int
*/
protected $currentFile;
/** /**
* Create a new command instance. * Create a new command instance.
* *
@ -50,6 +62,12 @@ class ImportMLPMA extends Command {
parent::__construct(); parent::__construct();
} }
public function handleInterrupt($signo) {
$this->error('Import aborted!');
$this->error('Resume it from here using: --startAt='.$this->currentFile);
$this->isInterrupted = true;
}
/** /**
* Execute the console command. * Execute the console command.
* *
@ -57,6 +75,8 @@ class ImportMLPMA extends Command {
*/ */
public function fire() public function fire()
{ {
pcntl_signal(SIGINT, [$this, 'handleInterrupt']);
$mlpmaPath = Config::get('app.files_directory').'mlpma'; $mlpmaPath = Config::get('app.files_directory').'mlpma';
$tmpPath = Config::get('app.files_directory').'tmp'; $tmpPath = Config::get('app.files_directory').'tmp';
@ -72,14 +92,25 @@ class ImportMLPMA extends Command {
$artists = File::directories($mlpmaPath); $artists = File::directories($mlpmaPath);
$this->info(sizeof($artists).' artists found!'); $this->info(sizeof($artists).' artists found!');
$this->comment('Importing tracks...'.PHP_EOL); $this->comment('Importing tracks...');
$totalFiles = sizeof($files); $totalFiles = sizeof($files);
$currentFile = 0;
$fileToStartAt = (int) $this->option('startAt') - 1;
$this->comment("Skipping $fileToStartAt files...".PHP_EOL);
$files = array_slice($files, $fileToStartAt);
$this->currentFile = $fileToStartAt;
foreach($files as $file) { foreach($files as $file) {
$currentFile++; $this->currentFile++;
$this->comment('['.$currentFile.'/'.$totalFiles.'] Importing track ['. $file->getFilename() .']...');
pcntl_signal_dispatch();
if ($this->isInterrupted) {
break;
}
$this->comment('['.$this->currentFile.'/'.$totalFiles.'] Importing track ['. $file->getFilename() .']...');
if (in_array($file->getExtension(), $this->ignoredExtensions)) { if (in_array($file->getExtension(), $this->ignoredExtensions)) {
$this->comment('This is not an audio file! Skipping...'.PHP_EOL); $this->comment('This is not an audio file! Skipping...'.PHP_EOL);
@ -143,7 +174,7 @@ class ImportMLPMA extends Command {
} }
// This is later used by the classification/publishing script to determine the publication date. // This is later used by the classification/publishing script to determine the publication date.
$parsedTags['released_at'] = $releasedAt; $parsedTags['released_at'] = $releasedAt->toDateTimeString();
//========================================================================================================== //==========================================================================================================
// Does this track have vocals? // Does this track have vocals?
@ -178,12 +209,14 @@ class ImportMLPMA extends Command {
$artist->slug = $artist->slug.'-'.Str::random(4); $artist->slug = $artist->slug.'-'.Str::random(4);
} }
$artist = $artist->save(); $artist->save();
} }
//========================================================================================================== //==========================================================================================================
// Extract the cover art, if any exists. // Extract the cover art, if any exists.
//========================================================================================================== //==========================================================================================================
$this->comment('Extracting cover art!');
$coverId = null; $coverId = null;
if (array_key_exists('comments', $allTags) && array_key_exists('picture', $allTags['comments'])) { if (array_key_exists('comments', $allTags) && array_key_exists('picture', $allTags['comments'])) {
$image = $allTags['comments']['picture'][0]; $image = $allTags['comments']['picture'][0];
@ -213,7 +246,7 @@ class ImportMLPMA extends Command {
$coverId = $cover->id; $coverId = $cover->id;
} else { } else {
$this->error('No cover art found!'); $this->comment('No cover art found!');
} }
@ -246,13 +279,9 @@ class ImportMLPMA extends Command {
//========================================================================================================== //==========================================================================================================
// Save this track. // Save this track.
//========================================================================================================== //==========================================================================================================
$title = $parsedTags['title'];
//
// $track = Track::where('user_id', '=', $artist->id)
// ->where('title', '=', $title)
// ->first();
// "upload" the track to Pony.fm // "Upload" the track to Pony.fm
$this->comment('Transcoding the track!');
Auth::loginUsingId($artist->id); Auth::loginUsingId($artist->id);
$trackFile = new UploadedFile($file->getPathname(), $file->getFilename(), $allTags['mime_type']); $trackFile = new UploadedFile($file->getPathname(), $file->getFilename(), $allTags['mime_type']);
@ -261,14 +290,29 @@ class ImportMLPMA extends Command {
$upload = new UploadTrackCommand(true); $upload = new UploadTrackCommand(true);
$result = $upload->execute(); $result = $upload->execute();
// var_dump(null);
if ($result->didFail()) { if ($result->didFail()) {
$this->error(json_encode($result->getValidator()->messages()->getMessages(), JSON_PRETTY_PRINT)); $this->error(json_encode($result->getValidator()->messages()->getMessages(), JSON_PRETTY_PRINT));
} else { } else {
// Save metadata.
$track = Track::find($result->getResponse()['id']);
$track->title = $parsedTags['title'];
$track->cover_id = $coverId;
$track->album_id = $albumId;
$track->track_number = $parsedTags['track_number'];
$track->released_at = $releasedAt;
$track->description = $parsedTags['comments'];
$track->is_downloadable = true;
$track->lyrics = $parsedTags['lyrics'];
$track->is_vocal = $isVocal;
$track->license_id = 2;
$track->save();
// If we made it to here, the track is intact! Log the import.
DB::table('mlpma_tracks') DB::table('mlpma_tracks')
->insert([ ->insert([
'track_id' => $result['id'], 'track_id' => $result->getResponse()['id'],
'path' => $file->getRelativePath(), 'path' => $file->getRelativePath(),
'filename' => $file->getFilename(), 'filename' => $file->getFilename(),
'extension' => $file->getExtension(), 'extension' => $file->getExtension(),
@ -276,20 +320,8 @@ class ImportMLPMA extends Command {
'parsed_tags' => json_encode($parsedTags), 'parsed_tags' => json_encode($parsedTags),
'raw_tags' => json_encode($rawTags), 'raw_tags' => json_encode($rawTags),
]); ]);
$track = Track::find($result['id']);
var_dump($track);
$track->title = $parsedTags['title'];
$track->cover_id = $coverId;
$track->album_id = $albumId;
$track->track_number = $parsedTags['track_number'];
$track->released_at = $releasedAt;
$track->is_vocal = $isVocal;
$track->save();
} }
echo PHP_EOL.PHP_EOL; echo PHP_EOL.PHP_EOL;
} }
} }
@ -311,7 +343,9 @@ class ImportMLPMA extends Command {
*/ */
protected function getOptions() protected function getOptions()
{ {
return array(); return array(
array('startAt', null, InputOption::VALUE_OPTIONAL, 'Track to start importing from. Useful for resuming an interrupted import.', 1),
);
} }

View file

@ -78,7 +78,6 @@
$isLossyUpload = !in_array($audioObject->getAudioCodec(), $this->_losslessFormats); $isLossyUpload = !in_array($audioObject->getAudioCodec(), $this->_losslessFormats);
if ($isLossyUpload) { if ($isLossyUpload) {
if ($audioObject->getAudioCodec() === 'mp3') { if ($audioObject->getAudioCodec() === 'mp3') {
$masterFormat = 'MP3'; $masterFormat = 'MP3';
@ -93,10 +92,11 @@
$trackFile = new TrackFile(); $trackFile = new TrackFile();
$trackFile->is_master = true; $trackFile->is_master = true;
$trackFile->format = $masterFormat; $trackFile->format = $masterFormat;
$trackFile->track_id = $track->id;
$trackFile->save();
// Lossy masters are copied into the datastore - no re-encoding involved. // Lossy masters are copied into the datastore - no re-encoding involved.
File::copy($source, $trackFile->getFilename()); File::copy($source, $trackFile->getFile());
$track->trackFiles()->save($trackFile);
} }
foreach (Track::$Formats as $name => $format) { foreach (Track::$Formats as $name => $format) {

View file

@ -448,8 +448,7 @@
$command .= '--genre ' . escapeshellarg($this->genre != null ? $this->genre->name : '') . ' '; $command .= '--genre ' . escapeshellarg($this->genre != null ? $this->genre->name : '') . ' ';
$command .= '--copyright ' . escapeshellarg('© '.$this->year.' '.$this->user->display_name).' '; $command .= '--copyright ' . escapeshellarg('© '.$this->year.' '.$this->user->display_name).' ';
$command .= '--comment "' . 'Downloaded from: https://pony.fm/' . '" '; $command .= '--comment "' . 'Downloaded from: https://pony.fm/' . '" ';
$command .= '--encodingTool "' . 'Pony.fm' . '" '; $command .= '--encodingTool "' . 'Pony.fm - https://pony.fm/' . '" ';
$command .= '--encodedBy "' . 'Pony.fm - https://pony.fm/' . '" ';
if ($this->album_id !== NULL) { if ($this->album_id !== NULL) {
$command .= '--album ' . escapeshellarg($this->album->title) . ' '; $command .= '--album ' . escapeshellarg($this->album->title) . ' ';