示例#1
0
 /**
  * @throws \Exception
  * @return CommandResponse
  */
 public function execute()
 {
     if ($this->_track->album_id != null) {
         $album = $this->_track->album;
         $this->_track->album_id = null;
         $this->_track->track_number = null;
         $this->_track->delete();
         $album->updateTrackNumbers();
     } else {
         $this->_track->delete();
     }
     return CommandResponse::succeed();
 }
 public function up()
 {
     foreach (Track::with('user')->get() as $track) {
         $track->updateHash();
         $track->save();
     }
 }
示例#3
0
 public function getIndex()
 {
     $recentQuery = Track::summary()->with(['genre', 'user', 'cover', 'user.avatar'])->whereIsLatest(true)->listed()->userDetails()->explicitFilter()->published()->orderBy('published_at', 'desc')->take(30);
     $recentTracks = [];
     foreach ($recentQuery->get() as $track) {
         $recentTracks[] = Track::mapPublicTrackSummary($track);
     }
     return Response::json(['recent_tracks' => $recentTracks, 'popular_tracks' => Track::popular(30, Auth::check() && Auth::user()->can_see_explicit_content)], 200);
 }
示例#4
0
 public function getTrackRadioDetails($hash)
 {
     $track = Track::with('user', 'album', 'user.avatar', 'cover', 'comments', 'genre')->published()->whereHash($hash)->first();
     if (!$track) {
         return Response::json(['message' => 'Track not found.'], 403);
     }
     $comments = [];
     foreach ($track->comments as $comment) {
         $comments[] = ['id' => $comment->id, 'created_at' => $comment->created_at, 'content' => $comment->content, 'user' => ['name' => $comment->user->display_name, 'id' => $comment->user->id, 'url' => $comment->user->url, 'avatars' => ['normal' => $comment->user->getAvatarUrl(Image::NORMAL), 'thumbnail' => $comment->user->getAvatarUrl(Image::THUMBNAIL), 'small' => $comment->user->getAvatarUrl(Image::SMALL)]]];
     }
     return Response::json(['id' => $track->id, 'title' => $track->title, 'description' => $track->description, 'lyrics' => $track->lyrics, 'user' => ['id' => $track->user->id, 'name' => $track->user->display_name, 'url' => $track->user->url, 'avatars' => ['thumbnail' => $track->user->getAvatarUrl(Image::THUMBNAIL), 'small' => $track->user->getAvatarUrl(Image::SMALL), 'normal' => $track->user->getAvatarUrl(Image::NORMAL)]], 'stats' => ['views' => $track->view_count, 'plays' => $track->play_count, 'downloads' => $track->download_count, 'comments' => $track->comment_count, 'favourites' => $track->favourite_count], 'url' => $track->url, 'is_vocal' => !!$track->is_vocal, 'is_explicit' => !!$track->is_explicit, 'is_downloadable' => !!$track->is_downloadable, 'published_at' => $track->published_at, 'duration' => $track->duration, 'genre' => $track->genre != null ? ['id' => $track->genre->id, 'name' => $track->genre->name] : null, 'type' => ['id' => $track->track_type->id, 'name' => $track->track_type->title], 'covers' => ['thumbnail' => $track->getCoverUrl(Image::THUMBNAIL), 'small' => $track->getCoverUrl(Image::SMALL), 'normal' => $track->getCoverUrl(Image::NORMAL)], 'comments' => $comments, 'source' => $track->source], 200);
 }
 public function up()
 {
     Schema::table('tracks', function ($table) {
         $table->string('hash', 32)->nullable()->indexed();
     });
     foreach (Track::with('user')->get() as $track) {
         $track->updateHash();
         $track->save();
     }
     Schema::table('tracks', function ($table) {
         $table->string('hash', 32)->notNullable()->change();
     });
 }
 /**
  * Run the migrations.
  *
  * @return void
  */
 public function up()
 {
     // 2015_05_25_011121_create_track_files_table.php only created
     // track_files records for non-deleted tracks. This migration
     // adds them for deleted tracks, too.
     $tracks = Track::with('trackFiles')->onlyTrashed()->get();
     foreach ($tracks as $track) {
         if ($track->trackFiles->count() === 0 && $track->source !== 'mlpma') {
             foreach (Track::$Formats as $name => $item) {
                 DB::table('track_files')->insert(['track_id' => $track->id, 'is_master' => $name === 'FLAC' ? true : false, 'format' => $name, 'created_at' => $track->created_at, 'updated_at' => Carbon\Carbon::now()]);
             }
         }
     }
 }
