30a6b080eb
Replace the server-rendered release upload form with a Livewire component, introducing an interactive admin release form that supports dynamic episode management, real‑time CDN path validation, and direct download file checks. Key changes: - New `AdminReleaseForm` Livewire component with dynamic episode fields, Tagify integration, and upload handling via Livewire's file uploads. - Added `CdnPathValidator` service to verify download and stream paths across all configured mirrors, caching results and capturing file sizes. - Extended `EpisodeService` and `GalleryService` to support array‑based data and temporary uploaded files from Livewire. - Persist validated download sizes and store the validation timestamp on the `downloads` table via a new migration; also add a unique constraint on `hentais.slug` to prevent duplicates. - Remove the old POST `/admin/release/upload` route and controller logic, along with the legacy `upload.js` script. - Add comprehensive feature and unit tests covering the new component and the CDN validation service.
61 lines
1.8 KiB
PHP
61 lines
1.8 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Jobs\GetFileSizeFromCDN;
|
|
use App\Models\Downloads;
|
|
use App\Models\Episode;
|
|
use Illuminate\Http\Request;
|
|
|
|
class DownloadService
|
|
{
|
|
public function createOrUpdateDownloads(Request $request, Episode $episode, int $index): void
|
|
{
|
|
$downloadTypes = [
|
|
'episodedlurl' => 'FHD',
|
|
'episodedlurlinterpolated' => 'FHDi',
|
|
'episodedlurl4k' => 'UHD',
|
|
'downloadUHDi' => 'UHDi',
|
|
];
|
|
|
|
foreach ($downloadTypes as $inputField => $type) {
|
|
$fieldName = $inputField.$index;
|
|
if ($request->filled($fieldName)) {
|
|
$download = Downloads::updateOrCreate([
|
|
'episode_id' => $episode->id,
|
|
'type' => $type,
|
|
], [
|
|
'url' => $request->input($fieldName),
|
|
]);
|
|
|
|
// Dispatch Job to get File Size from CDN
|
|
GetFileSizeFromCDN::dispatch($download->id);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Persist validated download URLs for an episode. Sizes are written
|
|
* directly from the CDN validation response, so no size job is dispatched.
|
|
*
|
|
* @param array<string, array{url: string, size?: float|int|null}> $downloads
|
|
*/
|
|
public function createOrUpdateDownloadsFromArray(Episode $episode, array $downloads): void
|
|
{
|
|
foreach ($downloads as $type => $data) {
|
|
if (empty($data['url'])) {
|
|
continue;
|
|
}
|
|
|
|
Downloads::updateOrCreate([
|
|
'episode_id' => $episode->id,
|
|
'type' => $type,
|
|
], [
|
|
'url' => $data['url'],
|
|
'size' => $data['size'] ?? null,
|
|
'validated_at' => now(),
|
|
]);
|
|
}
|
|
}
|
|
}
|