2024-02-05 13:27:17 +00:00
|
|
|
<?php
|
|
|
|
|
2024-02-23 18:36:02 +00:00
|
|
|
namespace App\Services\SongStorages;
|
2024-02-05 13:27:17 +00:00
|
|
|
|
|
|
|
use App\Exceptions\MethodNotImplementedException;
|
2024-02-05 22:47:13 +00:00
|
|
|
use App\Exceptions\SongPathNotFoundException;
|
|
|
|
use App\Models\Album;
|
|
|
|
use App\Models\Artist;
|
2024-02-05 13:27:17 +00:00
|
|
|
use App\Models\Song;
|
|
|
|
use App\Models\User;
|
2024-02-05 22:47:13 +00:00
|
|
|
use App\Repositories\SongRepository;
|
|
|
|
use App\Repositories\UserRepository;
|
|
|
|
use App\Services\MediaMetadataService;
|
2024-02-05 21:17:41 +00:00
|
|
|
use App\Values\SongStorageTypes;
|
2024-02-05 13:27:17 +00:00
|
|
|
use Illuminate\Http\UploadedFile;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The legacy storage implementation for Lambda and S3, to provide backward compatibility.
|
|
|
|
* In this implementation, the songs are supposed to be uploaded to S3 directly.
|
|
|
|
*/
|
2024-02-05 21:17:41 +00:00
|
|
|
final class S3LambdaStorage extends S3CompatibleStorage
|
2024-02-05 13:27:17 +00:00
|
|
|
{
|
2024-02-05 22:47:13 +00:00
|
|
|
public function __construct( // @phpcs:ignore
|
|
|
|
private MediaMetadataService $mediaMetadataService,
|
|
|
|
private SongRepository $songRepository,
|
|
|
|
private UserRepository $userRepository
|
|
|
|
) {
|
|
|
|
}
|
|
|
|
|
2024-02-05 13:27:17 +00:00
|
|
|
public function storeUploadedFile(UploadedFile $file, User $uploader): Song
|
|
|
|
{
|
2024-04-04 22:20:42 +00:00
|
|
|
self::assertSupported();
|
|
|
|
|
2024-02-05 13:27:17 +00:00
|
|
|
throw new MethodNotImplementedException('Lambda storage does not support uploading.');
|
|
|
|
}
|
|
|
|
|
2024-02-05 22:47:13 +00:00
|
|
|
public function createSongEntry(
|
|
|
|
string $bucket,
|
|
|
|
string $key,
|
|
|
|
string $artistName,
|
|
|
|
string $albumName,
|
|
|
|
string $albumArtistName,
|
|
|
|
?array $cover,
|
|
|
|
string $title,
|
|
|
|
float $duration,
|
|
|
|
int $track,
|
|
|
|
string $lyrics
|
|
|
|
): Song {
|
|
|
|
$user = $this->userRepository->getDefaultAdminUser();
|
|
|
|
$path = Song::getPathFromS3BucketAndKey($bucket, $key);
|
|
|
|
$artist = Artist::getOrCreate($artistName);
|
|
|
|
|
|
|
|
$albumArtist = $albumArtistName && $albumArtistName !== $artistName
|
|
|
|
? Artist::getOrCreate($albumArtistName)
|
|
|
|
: $artist;
|
|
|
|
|
|
|
|
$album = Album::getOrCreate($albumArtist, $albumName);
|
|
|
|
|
|
|
|
if ($cover) {
|
2024-03-19 22:48:12 +00:00
|
|
|
$this->mediaMetadataService->writeAlbumCover($album, base64_decode($cover['data'], true));
|
2024-02-05 22:47:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/** @var Song $song */
|
|
|
|
$song = Song::query()->updateOrCreate(['path' => $path], [
|
|
|
|
'album_id' => $album->id,
|
|
|
|
'artist_id' => $artist->id,
|
|
|
|
'title' => $title,
|
|
|
|
'length' => $duration,
|
|
|
|
'track' => $track,
|
|
|
|
'lyrics' => $lyrics,
|
|
|
|
'mtime' => time(),
|
|
|
|
'owner_id' => $user->id,
|
|
|
|
'is_public' => true,
|
|
|
|
'storage' => SongStorageTypes::S3_LAMBDA,
|
|
|
|
]);
|
|
|
|
|
|
|
|
return $song;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function deleteSongEntry(string $bucket, string $key): void
|
|
|
|
{
|
|
|
|
$path = Song::getPathFromS3BucketAndKey($bucket, $key);
|
|
|
|
$song = $this->songRepository->findOneByPath($path);
|
|
|
|
|
|
|
|
throw_unless((bool) $song, SongPathNotFoundException::create($path));
|
|
|
|
|
|
|
|
$song->delete();
|
|
|
|
}
|
|
|
|
|
2024-04-04 22:20:42 +00:00
|
|
|
protected function supported(): bool
|
2024-02-05 13:27:17 +00:00
|
|
|
{
|
2024-02-05 21:17:41 +00:00
|
|
|
return SongStorageTypes::supported(SongStorageTypes::S3_LAMBDA);
|
2024-02-05 13:27:17 +00:00
|
|
|
}
|
2024-02-23 16:03:54 +00:00
|
|
|
|
|
|
|
public function delete(Song $song, bool $backup = false): void
|
|
|
|
{
|
|
|
|
throw new MethodNotImplementedException('Lambda storage does not support deleting from filesystem.');
|
|
|
|
}
|
2024-02-05 13:27:17 +00:00
|
|
|
}
|