示例#7
0
 public function getTracks()
 {
     $query = Favourite::whereUserId(Auth::user()->id)->whereNotNull('track_id')->with(['track' => function ($query) {
         $query->userDetails()->published();
     }, 'track.user', 'track.genre', 'track.cover', 'track.album', 'track.album.user']);
     $tracks = [];
     foreach ($query->get() as $fav) {
         if ($fav->track == null) {
             continue;
         }
         $tracks[] = Track::mapPublicTrackSummary($fav->track);
     }
     return Response::json(["tracks" => $tracks], 200);
 }
示例#8
0
 /**
  * @throws \Exception
  * @return CommandResponse
  */
 public function execute()
 {
     $rules = ['content' => 'required', 'track_id' => 'exists:tracks,id', 'albums_id' => 'exists:albums,id', 'playlist_id' => 'exists:playlists,id', 'profile_id' => 'exists:users,id'];
     $validator = Validator::make($this->_input, $rules);
     if ($validator->fails()) {
         return CommandResponse::fail($validator);
     }
     $comment = new Comment();
     $comment->user_id = Auth::user()->id;
     $comment->content = $this->_input['content'];
     if ($this->_type == 'track') {
         $column = 'track_id';
     } else {
         if ($this->_type == 'user') {
             $column = 'profile_id';
         } else {
             if ($this->_type == 'album') {
                 $column = 'album_id';
             } else {
                 if ($this->_type == 'playlist') {
                     $column = 'playlist_id';
                 } else {
                     App::abort(500);
                 }
             }
         }
     }
     $comment->{$column} = $this->_id;
     $comment->save();
     // Recount the track's comments, if this is a track comment
     if ($this->_type === 'track') {
         $entity = Track::find($this->_id);
     } elseif ($this->_type === 'album') {
         $entity = Album::find($this->_id);
     } elseif ($this->_type === 'playlist') {
         $entity = Playlist::find($this->_id);
     } elseif ($this->_type === 'user') {
         $entity = User::find($this->_id);
     } else {
         App::abort(400, 'This comment is being added to an invalid entity!');
     }
     $entity->comment_count = Comment::where($column, $this->_id)->count();
     $entity->save();
     return CommandResponse::succeed(Comment::mapPublic($comment));
 }
示例#9
0
 /**
  * Execute the console command.
  *
  * @return mixed
  */
 public function handle()
 {
     /** @var Track $track */
     $track = Track::with('trackFiles')->withTrashed()->find((int) $this->argument('trackId'));
     if ($this->option('upload')) {
         foreach ($track->trackFiles as $trackFile) {
             $this->info("Re-encoding this track's {$trackFile->format} file...");
             $this->dispatch(new EncodeTrackFile($trackFile, false, true, false));
         }
     } else {
         foreach ($track->trackFiles as $trackFile) {
             if (!$trackFile->is_master) {
                 $this->info("Re-encoding this track's {$trackFile->format} file...");
                 $this->dispatch(new EncodeTrackFile($trackFile, true));
             }
         }
     }
 }
 /**
  * Run the migrations.
  *
  * @return void
  */
 public function up()
 {
     // Fill in the table
     DB::transaction(function () {
         Schema::create('track_files', function ($table) {
             $table->increments('id');
             $table->integer('track_id')->unsigned()->indexed();
             $table->boolean('is_master')->default(false)->indexed();
             $table->string('format')->indexed();
             $table->foreign('track_id')->references('id')->on('tracks');
             $table->timestamps();
         });
         foreach (Track::all() as $track) {
             foreach (Track::$Formats as $name => $item) {
                 DB::table('track_files')->insert(['track_id' => $track->id, 'is_master' => $name === 'FLAC' ? true : false, 'format' => $name, 'created_at' => $track->created_at, 'updated_at' => Carbon\Carbon::now()]);
             }
         }
     });
 }
示例#11
0
 /**
  * Execute the console command.
  *
  * @return mixed
  */
 public function handle()
 {
     if ($this->argument('trackId')) {
         $track = Track::findOrFail($this->argument('trackId'));
         $tracks = [$track];
     } else {
         $tracks = Track::whereNotNull('published_at')->withTrashed()->orderBy('id', 'asc')->get();
     }
     $numberOfTracks = sizeof($tracks);
     $this->info("Updating tags for {$numberOfTracks} tracks...");
     $bar = $this->output->createProgressBar($numberOfTracks);
     foreach ($tracks as $track) {
         /** @var $track Track */
         $track->updateTags();
         $bar->advance();
     }
     $bar->finish();
     $this->line('');
 }
