mirror of
https://github.com/Poniverse/Pony.fm.git
synced 2024-11-22 21:18:00 +01:00
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:
parent
f17e824586
commit
15760a1040
4 changed files with 101 additions and 46 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) . ' ';
|
||||||
|
|
Loading…
Reference in a new issue