refactor: prefer invokeable controllers

This commit is contained in:
Phan An 2024-01-02 13:07:37 +01:00
parent d8282557d7
commit 1ab8d7590f
30 changed files with 325 additions and 336 deletions

View file

@ -1,30 +0,0 @@
<?php
namespace App\Http\Controllers\API;
use App\Events\LibraryChanged;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\AlbumCoverUpdateRequest;
use App\Models\Album;
use App\Services\MediaMetadataService;
use Illuminate\Http\JsonResponse;
class AlbumCoverController extends Controller
{
public function __construct(private MediaMetadataService $mediaMetadataService)
{
}
public function update(AlbumCoverUpdateRequest $request, Album $album)
{
$this->mediaMetadataService->writeAlbumCover(
$album,
$request->getFileContentAsBinaryString(),
$request->getFileExtension()
);
event(new LibraryChanged());
return new JsonResponse(['coverUrl' => $album->cover]);
}
}

View file

@ -1,20 +0,0 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Models\Album;
use App\Services\MediaMetadataService;
use Illuminate\Http\JsonResponse;
class AlbumThumbnailController extends Controller
{
public function __construct(private MediaMetadataService $mediaMetadataService)
{
}
public function show(Album $album): JsonResponse
{
return response()->json(['thumbnailUrl' => $this->mediaMetadataService->getAlbumThumbnailUrl($album)]);
}
}

View file

@ -1,30 +0,0 @@
<?php
namespace App\Http\Controllers\API;
use App\Events\LibraryChanged;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\ArtistImageUpdateRequest;
use App\Models\Artist;
use App\Services\MediaMetadataService;
use Illuminate\Http\JsonResponse;
class ArtistImageController extends Controller
{
public function __construct(private MediaMetadataService $mediaMetadataService)
{
}
public function update(ArtistImageUpdateRequest $request, Artist $artist)
{
$this->mediaMetadataService->writeArtistImage(
$artist,
$request->getFileContentAsBinaryString(),
$request->getFileExtension()
);
event(new LibraryChanged());
return new JsonResponse(['imageUrl' => $artist->image]);
}
}

View file

@ -0,0 +1,19 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Models\User;
use App\Services\LastfmService;
use Illuminate\Contracts\Auth\Authenticatable;
class DisconnectFromLastfmController extends Controller
{
/** @param User $user */
public function __invoke(LastfmService $lastfm, Authenticatable $user)
{
$lastfm->setUserSessionKey($user, null);
return response()->noContent();
}
}

View file

@ -1,22 +0,0 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Resources\SongResource;
use App\Models\User;
use App\Repositories\SongRepository;
use Illuminate\Contracts\Auth\Authenticatable;
class FavoriteSongController extends Controller
{
/** @param User $user */
public function __construct(private SongRepository $songRepository, private ?Authenticatable $user)
{
}
public function index()
{
return SongResource::collection($this->songRepository->getFavorites($this->user));
}
}

View file

@ -0,0 +1,15 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Models\Album;
use App\Services\MediaMetadataService;
class FetchAlbumThumbnailController extends Controller
{
public function __invoke(Album $album, MediaMetadataService $mediaMetadataService)
{
return response()->json(['thumbnailUrl' => $mediaMetadataService->getAlbumThumbnailUrl($album)]);
}
}

View file

@ -5,14 +5,14 @@ namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Throwable;
class DemoCreditController extends Controller
class FetchDemoCreditController extends Controller
{
public function index()
public function __invoke()
{
try {
return response()->json(json_decode(file_get_contents(resource_path('demo-credits.json')), true));
} catch (Throwable) {
return response()->json([]);
return response()->json();
}
}
}

View file

@ -0,0 +1,18 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Resources\SongResource;
use App\Models\User;
use App\Repositories\SongRepository;
use Illuminate\Contracts\Auth\Authenticatable;
class FetchFavoriteSongsController extends Controller
{
/** @param User $user */
public function __invoke(SongRepository $repository, Authenticatable $user)
{
return SongResource::collection($repository->getFavorites($user));
}
}

View file