示例#12
0
 public static function mapPublicPlaylistShow(Playlist $playlist)
 {
     $tracks = [];
     foreach ($playlist->tracks as $track) {
         /** @var $track Track */
         $tracks[] = Track::mapPublicTrackSummary($track);
     }
     $formats = [];
     foreach (Track::$Formats as $name => $format) {
         $formats[] = ['name' => $name, 'extension' => $format['extension'], 'url' => $playlist->getDownloadUrl($name), 'size' => Helpers::formatBytes($playlist->getFilesize($name)), 'isCacheable' => in_array($name, Track::$CacheableFormats) ? true : false];
     }
     $comments = [];
     foreach ($playlist->comments as $comment) {
         $comments[] = Comment::mapPublic($comment);
     }
     $data = self::mapPublicPlaylistSummary($playlist);
     $data['tracks'] = $tracks;
     $data['comments'] = $comments;
     $data['formats'] = $formats;
     $data['share'] = ['url' => action('PlaylistsController@getShortlink', ['id' => $playlist->id]), 'tumblrUrl' => 'http://www.tumblr.com/share/link?url=' . urlencode($playlist->url) . '&name=' . urlencode($playlist->title) . '&description=' . urlencode($playlist->description), 'twitterUrl' => 'https://platform.twitter.com/widgets/tweet_button.html?text=' . $playlist->title . ' by ' . $playlist->user->display_name . ' on Pony.fm'];
     return $data;
 }
示例#13
0
 public function getShow($slug)
 {
     $user = User::whereSlug($slug)->whereNull('disabled_at')->userDetails()->with(['comments' => function ($query) {
         $query->with('user');
     }])->first();
     if (!$user) {
         App::abort(404);
     }
     $trackQuery = Track::summary()->published()->explicitFilter()->listed()->with('genre', 'cover', 'user')->userDetails()->whereUserId($user->id)->whereNotNull('published_at')->orderBy('created_at', 'desc')->take(20);
     $latestTracks = [];
     foreach ($trackQuery->get() as $track) {
         $latestTracks[] = Track::mapPublicTrackSummary($track);
     }
     $comments = [];
     foreach ($user->comments as $comment) {
         $comments[] = Comment::mapPublic($comment);
     }
     $userData = ['is_following' => false];
     if ($user->users->count()) {
         $userRow = $user->users[0];
         $userData = ['is_following' => (bool) $userRow->is_followed];
     }
     return Response::json(['artist' => ['id' => (int) $user->id, 'name' => $user->display_name, 'slug' => $user->slug, 'is_archived' => (bool) $user->is_archived, 'avatars' => ['small' => $user->getAvatarUrl(Image::SMALL), 'normal' => $user->getAvatarUrl(Image::NORMAL)], 'created_at' => $user->created_at, 'followers' => [], 'following' => [], 'latest_tracks' => $latestTracks, 'comments' => $comments, 'bio' => $user->bio, 'mlpforums_username' => $user->username, 'message_url' => $user->message_url, 'user_data' => $userData]], 200);
 }
示例#14
0
 public static function mapPrivateTrackSummary(Track $track)
 {
     return ['id' => $track->id, 'title' => $track->title, 'user_id' => $track->user_id, 'slug' => $track->slug, 'is_vocal' => $track->is_vocal, 'is_explicit' => $track->is_explicit, 'is_downloadable' => $track->is_downloadable, 'is_published' => $track->isPublished(), 'created_at' => $track->created_at->format('c'), 'published_at' => $track->published_at ? $track->published_at->format('c') : null, 'duration' => $track->duration, 'genre_id' => $track->genre_id, 'track_type_id' => $track->track_type_id, 'cover_url' => $track->getCoverUrl(Image::SMALL), 'is_listed' => !!$track->is_listed];
 }
示例#15
0
 function __construct($trackId, $input)
 {
     $this->_trackId = $trackId;
     $this->_track = Track::find($trackId);
     $this->_input = $input;
 }
示例#16
0
 public function getEdit($id)
 {
     $track = Track::with('showSongs')->find($id);
     if (!$track) {
         return $this->notFound('Track ' . $id . ' not found!');
     }
     if ($track->user_id != Auth::user()->id) {
         return $this->notAuthorized();
     }
     return Response::json(Track::mapPrivateTrackShow($track), 200);
 }
示例#17
0
 public function syncTrackIds($trackIds)
 {
     $trackIdsInAlbum = [];
     foreach ($this->tracks as $track) {
         $trackIdsInAlbum[] = $track->id;
     }
     $trackIdsCount = count($trackIds);
     $trackIdsInAlbumCount = count($trackIdsInAlbum);
     $isSame = true;
     if ($trackIdsInAlbumCount != $trackIdsCount) {
         $isSame = false;
     } else {
         for ($i = 0; $i < $trackIdsInAlbumCount; $i++) {
             if ($i >= $trackIdsCount || $trackIdsInAlbum[$i] != $trackIds[$i]) {
                 $isSame = false;
                 break;
             }
         }
     }
     if ($isSame) {
         return;
     }
     $index = 1;
     $tracksToRemove = [];
     $albumsToFix = [];
     foreach ($this->tracks as $track) {
         $tracksToRemove[$track->id] = $track;
     }
     foreach ($trackIds as $trackId) {
         if (!strlen(trim($trackId))) {
             continue;
         }
         /** @var $track Track */
         $track = Track::find($trackId);
         if ($track->album_id != null && $track->album_id != $this->id) {
             $albumsToFix[] = $track->album;
         }
         $track->album_id = $this->id;
         $track->track_number = $index;
         $track->updateTags();
         $track->save();
         unset($tracksToRemove[$track->id]);
         $index++;
     }
     foreach ($tracksToRemove as $track) {
         /** @var $track Track */
         $track->album_id = null;
         $track->track_number = null;
         $track->updateTags();
         $track->save();
     }
     foreach ($albumsToFix as $album) {
         /** @var $album Album */
         $album->updateTrackNumbers();
     }
     foreach (Track::$Formats as $name => $format) {
         Cache::forget($this->getCacheKey('filesize' . $name));
     }
 }
