/** * Creates a new Release model. * If creation is successful, the browser will be redirected to the 'view' page. * @return mixed */ public function actionCreate($artistId = null) { $release = new Release(); if ($artistId) { $release->artist_id = $artistId; } $covers = []; $tracks = []; $artist_name = $artistId ? $release->artist->original_name : ''; if (Yii::$app->request->isPost) { for ($i = 0; $i < count(Yii::$app->request->post('Cover', [])); $i++) { $covers[] = new Cover(); } for ($i = 0; $i < count(Yii::$app->request->post('Track', [])); $i++) { $tracks[] = new Track(); } $release->load(Yii::$app->request->post()); $is_release_valid = $release->validate(); if (!$release->artist_id) { $artist_name = Yii::$app->request->post()['artist_name']; $artist = new Artist(['original_name' => $artist_name, 'user_id' => Yii::$app->user->id]); $is_artist_valid = $artist->validate(); } else { $is_artist_valid = true; } Cover::loadMultiple($covers, Yii::$app->request->post()); $is_covers_valid = Cover::validateMultiple($covers); Track::loadMultiple($tracks, Yii::$app->request->post()); $is_tracks_valid = Track::validateMultiple($tracks); if ($is_release_valid && $is_artist_valid && $is_covers_valid && $is_tracks_valid) { $transaction = Yii::$app->db->beginTransaction(); try { if (isset($artist)) { $artist->save(false); $release->artist_id = $artist->id; } $release->save(false); foreach ($covers as $cover) { $release->link('covers', $cover); } foreach ($tracks as $track) { $release->link('tracks', $track); } $tags = Yii::$app->request->post('Release', ''); $tags = Tag::find()->where(['in', 'id', explode(',', $tags['tags'])])->all(); foreach ($tags as $tag) { $release->link('tags', $tag); } $transaction->commit(); return $this->redirect(['view', 'id' => $release->id]); } catch (\Exception $e) { $transaction->rollBack(); throw $e; } } } return $this->render('create', ['release' => $release, 'covers' => $covers, 'tracks' => $tracks, 'trackProto' => new Track(), 'artist_name' => $artist_name]); }
public function store(Request $request) { $validation = Validator::make($request->all(), ['artist' => 'required|unique:artists,artist_name']); if ($validation->fails()) { return redirect('artists/new')->withInput()->withErrors($validation); } // DB::table('artists')->insert([ // 'artist_name' => $request->input('artist') // ]); $artist = new Artist(['artist_name' => $request->input('artist')]); $artist->save(); return redirect('artists/new')->with('success', true); }
/** * Sync a song with all available media info against the database. * * @param SplFileInfo $file The SplFileInfo instance of the file. * * @return bool|Song A Song object on success, * true if file existing but unmodified, * or false on error. */ public function syncFile(SplFileInfo $file) { if (!($info = $this->getInfo($file))) { return false; } if (!$this->isNewOrChanged($file)) { return true; } $artist = Artist::get($info['artist']); $album = Album::get($artist, $info['album']); if ($info['cover'] && !$album->has_cover) { try { $album->generateCover($info['cover']); } catch (Exception $e) { Log::error($e); } } $info['album_id'] = $album->id; unset($info['artist']); unset($info['album']); unset($info['cover']); $song = Song::updateOrCreate(['id' => $this->getHash($file->getPathname())], $info); $song->save(); return $song; }
/** * Creates data provider instance with search query applied * * @param array $params * * @return ActiveDataProvider */ public function search($params) { $query = Artist::find(); $dataProvider = new ActiveDataProvider(['query' => $query]); $this->load($params); if (!$this->validate()) { // uncomment the following line if you do not want to return any records when validation fails // $query->where('0=1'); return $dataProvider; } $query->andFilterWhere(['id' => $this->id, 'user_id' => $this->user_id]); // $query->andFilterWhere(['like', 'original_name', $this->original_name]) // ->andFilterWhere(['like', 'latin_name', $this->latin_name]); $query->andWhere('original_name LIKE :original_name OR latin_name LIKE :latin_name')->addParams([':original_name' => "%{$this->original_name}%", ':latin_name' => "%{$this->latin_name}%"]); if (Utils::get('tags', $params)) { $query->leftJoin('artist_tag', 'artist_tag.artist_id = artist.id'); if (Utils::get('tags_mode', $params)) { # all tags $tags = explode(',', $params['tags']); foreach ($tags as $k => $v) { $tags[$k] = (int) $v; } $tags_count = count($tags); $tags = implode(',', $tags); $query->andWhere("(\n SELECT count(*)\n FROM artist_tag\n WHERE artist_tag.artist_id = artist.id\n AND artist_tag.tag_id IN ({$tags})\n ) = {$tags_count}"); } else { # any tag $query->andWhere(['in', 'artist_tag.tag_id', explode(',', $params['tags'])]); } } return $dataProvider; }
/** * Get an album using some provided information. * * @param Artist $artist * @param string $name * @param bool $isCompilation * * @return self */ public static function get(Artist $artist, $name, $isCompilation = false) { // If this is a compilation album, its artist must be "Various Artists" if ($isCompilation) { $artist = Artist::getVarious(); } return self::firstOrCreate(['artist_id' => $artist->id, 'name' => $name ?: self::UNKNOWN_NAME]); }
public function testUtf16Names() { $name = file_get_contents(__DIR__ . '/blobs/utf16'); $artist = Artist::get($name); $artist = Artist::get($name); // to make sure there's no constraint exception $this->assertEquals($artist->id, Artist::get($name)->id); }
public function testNameWithWeirdCharacters() { // Don't really think this is even necessary if the user has set a proper utf8 encoding // for the database. $name = '��Ой°Ы&囧rz'; $artist = factory(Artist::class)->create(['name' => $name]); $this->assertEquals($artist->id, Artist::get($name)->id); }
public function actionUpload() { Yii::$app->response->format = Response::FORMAT_JSON; $result = []; $files = UploadedFile::getInstances(new File(), 'uploadedFiles'); foreach ($files as $index => $file) { $model = new File(); $model->uploadedFiles = [$file]; $model->user_id = Yii::$app->user->id; $model->storage = File::STORAGE_OS; $model->extension = $file->extension; $model->type = File::defineType($model->extension); if ($model->upload()) { $item = ['id' => $model->id, 'url' => $model->getUrl(), 'type' => $model->getMimeType()]; if ($releaseId = Yii::$app->request->get('rid')) { $release = Release::findOne($releaseId); if ($release && $release->artist->user_id == Yii::$app->user->id) { if ($model->type == $model::TYPE_IMAGE) { $cover = new Cover(['release_id' => $release->id, 'file_id' => $model->id, 'is_main' => false]); $cover->save(); $item['image_id'] = $cover->id; } elseif ($model->type == $model::TYPE_AUDIO) { $track = new Track(['release_id' => $release->id, 'original_name' => $file->baseName, 'number' => $release->getTracks()->count() + 1, 'file_id' => $model->id]); $track->save(); $item['track_id'] = $track->id; $item['comname'] = $track->getComname(); $item['number'] = $track->number; } } } if ($artistId = Yii::$app->request->get('aid')) { $photo = new Photo(['artist_id' => (string) $artistId, 'file_id' => $model->id, 'is_main' => false]); $artist = Artist::findOne($artistId); if ($artist && $artist->user_id == Yii::$app->user->id) { $photo->save(); $item['image_id'] = $photo->id; } } // if ($model->type == $model::TYPE_AUDIO) { // $getID3 = new getID3(); // $tags = $getID3->analyze($model->getPath(true))['tags']['id3v2']; // $item['meta'] = [ // 'title' => $tags['title'][0], // 'number' => explode('/', $tags['track_number'][0])[0], // 'disc' => explode('/', $tags['part_of_a_set'][0])[0], // 'lyric' => $tags['unsynchronised_lyric'][0], // 'info' => $tags['comment'][0], // ]; // } if ($model->type == $model::TYPE_AUDIO) { $item['meta'] = ['title' => $file->baseName, 'number' => $index + 1, 'disc' => '', 'lyric' => '', 'info' => '']; } $result[] = $item; } } return $result; }
/** * Get a set of application data. * * @return \Illuminate\Http\JsonResponse */ public function index() { $playlists = Playlist::byCurrentUser()->orderBy('name')->with('songs')->get()->toArray(); // We don't need full song data, just ID's foreach ($playlists as &$playlist) { $playlist['songs'] = array_pluck($playlist['songs'], 'id'); } return response()->json(['artists' => Artist::orderBy('name')->with('albums', with('albums.songs'))->get(), 'settings' => Setting::lists('value', 'key')->all(), 'playlists' => $playlists, 'interactions' => Interaction::byCurrentUser()->get(), 'users' => auth()->user()->is_admin ? User::all() : [], 'currentUser' => auth()->user(), 'useLastfm' => env('LASTFM_API_KEY') && env('LASTFM_API_SECRET'), 'currentVersion' => Application::VERSION, 'latestVersion' => auth()->user()->is_admin ? app()->getLatestVersion() : Application::VERSION]); }
/** * Get a set of application data. * * @return \Illuminate\Http\JsonResponse */ public function index() { $playlists = Playlist::byCurrentUser()->orderBy('name')->with('songs')->get()->toArray(); // We don't need full song data, just ID's foreach ($playlists as &$playlist) { $playlist['songs'] = array_pluck($playlist['songs'], 'id'); } return response()->json(['artists' => Artist::orderBy('name')->with('albums', with('albums.songs'))->get(), 'settings' => auth()->user()->is_admin ? Setting::pluck('value', 'key')->all() : [], 'playlists' => $playlists, 'interactions' => Interaction::byCurrentUser()->get(), 'users' => auth()->user()->is_admin ? User::all() : [], 'currentUser' => auth()->user(), 'useLastfm' => Lastfm::used(), 'useYouTube' => YouTube::enabled(), 'allowDownload' => config('koel.download.allow'), 'cdnUrl' => app()->staticUrl(), 'currentVersion' => Application::VERSION, 'latestVersion' => auth()->user()->is_admin ? app()->getLatestVersion() : Application::VERSION]); }
/** * Fired every time a LibraryChanged event is triggered. * Remove empty albums and artists from our system. */ public function handle() { $inUseAlbums = Song::select('album_id')->groupBy('album_id')->get()->lists('album_id'); $inUseAlbums[] = Album::UNKNOWN_ID; Album::whereNotIn('id', $inUseAlbums)->delete(); $inUseArtists = Album::select('artist_id')->groupBy('artist_id')->get()->lists('artist_id'); $inUseArtists[] = Artist::UNKNOWN_ID; Artist::whereNotIn('id', $inUseArtists)->delete(); }
/** * Get a set of application data. * * @return \Illuminate\Http\JsonResponse */ public function index() { $playlists = Playlist::byCurrentUser()->orderBy('name')->with('songs')->get()->toArray(); // We don't need full song data, just ID's foreach ($playlists as &$playlist) { $playlist['songs'] = array_pluck($playlist['songs'], 'id'); } return response()->json(['artists' => Artist::orderBy('name')->with('albums', with('albums.songs'))->get(), 'settings' => Setting::all()->lists('value', 'key'), 'playlists' => $playlists, 'interactions' => Interaction::byCurrentUser()->get(), 'users' => auth()->user()->is_admin ? User::all() : [], 'user' => auth()->user()]); }
/** * Run the migrations. * * @return void */ public function up() { // This is to fix the auto increment bug caused by 2016_04_16_082627_create_various_artists // Return if the database driver is not MySQL. if (DB::getDriverName() !== 'mysql') { return; } $latestArtist = Artist::orderBy('id', 'DESC')->first(); DB::statement('ALTER TABLE artists AUTO_INCREMENT=' . ($latestArtist->id + 1)); }
public function testSingleUpdateAllInfo() { $this->expectsEvents(LibraryChanged::class); $this->createSampleMediaSet(); $song = Song::orderBy('id', 'desc')->first(); $this->actingAs(factory(User::class, 'admin')->create())->put('/api/songs', ['songs' => [$song->id], 'data' => ['title' => 'Foo Bar', 'artistName' => 'John Cena', 'albumName' => 'One by One', 'lyrics' => 'Lorem ipsum dolor sic amet.', 'track' => 1]])->seeStatusCode(200); $artist = Artist::whereName('John Cena')->first(); $this->assertNotNull($artist); $album = Album::whereName('One by One')->first(); $this->assertNotNull($album); $this->seeInDatabase('songs', ['id' => $song->id, 'album_id' => $album->id, 'lyrics' => 'Lorem ipsum dolor sic amet.', 'track' => 1]); }
/** * Store a new song or update an existing one with data from AWS. * * @param PutSongRequest $request * * @return \Illuminate\Http\JsonResponse */ public function put(PutSongRequest $request) { $path = "s3://{$request->bucket}/{$request->key}"; $tags = $request->tags; $artist = Artist::get(array_get($tags, 'artist')); $compilation = (bool) trim(array_get($tags, 'albumartist')); $album = Album::get($artist, array_get($tags, 'album'), $compilation); if ($cover = array_get($tags, 'cover')) { $album->writeCoverFile(base64_decode($cover['data']), $cover['extension']); } $song = Song::updateOrCreate(['id' => Media::getHash($path)], ['path' => $path, 'album_id' => $album->id, 'contributing_artist_id' => $compilation ? $artist->id : null, 'title' => trim(array_get($tags, 'title', '')), 'length' => array_get($tags, 'duration', 0), 'track' => intval(array_get($tags, 'track')), 'lyrics' => array_get($tags, 'lyrics', ''), 'mtime' => time()]); return response()->json($song); }
public function show($id) { $artist = Artist::with('label')->findOrFail($id); $tracks = $artist->tracks()->get(); $images = ['header_url' => $artist->header_url, 'cover_url' => $artist->cover_url]; $links = []; foreach (['twitter', 'facebook', 'soundcloud'] as $service) { if ($artist->{$service}) { $links[] = ['title' => ucwords($service), 'url' => $artist->{$service}, 'icon' => $service, 'class' => $service]; } } if ($artist->website) { $links[] = ['title' => trans('artist.links.site'), 'url' => $artist->website, 'icon' => 'globe', 'class' => '']; } return view('artists.show')->with('artist', $artist)->with('links', $links)->with('tracks', json_collection($tracks, new ArtistTrackTransformer()))->with('images', $images); }
/** * Create the "Various Artists". * * @return void */ public function up() { Artist::unguard(); $existingArtist = Artist::find(Artist::VARIOUS_ID); if ($existingArtist) { if ($existingArtist->name === Artist::VARIOUS_NAME) { goto ret; } // There's an existing artist with that special ID, but it's not our Various Artist // We move it to the end of the table. $latestArtist = Artist::orderBy('id', 'DESC')->first(); $existingArtist->id = $latestArtist->id + 1; $existingArtist->save(); } Artist::create(['id' => Artist::VARIOUS_ID, 'name' => Artist::VARIOUS_NAME]); ret: Artist::reguard(); }
public function show($id) { $artist = Artist::with('label')->findOrFail($id); $albums = $artist->albums()->where('visible', true)->with(['tracks' => function ($query) { $query->orderBy('display_order', 'ASC'); }])->get(); $tracks = $artist->tracks()->whereNull('album_id')->orderBy('display_order', 'ASC NULLS LAST')->get(); $images = ['header_url' => $artist->header_url, 'cover_url' => $artist->cover_url]; // should probably move services to a separate model if the number increases further $links = []; foreach (['soundcloud', 'twitter', 'facebook', 'bandcamp', 'patreon'] as $service) { if ($artist->{$service}) { $links[] = ['title' => ucwords($service), 'url' => $artist->{$service}, 'icon' => $service === 'patreon' ? "extra-social-{$service}" : $service, 'class' => $service]; } } if ($artist->website) { $links[] = ['title' => trans('artist.links.site'), 'url' => $artist->website, 'icon' => 'globe', 'class' => 'website']; } return view('artists.show')->with('artist', $artist)->with('links', $links)->with('albums', json_collection($albums, new ArtistAlbumTransformer(), ['tracks']))->with('tracks', json_collection($tracks, new ArtistTrackTransformer()))->with('images', $images); }
/** * Create the "Various Artists". * * @return void */ public function up() { // Make sure modified artists cascade the album's artist_id field. Schema::table('albums', function ($table) { $table->dropForeign('albums_artist_id_foreign'); $table->foreign('artist_id')->references('id')->on('artists')->onUpdate('cascade')->onDelete('cascade'); }); Artist::unguard(); $existingArtist = Artist::find(Artist::VARIOUS_ID); if ($existingArtist) { if ($existingArtist->name === Artist::VARIOUS_NAME) { goto ret; } // There's an existing artist with that special ID, but it's not our Various Artist // We move it to the end of the table. $latestArtist = Artist::orderBy('id', 'DESC')->first(); $existingArtist->id = $latestArtist->id + 1; $existingArtist->save(); } Artist::create(['id' => Artist::VARIOUS_ID, 'name' => Artist::VARIOUS_NAME]); ret: Artist::reguard(); }
public function actionArtist() { $model = Artist::findOne(Yii::$app->request->post('pk', '')); $ownerId = $model->user_id; if (Yii::$app->request->post('name', '') == 'artist-tags') { $artistTags = (new \yii\db\Query())->select('tag_id')->from('artist_tag')->where(['artist_id' => $model->id])->column(); $requestTags = Yii::$app->request->post('value', []); foreach ($requestTags as $tagId) { if (!in_array($tagId, $artistTags)) { $tag = Tag::findOne($tagId); if ($tag) { $model->link('tags', $tag); } } } foreach ($artistTags as $tagId) { if (!in_array($tagId, $requestTags)) { Yii::$app->db->createCommand()->delete('artist_tag', ['artist_id' => $model->id, 'tag_id' => $tagId])->execute(); } } return null; } return self::update($model, $ownerId); }
public function testArtist() { $artist = Artist::first(); $mocked = Download::shouldReceive('from')->once()->andReturn($this->mediaPath . '/blank.mp3'); $this->get("api/download/artist/{$artist->id}")->seeStatusCode(200); }
protected function fromArtist(Artist $artist) { // Don't forget the contributed songs. $songs = $artist->songs->merge($artist->getContributedSongs()); return $this->fromMultipleSongs($songs); }
public function testSingleUpdateAllInfoYesCompilation() { $admin = factory(User::class, 'admin')->create(); $song = Song::orderBy('id', 'desc')->first(); $this->actingAs($admin)->put('/api/songs', ['songs' => [$song->id], 'data' => ['title' => 'Foo Bar', 'artistName' => 'John Cena', 'albumName' => 'One by One', 'lyrics' => 'Lorem ipsum dolor sic amet.', 'track' => 1, 'compilationState' => 1]])->seeStatusCode(200); $compilationAlbum = Album::whereArtistIdAndName(Artist::VARIOUS_ID, 'One by One')->first(); $this->assertNotNull($compilationAlbum); $contributingArtist = Artist::whereName('John Cena')->first(); $this->assertNotNull($contributingArtist); $this->seeInDatabase('songs', ['id' => $song->id, 'contributing_artist_id' => $contributingArtist->id, 'album_id' => $compilationAlbum->id, 'lyrics' => 'Lorem ipsum dolor sic amet.', 'track' => 1]); // Now try changing stuff and make sure things work. // Case 1: Keep compilation state and artist the same $this->actingAs($admin)->put('/api/songs', ['songs' => [$song->id], 'data' => ['title' => 'Barz Qux', 'artistName' => 'John Cena', 'albumName' => 'Two by Two', 'lyrics' => 'Lorem ipsum dolor sic amet.', 'track' => 1, 'compilationState' => 2]])->seeStatusCode(200); $compilationAlbum = Album::whereArtistIdAndName(Artist::VARIOUS_ID, 'Two by Two')->first(); $this->assertNotNull($compilationAlbum); $contributingArtist = Artist::whereName('John Cena')->first(); $this->assertNotNull($contributingArtist); $this->seeInDatabase('songs', ['id' => $song->id, 'contributing_artist_id' => $contributingArtist->id, 'album_id' => $compilationAlbum->id]); // Case 2: Keep compilation state, but change the artist. $this->actingAs($admin)->put('/api/songs', ['songs' => [$song->id], 'data' => ['title' => 'Barz Qux', 'artistName' => 'Foo Fighters', 'albumName' => 'One by One', 'lyrics' => 'Lorem ipsum dolor sic amet.', 'track' => 1, 'compilationState' => 2]])->seeStatusCode(200); $compilationAlbum = Album::whereArtistIdAndName(Artist::VARIOUS_ID, 'One by One')->first(); $this->assertNotNull($compilationAlbum); $contributingArtist = Artist::whereName('Foo Fighters')->first(); $this->assertNotNull($contributingArtist); $this->seeInDatabase('songs', ['id' => $song->id, 'contributing_artist_id' => $contributingArtist->id, 'album_id' => $compilationAlbum->id]); // Case 3: Change compilation state only $this->actingAs($admin)->put('/api/songs', ['songs' => [$song->id], 'data' => ['title' => 'Barz Qux', 'artistName' => 'Foo Fighters', 'albumName' => 'One by One', 'lyrics' => 'Lorem ipsum dolor sic amet.', 'track' => 1, 'compilationState' => 0]])->seeStatusCode(200); $artist = Artist::whereName('Foo Fighters')->first(); $this->assertNotNull($artist); $album = Album::whereArtistIdAndName($artist->id, 'One by One')->first(); $this->seeInDatabase('songs', ['id' => $song->id, 'contributing_artist_id' => null, 'album_id' => $album->id]); // Case 3: Change compilation state and artist // Remember to set the compliation state back to 1 $this->actingAs($admin)->put('/api/songs', ['songs' => [$song->id], 'data' => ['title' => 'Barz Qux', 'artistName' => 'Foo Fighters', 'albumName' => 'One by One', 'lyrics' => 'Lorem ipsum dolor sic amet.', 'track' => 1, 'compilationState' => 1]])->put('/api/songs', ['songs' => [$song->id], 'data' => ['title' => 'Twilight of the Thunder God', 'artistName' => 'Amon Amarth', 'albumName' => 'Twilight of the Thunder God', 'lyrics' => 'Thor! Nanananananana Batman.', 'track' => 1, 'compilationState' => 0]])->seeStatusCode(200); $artist = Artist::whereName('Amon Amarth')->first(); $this->assertNotNull($artist); $album = Album::whereArtistIdAndName($artist->id, 'Twilight of the Thunder God')->first(); $this->assertNotNull($album); $this->seeInDatabase('songs', ['id' => $song->id, 'contributing_artist_id' => null, 'album_id' => $album->id, 'lyrics' => 'Thor! Nanananananana Batman.']); }
/** * Tidy up the library by deleting empty albums and artists. */ public function tidy() { $inUseAlbums = Song::select('album_id')->groupBy('album_id')->get()->lists('album_id')->toArray(); $inUseAlbums[] = Album::UNKNOWN_ID; Album::whereNotIn('id', $inUseAlbums)->delete(); $inUseArtists = Album::select('artist_id')->groupBy('artist_id')->get()->lists('artist_id')->toArray(); $contributingArtists = Song::distinct()->select('contributing_artist_id')->groupBy('contributing_artist_id')->get()->lists('contributing_artist_id')->toArray(); $inUseArtists = array_merge($inUseArtists, $contributingArtists); $inUseArtists[] = Artist::UNKNOWN_ID; $inUseArtists[] = Artist::VARIOUS_ID; Artist::whereNotIn('id', $inUseArtists)->delete(); }
/** * Update a single song's info. * * @param string $title * @param string $albumName * @param string $artistName * @param string $lyrics * @param int $track * @param int $compilationState * * @return self */ public function updateSingle($title, $albumName, $artistName, $lyrics, $track, $compilationState) { // If the artist name is "Various Artists", it's a compilation song no matter what. if ($artistName === Artist::VARIOUS_NAME) { $compilationState = 1; } // If the complitation state is "no change," we determine it via the current // "contributing_artist_id" field value. if ($compilationState === 2) { $compilationState = $this->contributing_artist_id ? 1 : 0; } $album = null; if ($compilationState === 0) { // Not a compilation song $this->contributing_artist_id = null; $albumArtist = Artist::get($artistName); $album = Album::get($albumArtist, $albumName, false); } else { $contributingArtist = Artist::get($artistName); $this->contributing_artist_id = $contributingArtist->id; $album = Album::get(Artist::getVarious(), $albumName, true); } $this->album_id = $album->id; $this->lyrics = $lyrics; $this->track = $track; $this->save(); // Get the updated record, with album and all. $updatedSong = self::with('album', 'album.artist', 'contributingArtist')->find($this->id); // Make sure lyrics is included in the returned JSON. $updatedSong->makeVisible('lyrics'); return $updatedSong; }
/** * Sync the song with all available media info against the database. * * @param array $tags The (selective) tags to sync (if the song exists) * @param bool $force Whether to force syncing, even if the file is unchaged * * @return bool|Song A Song object on success, * true if file exists but is unmodified, * or false on an error. */ public function sync($tags, $force = false) { // If the file is not new or changed and we're not forcing update, don't do anything. if (!$this->isNewOrChanged() && !$force) { return true; } // If the file is invalid, don't do anything. if (!($info = $this->getInfo())) { return false; } if ($this->isChanged() || $force) { // This is a changed file, or the user is forcing updates. // We cater for the tags by removing those not specified. $info = array_intersect_key($info, array_flip($tags)); $artist = isset($info['artist']) ? Artist::get($info['artist']) : $this->song->album->artist; $album = isset($info['album']) ? Album::get($artist, $info['album']) : $this->song->album; } else { $album = Album::get(Artist::get($info['artist']), $info['album']); } if (!empty($info['cover']) && !$album->has_cover) { try { $album->generateCover($info['cover']); } catch (Exception $e) { Log::error($e); } } $info['album_id'] = $album->id; // Remove these values from the info array, so that we can just use the array as model's input data. array_forget($info, ['artist', 'album', 'cover']); $song = Song::updateOrCreate(['id' => $this->hash], $info); $song->save(); return $song; }
/** * @return \yii\db\ActiveQuery */ public function getArtist() { return $this->hasOne(Artist::className(), ['id' => 'artist_id']); }
/** * Finds the Artist model based on its primary key value. * If the model is not found, a 404 HTTP exception will be thrown. * @param integer $id * @return Artist the loaded model * @throws NotFoundHttpException if the model cannot be found */ protected function findModel($id) { if (($model = Artist::findOne($id)) !== null) { if ($model->user_id != Yii::$app->user->id) { throw new ForbiddenHttpException(); } return $model; } else { throw new NotFoundHttpException('The requested page does not exist.'); } }
/** * Get extra information about an artist via Last.fm. * * @param Artist $artist * * @return \Illuminate\Http\JsonResponse */ public function getInfo(Artist $artist) { return response()->json($artist->getInfo()); }
/** * Sync the song with all available media info against the database. * * @param array $tags The (selective) tags to sync (if the song exists) * @param bool $force Whether to force syncing, even if the file is unchanged * * @return bool|Song A Song object on success, * true if file exists but is unmodified, * or false on an error. */ public function sync($tags, $force = false) { // If the file is not new or changed and we're not forcing update, don't do anything. if (!$this->isNewOrChanged() && !$force) { return true; } // If the file is invalid, don't do anything. if (!($info = $this->getInfo())) { return false; } // Fixes #366. If the file is new, we use all tags by simply setting $force to false. if ($this->isNew()) { $force = false; } $artist = null; if ($this->isChanged() || $force) { // This is a changed file, or the user is forcing updates. // In such a case, the user must have specified a list of tags to sync. // A sample command could be: ./artisan koel:sync --force --tags=artist,album,lyrics // We cater for these tags by removing those not specified. // There's a special case with 'album' though. // If 'compilation' tag is specified, 'album' must be counted in as well. // But if 'album' isn't specified, we don't want to update normal albums. // This variable is to keep track of this state. $changeCompilationAlbumOnly = false; if (in_array('compilation', $tags, true) && !in_array('album', $tags, true)) { $tags[] = 'album'; $changeCompilationAlbumOnly = true; } $info = array_intersect_key($info, array_flip($tags)); // If the "artist" tag is specified, use it. // Otherwise, re-use the existing model value. $artist = isset($info['artist']) ? Artist::get($info['artist']) : $this->song->album->artist; $isCompilation = (bool) array_get($info, 'compilation'); // If the "album" tag is specified, use it. // Otherwise, re-use the existing model value. if (isset($info['album'])) { $album = $changeCompilationAlbumOnly ? $this->song->album : Album::get($artist, $info['album'], $isCompilation); } else { $album = $this->song->album; } } else { // The file is newly added. $isCompilation = (bool) array_get($info, 'compilation'); $artist = Artist::get($info['artist']); $album = Album::get($artist, $info['album'], $isCompilation); } if (!$album->has_cover) { // If the album has no cover, we try to get the cover image from existing tag data if (!empty($info['cover'])) { try { $album->generateCover($info['cover']); } catch (Exception $e) { Log::error($e); } } elseif ($cover = $this->getCoverFileUnderSameDirectory()) { $album->copyCoverFile($cover); } } $info['album_id'] = $album->id; // If the song is part of a compilation, make sure we properly set its // artist and contributing artist attributes. if ($isCompilation) { $info['contributing_artist_id'] = $artist->id; } // Remove these values from the info array, so that we can just use the array as model's input data. array_forget($info, ['artist', 'albumartist', 'album', 'cover', 'compilation']); return Song::updateOrCreate(['id' => $this->hash], $info); }