2024-02-05 11:50:06 +00:00
|
|
|
<?php
|
|
|
|
|
2024-02-23 18:36:02 +00:00
|
|
|
namespace App\Services\SongStorages;
|
2024-02-05 11:50:06 +00:00
|
|
|
|
2024-02-23 18:36:02 +00:00
|
|
|
use App\Filesystems\DropboxFilesystem;
|
2024-02-05 11:50:06 +00:00
|
|
|
use App\Models\Song;
|
|
|
|
use App\Models\User;
|
|
|
|
use App\Services\FileScanner;
|
2024-02-05 21:17:41 +00:00
|
|
|
use App\Values\SongStorageTypes;
|
2024-02-05 11:50:06 +00:00
|
|
|
use Illuminate\Http\UploadedFile;
|
2024-02-05 21:17:41 +00:00
|
|
|
use Illuminate\Support\Facades\Cache;
|
2024-02-05 11:50:06 +00:00
|
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
use Illuminate\Support\Facades\File;
|
2024-02-05 21:17:41 +00:00
|
|
|
use Illuminate\Support\Facades\Http;
|
2024-02-05 11:50:06 +00:00
|
|
|
|
2024-02-05 13:27:17 +00:00
|
|
|
final class DropboxStorage extends CloudStorage
|
2024-02-05 11:50:06 +00:00
|
|
|
{
|
2024-02-23 18:36:02 +00:00
|
|
|
public function __construct(
|
|
|
|
protected FileScanner $scanner,
|
2024-04-18 11:27:07 +00:00
|
|
|
private readonly DropboxFilesystem $filesystem,
|
|
|
|
private readonly array $config
|
2024-02-23 18:36:02 +00:00
|
|
|
) {
|
2024-02-05 11:50:06 +00:00
|
|
|
parent::__construct($scanner);
|
|
|
|
|
2024-02-23 18:36:02 +00:00
|
|
|
$this->filesystem->getAdapter()->getClient()->setAccessToken($this->maybeRefreshAccessToken());
|
2024-02-05 11:50:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public function storeUploadedFile(UploadedFile $file, User $uploader): Song
|
|
|
|
{
|
2024-04-04 22:20:42 +00:00
|
|
|
self::assertSupported();
|
|
|
|
|
2024-02-05 11:50:06 +00:00
|
|
|
return DB::transaction(function () use ($file, $uploader): Song {
|
|
|
|
$result = $this->scanUploadedFile($file, $uploader);
|
|
|
|
$song = $this->scanner->getSong();
|
|
|
|
$key = $this->generateStorageKey($file->getClientOriginalName(), $uploader);
|
|
|
|
|
|
|
|
$this->filesystem->write($key, File::get($result->path));
|
2024-02-23 18:36:02 +00:00
|
|
|
|
2024-02-05 21:17:41 +00:00
|
|
|
$song->update([
|
|
|
|
'path' => "dropbox://$key",
|
|
|
|
'storage' => SongStorageTypes::DROPBOX,
|
|
|
|
]);
|
2024-02-05 11:50:06 +00:00
|
|
|
|
|
|
|
File::delete($result->path);
|
|
|
|
|
|
|
|
return $song;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2024-02-05 21:17:41 +00:00
|
|
|
private function maybeRefreshAccessToken(): string
|
|
|
|
{
|
|
|
|
$accessToken = Cache::get('dropbox_access_token');
|
|
|
|
|
|
|
|
if ($accessToken) {
|
|
|
|
return $accessToken;
|
|
|
|
}
|
|
|
|
|
|
|
|
$response = Http::asForm()
|
|
|
|
->withBasicAuth($this->config['app_key'], $this->config['app_secret'])
|
|
|
|
->post('https://api.dropboxapi.com/oauth2/token', [
|
|
|
|
'refresh_token' => $this->config['refresh_token'],
|
|
|
|
'grant_type' => 'refresh_token',
|
2024-02-23 18:36:02 +00:00
|
|
|
]);
|
2024-02-05 21:17:41 +00:00
|
|
|
|
|
|
|
Cache::put(
|
|
|
|
'dropbox_access_token',
|
2024-02-23 18:36:02 +00:00
|
|
|
$response->json('access_token'),
|
|
|
|
now()->addSeconds($response->json('expires_in') - 60) // 60 seconds buffer
|
2024-02-05 21:17:41 +00:00
|
|
|
);
|
|
|
|
|
2024-02-23 18:36:02 +00:00
|
|
|
return $response->json('access_token');
|
2024-02-05 21:17:41 +00:00
|
|
|
}
|
|
|
|
|
2024-02-05 11:50:06 +00:00
|
|
|
public function getSongPresignedUrl(Song $song): string
|
|
|
|
{
|
2024-04-04 22:20:42 +00:00
|
|
|
self::assertSupported();
|
|
|
|
|
2024-02-23 18:36:02 +00:00
|
|
|
return $this->filesystem->temporaryUrl($song->storage_metadata->getPath());
|
2024-02-05 11:50:06 +00:00
|
|
|
}
|
2024-02-05 21:17:41 +00:00
|
|
|
|
2024-04-18 11:27:07 +00:00
|
|
|
public function supported(): bool
|
2024-02-05 21:17:41 +00:00
|
|
|
{
|
|
|
|
return SongStorageTypes::supported(SongStorageTypes::DROPBOX);
|
|
|
|
}
|
|
|
|
|
2024-02-23 16:03:54 +00:00
|
|
|
public function delete(Song $song, bool $backup = false): void
|
|
|
|
{
|
2024-04-04 22:20:42 +00:00
|
|
|
self::assertSupported();
|
|
|
|
|
2024-02-23 16:03:54 +00:00
|
|
|
$path = $song->storage_metadata->getPath();
|
|
|
|
|
|
|
|
if ($backup) {
|
|
|
|
$this->filesystem->move($path, "backup/$path");
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->filesystem->delete($path);
|
|
|
|
}
|
|
|
|
|
2024-02-05 21:17:41 +00:00
|
|
|
public function testSetup(): void
|
|
|
|
{
|
|
|
|
$this->filesystem->write('test.txt', 'Koel test file.');
|
|
|
|
$this->filesystem->delete('test.txt');
|
|
|
|
}
|
2024-02-05 11:50:06 +00:00
|
|
|
}
|