示例#18
0
 /**
  * Execute the console command.
  *
  * @return void
  */
 public function handle()
 {
     // Get the list of tracks that need classification
     $tracks = DB::table('mlpma_tracks')->orderBy('id')->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) {
         $this->currentTrack++;
         $this->comment('[' . $this->currentTrack . '/' . $totalTracks . '] Classifying track [' . $track->filename . ']...');
         $parsedTags = json_decode($track->parsed_tags, true);
         //==========================================================================================================
         // Original, show song remix, fan song remix, show audio remix, or ponified song?
         //==========================================================================================================
         $sanitizedTrackTitle = $parsedTags['title'];
         $sanitizedTrackTitle = str_replace(['-', '+', '~', 'ft.', '*', '(', ')', '.'], ' ', $sanitizedTrackTitle);
         $queriedTitle = DB::connection()->getPdo()->quote($sanitizedTrackTitle);
         $officialSongs = ShowSong::select(['id', 'title'])->whereRaw("\n                MATCH (title)\n                AGAINST ({$queriedTitle} IN BOOLEAN MODE)\n                ")->get();
         // If it has "Ingram" in the name, it's definitely an official song remix.
         if (Str::contains(Str::lower($track->filename), 'ingram')) {
             $this->info('This is an official song remix!');
             list($trackType, $linkedSongIds) = $this->classifyTrack($track->filename, $officialSongs, true, $parsedTags);
             // If it has "remix" in the name, it's definitely a remix.
         } else {
             if (Str::contains(Str::lower($sanitizedTrackTitle), 'remix')) {
                 $this->info('This is some kind of remix!');
                 list($trackType, $linkedSongIds) = $this->classifyTrack($track->filename, $officialSongs, false, $parsedTags);
                 // No idea what this is. Have the pony at the terminal figure it out!
             } else {
                 list($trackType, $linkedSongIds) = $this->classifyTrack($track->filename, $officialSongs, false, $parsedTags);
             }
         }
         //==========================================================================================================
         // Attach the data and publish the track!
         //==========================================================================================================
         $track = Track::find($track->track_id);
         $track->track_type_id = $trackType;
         $track->published_at = $parsedTags['released_at'];
         $track->save();
         if (sizeof($linkedSongIds) > 0) {
             $track->showSongs()->sync($linkedSongIds);
         }
         echo PHP_EOL;
     }
 }
示例#19
0
 public function getDownload($id, $extension)
 {
     $track = Track::find($id);
     if (!$track || !$track->canView(Auth::user())) {
         App::abort(404);
     }
     $trackFile = TrackFile::findOrFailByExtension($track->id, $extension);
     ResourceLogItem::logItem('track', $id, ResourceLogItem::DOWNLOAD, $trackFile->getFormat()['index']);
     $response = Response::make('', 200);
     $filename = $trackFile->getFile();
     if (Config::get('app.sendfile')) {
         $response->header('X-Sendfile', $filename);
         $response->header('Content-Disposition', 'attachment; filename="' . $trackFile->getDownloadFilename() . '"');
     } else {
         $response->header('X-Accel-Redirect', $filename);
         $response->header('Content-Disposition', 'attachment; filename="' . $trackFile->getDownloadFilename() . '"');
     }
     $time = gmdate(filemtime($filename));
     if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $time == $_SERVER['HTTP_IF_MODIFIED_SINCE']) {
         header('HTTP/1.0 304 Not Modified');
         exit;
     }
     $response->header('Last-Modified', $time);
     $response->header('Content-Type', $trackFile->getFormat()['mime_type']);
     return $response;
 }
示例#20
0
 public function popular()
 {
     $tracks = collect(Track::popular(10));
     $json = ['total_tracks' => $tracks->count(), 'tracks' => $tracks->toArray()];
     return Response::json($json, 200);
 }
 /**
  * Execute the console command.
  *
  * @return mixed
  */
 public function handle()
 {
     $affectedTracks = Track::mlpma()->whereNull('published_at')->update(['track_type_id' => TrackType::UNCLASSIFIED_TRACK, 'published_at' => DB::raw('released_at'), 'updated_at' => Carbon::now()]);
     $this->info("Updated {$affectedTracks} tracks.");
 }
