/** * @throws \Exception * @return CommandResponse */ public function execute() { $rules = ['title' => 'required|min:3|max:50', 'cover' => 'image|mimes:png|min_width:350|min_height:350', 'cover_id' => 'exists:images,id', 'track_ids' => 'exists:tracks,id']; $validator = Validator::make($this->_input, $rules); if ($validator->fails()) { return CommandResponse::fail($validator); } $album = new Album(); $album->user_id = Auth::user()->id; $album->title = $this->_input['title']; $album->description = $this->_input['description']; if (isset($this->_input['cover_id'])) { $album->cover_id = $this->_input['cover_id']; } else { if (isset($this->_input['cover'])) { $cover = $this->_input['cover']; $album->cover_id = Image::upload($cover, Auth::user())->id; } else { if (isset($this->_input['remove_cover']) && $this->_input['remove_cover'] == 'true') { $album->cover_id = null; } } } $trackIds = explode(',', $this->_input['track_ids']); $album->save(); $album->syncTrackIds($trackIds); return CommandResponse::succeed(['id' => $album->id]); }
public function getImage($id, $type, $extension) { $coverType = Image::getImageTypeFromName($type); if ($coverType == null) { App::abort(404); } $image = Image::find($id); if (!$image) { App::abort(404); } $response = Response::make('', 200); $filename = $image->getFile($coverType['id']); if (!is_file($filename)) { $redirect = url('/images/icons/profile_' . Image::$ImageTypes[$coverType['id']]['name'] . '.png'); return Redirect::to($redirect); } if (Config::get('app.sendfile')) { $response->header('X-Sendfile', $filename); } else { $response->header('X-Accel-Redirect', $filename); } $response->header('Content-Disposition', "filename=\"ponyfm-i{$id}-{$type}.{$image->extension}\""); $response->header('Content-Type', $image->mime); $lastModified = filemtime($filename); $response->header('Last-Modified', $lastModified); $response->header('Cache-Control', 'max-age=' . 60 * 60 * 24 * 7); return $response; }
public static function upload(UploadedFile $file, $user) { $userId = $user; if ($user instanceof User) { $userId = $user->id; } $hash = md5_file($file->getPathname()); $image = Image::whereHash($hash)->whereUploadedBy($userId)->first(); if ($image) { return $image; } $image = new Image(); try { $image->uploaded_by = $userId; $image->size = $file->getSize(); $image->filename = $file->getClientOriginalName(); $image->extension = $file->getClientOriginalExtension(); $image->mime = $file->getMimeType(); $image->hash = $hash; $image->save(); $image->ensureDirectoryExists(); foreach (self::$ImageTypes as $coverType) { if ($coverType['id'] === self::ORIGINAL && $image->mime === 'image/jpeg') { $command = 'cp ' . $file->getPathname() . ' ' . $image->getFile($coverType['id']); } else { // ImageMagick options reference: http://www.imagemagick.org/script/command-line-options.php $command = 'convert 2>&1 "' . $file->getPathname() . '" -background white -alpha remove -alpha off -strip'; if ($image->mime === 'image/jpeg') { $command .= ' -quality 100 -format jpeg'; } else { $command .= ' -quality 95 -format png'; } if (isset($coverType['width']) && isset($coverType['height'])) { $command .= " -thumbnail {$coverType['width']}x{$coverType['height']}^ -gravity center -extent {$coverType['width']}x{$coverType['height']}"; } $command .= ' "' . $image->getFile($coverType['id']) . '"'; } External::execute($command); chmod($image->getFile($coverType['id']), 0644); } return $image; } catch (\Exception $e) { $image->delete(); throw $e; } }
public function getOwned() { $query = Image::where('uploaded_by', \Auth::user()->id); $images = []; foreach ($query->get() as $image) { $images[] = ['id' => $image->id, 'urls' => ['small' => $image->getUrl(Image::SMALL), 'normal' => $image->getUrl(Image::NORMAL), 'thumbnail' => $image->getUrl(Image::THUMBNAIL), 'original' => $image->getUrl(Image::ORIGINAL)], 'filename' => $image->filename]; } return Response::json($images, 200); }
/** * @throws \Exception * @return CommandResponse */ public function execute() { $user = Auth::user(); $rules = ['display_name' => 'required|min:3|max:26', 'bio' => 'textarea_length:250']; if ($this->_input['sync_names'] == 'true') { $this->_input['display_name'] = $user->username; } if ($this->_input['uses_gravatar'] == 'true') { $rules['gravatar'] = 'email'; } else { $rules['avatar'] = 'image|mimes:png|min_width:350|min_height:350'; $rules['avatar_id'] = 'exists:images,id'; } $validator = Validator::make($this->_input, $rules); if ($validator->fails()) { return CommandResponse::fail($validator); } if ($this->_input['uses_gravatar'] != 'true') { if ($user->avatar_id == null && !isset($this->_input['avatar']) && !isset($this->_input['avatar_id'])) { $validator->messages()->add('avatar', 'You must upload or select an avatar if you are not using gravatar!'); return CommandResponse::fail($validator); } } $user->bio = $this->_input['bio']; $user->display_name = $this->_input['display_name']; $user->sync_names = $this->_input['sync_names'] == 'true'; $user->can_see_explicit_content = $this->_input['can_see_explicit_content'] == 'true'; $user->uses_gravatar = $this->_input['uses_gravatar'] == 'true'; if ($user->uses_gravatar) { $user->avatar_id = null; $user->gravatar = $this->_input['gravatar']; } else { if (isset($this->_input['avatar_id'])) { $user->avatar_id = $this->_input['avatar_id']; } else { if (isset($this->_input['avatar'])) { $user->avatar_id = Image::upload($this->_input['avatar'], $user)->id; } } } $user->save(); return CommandResponse::succeed(); }
/** * 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(); } }); } }
/** * Execute the console command. * * @return mixed */ public function handle() { DB::connection()->disableQueryLog(); $oldDb = DB::connection('old'); $this->call('migrate:refresh'); $oldUsers = $oldDb->table('users')->get(); $this->info('Syncing Users'); foreach ($oldUsers as $user) { $displayName = $user->display_name; if (!$displayName) { $displayName = $user->username; } if (!$displayName) { $displayName = $user->username; } if (!$displayName) { continue; } DB::table('users')->insert(['id' => $user->id, 'display_name' => $displayName, 'email' => $user->email, 'created_at' => $user->created_at, 'updated_at' => $user->updated_at, 'slug' => $user->slug, 'bio' => $user->bio, 'sync_names' => $user->sync_names, 'can_see_explicit_content' => $user->can_see_explicit_content, 'username' => $user->username, 'uses_gravatar' => $user->uses_gravatar, 'gravatar' => $user->gravatar, 'avatar_id' => null]); $coverId = null; if (!$user->uses_gravatar) { try { $coverFile = $this->getIdDirectory('users', $user->id) . '/' . $user->id . '_.png'; $coverId = Image::upload(new UploadedFile($coverFile, $user->id . '_.png'), $user->id)->id; DB::table('users')->where('id', $user->id)->update(['avatar_id' => $coverId]); } catch (\Exception $e) { $this->error('Could copy user avatar ' . $user->id . ' because ' . $e->getMessage()); DB::table('users')->where('id', $user->id)->update(['uses_gravatar' => true]); } } } $this->info('Syncing Genres'); $oldGenres = $oldDb->table('genres')->get(); foreach ($oldGenres as $genre) { DB::table('genres')->insert(['id' => $genre->id, 'name' => $genre->title, 'slug' => $genre->slug]); } $this->info('Syncing Albums'); $oldAlbums = $oldDb->table('albums')->get(); foreach ($oldAlbums as $playlist) { $logViews = $oldDb->table('album_log_views')->whereAlbumId($playlist->id)->get(); $logDownload = $oldDb->table('album_log_downloads')->whereAlbumId($playlist->id)->get(); DB::table('albums')->insert(['title' => $playlist->title, 'description' => $playlist->description, 'created_at' => $playlist->created_at, 'updated_at' => $playlist->updated_at, 'deleted_at' => $playlist->deleted_at, 'slug' => $playlist->slug, 'id' => $playlist->id, 'user_id' => $playlist->user_id, 'view_count' => 0, 'download_count' => 0]); foreach ($logViews as $logItem) { try { DB::table('resource_log_items')->insert(['user_id' => $logItem->user_id, 'log_type' => ResourceLogItem::VIEW, 'album_id' => $logItem->album_id, 'created_at' => $logItem->created_at, 'ip_address' => $logItem->ip_address]); } catch (\Exception $e) { $this->error('Could insert log item for album ' . $playlist->id . ' because ' . $e->getMessage()); } } foreach ($logDownload as $logItem) { try { DB::table('resource_log_items')->insert(['user_id' => $logItem->user_id, 'log_type' => ResourceLogItem::DOWNLOAD, 'album_id' => $logItem->album_id, 'created_at' => $logItem->created_at, 'ip_address' => $logItem->ip_address, 'track_format_id' => $logItem->track_file_format_id - 1]); } catch (\Exception $e) { $this->error('Could insert log item for album ' . $playlist->id . ' because ' . $e->getMessage()); } } } $this->info('Syncing Tracks'); $oldTracks = $oldDb->table('tracks')->get(); foreach ($oldTracks as $track) { $coverId = null; if ($track->cover) { try { $coverFile = $this->getIdDirectory('tracks', $track->id) . '/' . $track->id . '_' . $track->cover . '.png'; $coverId = Image::upload(new UploadedFile($coverFile, $track->id . '_' . $track->cover . '.png'), $track->user_id)->id; } catch (\Exception $e) { $this->error('Could copy track cover ' . $track->id . ' because ' . $e->getMessage()); } } $trackLogViews = $oldDb->table('track_log_views')->whereTrackId($track->id)->get(); $trackLogPlays = $oldDb->table('track_log_plays')->whereTrackId($track->id)->get(); $trackLogDownload = $oldDb->table('track_log_downloads')->whereTrackId($track->id)->get(); DB::table('tracks')->insert(['id' => $track->id, 'title' => $track->title, 'slug' => $track->slug, 'description' => $track->description, 'lyrics' => $track->lyrics, 'created_at' => $track->created_at, 'deleted_at' => $track->deleted_at, 'updated_at' => $track->updated_at, 'released_at' => $track->released_at, 'published_at' => $track->published_at, 'genre_id' => $track->genre_id, 'is_explicit' => $track->explicit, 'is_downloadable' => $track->downloadable, 'is_vocal' => $track->is_vocal, 'track_type_id' => $track->track_type_id, 'track_number' => $track->track_number, 'user_id' => $track->user_id, 'album_id' => $track->album_id, 'cover_id' => $coverId, 'license_id' => $track->license_id, 'duration' => $track->duration, 'view_count' => 0, 'play_count' => 0, 'download_count' => 0]); foreach ($trackLogViews as $logItem) { try { DB::table('resource_log_items')->insert(['user_id' => $logItem->user_id, 'log_type' => ResourceLogItem::VIEW, 'track_id' => $logItem->track_id, 'created_at' => $logItem->created_at, 'ip_address' => $logItem->ip_address]); } catch (\Exception $e) { $this->error('Could insert log item for track ' . $track->id . ' because ' . $e->getMessage()); } } foreach ($trackLogPlays as $logItem) { try { DB::table('resource_log_items')->insert(['user_id' => $logItem->user_id, 'log_type' => ResourceLogItem::PLAY, 'track_id' => $logItem->track_id, 'created_at' => $logItem->created_at, 'ip_address' => $logItem->ip_address]); } catch (\Exception $e) { $this->error('Could insert log item for track ' . $track->id . ' because ' . $e->getMessage()); } } foreach ($trackLogDownload as $logItem) { try { DB::table('resource_log_items')->insert(['user_id' => $logItem->user_id, 'log_type' => ResourceLogItem::DOWNLOAD, 'track_id' => $logItem->track_id, 'created_at' => $logItem->created_at, 'ip_address' => $logItem->ip_address, 'track_format_id' => $logItem->track_file_format_id - 1]); } catch (\Exception $e) { $this->error('Could insert log item for track ' . $track->id . ' because ' . $e->getMessage()); } } } $oldShowSongs = $oldDb->table('song_track')->get(); foreach ($oldShowSongs as $song) { try { DB::table('show_song_track')->insert(['id' => $song->id, 'show_song_id' => $song->song_id, 'track_id' => $song->track_id]); } catch (\Exception $e) { $this->error('Could insert show track item for ' . $song->track_id . ' because ' . $e->getMessage()); } } $this->info('Syncing Playlists'); $oldPlaylists = $oldDb->table('playlists')->get(); foreach ($oldPlaylists as $playlist) { $logViews = $oldDb->table('playlist_log_views')->wherePlaylistId($playlist->id)->get(); $logDownload = $oldDb->table('playlist_log_downloads')->wherePlaylistId($playlist->id)->get(); DB::table('playlists')->insert(['title' => $playlist->title, 'description' => $playlist->description, 'created_at' => $playlist->created_at, 'updated_at' => $playlist->updated_at, 'deleted_at' => $playlist->deleted_at, 'slug' => $playlist->slug, 'id' => $playlist->id, 'user_id' => $playlist->user_id, 'is_public' => true, 'view_count' => 0, 'download_count' => 0]); foreach ($logViews as $logItem) { try { DB::table('resource_log_items')->insert(['user_id' => $logItem->user_id, 'log_type' => ResourceLogItem::VIEW, 'playlist_id' => $logItem->playlist_id, 'created_at' => $logItem->created_at, 'ip_address' => $logItem->ip_address]); } catch (\Exception $e) { $this->error('Could insert log item for playlist ' . $playlist->id . ' because ' . $e->getMessage()); } } foreach ($logDownload as $logItem) { try { DB::table('resource_log_items')->insert(['user_id' => $logItem->user_id, 'log_type' => ResourceLogItem::DOWNLOAD, 'playlist_id' => $logItem->playlist_id, 'created_at' => $logItem->created_at, 'ip_address' => $logItem->ip_address, 'track_format_id' => $logItem->track_file_format_id - 1]); } catch (\Exception $e) { $this->error('Could insert log item for playlist ' . $playlist->id . ' because ' . $e->getMessage()); } } } $this->info('Syncing Playlist Tracks'); $oldPlaylistTracks = $oldDb->table('playlist_track')->get(); foreach ($oldPlaylistTracks as $playlistTrack) { DB::table('playlist_track')->insert(['id' => $playlistTrack->id, 'created_at' => $playlistTrack->created_at, 'updated_at' => $playlistTrack->updated_at, 'position' => $playlistTrack->position, 'playlist_id' => $playlistTrack->playlist_id, 'track_id' => $playlistTrack->track_id]); } $this->info('Syncing Comments'); $oldComments = $oldDb->table('comments')->get(); foreach ($oldComments as $comment) { try { DB::table('comments')->insert(['id' => $comment->id, 'user_id' => $comment->user_id, 'created_at' => $comment->created_at, 'deleted_at' => $comment->deleted_at, 'updated_at' => $comment->updated_at, 'content' => $comment->content, 'track_id' => $comment->track_id, 'album_id' => $comment->album_id, 'playlist_id' => $comment->playlist_id, 'profile_id' => $comment->profile_id]); } catch (Exception $e) { $this->error('Could not sync comment ' . $comment->id . ' because ' . $e->getMessage()); } } $this->info('Syncing Favourites'); $oldFavs = $oldDb->table('favourites')->get(); foreach ($oldFavs as $fav) { try { DB::table('favourites')->insert(['id' => $fav->id, 'user_id' => $fav->user_id, 'created_at' => $fav->created_at, 'track_id' => $fav->track_id, 'album_id' => $fav->album_id, 'playlist_id' => $fav->playlist_id]); } catch (Exception $e) { $this->error('Could not sync favourite ' . $fav->id . ' because ' . $e->getMessage()); } } $this->info('Syncing Followers'); $oldFollowers = $oldDb->table('user_follower')->get(); foreach ($oldFollowers as $follower) { try { DB::table('followers')->insert(['id' => $follower->id, 'user_id' => $follower->follower_id, 'artist_id' => $follower->user_id, 'created_at' => $follower->created_at]); } catch (Exception $e) { $this->error('Could not sync follower ' . $follower->id . ' because ' . $e->getMessage()); } } }
/** * @throws \Exception * @return CommandResponse */ public function execute() { $isVocal = isset($this->_input['is_vocal']) && $this->_input['is_vocal'] == 'true' ? true : false; $rules = ['title' => 'required|min:3|max:80', 'released_at' => 'before:' . date('Y-m-d', time() + 86400 * 2) . (isset($this->_input['released_at']) && $this->_input['released_at'] != "" ? '|date' : ''), 'license_id' => 'required|exists:licenses,id', 'genre_id' => 'required|exists:genres,id', 'cover' => 'image|mimes:png,jpeg|min_width:350|min_height:350', 'track_type_id' => 'required|exists:track_types,id|not_in:' . TrackType::UNCLASSIFIED_TRACK, 'songs' => 'required_when:track_type,2|exists:songs,id', 'cover_id' => 'exists:images,id', 'album_id' => 'exists:albums,id']; if ($isVocal) { $rules['lyrics'] = 'required'; } if (isset($this->_input['track_type_id']) && $this->_input['track_type_id'] == 2) { $rules['show_song_ids'] = 'required|exists:show_songs,id'; } $validator = \Validator::make($this->_input, $rules); if ($validator->fails()) { return CommandResponse::fail($validator); } $track = $this->_track; $track->title = $this->_input['title']; $track->released_at = isset($this->_input['released_at']) && $this->_input['released_at'] != "" ? strtotime($this->_input['released_at']) : null; $track->description = isset($this->_input['description']) ? $this->_input['description'] : ''; $track->lyrics = isset($this->_input['lyrics']) ? $this->_input['lyrics'] : ''; $track->license_id = $this->_input['license_id']; $track->genre_id = $this->_input['genre_id']; $track->track_type_id = $this->_input['track_type_id']; $track->is_explicit = $this->_input['is_explicit'] == 'true'; $track->is_downloadable = $this->_input['is_downloadable'] == 'true'; $track->is_listed = $this->_input['is_listed'] == 'true'; $track->is_vocal = $isVocal; if (isset($this->_input['album_id']) && strlen(trim($this->_input['album_id']))) { if ($track->album_id != null && $track->album_id != $this->_input['album_id']) { $this->removeTrackFromAlbum($track); } if ($track->album_id != $this->_input['album_id']) { $album = Album::find($this->_input['album_id']); $track->track_number = $album->tracks()->count() + 1; $track->album_id = $this->_input['album_id']; Album::whereId($album->id)->update(['track_count' => DB::raw('(SELECT COUNT(id) FROM tracks WHERE album_id = ' . $album->id . ')')]); } } else { if ($track->album_id != null) { $this->removeTrackFromAlbum($track); } $track->track_number = null; $track->album_id = null; } if ($track->track_type_id == TrackType::OFFICIAL_TRACK_REMIX) { $track->showSongs()->sync(explode(',', $this->_input['show_song_ids'])); } else { $track->showSongs()->sync([]); } if ($track->published_at == null) { $track->published_at = new \DateTime(); DB::table('tracks')->whereUserId($track->user_id)->update(['is_latest' => false]); $track->is_latest = true; } if (isset($this->_input['cover_id'])) { $track->cover_id = $this->_input['cover_id']; } else { if (isset($this->_input['cover'])) { $cover = $this->_input['cover']; $track->cover_id = Image::upload($cover, Auth::user())->id; } else { if ($this->_input['remove_cover'] == 'true') { $track->cover_id = null; } } } $track->updateTags(); $track->save(); User::whereId($this->_track->user_id)->update(['track_count' => DB::raw('(SELECT COUNT(id) FROM tracks WHERE deleted_at IS NULL AND published_at IS NOT NULL AND user_id = ' . $this->_track->user_id . ')')]); return CommandResponse::succeed(['real_cover_url' => $track->getCoverUrl(Image::NORMAL)]); }
/** * 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; } }
/** * Extracts a file's tags. * * @param UploadedFile $file * @param User $artist * @param string $audioCodec * @return array the "processed" and raw tags extracted from the file * @throws \Exception */ protected function parseOriginalTags(UploadedFile $file, User $artist, string $audioCodec) { //========================================================================================================== // 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 ($audioCodec === 'mp3') { list($parsedTags, $rawTags) = $this->getId3Tags($allTags); } elseif (Str::startsWith($audioCodec, 'aac')) { list($parsedTags, $rawTags) = $this->getAtomTags($allTags); } elseif ($audioCodec === 'vorbis') { list($parsedTags, $rawTags) = $this->getVorbisTags($allTags); } elseif ($audioCodec === 'flac') { list($parsedTags, $rawTags) = $this->getVorbisTags($allTags); } elseif (Str::startsWith($audioCodec, ['pcm', 'adpcm'])) { list($parsedTags, $rawTags) = $this->getAtomTags($allTags); } //========================================================================================================== // Fill in the title tag if it's missing //========================================================================================================== $parsedTags['title'] = $parsedTags['title'] ?? pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME); //========================================================================================================== // Determine the release date. //========================================================================================================== if ($parsedTags['release_date'] === null && $parsedTags['year'] !== null) { $parsedTags['release_date'] = Carbon::create($parsedTags['year'], 1, 1); } //========================================================================================================== // Does this track have vocals? //========================================================================================================== $parsedTags['is_vocal'] = $parsedTags['lyrics'] !== null; //========================================================================================================== // Determine the genre. //========================================================================================================== $genreName = $parsedTags['genre']; if ($genreName) { $parsedTags['genre_id'] = $this->getGenreId($genreName); } else { $parsedTags['genre_id'] = $this->getGenreId('Unknown'); } //========================================================================================================== // Extract the cover art, if any exists. //========================================================================================================== $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'; } else { throw new BadRequestHttpException('Unknown cover format embedded in the track file!'); } // write temporary image file $tmpPath = Config::get('ponyfm.files_directory') . '/tmp'; $filename = $file->getFilename() . ".cover.{$extension}"; $imageFilePath = "{$tmpPath}/{$filename}"; File::put($imageFilePath, $image['data']); $imageFile = new UploadedFile($imageFilePath, $filename, $image['image_mime']); $cover = Image::upload($imageFile, $artist); $coverId = $cover->id; } else { // no cover art was found - carry on } $parsedTags['cover_id'] = $coverId; //========================================================================================================== // Is this part of an album? //========================================================================================================== $albumId = null; $albumName = $parsedTags['album']; if ($albumName !== null) { $albumId = $this->getAlbumId($artist->id, $albumName, $coverId); } $parsedTags['album_id'] = $albumId; return [$parsedTags, $rawTags]; }