@ -18,41 +18,37 @@ use App\Services\SpotifyService;
use App\Services\YouTubeService;
use Illuminate\Contracts\Auth\Authenticatable;
class DataController extends Controller
class FetchInitialDataController extends Controller
{
/** @param User $user */
public function __construct(
private ITunesService $iTunesService,
private SettingRepository $settingRepository,
private SongRepository $songRepository,
private ApplicationInformationService $applicationInformationService,
private QueueService $queueService,
private ?Authenticatable $user
public function __invoke(
ITunesService $iTunesService,
SettingRepository $settingRepository,
SongRepository $songRepository,
ApplicationInformationService $applicationInformationService,
QueueService $queueService,
?Authenticatable $user
) {
}
public function index()
{
return response()->json([
'settings' => $this->user->is_admin ? $this->settingRepository->getAllAsKeyValueArray() : [],
'playlists' => PlaylistResource::collection($this->user->playlists),
'playlist_folders' => PlaylistFolderResource::collection($this->user->playlist_folders),
'current_user' => UserResource::make($this->user, true),
'settings' => $user->is_admin ? $settingRepository->getAllAsKeyValueArray() : [],
'playlists' => PlaylistResource::collection($user->playlists),
'playlist_folders' => PlaylistFolderResource::collection($user->playlist_folders),
'current_user' => UserResource::make($user, true),
'use_last_fm' => LastfmService::used(),
'use_spotify' => SpotifyService::enabled(),
'use_you_tube' => YouTubeService::enabled(),
'use_i_tunes' => $this->iTunesService->used(),
'use_i_tunes' => $iTunesService->used(),
'allow_download' => config('koel.download.allow'),
'supports_transcoding' => config('koel.streaming.ffmpeg_path')
&& is_executable(config('koel.streaming.ffmpeg_path')),
'cdn_url' => static_url(),
'current_version' => koel_version(),
'latest_version' => $this->user->is_admin
? $this->applicationInformationService->getLatestVersionNumber()
'latest_version' => $user->is_admin
? $applicationInformationService->getLatestVersionNumber()
: koel_version(),
'song_count' => $this->songRepository->count(),
'song_length' => $this->songRepository->getTotalLength(),
'queue_state' => QueueStateResource::make($this->queueService->getQueueState($this->user)),
'song_count' => $songRepository->count(),
'song_length' => $songRepository->getTotalLength(),
'queue_state' => QueueStateResource::make($queueService->getQueueState($user)),
]);
}
}

View file

@ -0,0 +1,30 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Resources\AlbumResource;
use App\Http\Resources\ArtistResource;
use App\Http\Resources\SongResource;
use App\Repositories\AlbumRepository;
use App\Repositories\ArtistRepository;
use App\Repositories\SongRepository;
class FetchOverviewController extends Controller
{
public function __invoke(
SongRepository $songRepository,
AlbumRepository $albumRepository,
ArtistRepository $artistRepository
) {
return response()->json([
'most_played_songs' => SongResource::collection($songRepository->getMostPlayed()),
'recently_played_songs' => SongResource::collection($songRepository->getRecentlyPlayed()),
'recently_added_albums' => AlbumResource::collection($albumRepository->getRecentlyAdded()),
'recently_added_songs' => SongResource::collection($songRepository->getRecentlyAdded()),
'most_played_artists' => ArtistResource::collection($artistRepository->getMostPlayed()),
'most_played_albums' => AlbumResource::collection($albumRepository->getMostPlayed()),
]);
}
}

View file

@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Resources\SongResource;
use App\Models\User;
use App\Repositories\SongRepository;
use Illuminate\Contracts\Auth\Authenticatable;
class FetchRecentlyPlayedSongController extends Controller
{
private const MAX_ITEM_COUNT = 128;
/** @param User $user */
public function __invoke(SongRepository $repository, ?Authenticatable $user)
{
return SongResource::collection($repository->getRecentlyPlayed(self::MAX_ITEM_COUNT, $user));
}
}

View file

@ -0,0 +1,23 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\FetchSongsForQueueRequest;
use App\Http\Resources\SongResource;
use App\Models\User;
use App\Repositories\SongRepository;
use Illuminate\Contracts\Auth\Authenticatable;
class FetchSongsForQueueController extends Controller
{
/** @param User $user */
public function __invoke(FetchSongsForQueueRequest $request, SongRepository $repository, Authenticatable $user)
{
return SongResource::collection(
$request->order === 'rand'
? $repository->getRandom($request->limit, $user)
: $repository->getForQueue($request->sort, $request->order, $request->limit, $user)
);
}
}

View file

@ -1,31 +0,0 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\LastfmSetSessionKeyRequest;
use App\Models\User;
use App\Services\LastfmService;
use Illuminate\Contracts\Auth\Authenticatable;
class LastfmController extends Controller
{
/** @param User $currentUser */
public function __construct(private LastfmService $lastfm, private ?Authenticatable $currentUser)
{
}
public function setSessionKey(LastfmSetSessionKeyRequest $request)
{
$this->lastfm->setUserSessionKey($this->currentUser, $request->key);
return response()->noContent();
}
public function disconnect()
{
$this->lastfm->setUserSessionKey($this->currentUser, null);
return response()->noContent();
}
}

View file

@ -1,33 +0,0 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Resources\AlbumResource;
use App\Http\Resources\ArtistResource;
use App\Http\Resources\SongResource;
use App\Repositories\AlbumRepository;
use App\Repositories\ArtistRepository;
use App\Repositories\SongRepository;
class OverviewController extends Controller
{
public function __construct(
private SongRepository $songRepository,
private AlbumRepository $albumRepository,
private ArtistRepository $artistRepository
) {
}
public function index()
{
return response()->json([
'most_played_songs' => SongResource::collection($this->songRepository->getMostPlayed()),
'recently_played_songs' => SongResource::collection($this->songRepository->getRecentlyPlayed()),
'recently_added_albums' => AlbumResource::collection($this->albumRepository->getRecentlyAdded()),
'recently_added_songs' => SongResource::collection($this->songRepository->getRecentlyAdded()),
'most_played_artists' => ArtistResource::collection($this->artistRepository->getMostPlayed()),
'most_played_albums' => AlbumResource::collection($this->albumRepository->getMostPlayed()),
]);
}
}

View file

@ -1,60 +0,0 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\QueueFetchSongRequest;
use App\Http\Requests\API\UpdatePlaybackStatusRequest;
use App\Http\Requests\API\UpdateQueueStateRequest;
use App\Http\Resources\QueueStateResource;
use App\Http\Resources\SongResource;
use App\Models\User;
use App\Repositories\SongRepository;
use App\Services\QueueService;
use Illuminate\Contracts\Auth\Authenticatable;
class QueueController extends Controller
{
/** @param User $user */
public function __construct(
private SongRepository $songRepository,
private QueueService $queueService,
private ?Authenticatable $user
) {
}
public function getState()
{
return QueueStateResource::make($this->queueService->getQueueState($this->user));
}
public function updateState(UpdateQueueStateRequest $request)
{
$this->queueService->updateQueueState($this->user, $request->songs);
return response()->noContent();
}
public function updatePlaybackStatus(UpdatePlaybackStatusRequest $request)
{
$this->queueService->updatePlaybackStatus($this->user, $request->song, $request->position);
return response()->noContent();
}
public function fetchSongs(QueueFetchSongRequest $request)
{
if ($request->order === 'rand') {
return SongResource::collection($this->songRepository->getRandom($request->limit, $this->user));
}
return SongResource::collection(
$this->songRepository->getForQueue(
$request->sort,
$request->order,
$request->limit,
$this->user
)
);
}
}

View file

@ -0,0 +1,30 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\UpdateQueueStateRequest;
use App\Http\Resources\QueueStateResource;
use App\Models\User;
use App\Services\QueueService;
use Illuminate\Contracts\Auth\Authenticatable;
class QueueStateController extends Controller
{
/** @param User $user */
public function __construct(private QueueService $queueService, private ?Authenticatable $user)
{
}
public function show()
{
return QueueStateResource::make($this->queueService->getQueueState($this->user));
}
public function update(UpdateQueueStateRequest $request)
{
$this->queueService->updateQueueState($this->user, $request->songs);
return response()->noContent();
}
}

View file

@ -1,24 +0,0 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Resources\SongResource;
use App\Models\User;
use App\Repositories\SongRepository;
use Illuminate\Contracts\Auth\Authenticatable;
class RecentlyPlayedSongController extends Controller
{
private const MAX_ITEM_COUNT = 128;
/** @param User $user */
public function __construct(private SongRepository $songRepository, private ?Authenticatable $user)
{
}
public function index()
{
return SongResource::collection($this->songRepository->getRecentlyPlayed(self::MAX_ITEM_COUNT, $this->user));
}
}

View file

@ -3,7 +3,7 @@
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\ScrobbleStoreRequest;
use App\Http\Requests\API\ScrobbleRequest;
use App\Jobs\ScrobbleJob;
use App\Models\Song;
use App\Models\User;
@ -11,15 +11,11 @@ use Illuminate\Contracts\Auth\Authenticatable;
class ScrobbleController extends Controller
{
/** @param User $currentUser */
public function __construct(private ?Authenticatable $currentUser)
/** @param User $user */
public function __invoke(ScrobbleRequest $request, Song $song, Authenticatable $user)
{
}
public function store(ScrobbleStoreRequest $request, Song $song)
{
if (!$song->artist->is_unknown && $this->currentUser->connectedToLastfm()) {
ScrobbleJob::dispatch($this->currentUser, $song, $request->timestamp);
if (!$song->artist->is_unknown && $user->connectedToLastfm()) {
ScrobbleJob::dispatch($user, $song, $request->timestamp);
}
return response()->noContent();

View file

@ -0,0 +1,16 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\YouTubeSearchRequest;
use App\Models\Song;
use App\Services\YouTubeService;
class SearchYouTubeController extends Controller
{
public function __invoke(YouTubeSearchRequest $request, Song $song, YouTubeService $youTubeService)
{
return response()->json($youTubeService->searchVideosRelatedToSong($song, $request->pageToken));
}
}

View file

@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\SetLastfmSessionKeyRequest;
use App\Models\User;
use App\Services\LastfmService;
use Illuminate\Contracts\Auth\Authenticatable;
class SetLastfmSessionKeyController extends Controller
{
/** @param User $user */
public function __invoke(SetLastfmSessionKeyRequest $request, LastfmService $lastfm, Authenticatable $user)
{
$lastfm->setUserSessionKey($user, $request->key);
return response()->noContent();
}
}

View file

@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\UpdatePlaybackStatusRequest;
use App\Models\User;
use App\Services\QueueService;
use Illuminate\Contracts\Auth\Authenticatable;
class UpdatePlaybackStatusController extends Controller
{
/** @param User $user */
public function __invoke(UpdatePlaybackStatusRequest $request, QueueService $queueService, Authenticatable $user)
{
$queueService->updatePlaybackStatus($user, $request->song, $request->position);
return response()->noContent();
}
}

View file

@ -0,0 +1,25 @@
<?php
namespace App\Http\Controllers\API;
use App\Events\LibraryChanged;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\UploadAlbumCoverRequest;
use App\Models\Album;
use App\Services\MediaMetadataService;
class UploadAlbumCoverController extends Controller
{
public function __invoke(UploadAlbumCoverRequest $request, Album $album, MediaMetadataService $mediaMetadataService)
{
$mediaMetadataService->writeAlbumCover(
$album,
$request->getFileContentAsBinaryString(),
$request->getFileExtension()
);
event(new LibraryChanged());
return response()->json(['coverUrl' => $album->cover]);
}
}

View file

@ -0,0 +1,28 @@
<?php
namespace App\Http\Controllers\API;
use App\Events\LibraryChanged;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\UploadArtistImageRequest;
use App\Models\Artist;
use App\Services\MediaMetadataService;
class UploadArtistImageController extends Controller
{
public function __invoke(
UploadArtistImageRequest $request,
Artist $artist,
MediaMetadataService $mediaMetadataService
) {
$mediaMetadataService->writeArtistImage(
$artist,
$request->getFileContentAsBinaryString(),
$request->getFileExtension()
);
event(new LibraryChanged());
return response()->json(['imageUrl' => $artist->image]);
}
}

View file

@ -1,20 +0,0 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\YouTubeSearchRequest;
use App\Models\Song;
use App\Services\YouTubeService;
class YouTubeController extends Controller
{
public function __construct(private YouTubeService $youTubeService)
{
}
public function searchVideosRelatedToSong(YouTubeSearchRequest $request, Song $song)
{
return response()->json($this->youTubeService->searchVideosRelatedToSong($song, $request->pageToken));
}
}

View file

@ -10,7 +10,7 @@ use Illuminate\Validation\Rule;
* @property-read string $order
* @property-read int $limit
*/
class QueueFetchSongRequest extends Request
class FetchSongsForQueueRequest extends Request
{
/** @return array<mixed> */
public function rules(): array

View file

@ -5,7 +5,7 @@ namespace App\Http\Requests\API;
/**
* @property int $timestamp
*/
class ScrobbleStoreRequest extends Request
class ScrobbleRequest extends Request
{
/** @return array<mixed> */
public function rules(): array

View file

@ -5,7 +5,7 @@ namespace App\Http\Requests\API;
/**
* @property string $key
*/
class LastfmSetSessionKeyRequest extends Request
class SetLastfmSessionKeyRequest extends Request
{
/** @return array<mixed> */
public function rules(): array

View file

@ -3,7 +3,7 @@
namespace App\Http\Requests\API;
/** @property string $cover */
class AlbumCoverUpdateRequest extends MediaImageUpdateRequest
class UploadAlbumCoverRequest extends MediaImageUpdateRequest
{
protected function getImageFieldName(): string
{

View file

@ -3,7 +3,7 @@
namespace App\Http\Requests\API;
/** @property string $image */
class ArtistImageUpdateRequest extends MediaImageUpdateRequest
class UploadArtistImageRequest extends MediaImageUpdateRequest
{
protected function getImageFieldName(): string
{

View file

@ -2,44 +2,47 @@
use App\Facades\YouTube;
use App\Http\Controllers\API\AlbumController;
use App\Http\Controllers\API\AlbumCoverController;
use App\Http\Controllers\API\AlbumSongController;
use App\Http\Controllers\API\AlbumThumbnailController;
use App\Http\Controllers\API\ArtistAlbumController;
use App\Http\Controllers\API\ArtistController;
use App\Http\Controllers\API\ArtistImageController;
use App\Http\Controllers\API\ArtistSongController;
use App\Http\Controllers\API\AuthController;
use App\Http\Controllers\API\DataController;
use App\Http\Controllers\API\DemoCreditController;
use App\Http\Controllers\API\DisconnectFromLastfmController;
use App\Http\Controllers\API\ExcerptSearchController;
use App\Http\Controllers\API\FavoriteSongController;
use App\Http\Controllers\API\FetchAlbumInformationController;
use App\Http\Controllers\API\FetchAlbumThumbnailController;
use App\Http\Controllers\API\FetchArtistInformationController;
use App\Http\Controllers\API\FetchDemoCreditController;
use App\Http\Controllers\API\FetchFavoriteSongsController;
use App\Http\Controllers\API\FetchInitialDataController;
use App\Http\Controllers\API\FetchOverviewController;
use App\Http\Controllers\API\FetchRandomSongsInGenreController;
use App\Http\Controllers\API\FetchRecentlyPlayedSongController;
use App\Http\Controllers\API\FetchSongsForQueueController;
use App\Http\Controllers\API\GenreController;
use App\Http\Controllers\API\GenreSongController;
use App\Http\Controllers\API\Interaction\BatchLikeController;
use App\Http\Controllers\API\Interaction\LikeController;
use App\Http\Controllers\API\Interaction\PlayCountController;
use App\Http\Controllers\API\LastfmController;
use App\Http\Controllers\API\ObjectStorage\S3\SongController as S3SongController;
use App\Http\Controllers\API\OverviewController;
use App\Http\Controllers\API\PlaylistController;
use App\Http\Controllers\API\PlaylistFolderController;
use App\Http\Controllers\API\PlaylistFolderPlaylistController;
use App\Http\Controllers\API\PlaylistSongController;
use App\Http\Controllers\API\ProfileController;
use App\Http\Controllers\API\QueueController;
use App\Http\Controllers\API\RecentlyPlayedSongController;
use App\Http\Controllers\API\QueueStateController;
use App\Http\Controllers\API\ScrobbleController;
use App\Http\Controllers\API\SearchYouTubeController;
use App\Http\Controllers\API\SetLastfmSessionKeyController;
use App\Http\Controllers\API\SettingController;
use App\Http\Controllers\API\SongController;
use App\Http\Controllers\API\SongSearchController;
use App\Http\Controllers\API\UpdatePlaybackStatusController;
use App\Http\Controllers\API\UploadAlbumCoverController;
use App\Http\Controllers\API\UploadArtistImageController;
use App\Http\Controllers\API\UploadController;
use App\Http\Controllers\API\UserController;
use App\Http\Controllers\API\UserInvitationController;
use App\Http\Controllers\API\YouTubeController;
use App\Models\Song;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
@ -69,13 +72,13 @@ Route::prefix('api')->middleware('api')->group(static function (): void {
return $pusher->socket_auth($request->channel_name, $request->socket_id);
})->name('broadcasting.auth');
Route::get('overview', [OverviewController::class, 'index']);
Route::get('data', [DataController::class, 'index']);
Route::get('overview', FetchOverviewController::class);
Route::get('data', FetchInitialDataController::class);
Route::get('queue/fetch', [QueueController::class, 'fetchSongs']);
Route::get('queue/state', [QueueController::class, 'getState']);
Route::put('queue/state', [QueueController::class, 'updateState']);
Route::put('queue/playback-status', [QueueController::class, 'updatePlaybackStatus']);
Route::get('queue/fetch', FetchSongsForQueueController::class);
Route::put('queue/playback-status', UpdatePlaybackStatusController::class);
Route::get('queue/state', [QueueStateController::class, 'show']);
Route::put('queue/state', [QueueStateController::class, 'update']);
Route::put('settings', [SettingController::class, 'update']);
@ -86,7 +89,7 @@ Route::prefix('api')->middleware('api')->group(static function (): void {
Route::apiResource('artists.albums', ArtistAlbumController::class);
Route::apiResource('artists.songs', ArtistSongController::class);
Route::post('songs/{song}/scrobble', [ScrobbleController::class, 'store'])->where(['song' => Song::ID_REGEX]);
Route::post('songs/{song}/scrobble', ScrobbleController::class)->where(['song' => Song::ID_REGEX]);
Route::apiResource('songs', SongController::class)
->except('update', 'destroy')
@ -103,8 +106,8 @@ Route::prefix('api')->middleware('api')->group(static function (): void {
Route::post('interaction/batch/like', [BatchLikeController::class, 'store']);
Route::post('interaction/batch/unlike', [BatchLikeController::class, 'destroy']);
Route::get('songs/recently-played', [RecentlyPlayedSongController::class, 'index']);
Route::get('songs/favorite', [FavoriteSongController::class, 'index']);
Route::get('songs/recently-played', FetchRecentlyPlayedSongController::class);
Route::get('songs/favorite', FetchFavoriteSongsController::class);
Route::apiResource('playlist-folders', PlaylistFolderController::class);
Route::apiResource('playlist-folders.playlists', PlaylistFolderPlaylistController::class)->except('destroy');
@ -130,12 +133,12 @@ Route::prefix('api')->middleware('api')->group(static function (): void {
Route::put('me', [ProfileController::class, 'update']);
// Last.fm-related routes
Route::post('lastfm/session-key', [LastfmController::class, 'setSessionKey']);
Route::delete('lastfm/disconnect', [LastfmController::class, 'disconnect'])->name('lastfm.disconnect');
Route::post('lastfm/session-key', SetLastfmSessionKeyController::class);
Route::delete('lastfm/disconnect', DisconnectFromLastfmController::class)->name('lastfm.disconnect');
// YouTube-related routes
if (YouTube::enabled()) {
Route::get('youtube/search/song/{song}', [YouTubeController::class, 'searchVideosRelatedToSong']);
Route::get('youtube/search/song/{song}', SearchYouTubeController::class);
}
// Media information routes
@ -143,9 +146,9 @@ Route::prefix('api')->middleware('api')->group(static function (): void {
Route::get('artists/{artist}/information', FetchArtistInformationController::class);
// Cover/image upload routes
Route::put('album/{album}/cover', [AlbumCoverController::class, 'update']);
Route::put('artist/{artist}/image', [ArtistImageController::class, 'update']);
Route::get('album/{album}/thumbnail', [AlbumThumbnailController::class, 'show']);
Route::put('album/{album}/cover', UploadAlbumCoverController::class);
Route::put('artist/{artist}/image', UploadArtistImageController::class);
Route::get('album/{album}/thumbnail', FetchAlbumThumbnailController::class);
Route::get('search', ExcerptSearchController::class);
Route::get('search/songs', SongSearchController::class);
@ -160,5 +163,5 @@ Route::prefix('api')->middleware('api')->group(static function (): void {
Route::delete('song', [S3SongController::class, 'remove'])->name('s3.song.remove'); // and here.
});
Route::get('demo/credits', [DemoCreditController::class, 'index']);
Route::get('demo/credits', FetchDemoCreditController::class);
});