示例#22
0
 /**
  * Execute the console command.
  *
  * @return void
  */
 public function handle()
 {
     pcntl_signal(SIGINT, [$this, 'handleInterrupt']);
     $mlpmaPath = Config::get('ponyfm.files_directory') . '/mlpma';
     $tmpPath = Config::get('ponyfm.files_directory') . '/tmp';
     if (!File::exists($tmpPath)) {
         File::makeDirectory($tmpPath);
     }
     $UNKNOWN_GENRE = Genre::firstOrCreate(['name' => 'Unknown', 'slug' => 'unknown']);
     $this->comment('Enumerating MLP Music Archive source files...');
     $files = File::allFiles($mlpmaPath);
     $this->info(sizeof($files) . ' files found!');
     $this->comment('Enumerating artists...');
     $artists = File::directories($mlpmaPath);
     $this->info(sizeof($artists) . ' artists found!');
     $this->comment('Importing tracks...');
     $totalFiles = sizeof($files);
     $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) {
         $this->currentFile++;
         pcntl_signal_dispatch();
         if ($this->isInterrupted) {
             break;
         }
         $this->comment('[' . $this->currentFile . '/' . $totalFiles . '] Importing track [' . $file->getFilename() . ']...');
         if (in_array($file->getExtension(), $this->ignoredExtensions)) {
             $this->comment('This is not an audio file! Skipping...' . PHP_EOL);
             continue;
         }
         // Has this track already been imported?
         $importedTrack = DB::table('mlpma_tracks')->where('filename', '=', $file->getFilename())->first();
         if ($importedTrack) {
             $this->comment('This track has already been imported! Skipping...' . PHP_EOL);
             continue;
         }
         //==========================================================================================================
         // Extract the original tags.
         //==========================================================================================================
         $getId3 = new getID3();
         // all tags read by getID3, including the cover art
         $allTags = $getId3->analyze($file->getPathname());
         // tags specific to a file format (ID3 or Atom), pre-normalization but with cover art removed
         $rawTags = [];
         // normalized tags used by Pony.fm
         $parsedTags = [];
         if (Str::lower($file->getExtension()) === 'mp3') {
             list($parsedTags, $rawTags) = $this->getId3Tags($allTags);
         } elseif (Str::lower($file->getExtension()) === 'm4a') {
             list($parsedTags, $rawTags) = $this->getAtomTags($allTags);
         } elseif (Str::lower($file->getExtension()) === 'ogg') {
             list($parsedTags, $rawTags) = $this->getVorbisTags($allTags);
         } elseif (Str::lower($file->getExtension()) === 'flac') {
             list($parsedTags, $rawTags) = $this->getVorbisTags($allTags);
         } elseif (Str::lower($file->getExtension()) === 'wav') {
             list($parsedTags, $rawTags) = $this->getAtomTags($allTags);
         }
         //==========================================================================================================
         // Determine the release date.
         //==========================================================================================================
         $modifiedDate = Carbon::createFromTimeStampUTC(File::lastModified($file->getPathname()));
         $taggedYear = $parsedTags['year'];
         $this->info('Modification year: ' . $modifiedDate->year);
         $this->info('Tagged year: ' . $taggedYear);
         if ($taggedYear !== null && $modifiedDate->year === $taggedYear) {
             $releasedAt = $modifiedDate;
         } elseif ($taggedYear !== null && Str::length((string) $taggedYear) !== 4) {
             $this->error('This track\'s tagged year makes no sense! Using the track\'s last modified date...');
             $releasedAt = $modifiedDate;
         } elseif ($taggedYear !== null && $modifiedDate->year !== $taggedYear) {
             $this->error('Release years don\'t match! Using the tagged year...');
             $releasedAt = Carbon::create($taggedYear);
         } else {
             // $taggedYear is null
             $this->error('This track isn\'t tagged with its release year! Using the track\'s last modified date...');
             $releasedAt = $modifiedDate;
         }
         // This is later used by the classification/publishing script to determine the publication date.
         $parsedTags['released_at'] = $releasedAt->toDateTimeString();
         //==========================================================================================================
         // Does this track have vocals?
         //==========================================================================================================
         $isVocal = $parsedTags['lyrics'] !== null;
         //==========================================================================================================
         // Fill in the title tag if it's missing.
         //==========================================================================================================
         if (!$parsedTags['title']) {
             $parsedTags['title'] = $file->getBasename('.' . $file->getExtension());
         }
         //==========================================================================================================
         // Determine the genre.
         //==========================================================================================================
         $genreName = $parsedTags['genre'];
         $genreSlug = Str::slug($genreName);
         $this->info('Genre: ' . $genreName);
         if ($genreName && $genreSlug !== '') {
             $genre = Genre::where('name', '=', $genreName)->first();
             if ($genre) {
                 $genreId = $genre->id;
             } else {
                 $genre = new Genre();
                 $genre->name = $genreName;
                 $genre->slug = $genreSlug;
                 $genre->save();
                 $genreId = $genre->id;
                 $this->comment('Created a new genre!');
             }
         } else {
             $genreId = $UNKNOWN_GENRE->id;
             // "Unknown" genre ID
         }
         //==========================================================================================================
         // Determine which artist account this file belongs to using the containing directory.
         //==========================================================================================================
         $this->info('Path to file: ' . $file->getRelativePath());
         $path_components = explode(DIRECTORY_SEPARATOR, $file->getRelativePath());
         $artist_name = $path_components[0];
         $album_name = array_key_exists(1, $path_components) ? $path_components[1] : null;
         $this->info('Artist: ' . $artist_name);
         $this->info('Album: ' . $album_name);
         $artist = User::where('display_name', '=', $artist_name)->first();
         if (!$artist) {
             $artist = new User();
             $artist->display_name = $artist_name;
             $artist->email = null;
             $artist->is_archived = true;
             $artist->slug = Str::slug($artist_name);
             $slugExists = User::where('slug', '=', $artist->slug)->first();
             if ($slugExists) {
                 $this->error('Horsefeathers! The slug ' . $artist->slug . ' is already taken!');
                 $artist->slug = $artist->slug . '-' . Str::random(4);
             }
             $artist->save();
         }
         //==========================================================================================================
         // Extract the cover art, if any exists.
         //==========================================================================================================
         $this->comment('Extracting cover art!');
         $coverId = null;
         if (array_key_exists('comments', $allTags) && array_key_exists('picture', $allTags['comments'])) {
             $image = $allTags['comments']['picture'][0];
             if ($image['image_mime'] === 'image/png') {
                 $extension = 'png';
             } elseif ($image['image_mime'] === 'image/jpeg') {
                 $extension = 'jpg';
             } elseif ($image['image_mime'] === 'image/gif') {
                 $extension = 'gif';
             } else {
                 $this->error('Unknown cover art format!');
             }
             // write temporary image file
             $imageFilename = $file->getFilename() . ".cover.{$extension}";
             $imageFilePath = "{$tmpPath}/" . $imageFilename;
             File::put($imageFilePath, $image['data']);
             $imageFile = new UploadedFile($imageFilePath, $imageFilename, $image['image_mime']);
             $cover = Image::upload($imageFile, $artist);
             $coverId = $cover->id;
         } else {
             $this->comment('No cover art found!');
         }
         //==========================================================================================================
         // Is this part of an album?
         //==========================================================================================================
         $albumId = null;
         $albumName = $parsedTags['album'];
         if ($albumName !== null) {
             $album = Album::where('user_id', '=', $artist->id)->where('title', '=', $albumName)->first();
             if (!$album) {
                 $album = new Album();
                 $album->title = $albumName;
                 $album->user_id = $artist->id;
                 $album->cover_id = $coverId;
                 $album->save();
             }
             $albumId = $album->id;
         }
         //==========================================================================================================
         // Save this track.
         //==========================================================================================================
         // "Upload" the track to Pony.fm
         $this->comment('Transcoding the track!');
         Auth::loginUsingId($artist->id);
         $trackFile = new UploadedFile($file->getPathname(), $file->getFilename(), $allTags['mime_type']);
         Input::instance()->files->add(['track' => $trackFile]);
         $upload = new UploadTrackCommand(true, true);
         $result = $upload->execute();
         if ($result->didFail()) {
             $this->error(json_encode($result->getMessages(), JSON_PRETTY_PRINT));
         } else {
             // Save metadata.
             $track = Track::find($result->getResponse()['id']);
             $track->title = $parsedTags['title'];
             $track->cover_id = $coverId;
             $track->album_id = $albumId;
             $track->genre_id = $genreId;
             $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')->insert(['track_id' => $result->getResponse()['id'], 'path' => $file->getRelativePath(), 'filename' => $file->getFilename(), 'extension' => $file->getExtension(), 'imported_at' => Carbon::now(), 'parsed_tags' => json_encode($parsedTags), 'raw_tags' => json_encode($rawTags)]);
         }
         echo PHP_EOL . PHP_EOL;
     }
 }
 function __construct($playlistId, $trackId)
 {
     $this->_playlist = Playlist::find($playlistId);
     $this->_track = Track::find($trackId);
 }
