This commit is contained in:
2025-09-18 15:31:27 +02:00
commit 2abba0c2b7
406 changed files with 31879 additions and 0 deletions

View File

@@ -0,0 +1,38 @@
<?php
namespace App\Services;
use App\Models\Downloads;
use App\Models\Episode;
use App\Jobs\GetFileSizeFromCDN;
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);
}
}
}
}

View File

@@ -0,0 +1,116 @@
<?php
namespace App\Services;
use App\Models\Episode;
use App\Models\Hentai;
use App\Models\Studios;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\Laravel\Facades\Image;
use Intervention\Image\Encoders\WebpEncoder;
class EpisodeService
{
public function generateSlug(string $title): string
{
$slug = Str::slug($title);
$slugParts = explode('-', $slug);
$lastPart = $slugParts[array_key_last($slugParts)];
if (is_numeric($lastPart) && $lastPart < 1000) {
$slugParts[array_key_last($slugParts)] = 's'.$lastPart;
return implode('-', $slugParts);
}
return $slug;
}
public function createEpisode(
Request $request,
Hentai $hentai,
int $episodeNumber,
Studios $studio = null,
Episode $referenceEpisode = null
): Episode
{
$episode = new Episode();
$episode->title = $referenceEpisode->title ?? $request->input('title');
$episode->title_search = preg_replace("/[^A-Za-z0-9 ]/", '', $episode->title);
$episode->title_jpn = $referenceEpisode->title_jpn ?? $request->input('title_jpn');
$episode->slug = "{$hentai->slug}-{$episodeNumber}";
$episode->hentai_id = $hentai->id;
$episode->studios_id = $referenceEpisode->studio->id ?? $studio->id;
$episode->episode = $episodeNumber;
$episode->description = $referenceEpisode ? $request->input('description') : $request->input("description{$episodeNumber}");
$episode->url = $referenceEpisode ? $request->input('baseurl') : rtrim($request->input('baseurl'), '/').'/E'.str_pad($episodeNumber, 2, '0', STR_PAD_LEFT);
$episode->view_count = 0;
$episode->interpolated = true;
$episode->is_dvd_aspect = false;
$episode->release_date = $referenceEpisode->release_date ?? Carbon::parse($request->input('releasedate'))->format('Y-m-d');
$episode->cover_url = "/images/hentai/{$hentai->slug}/cover-ep-{$episodeNumber}.webp";
$episode->save();
// Tagging
$tags = $referenceEpisode ? $referenceEpisode->tags : json_decode($request->input('tags'));
foreach ($tags as $t) {
$episode->tag($referenceEpisode ? $t->name : $t->value);
}
return $episode;
}
public function updateEpisode(Request $request, Studios $studio, int $episodeId): Episode
{
$episode = Episode::where('id', $episodeId)->firstOrFail();
$episode->studios_id = $studio->id;
$episode->description = $request->input('description');
$episode->url = $request->input('baseurl');
$episode->release_date = Carbon::parse($request->input('releasedate'))->format('Y-m-d');
$episode->interpolated = $request->input('interpolated') == 'yes';
$episode->interpolated_uhd = $request->input('downloadUHDi1') ? true : false;
$episode->is_dvd_aspect = $request->input('dvd') == 'yes';
$episode->save();
// Tagging
$tags = json_decode($request->input('tags'));
$newtags = [];
foreach ($tags as $t) {
$newtags[] = $t->value;
}
$episode->retag($newtags);
return $episode;
}
public function getOrCreateStudio(string $studioName): Studios
{
return Studios::firstOrCreate(
['name' => $studioName],
['slug' => Str::slug($studioName)]
);
}
public function createOrUpdateCover(Request $request, Episode $episode, string $slug, int $episodeNumber): void
{
if (! $request->hasFile("episodecover{$episodeNumber}")) {
return;
}
// Create Folder for Image Upload
if (! Storage::disk('public')->exists("/images/hentai/{$slug}")) {
Storage::disk('public')->makeDirectory("/images/hentai/{$slug}");
}
// Encode and save cover image
Image::read($request->file("episodecover{$episodeNumber}")->getRealPath())
->cover(268, 394)
->encode(new WebpEncoder())
->save(Storage::disk('public')->path($episode->cover_url));
}
}

View File

@@ -0,0 +1,80 @@
<?php
namespace App\Services;
use App\Models\Episode;
use App\Models\Gallery;
use App\Models\Hentai;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\Laravel\Facades\Image;
use Intervention\Image\Encoders\WebpEncoder;
class GalleryService
{
public function createOrUpdateGallery(Request $request, Hentai $hentai, Episode $episode, int $episodeNumber, bool $override = false): void
{
$galleryInputNumber = $override ? 1 : $episodeNumber;
if($request->hasFile('episodegallery'.$galleryInputNumber)) {
$this->deleteOldGallery($episode);
$this->createGalleryFolder($hentai);
$counter = 0;
foreach($request->file('episodegallery'.$galleryInputNumber) as $file) {
$gallery = $this->createGallery($hentai, $episode, $episodeNumber, $counter);
$this->saveGalleryImage($gallery, $file);
$counter += 1;
}
}
}
private function createGalleryFolder(Hentai $hentai): void
{
// Create Folder for Image Upload
if (! Storage::disk('public')->exists("/images/hentai/{$hentai->slug}")) {
Storage::disk('public')->makeDirectory("/images/hentai/{$hentai->slug}");
}
}
private function createGallery(Hentai $hentai, Episode $episode, int $episodeNumber, int $counter): Gallery
{
$gallery = new Gallery();
$gallery->hentai_id = $hentai->id;
$gallery->episode_id = $episode->id;
$gallery->image_url = "/images/hentai/{$hentai->slug}/gallery-ep-{$episodeNumber}-{$counter}.webp";
$gallery->thumbnail_url = "/images/hentai/{$hentai->slug}/gallery-ep-{$episodeNumber}-{$counter}-thumbnail.webp";
$gallery->save();
return $gallery;
}
private function saveGalleryImage(Gallery $gallery, $sourceImage): void
{
Image::read($sourceImage->getRealPath())
->cover(1920, 1080)
->encode(new WebpEncoder())
->save(Storage::disk('public')->path($gallery->image_url));
Image::read($sourceImage->getRealPath())
->cover(960, 540)
->encode(new WebpEncoder())
->save(Storage::disk('public')->path($gallery->thumbnail_url));
}
private function deleteOldGallery(Episode $episode): void
{
$oldGallery = Gallery::where('episode_id', $episode->id)->get();
foreach ($oldGallery as $oldImage) {
Storage::disk('public')->delete($oldImage->image_url);
Storage::disk('public')->delete($oldImage->thumbnail_url);
$oldImage->forceDelete();
}
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace App\Services;
use App\Models\Playlist;
use App\Models\PlaylistEpisode;
class PlaylistService
{
public function reorderPositions(Playlist $playlist): void
{
$episodes = PlaylistEpisode::where('playlist_id', $playlist->id)
->orderBy('position')
->get();
foreach ($episodes as $index => $episode) {
$episode->position = $index + 1;
$episode->save();
}
}
public function swapPositions(PlaylistEpisode $a, PlaylistEpisode $b): void
{
$temp = $a->position;
$a->position = $b->position;
$b->position = $temp;
$a->save();
$b->save();
}
}