示例#24
0
 /**
  * Execute the console command.
  *
  * @return mixed
  */
 public function handle()
 {
     // Get list of affected users
     $usernames = DB::table('users')->select(['username', DB::raw('COUNT(*) as count')])->whereNull('disabled_at')->whereNotNull('username')->groupBy(DB::raw('LOWER(username)'))->having('count', '>=', 2)->lists('username');
     foreach ($usernames as $username) {
         // Find the relevant accounts
         // ==========================
         /** @var Collection $accounts */
         $accounts = User::where('username', $username)->orderBy('created_at', 'ASC')->get();
         $firstAccount = $accounts[0];
         $accounts->forget(0);
         $accountIds = $accounts->pluck('id');
         // Reassign content
         // ================
         // This is done with the less-efficient-than-raw-SQL Eloquent
         // methods to generate appropriate revision logs.
         $this->info('Merging duplicates for: ' . $firstAccount->username);
         DB::transaction(function () use($accounts, $accountIds, $firstAccount) {
             foreach (Album::whereIn('user_id', $accountIds)->get() as $album) {
                 $album->user_id = $firstAccount->id;
                 $album->save();
             }
             foreach (Comment::whereIn('user_id', $accountIds)->get() as $comment) {
                 $comment->user_id = $firstAccount->id;
                 $comment->save();
             }
             foreach (Favourite::whereIn('user_id', $accountIds)->get() as $favourite) {
                 $favourite->user_id = $firstAccount->id;
                 $favourite->save();
             }
             foreach (Follower::whereIn('artist_id', $accountIds)->get() as $follow) {
                 $follow->artist_id = $firstAccount->id;
                 $follow->save();
             }
             foreach (Image::whereIn('uploaded_by', $accountIds)->get() as $image) {
                 $image->uploaded_by = $firstAccount->id;
                 $image->save();
             }
             foreach (Image::whereIn('uploaded_by', $accountIds)->get() as $image) {
                 $image->uploaded_by = $firstAccount->id;
                 $image->save();
             }
             DB::table('oauth2_tokens')->whereIn('user_id', $accountIds)->update(['user_id' => $firstAccount->id]);
             foreach (PinnedPlaylist::whereIn('user_id', $accountIds)->get() as $playlist) {
                 $playlist->user_id = $firstAccount->id;
                 $playlist->save();
             }
             foreach (Playlist::whereIn('user_id', $accountIds)->get() as $playlist) {
                 $playlist->user_id = $firstAccount->id;
                 $playlist->save();
             }
             foreach (ResourceLogItem::whereIn('user_id', $accountIds)->get() as $item) {
                 $item->user_id = $firstAccount->id;
                 $item->save();
             }
             foreach (ResourceUser::whereIn('user_id', $accountIds)->get() as $item) {
                 $item->user_id = $firstAccount->id;
                 $item->save();
             }
             foreach (Track::whereIn('user_id', $accountIds)->get() as $track) {
                 $track->user_id = $firstAccount->id;
                 $track->save();
             }
             foreach ($accounts as $account) {
                 $account->disabled_at = Carbon::now();
                 $account->save();
             }
         });
     }
 }
示例#25
0
 /**
  * @throws \Exception
  * @return CommandResponse
  */
 public function execute()
 {
     $user = \Auth::user();
     $trackFile = \Input::file('track', null);
     if (null === $trackFile) {
         return CommandResponse::fail(['track' => ['You must upload an audio file!']]);
     }
     $audio = \AudioCache::get($trackFile->getPathname());
     list($parsedTags, $rawTags) = $this->parseOriginalTags($trackFile, $user, $audio->getAudioCodec());
     $track = new Track();
     $track->user_id = $user->id;
     $track->title = Input::get('title', $parsedTags['title']);
     $track->duration = $audio->getDuration();
     $track->save();
     $track->ensureDirectoryExists();
     if (!is_dir(Config::get('ponyfm.files_directory') . '/queued-tracks')) {
         mkdir(Config::get('ponyfm.files_directory') . '/queued-tracks', 0755, true);
     }
     $trackFile = $trackFile->move(Config::get('ponyfm.files_directory') . '/queued-tracks', $track->id);
     $input = Input::all();
     $input['track'] = $trackFile;
     $validator = \Validator::make($input, ['track' => 'required|' . ($this->_allowLossy ? '' : 'audio_format:' . implode(',', $this->_losslessFormats) . '|') . ($this->_allowShortTrack ? '' : 'min_duration:30|') . 'audio_channels:1,2', 'auto_publish' => 'boolean', 'title' => 'string', 'track_type_id' => 'exists:track_types,id', 'genre' => 'string', 'album' => 'string', 'track_number' => 'integer', 'released_at' => 'date_format:' . Carbon::ISO8601, 'description' => 'string', 'lyrics' => 'string', 'is_vocal' => 'boolean', 'is_explicit' => 'boolean', 'is_downloadable' => 'boolean', 'is_listed' => 'boolean', 'cover' => 'image|mimes:png,jpeg|min_width:350|min_height:350', 'metadata' => 'json']);
     if ($validator->fails()) {
         $track->delete();
         return CommandResponse::fail($validator);
     }
     // Process optional track fields
     $autoPublish = (bool) ($input['auto_publish'] ?? $this->_autoPublishByDefault);
     if (Input::hasFile('cover')) {
         $track->cover_id = Image::upload(Input::file('cover'), $track->user_id)->id;
     } else {
         $track->cover_id = $parsedTags['cover_id'];
     }
     $track->title = $input['title'] ?? $parsedTags['title'] ?? $track->title;
     $track->track_type_id = $input['track_type_id'] ?? TrackType::UNCLASSIFIED_TRACK;
     $track->genre_id = isset($input['genre']) ? $this->getGenreId($input['genre']) : $parsedTags['genre_id'];
     $track->album_id = isset($input['album']) ? $this->getAlbumId($user->id, $input['album']) : $parsedTags['album_id'];
     if ($track->album_id === null) {
         $track->track_number = null;
     } else {
         $track->track_number = $input['track_number'] ?? $parsedTags['track_number'];
     }
     $track->released_at = isset($input['released_at']) ? Carbon::createFromFormat(Carbon::ISO8601, $input['released_at']) : $parsedTags['release_date'];
     $track->description = $input['description'] ?? $parsedTags['comments'];
     $track->lyrics = $input['lyrics'] ?? $parsedTags['lyrics'];
     $track->is_vocal = $input['is_vocal'] ?? $parsedTags['is_vocal'];
     $track->is_explicit = $input['is_explicit'] ?? false;
     $track->is_downloadable = $input['is_downloadable'] ?? true;
     $track->is_listed = $input['is_listed'] ?? true;
     $track->source = $this->_customTrackSource ?? 'direct_upload';
     // If json_decode() isn't called here, Laravel will surround the JSON
     // string with quotes when storing it in the database, which breaks things.
     $track->metadata = json_decode(Input::get('metadata', null));
     $track->original_tags = ['parsed_tags' => $parsedTags, 'raw_tags' => $rawTags];
     $track->save();
     try {
         $source = $trackFile->getPathname();
         // Lossy uploads need to be identified and set as the master file
         // without being re-encoded.
         $audioObject = AudioCache::get($source);
         $isLossyUpload = !in_array($audioObject->getAudioCodec(), $this->_losslessFormats);
         if ($isLossyUpload) {
             if ($audioObject->getAudioCodec() === 'mp3') {
                 $masterFormat = 'MP3';
             } else {
                 if (Str::startsWith($audioObject->getAudioCodec(), 'aac')) {
                     $masterFormat = 'AAC';
                 } else {
                     if ($audioObject->getAudioCodec() === 'vorbis') {
                         $masterFormat = 'OGG Vorbis';
                     } else {
                         $validator->messages()->add('track', 'The track does not contain audio in a known lossy format.');
                         $track->delete();
                         return CommandResponse::fail($validator);
                     }
                 }
             }
             $trackFile = new TrackFile();
             $trackFile->is_master = true;
             $trackFile->format = $masterFormat;
             $trackFile->track_id = $track->id;
             $trackFile->save();
             // Lossy masters are copied into the datastore - no re-encoding involved.
             File::copy($source, $trackFile->getFile());
         }
         $trackFiles = [];
         foreach (Track::$Formats as $name => $format) {
             // Don't bother with lossless transcodes of lossy uploads, and
             // don't re-encode the lossy master.
             if ($isLossyUpload && ($format['is_lossless'] || $name === $masterFormat)) {
                 continue;
             }
             $trackFile = new TrackFile();
             $trackFile->is_master = $name === 'FLAC' ? true : false;
             $trackFile->format = $name;
             $trackFile->status = TrackFile::STATUS_PROCESSING_PENDING;
             if (in_array($name, Track::$CacheableFormats) && $trackFile->is_master == false) {
                 $trackFile->is_cacheable = true;
             } else {
                 $trackFile->is_cacheable = false;
             }
             $track->trackFiles()->save($trackFile);
             // All TrackFile records we need are synchronously created
             // before kicking off the encode jobs in order to avoid a race
             // condition with the "temporary" source file getting deleted.
             $trackFiles[] = $trackFile;
         }
         try {
             foreach ($trackFiles as $trackFile) {
                 $this->dispatch(new EncodeTrackFile($trackFile, false, true, $autoPublish));
             }
         } catch (InvalidEncodeOptionsException $e) {
             $track->delete();
             return CommandResponse::fail(['track' => [$e->getMessage()]]);
         }
     } catch (\Exception $e) {
         $track->delete();
         throw $e;
     }
     return CommandResponse::succeed(['id' => $track->id, 'name' => $track->name, 'title' => $track->title, 'slug' => $track->slug, 'autoPublish' => $autoPublish]);
 }