From ce10c0b7be16dfd8194dfcc3b303221a9b1e609b Mon Sep 17 00:00:00 2001 From: DariusIII Date: Fri, 13 Feb 2026 15:27:28 +0100 Subject: [PATCH] Remove XXX covers processing and related code --- .../Commands/NntmuxResetPostProcessing.php | 25 - app/Console/Commands/ProcessAdultMovies.php | 114 --- app/Console/Commands/RecategorizeReleases.php | 1 - app/Console/Commands/TmuxMonitor.php | 1 - app/Console/Commands/UpdatePostProcess.php | 10 +- .../helper/age_verification_helpers.php | 186 ---- app/Extensions/helper/helpers.php | 52 +- .../Controllers/Admin/AdminUserController.php | 3 +- app/Http/Controllers/AdultController.php | 50 +- app/Http/Controllers/CoverController.php | 2 +- app/Http/Controllers/DetailsController.php | 25 - app/Http/Controllers/ProfileController.php | 2 +- app/Models/XxxInfo.php | 231 ----- .../AdultProcessingServiceProvider.php | 52 - .../AdultProcessingPassable.php | 99 -- .../AdultProcessingPipeline.php | 792 --------------- .../AdultProcessing/AdultProcessingResult.php | 146 --- .../AdultProcessing/AdultReleaseContext.php | 46 - .../AgeVerificationManager.php | 397 -------- .../Pipes/AbstractAdultProviderPipe.php | 913 ------------------ .../AdultProcessing/Pipes/AdePipe.php | 398 -------- .../AdultProcessing/Pipes/AdmPipe.php | 299 ------ .../AdultProcessing/Pipes/AebnPipe.php | 576 ----------- .../AdultProcessing/Pipes/Data18Pipe.php | 525 ---------- .../AdultProcessing/Pipes/HotmoviesPipe.php | 364 ------- .../AdultProcessing/Pipes/IafdPipe.php | 518 ---------- .../AdultProcessing/Pipes/PoppornPipe.php | 534 ---------- app/Services/PostProcessService.php | 16 - app/Services/ReleaseRemoverService.php | 2 +- app/Services/Tmux/Tmux.php | 6 +- app/Services/Tmux/TmuxLayoutBuilder.php | 3 - app/Services/Tmux/TmuxOutput.php | 9 +- app/Services/Tmux/TmuxTaskRunner.php | 29 - app/Services/XXXProcessor.php | 38 - app/Services/XxxBrowseService.php | 215 ----- bootstrap/providers.php | 1 - ...0_drop_xxxinfo_and_releases_xxxinfo_id.php | 51 + database/schema/mariadb-schema.sql | 26 - database/schema/mysql-schema.sql | 26 - manage_adult_cookies.php | 169 ---- phpstan-baseline.neon | 30 - resources/views/admin/site/edit.blade.php | 23 - resources/views/admin/users/edit.blade.php | 9 - resources/views/details/index.blade.php | 35 - resources/views/profile/edit.blade.php | 5 - resources/views/profile/index.blade.php | 4 - resources/views/xxx/index.blade.php | 343 ++----- routes/web.php | 2 +- storage/covers/xxx/.gitignore | 4 - storage/covers/xxx/no-backdrop.jpg | Bin 306639 -> 0 bytes storage/covers/xxx/no-cover.jpg | Bin 3563 -> 0 bytes tests/Feature/AdultProcessingPipelineTest.php | 317 ------ 52 files changed, 175 insertions(+), 7549 deletions(-) delete mode 100644 app/Console/Commands/ProcessAdultMovies.php delete mode 100644 app/Extensions/helper/age_verification_helpers.php delete mode 100644 app/Models/XxxInfo.php delete mode 100644 app/Providers/AdultProcessingServiceProvider.php delete mode 100644 app/Services/AdultProcessing/AdultProcessingPassable.php delete mode 100644 app/Services/AdultProcessing/AdultProcessingPipeline.php delete mode 100644 app/Services/AdultProcessing/AdultProcessingResult.php delete mode 100644 app/Services/AdultProcessing/AdultReleaseContext.php delete mode 100644 app/Services/AdultProcessing/AgeVerificationManager.php delete mode 100644 app/Services/AdultProcessing/Pipes/AbstractAdultProviderPipe.php delete mode 100644 app/Services/AdultProcessing/Pipes/AdePipe.php delete mode 100644 app/Services/AdultProcessing/Pipes/AdmPipe.php delete mode 100644 app/Services/AdultProcessing/Pipes/AebnPipe.php delete mode 100644 app/Services/AdultProcessing/Pipes/Data18Pipe.php delete mode 100644 app/Services/AdultProcessing/Pipes/HotmoviesPipe.php delete mode 100644 app/Services/AdultProcessing/Pipes/IafdPipe.php delete mode 100644 app/Services/AdultProcessing/Pipes/PoppornPipe.php delete mode 100644 app/Services/XXXProcessor.php delete mode 100644 app/Services/XxxBrowseService.php create mode 100644 database/migrations/2026_02_13_000000_drop_xxxinfo_and_releases_xxxinfo_id.php delete mode 100644 manage_adult_cookies.php delete mode 100644 storage/covers/xxx/.gitignore delete mode 100644 storage/covers/xxx/no-backdrop.jpg delete mode 100644 storage/covers/xxx/no-cover.jpg delete mode 100644 tests/Feature/AdultProcessingPipelineTest.php diff --git a/app/Console/Commands/NntmuxResetPostProcessing.php b/app/Console/Commands/NntmuxResetPostProcessing.php index 12bb62552..fdc0616e5 100644 --- a/app/Console/Commands/NntmuxResetPostProcessing.php +++ b/app/Console/Commands/NntmuxResetPostProcessing.php @@ -79,7 +79,6 @@ class NntmuxResetPostProcessing extends Command 'bookinfo_id' => null, 'videos_id' => 0, 'tv_episodes_id' => 0, - 'xxxinfo_id' => 0, 'passwordstatus' => -1, 'haspreview' => -1, 'jpgstatus' => 0, @@ -137,7 +136,6 @@ class NntmuxResetPostProcessing extends Command $this->resetMusic(); break; case 'adult': - $this->resetAdult(); break; case 'tv': $this->resetTv(); @@ -323,29 +321,6 @@ class NntmuxResetPostProcessing extends Command } } - private function resetAdult(): void - { - $qry = Release::query()->whereNotNull('xxxinfo_id')->whereBetween('categories_id', [Category::XXX_ROOT, Category::XXX_OTHER])->get(); - $total = $qry->count(); - if ($total > 0) { - $bar = $this->output->createProgressBar($total); - $bar->setOverwrite(true); // Terminal needs to support ANSI Encoding for this? - $bar->start(); - foreach ($qry as $releases) { - Release::query()->where('id', $releases->id)->update( - [ - 'xxxinfo_id' => null, - ]); - $bar->advance(); - } - $bar->finish(); - $this->newLine(); - $this->info(number_format($total).' xxxinfo_id\'s reset.'); - } else { - $this->info('No releases to reset'); - } - } - private function resetTv(): void { $qry = Release::query()->where('videos_id', '!=', 0)->where('tv_episodes_id', '!=', 0)->whereBetween('categories_id', [Category::TV_ROOT, Category::TV_OTHER])->get(); diff --git a/app/Console/Commands/ProcessAdultMovies.php b/app/Console/Commands/ProcessAdultMovies.php deleted file mode 100644 index 169da9c76..000000000 --- a/app/Console/Commands/ProcessAdultMovies.php +++ /dev/null @@ -1,114 +0,0 @@ -error('Adult movie lookup is disabled in settings. Enable "lookupxxx" to use this command.'); - - return Command::FAILURE; - } - - $debug = $this->option('debug'); - $title = $this->option('title'); - $limit = $this->option('limit'); - - $pipeline = new AdultProcessingPipeline([], true); - - if ($title) { - // Process a single title - $this->info("Looking up: {$title}"); - - $result = $pipeline->processMovie($title, $debug); - - if ($result['status'] === 'matched') { - $this->info("Match found on {$result['provider']}!"); - $title_display = $result['movieData']['title'] ?? 'N/A'; - $synopsis_display = substr($result['movieData']['synopsis'] ?? 'N/A', 0, 200); - $this->line("Title: {$title_display}"); - $this->line("Synopsis: {$synopsis_display}..."); - - if (! empty($result['movieData']['boxcover'])) { - $cover_url = $result['movieData']['boxcover']; - $this->line("Cover: {$cover_url}"); - } - - if ($debug && ! empty($result['debug'])) { - $this->newLine(); - $this->line('Debug Info:'); - $this->line(json_encode($result['debug'], JSON_PRETTY_PRINT)); - } - } else { - $this->warn("No match found for: {$title}"); - - if ($debug && ! empty($result['debug'])) { - $this->newLine(); - $this->line('Debug Info:'); - $this->line(json_encode($result['debug'], JSON_PRETTY_PRINT)); - } - } - } else { - // Process all pending releases - $this->info('Processing adult movie releases using pipeline...'); - - if ($limit) { - $this->info("Limited to {$limit} releases"); - } - - $pipeline->processXXXReleases(); - - $stats = $pipeline->getStats(); - - $this->newLine(); - $this->table( - ['Metric', 'Value'], - [ - ['Processed', $stats['processed']], - ['Matched', $stats['matched']], - ['Failed', $stats['failed']], - ['Skipped', $stats['skipped']], - ['Duration', sprintf('%.2f seconds', $stats['duration'])], - ] - ); - - if (! empty($stats['providers'])) { - $this->newLine(); - $this->info('Provider Statistics:'); - $providerData = []; - foreach ($stats['providers'] as $provider => $count) { - $providerData[] = [$provider, $count]; - } - $this->table(['Provider', 'Matches'], $providerData); - } - } - - return Command::SUCCESS; - } -} diff --git a/app/Console/Commands/RecategorizeReleases.php b/app/Console/Commands/RecategorizeReleases.php index d68b7e646..e9b57b94b 100644 --- a/app/Console/Commands/RecategorizeReleases.php +++ b/app/Console/Commands/RecategorizeReleases.php @@ -87,7 +87,6 @@ class RecategorizeReleases extends Command 'gamesinfo_id' => 0, 'bookinfo_id' => 0, 'anidbid' => null, - 'xxxinfo_id' => 0, 'categories_id' => $catId['categories_id'], ]); diff --git a/app/Console/Commands/TmuxMonitor.php b/app/Console/Commands/TmuxMonitor.php index 625f3178c..7b277cb86 100644 --- a/app/Console/Commands/TmuxMonitor.php +++ b/app/Console/Commands/TmuxMonitor.php @@ -245,6 +245,5 @@ class TmuxMonitor extends Command $this->taskRunner->runPaneTask('tv', [], $runVar); $this->taskRunner->runPaneTask('movies', [], $runVar); $this->taskRunner->runPaneTask('amazon', [], $runVar); - $this->taskRunner->runPaneTask('xxx', [], $runVar); } } diff --git a/app/Console/Commands/UpdatePostProcess.php b/app/Console/Commands/UpdatePostProcess.php index 764dd22ed..7f96ea361 100644 --- a/app/Console/Commands/UpdatePostProcess.php +++ b/app/Console/Commands/UpdatePostProcess.php @@ -16,7 +16,7 @@ class UpdatePostProcess extends Command * @var string */ protected $signature = 'update:postprocess - {type : Type (all, nfo, movies, tv, music, console, games, book, anime, xxx, additional, amazon)} + {type : Type (all, nfo, movies, tv, music, console, games, book, anime, additional, amazon)} {echo? : Echo output (true/false, default: true)}'; /** @@ -43,7 +43,6 @@ class UpdatePostProcess extends Command 'music' => false, 'nfo' => true, 'tv' => false, - 'xxx' => false, ]; public function __construct( @@ -80,7 +79,6 @@ class UpdatePostProcess extends Command 'book' => $this->postProcessService->processBooks(), 'anime' => $this->postProcessService->processAnime(), 'tv' => $this->postProcessService->processTv(), - 'xxx' => $this->postProcessService->processXXX(), 'additional' => $this->postProcessService->processAdditional(), }; @@ -108,13 +106,12 @@ class UpdatePostProcess extends Command $this->line(' book - Processes books'); $this->line(' anime - Processes anime'); $this->line(' tv - Processes tv'); - $this->line(' xxx - Processes xxx'); $this->line(' additional - Processes previews/mediainfo/etc...'); - $this->line(' amazon - Processes books, music, console, games, and xxx'); + $this->line(' amazon - Processes books, music, console, and games'); } /** - * Process amazon types (books, music, console, games, xxx). + * Process amazon types (books, music, console, games). */ private function processAmazon(): void { @@ -122,7 +119,6 @@ class UpdatePostProcess extends Command $this->postProcessService->processMusic(); $this->postProcessService->processConsoles(); $this->postProcessService->processGames(); - $this->postProcessService->processXXX(); } /** diff --git a/app/Extensions/helper/age_verification_helpers.php b/app/Extensions/helper/age_verification_helpers.php deleted file mode 100644 index 5a4c3c802..000000000 --- a/app/Extensions/helper/age_verification_helpers.php +++ /dev/null @@ -1,186 +0,0 @@ -|false - */ - function getRawHtmlWithAgeVerification($url, $cookie = false, $postData = null) - { - static $ageVerificationManager = null; - - // Initialize manager on first use - if ($ageVerificationManager === null) { - $ageVerificationManager = new AgeVerificationManager; - } - - // Check if this is an adult site that needs age verification - $adultSites = [ - 'adultdvdempire.com', - 'adultdvdmarketplace.com', - 'aebn.net', - 'hotmovies.com', - 'popporn.com', - ]; - - $isAdultSite = false; - foreach ($adultSites as $site) { - if (stripos($url, $site) !== false) { - $isAdultSite = true; - break; - } - } - - // For adult sites, use the age verification manager - if ($isAdultSite) { - try { - $options = []; - - // Handle POST data if provided - if ($postData !== null) { - $options['form_params'] = $postData; - $cookieJar = $ageVerificationManager->getCookieJar($url); - - $client = new Client([ - 'cookies' => $cookieJar, - 'headers' => [ - 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', - 'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', - ], - ]); - - $response = $client->post($url, $options); - $html = $response->getBody()->getContents(); - } else { - $html = $ageVerificationManager->makeRequest($url, $options); - } - - // Try to decode as JSON (some APIs return JSON) - if ($html !== false) { - $jsonResponse = json_decode($html, true); - if (json_last_error() === JSON_ERROR_NONE) { - return $jsonResponse; - } - } - - return $html; - - } catch (RequestException $e) { - if (config('app.debug') === true) { - Log::error('getRawHtmlWithAgeVerification: '.$e->getMessage()); - } - - return false; - } catch (\Exception $e) { - if (config('app.debug') === true) { - Log::error('getRawHtmlWithAgeVerification: '.$e->getMessage()); - } - - return false; - } - } - - // For non-adult sites, use standard approach - return getRawHtml($url, $cookie, $postData); - } -} - -if (! function_exists('initializeAdultSiteCookies')) { - /** - * Initialize age verification cookies for all adult sites - * Run this once during application setup - * - * @return array Statistics about initialized cookies - */ - function initializeAdultSiteCookies(): array - { - $manager = new AgeVerificationManager; - - $sites = [ - 'https://www.adultdvdempire.com', - 'https://www.adultdvdmarketplace.com', - 'https://straight.theater.aebn.net', - 'https://www.hotmovies.com', - 'https://www.popporn.com', - ]; - - $results = [ - 'initialized' => 0, - 'failed' => 0, - 'sites' => [], - ]; - - foreach ($sites as $url) { - try { - // Making a request will automatically set up cookies - $cookieJar = $manager->getCookieJar($url); - $domain = parse_url($url, PHP_URL_HOST); - - $results['sites'][$domain] = [ - 'status' => 'initialized', - 'cookies' => count($cookieJar), - ]; - $results['initialized']++; - - } catch (\Exception $e) { - $domain = parse_url($url, PHP_URL_HOST); - $results['sites'][$domain] = [ - 'status' => 'failed', - 'error' => $e->getMessage(), - ]; - $results['failed']++; - } - } - - return $results; - } -} - -if (! function_exists('getAdultSiteCookieStats')) { - /** - * Get statistics about stored adult site cookies - * - * @return array Cookie statistics - */ - function getAdultSiteCookieStats(): array - { - $manager = new AgeVerificationManager; - - return $manager->getCookieStats(); - } -} - -if (! function_exists('clearAdultSiteCookies')) { - /** - * Clear all stored adult site cookies - * - * @param string|null $domain Optional specific domain to clear - * @return int|bool Number of cookies cleared (or bool for specific domain) - */ - function clearAdultSiteCookies(?string $domain = null) - { - $manager = new AgeVerificationManager; - - if ($domain !== null) { - return $manager->clearCookies($domain); - } - - return $manager->clearAllCookies(); - } -} diff --git a/app/Extensions/helper/helpers.php b/app/Extensions/helper/helpers.php index 754d96df1..0060ba6ed 100644 --- a/app/Extensions/helper/helpers.php +++ b/app/Extensions/helper/helpers.php @@ -2,7 +2,6 @@ use App\Models\Country as CountryModel; use App\Models\Release; -use App\Models\XxxInfo; use App\Services\Nzb\NzbService; use GuzzleHttp\Client; use GuzzleHttp\Cookie\CookieJar; @@ -39,45 +38,7 @@ if (! function_exists('getRawHtml')) { } } - // For adult sites, use age verification manager if available - if ($isAdultSite && class_exists('\App\Services\AdultProcessing\AgeVerificationManager')) { - try { - static $ageVerificationManager = null; - if ($ageVerificationManager === null) { - $ageVerificationManager = new \App\Services\AdultProcessing\AgeVerificationManager; - } - - if ($postData !== null) { - // Handle POST requests - $cookieJar = $ageVerificationManager->getCookieJar($url); - $client = new Client([ - 'cookies' => $cookieJar, - 'headers' => ['User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'], - ]); - - $response = $client->post($url, ['form_params' => $postData]); - $response = $response->getBody()->getContents(); - } else { - $response = $ageVerificationManager->makeRequest($url); - } - - if ($response !== false) { - $jsonResponse = json_decode($response, true); - if (json_last_error() === JSON_ERROR_NONE) { - return $jsonResponse; - } - - return $response; - } - } catch (\Exception $e) { - // Fall through to standard method - if (function_exists('config') && config('app.debug') === true) { - Log::error('Age verification failed, falling back to standard method: '.$e->getMessage()); - } - } - } - - // Standard method for non-adult sites or if age verification fails + // Standard method $cookieJar = new CookieJar; $client = new Client(['headers' => ['User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246']]); if ($cookie !== false && $cookie !== null && $cookie !== '') { @@ -121,10 +82,6 @@ if (! function_exists('makeFieldLinks')) { if (trim($ta) === '') { continue; } - if ($type === 'xxx' && $field === 'genre') { - $ta = XxxInfo::getGenres(true, (int) $ta); - $ta = $ta['title'] ?? ''; - } if ($i > 7) { break; } @@ -492,7 +449,6 @@ if (! function_exists('getReleaseCover')) { $consoleinfo_id = $getValue($release, 'consoleinfo_id'); $bookinfo_id = $getValue($release, 'bookinfo_id'); $gamesinfo_id = $getValue($release, 'gamesinfo_id'); - $xxxinfo_id = $getValue($release, 'xxxinfo_id'); $anidbid = $getValue($release, 'anidbid'); if (! empty($imdbid) && $imdbid > 0) { @@ -510,9 +466,6 @@ if (! function_exists('getReleaseCover')) { } elseif (! empty($gamesinfo_id)) { $coverType = 'games'; $coverId = $gamesinfo_id; - } elseif (! empty($xxxinfo_id)) { - $coverType = 'xxx'; - $coverId = $xxxinfo_id; } elseif (! empty($anidbid) && $anidbid > 0) { $coverType = 'anime'; $coverId = $anidbid; @@ -970,9 +923,6 @@ if (! function_exists('getRange')) { function getRange(mixed $tableName): \Illuminate\Contracts\Pagination\LengthAwarePaginator // @phpstan-ignore missingType.generics { $range = \Illuminate\Support\Facades\DB::table($tableName); - if ($tableName === 'xxxinfo') { - $range->selectRaw('UNCOMPRESS(plot) AS plot'); - } return $range->orderByDesc('created_at')->paginate(config('nntmux.items_per_page')); } diff --git a/app/Http/Controllers/Admin/AdminUserController.php b/app/Http/Controllers/Admin/AdminUserController.php index 6dfbb5b7c..d7a74b75d 100644 --- a/app/Http/Controllers/Admin/AdminUserController.php +++ b/app/Http/Controllers/Admin/AdminUserController.php @@ -132,7 +132,6 @@ class AdminUserController extends BasePageController 'notes' => '', 'invites' => $defaultInvites, 'movieview' => 0, - 'xxxview' => 0, 'musicview' => 0, 'consoleview' => 0, 'gameview' => 0, @@ -236,7 +235,7 @@ class AdminUserController extends BasePageController ($request->has('movieview') ? 1 : 0), ($request->has('musicview') ? 1 : 0), ($request->has('gameview') ? 1 : 0), - ($request->has('xxxview') ? 1 : 0), + ($editedUser->xxxview ? 1 : 0), ($request->has('consoleview') ? 1 : 0), ($request->has('bookview') ? 1 : 0) ); diff --git a/app/Http/Controllers/AdultController.php b/app/Http/Controllers/AdultController.php index 51dd03e4f..6f5910e40 100644 --- a/app/Http/Controllers/AdultController.php +++ b/app/Http/Controllers/AdultController.php @@ -3,19 +3,18 @@ namespace App\Http\Controllers; use App\Models\Category; -use App\Models\XxxInfo; -use App\Services\XxxBrowseService; +use App\Services\Releases\ReleaseBrowseService; use Illuminate\Http\Request; use Illuminate\Support\Arr; class AdultController extends BasePageController { - private XxxBrowseService $xxxBrowseService; + private ReleaseBrowseService $releaseBrowseService; - public function __construct(XxxBrowseService $xxxBrowseService) + public function __construct(ReleaseBrowseService $releaseBrowseService) { parent::__construct(); - $this->xxxBrowseService = $xxxBrowseService; + $this->releaseBrowseService = $releaseBrowseService; } /** @@ -26,11 +25,10 @@ class AdultController extends BasePageController $moviecats = Category::getChildren(Category::XXX_ROOT); $mtmp = []; foreach ($moviecats as $mcat) { - $mtmp[] = - [ - 'id' => $mcat->id, - 'title' => $mcat->title, - ]; + $mtmp[] = [ + 'id' => $mcat->id, + 'title' => $mcat->title, + ]; } $category = $request->has('t') ? $request->input('t') : Category::XXX_ROOT; if ($id && \in_array($id, Arr::pluck($mtmp, 'title'), false)) { @@ -43,40 +41,24 @@ class AdultController extends BasePageController $catarray = []; $catarray[] = $category; - $ordering = $this->xxxBrowseService->getXXXOrdering(); + $ordering = $this->releaseBrowseService->getBrowseOrdering(); $orderby = $request->has('ob') && \in_array($request->input('ob'), $ordering, false) ? $request->input('ob') : ''; $page = $request->has('page') && is_numeric($request->input('page')) ? $request->input('page') : 1; $offset = ($page - 1) * config('nntmux.items_per_page'); - $rslt = $this->xxxBrowseService->getXXXRange($page, $catarray, $offset, config('nntmux.items_per_page'), $orderby, -1, $this->userdata['categoryexclusions']); // @phpstan-ignore argument.type - $results = $this->paginate($rslt, $rslt[0]->_totalcount ?? 0, config('nntmux.items_per_page'), $page, $request->url(), $request->query()); - - $title = ($request->has('title') && ! empty($request->input('title'))) ? stripslashes($request->input('title')) : ''; - - $actors = ($request->has('actors') && ! empty($request->input('actors'))) ? stripslashes($request->input('actors')) : ''; - - $director = ($request->has('director') && ! empty($request->input('director'))) ? stripslashes($request->input('director')) : ''; - - $genres = XxxInfo::getAllGenres(true); - $genre = ($request->has('genre') && \in_array($request->input('genre'), $genres, false)) ? $request->input('genre') : ''; - - $browseby_link = '&title='.$title.'&actors='.$actors.'&director='.$director.'&genre='.$genre; + $rslt = $this->releaseBrowseService->getBrowseRange($page, $catarray, $offset, config('nntmux.items_per_page'), $orderby, -1, (array) ($this->userdata->categoryexclusions ?? []), -1); + $results = $this->paginate($rslt ?? [], isset($rslt[0]->_totalcount) ? $rslt[0]->_totalcount : 0, config('nntmux.items_per_page'), $page, $request->url(), $request->query()); if ((int) $category === -1) { $catname = 'All'; } else { $cdata = Category::find($category); - if ($cdata !== null) { - $catname = $cdata->title; - } else { - $catname = 'All'; - } + $catname = $cdata !== null ? $cdata->title : 'All'; } - // Build order by URLs $orderByUrls = []; foreach ($ordering as $ordertype) { - $orderByUrls['orderby'.$ordertype] = url('/XXX/'.($id ?: 'All').'?t='.$category.$browseby_link.'&ob='.$ordertype.'&offset=0'); + $orderByUrls['orderby'.$ordertype] = url('/XXX/'.($id ?: 'All').'?t='.$category.'&ob='.$ordertype.'&offset=0'); } $this->viewData = array_merge($this->viewData, [ @@ -84,11 +66,7 @@ class AdultController extends BasePageController 'category' => $category, 'categorytitle' => $id, 'catname' => $catname, - 'title' => stripslashes($title), - 'actors' => $actors, - 'director' => $director, - 'genres' => $genres, - 'genre' => $genre, + 'ordering' => $ordering, 'results' => $results, 'lastvisit' => $this->userdata['lastlogin'] ?? null, 'meta_title' => 'Browse XXX', diff --git a/app/Http/Controllers/CoverController.php b/app/Http/Controllers/CoverController.php index b187a21f9..bbff32d8e 100644 --- a/app/Http/Controllers/CoverController.php +++ b/app/Http/Controllers/CoverController.php @@ -18,7 +18,7 @@ class CoverController extends Controller public function show(string $type, string $filename) { // Validate cover type - $validTypes = ['anime', 'audio', 'audiosample', 'book', 'console', 'games', 'movies', 'music', 'preview', 'sample', 'tvrage', 'video', 'xxx', 'tvshows']; + $validTypes = ['anime', 'audio', 'audiosample', 'book', 'console', 'games', 'movies', 'music', 'preview', 'sample', 'tvrage', 'video', 'tvshows']; if (! in_array($type, $validTypes)) { abort(404); diff --git a/app/Http/Controllers/DetailsController.php b/app/Http/Controllers/DetailsController.php index 174f9e77f..f76775dbc 100644 --- a/app/Http/Controllers/DetailsController.php +++ b/app/Http/Controllers/DetailsController.php @@ -13,7 +13,6 @@ use App\Models\ReleaseReport; use App\Models\Settings; use App\Models\UserDownload; use App\Models\Video; -use App\Models\XxxInfo; use App\Services\AnidbService; use App\Services\BookService; use App\Services\ConsoleService; @@ -22,7 +21,6 @@ use App\Services\MovieService; use App\Services\MusicService; use App\Services\ReleaseExtraService; use App\Services\Releases\ReleaseSearchService; -use App\Services\XxxBrowseService; use Illuminate\Http\Request; class DetailsController extends BasePageController @@ -31,20 +29,16 @@ class DetailsController extends BasePageController private MovieService $movieService; - private XxxBrowseService $xxxBrowseService; - private ReleaseExtraService $releaseExtraService; public function __construct( ReleaseSearchService $releaseSearchService, MovieService $movieService, - XxxBrowseService $xxxBrowseService, ReleaseExtraService $releaseExtraService ) { parent::__construct(); $this->releaseSearchService = $releaseSearchService; $this->movieService = $movieService; - $this->xxxBrowseService = $xxxBrowseService; $this->releaseExtraService = $releaseExtraService; } @@ -104,24 +98,6 @@ class DetailsController extends BasePageController } } - $xxx = ''; - if ($data['xxxinfo_id'] !== '' && $data['xxxinfo_id'] !== 0) { - $xxx = XxxInfo::getXXXInfo($data['xxxinfo_id']); - - if (isset($xxx['trailers'])) { - $xxx['trailers'] = $this->xxxBrowseService->insertSwf($xxx['classused'], $xxx['trailers']); - } - - if ($xxx && isset($xxx['title'])) { - $xxx['title'] = str_replace(['/', '\\'], '', $xxx['title']); - $xxx['actors'] = makeFieldLinks($xxx, 'actors', 'xxx'); - $xxx['genre'] = makeFieldLinks($xxx, 'genre', 'xxx'); - $xxx['director'] = makeFieldLinks($xxx, 'director', 'xxx'); - } else { - $xxx = false; - } - } - $game = ''; if (! empty($data['gamesinfo_id'])) { $game = (new GamesService)->getGamesInfoById($data['gamesinfo_id']); @@ -176,7 +152,6 @@ class DetailsController extends BasePageController 'nfo' => $nfo, 'show' => $showInfo, 'movie' => $mov, - 'xxx' => $xxx, 'anidb' => $AniDBAPIArray, 'music' => $mus, 'con' => $con, diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php index f11b05715..7fceb95d7 100644 --- a/app/Http/Controllers/ProfileController.php +++ b/app/Http/Controllers/ProfileController.php @@ -149,7 +149,7 @@ class ProfileController extends BasePageController $request->has('movieview') ? 1 : 0, $request->has('musicview') ? 1 : 0, $request->has('gameview') ? 1 : 0, - $request->has('xxxview') ? 1 : 0, + $this->userdata->xxxview ? 1 : 0, $request->has('consoleview') ? 1 : 0, $request->has('bookview') ? 1 : 0, 'None', diff --git a/app/Models/XxxInfo.php b/app/Models/XxxInfo.php deleted file mode 100644 index 29f506350..000000000 --- a/app/Models/XxxInfo.php +++ /dev/null @@ -1,231 +0,0 @@ - - */ - protected $guarded = []; - - /** - * Get releases associated with this XXX info. - * - * @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\Release, $this> - */ - public function releases(): HasMany - { - return $this->hasMany(Release::class, 'xxxinfo_id'); - } - - /** - * Get info for a xxx id with decompressed plot. - */ - public static function getXXXInfo(int $xxxid): ?self - { - return self::query() - ->where('id', $xxxid) - ->selectRaw('*, UNCOMPRESS(plot) as plot') - ->first(); - } - - /** - * Update XXX Information. - */ - public static function updateXxxInfo( - string $id, - string $title = '', - string $tagLine = '', - string $plot = '', - string $genre = '', - string $director = '', - string $actors = '', - string $extras = '', - string $productInfo = '', - string $trailers = '', - string $directUrl = '', - string $classUsed = '', - string $cover = '', - string $backdrop = '' - ): void { - if (! empty($id)) { - self::query()->where('id', $id)->update([ - 'title' => $title, - 'tagline' => $tagLine, - 'plot' => "\x1f\x8b\x08\x00".gzcompress($plot), - 'genre' => substr($genre, 0, 64), - 'director' => $director, - 'actors' => $actors, - 'extras' => $extras, - 'productinfo' => $productInfo, - 'trailers' => $trailers, - 'directurl' => $directUrl, - 'classused' => $classUsed, - 'cover' => empty($cover) ? 0 : $cover, - 'backdrop' => empty($backdrop) ? 0 : $backdrop, - ]); - } - } - - /** - * Get all genres for search-filter.tpl. - * - * @return array - */ - public static function getAllGenres(bool $activeOnly = false): array - { - $ret = []; - if ($activeOnly) { - $res = Genre::query() - ->where(['disabled' => 0, 'type' => Category::XXX_ROOT]) - ->orderBy('title') - ->get(['title']) - ->toArray(); - } else { - $res = Genre::query() - ->where(['type' => Category::XXX_ROOT]) - ->orderBy('title') - ->get(['title']) - ->toArray(); - } - - return array_column($res, 'title'); - } - - /** - * Get a specific genre. - * - * @return list - * @return array - */ - public static function getGenres(bool $activeOnly = false, ?int $gid = null): mixed - { - if ($activeOnly) { - return Genre::query() - ->where(['disabled' => 0, 'type' => Category::XXX_ROOT]) - ->when($gid !== null, fn ($query) => $query->where('id', $gid)) - ->orderBy('title') - ->first(['title']); - } - - return Genre::query() - ->where(['type' => Category::XXX_ROOT]) - ->when($gid !== null, fn ($query) => $query->where('id', $gid)) - ->orderBy('title') - ->first(['title']); - } - - /** - * Get Genre id's of the title. - * - * @param array|string $arr - Array or String - * @return string - If array .. 1,2,3,4 if string .. 1 - */ - public static function getGenreID(array|string $arr): string - { - $ret = null; - - if (! \is_array($arr)) { - $res = Genre::query()->where('title', $arr)->first(['id']); - if ($res !== null) { - return (string) $res['id']; - } - - return ''; - } - - foreach ($arr as $key => $value) { - $res = Genre::query()->where('title', $value)->first(['id']); - if ($res !== null) { - $ret .= ','.$res['id']; - } else { - $ret .= ','.self::insertGenre($value); - } - } - - $ret = ltrim($ret, ','); - - return $ret; - } - - /** - * Inserts Genre and returns last affected row (Genre ID). - */ - private static function insertGenre(?string $genre): int|string - { - $res = ''; - if ($genre !== null) { - $res = Genre::query()->insertGetId([ - 'title' => $genre, - 'type' => Category::XXX_ROOT, - 'disabled' => 0, - ]); - } - - return $res; - } - - /** - * Checks xxxinfo to make sure releases exist. - */ - public static function checkXXXInfoExists(string $releaseName): ?self - { - return self::query() - ->where('title', 'like', '%'.$releaseName.'%') - ->first(['id', 'title']); - } -} diff --git a/app/Providers/AdultProcessingServiceProvider.php b/app/Providers/AdultProcessingServiceProvider.php deleted file mode 100644 index d1fa09aca..000000000 --- a/app/Providers/AdultProcessingServiceProvider.php +++ /dev/null @@ -1,52 +0,0 @@ -app->singleton(AebnPipe::class, fn () => new AebnPipe); - $this->app->singleton(IafdPipe::class, fn () => new IafdPipe); - $this->app->singleton(Data18Pipe::class, fn () => new Data18Pipe); - $this->app->singleton(PoppornPipe::class, fn () => new PoppornPipe); - $this->app->singleton(AdmPipe::class, fn () => new AdmPipe); - $this->app->singleton(AdePipe::class, fn () => new AdePipe); - $this->app->singleton(HotmoviesPipe::class, fn () => new HotmoviesPipe); - - // Register the pipeline with all default pipes - $this->app->singleton(AdultProcessingPipeline::class, function ($app) { - return new AdultProcessingPipeline([ - $app->make(AebnPipe::class), - $app->make(IafdPipe::class), - $app->make(Data18Pipe::class), - $app->make(PoppornPipe::class), - $app->make(AdmPipe::class), - $app->make(AdePipe::class), - $app->make(HotmoviesPipe::class), - ]); - }); - } - - /** - * Bootstrap services. - */ - public function boot(): void - { - // - } -} diff --git a/app/Services/AdultProcessing/AdultProcessingPassable.php b/app/Services/AdultProcessing/AdultProcessingPassable.php deleted file mode 100644 index 1918256c1..000000000 --- a/app/Services/AdultProcessing/AdultProcessingPassable.php +++ /dev/null @@ -1,99 +0,0 @@ - - */ - public array $providerResults = []; - - public ?string $cookie = null; - - public function __construct(AdultReleaseContext $context, bool $debug = false, ?string $cookie = null) - { - $this->context = $context; - $this->debug = $debug; - $this->cookie = $cookie; - $this->result = AdultProcessingResult::pending(); - } - - /** - * Check if we should stop processing (match found). - */ - public function shouldStopProcessing(): bool - { - return $this->result->isMatched(); - } - - /** - * Update the result from a provider. - */ - public function updateResult(AdultProcessingResult $result, string $providerName): void - { - if ($this->debug) { - $this->providerResults[$providerName] = [ - 'status' => $result->status, - 'title' => $result->title, - 'debug' => $result->debug, - ]; - } - - // Update if we got a match - if ($result->isMatched()) { - $this->result = $result; - } - } - - /** - * Get the clean title for searching. - */ - public function getCleanTitle(): string - { - return $this->context->cleanTitle; - } - - /** - * Get the cookie string. - */ - public function getCookie(): ?string - { - return $this->cookie; - } - - /** - * Build the final result array. - * - * @return array - */ - public function toArray(): array - { - $returnValue = [ - 'status' => $this->result->status, - 'title' => $this->result->title, - 'provider' => $this->result->providerName, - 'movieData' => $this->result->movieData, - ]; - - if ($this->debug) { - $returnValue['debug'] = [ - 'release_id' => $this->context->releaseId, - 'search_name' => $this->context->searchName, - 'clean_title' => $this->context->cleanTitle, - 'provider_results' => $this->providerResults, - ]; - } - - return $returnValue; - } -} diff --git a/app/Services/AdultProcessing/AdultProcessingPipeline.php b/app/Services/AdultProcessing/AdultProcessingPipeline.php deleted file mode 100644 index 945783d86..000000000 --- a/app/Services/AdultProcessing/AdultProcessingPipeline.php +++ /dev/null @@ -1,792 +0,0 @@ - - */ - protected Collection $pipes; // @phpstan-ignore missingType.generics - - protected int $movieQty; - - protected bool $echoOutput; - - protected ReleaseImageService $releaseImage; - - protected string $imgSavePath; - - protected string $cookie; - - protected string $showPasswords; - - /** - * Processing statistics. - * - * @var array - */ - protected array $stats = [ - 'processed' => 0, - 'matched' => 0, - 'failed' => 0, - 'skipped' => 0, - 'duration' => 0.0, - 'providers' => [], - ]; - - /** - * @param iterable $pipes - */ - public function __construct(iterable $pipes = [], bool $echoOutput = true) - { - /** @phpstan-ignore argument.templateType */ - $this->pipes = collect($pipes); - - if ($this->pipes->isEmpty()) { - $this->pipes = $this->getDefaultPipes(); - } - - $this->pipes = $this->pipes->sortBy(fn (AbstractAdultProviderPipe $p) => $p->getPriority()); - - // Try to get settings from database, but handle failures gracefully (e.g., in child processes) - try { - $this->movieQty = (int) (Settings::settingValue('maxxxxprocessed') ?? 100); - $this->showPasswords = app(\App\Services\Releases\ReleaseBrowseService::class)->showPasswords(); - } catch (\Exception $e) { - // Fallback values for child processes where DB might not be available - $this->movieQty = 100; - $this->showPasswords = ''; - } - - $this->echoOutput = $echoOutput; - $this->releaseImage = new ReleaseImageService; - $this->imgSavePath = storage_path('covers/xxx/'); - $this->cookie = resource_path('tmp/xxx.cookie'); - } - - /** - * Create a lightweight instance for child process use. - * This avoids database calls that may fail in forked processes. - */ - protected static function createForChildProcess(string $cookie, bool $echoOutput, string $imgSavePath): self - { - $instance = new self([], $echoOutput); - $instance->cookie = $cookie; - $instance->imgSavePath = $imgSavePath; - - return $instance; - } - - /** - * Get the default pipes in priority order. - * - * @return Collection - */ - protected function getDefaultPipes(): Collection - { - return collect([ - new AebnPipe, - new IafdPipe, - new Data18Pipe, - new PoppornPipe, - new AdmPipe, - new AdePipe, - new HotmoviesPipe, - ]); - } - - /** - * Add a provider pipe to the pipeline. - */ - public function addPipe(AbstractAdultProviderPipe $pipe): self - { - $this->pipes->push($pipe); - $this->pipes = $this->pipes->sortBy(fn (AbstractAdultProviderPipe $p) => $p->getPriority()); - - return $this; - } - - /** - * Process a single movie title through the pipeline. - * - * @param string $movie Movie title to search for - * @param bool $debug Whether to include debug information - * @return array Processing result - */ - public function processMovie(string $movie, bool $debug = false): array - { - $context = AdultReleaseContext::fromTitle($movie); - $passable = new AdultProcessingPassable($context, $debug, $this->cookie); - - // Set echo output on all pipes - foreach ($this->pipes as $pipe) { - $pipe->setEchoOutput($this->echoOutput); - } - - /** @var AdultProcessingPassable $result */ - $result = app(Pipeline::class) - ->send($passable) - ->through($this->pipes->values()->all()) - ->thenReturn(); - - return $result->toArray(); - } - - /** - * Process a single release through the pipeline. - * - * @param array|object $release Release data - * @param string $cleanTitle Cleaned movie title - * @param bool $debug Whether to include debug information - * @return array Processing result - */ - public function processRelease(array|object $release, string $cleanTitle, bool $debug = false): array - { - $context = AdultReleaseContext::fromRelease($release, $cleanTitle); - $passable = new AdultProcessingPassable($context, $debug, $this->cookie); - - // Set echo output on all pipes - foreach ($this->pipes as $pipe) { - $pipe->setEchoOutput($this->echoOutput); - } - - /** @var AdultProcessingPassable $result */ - $result = app(Pipeline::class) - ->send($passable) - ->through($this->pipes->values()->all()) - ->thenReturn(); - - return $result->toArray(); - } - - /** - * Process all XXX releases where xxxinfo_id is 0. - * - * Uses Laravel's native Concurrency facade for parallel processing when possible. - */ - public function processXXXReleases(): void - { - $startTime = microtime(true); - $this->resetStats(); - - try { - $releases = $this->getReleasesToProcess(); - $releaseCount = count($releases); - - if ($releaseCount === 0) { - if ($this->echoOutput) { - cli()->header('No XXX releases to process.'); - } - - return; - } - - if ($this->echoOutput) { - cli()->header('Processing '.$releaseCount.' XXX releases using pipeline.'); - } - - // Process releases in batches for parallel processing - $batchSize = min(5, $releaseCount); // Process up to 5 at a time - $batches = array_chunk($releases->toArray(), $batchSize); - - foreach ($batches as $batchIndex => $batch) { - if ($this->echoOutput) { - cli()->info('Processing batch '.($batchIndex + 1).' of '.count($batches)); - } - $this->processBatch($batch); // @phpstan-ignore argument.type - } - } catch (\Throwable $e) { - Log::error('processXXXReleases failed: '.$e->getMessage(), [ - 'exception' => get_class($e), - 'file' => $e->getFile(), - 'line' => $e->getLine(), - 'trace' => $e->getTraceAsString(), - ]); - - if ($this->echoOutput) { - cli()->error('Error during processing: '.$e->getMessage()); - } - } - - $this->stats['duration'] = microtime(true) - $startTime; - - if ($this->echoOutput) { - $this->outputStats(); - } - } - - /** - * Process a batch of releases using Laravel's native Concurrency for parallel execution. - * - * Note: Due to serialization limitations with DOMDocument and HtmlDomParser, - * we process releases sequentially within the batch but can process multiple - * batches concurrently using async tasks that create fresh instances. - * - * @param array $batch - */ - protected function processBatch(array $batch): void - { - // Check if we can use async processing - // For now, disable async to avoid child process issues with database connections - // TODO: Re-enable async when database connection pooling is properly configured - $useAsync = $this->canUseAsync() && config('nntmux.adult_processing_async', false); - - if (! $useAsync) { - // Fall back to sequential processing (more reliable) - foreach ($batch as $release) { - $releaseId = (int) ($release['id'] ?? 0); - - if ($releaseId <= 0) { - Log::warning('Invalid release ID in batch: '.json_encode($release)); - $this->stats['failed']++; - - continue; - } - - try { - $this->processReleaseItem($release); - } catch (\Throwable $e) { - // processReleaseItem should handle its own exceptions, but this is a fallback - Log::error('Unexpected error in processBatch for release '.$releaseId.': '.$e->getMessage()); - $this->stats['failed']++; - - // Ensure the release is marked as processed to avoid infinite loop - try { - $this->updateReleaseXxxId($releaseId, -2); - } catch (\Throwable $updateError) { - Log::error('Failed to update release '.$releaseId.' with error code: '.$updateError->getMessage()); - } - } - } - - return; - } - - // For async processing using Laravel's native Concurrency facade - // We create independent tasks with only serializable data - $cookie = $this->cookie; - $echoOutput = $this->echoOutput; - $imgSavePath = $this->imgSavePath; - - $tasks = []; - foreach ($batch as $idx => $release) { - // Extract only the serializable data needed - $releaseData = [ - 'id' => $release['id'], - 'searchname' => $release['searchname'], - ]; - - $tasks[$idx] = fn () => self::processReleaseInChildProcess($releaseData, $cookie, $echoOutput, $imgSavePath); - } - - try { - $results = Concurrency::run($tasks); - - // Update stats based on results - foreach ($results as $result) { - if (is_array($result)) { - if ($result['matched']) { - $this->stats['matched']++; - } - if (isset($result['provider'])) { - $this->stats['providers'][$result['provider']] = - ($this->stats['providers'][$result['provider']] ?? 0) + 1; - } - } - $this->stats['processed']++; - } - } catch (\Throwable $e) { - Log::error('Async batch processing failed: '.$e->getMessage()); - - // Mark all releases in batch as processed with error to avoid infinite loop - foreach ($batch as $release) { - $this->stats['failed']++; - try { - Release::query()->where('id', $release['id'])->update(['xxxinfo_id' => -2]); - } catch (\Throwable $updateError) { - Log::error('Failed to mark release '.$release['id'].' as processed: '.$updateError->getMessage()); - } - } - } - } - - /** - * Process a release in a child process with fresh instances. - * This is a static method to avoid serializing $this. - * - * @param array $releaseData - * @return array - */ - protected static function processReleaseInChildProcess( - array $releaseData, - string $cookie, - bool $echoOutput, - string $imgSavePath - ): array { - // Create fresh pipeline instance in child process - $pipeline = new self([], $echoOutput); - $pipeline->cookie = $cookie; - $pipeline->imgSavePath = $imgSavePath; - - $result = [ - 'id' => $releaseData['id'], - 'xxxinfo_id' => -2, - 'matched' => false, - 'provider' => null, - ]; - - $cleanTitle = $pipeline->parseXXXSearchName($releaseData['searchname']); - - if ($cleanTitle === false) { - Release::query()->where('id', $releaseData['id'])->update(['xxxinfo_id' => -2]); - - return $result; - } - - // Check if we already have this movie in the database - $existingInfo = $pipeline->checkXXXInfoExists($cleanTitle); - - if ($existingInfo !== null) { - $result['xxxinfo_id'] = (int) $existingInfo['id']; - $result['matched'] = true; - } else { - $xxxId = $pipeline->updateXXXInfo($cleanTitle, $releaseData); - $result['xxxinfo_id'] = $xxxId; - $result['matched'] = $xxxId > 0; - - // Get the provider from the result - if ($xxxId > 0) { - $info = XxxInfo::find($xxxId); - if ($info) { - $result['provider'] = $info->classused; - } - } - } - - Release::query()->where('id', $releaseData['id'])->update(['xxxinfo_id' => $result['xxxinfo_id']]); - - return $result; - } - - /** - * Process a single release item. - * - * @param array $release - * @return int XXX info ID or error code - */ - protected function processReleaseItem(array $release): int - { - $idCheck = -2; - $releaseId = (int) ($release['id'] ?? 0); - - if ($releaseId <= 0) { - Log::warning('Invalid release ID in processReleaseItem'); - $this->stats['failed']++; - - return $idCheck; - } - - try { - $cleanTitle = $this->parseXXXSearchName($release['searchname'] ?? ''); - - if ($cleanTitle === false) { - if ($this->echoOutput) { - cli()->primary('.'); - } - $this->updateReleaseXxxId($releaseId, $idCheck); - $this->stats['skipped']++; - - return $idCheck; - } - - // Check if we already have this movie in the database - $existingInfo = $this->checkXXXInfoExists($cleanTitle); - - if ($existingInfo !== null) { - if ($this->echoOutput) { - cli()->info('Local match found for XXX Movie: '.$cleanTitle); - } - $idCheck = (int) $existingInfo['id']; - } else { - if ($this->echoOutput) { - cli()->info('Looking up: '.$cleanTitle); - cli()->info('Local match not found, checking web!'); - } - - $idCheck = $this->updateXXXInfo($cleanTitle, $release); - - // If updateXXXInfo returned false, treat as -2 - if ($idCheck === false) { - $idCheck = -2; - } - } - - $this->updateReleaseXxxId($releaseId, $idCheck); - $this->stats['processed']++; - - if ($idCheck > 0) { - $this->stats['matched']++; - } - } catch (\Throwable $e) { - Log::error('Processing failed for release '.$releaseId.': '.$e->getMessage(), [ - 'exception' => get_class($e), - 'file' => $e->getFile(), - 'line' => $e->getLine(), - 'trace' => $e->getTraceAsString(), - ]); - - // Still mark as processed with error code to avoid infinite loop - try { - $this->updateReleaseXxxId($releaseId, -2); - } catch (\Throwable $updateError) { - Log::error('Failed to update release '.$releaseId.' after processing error: '.$updateError->getMessage()); - } - $this->stats['failed']++; - } - - return $idCheck; - } - - /** - * Update XXX information from pipeline results. - * - * @param array $release - * @return int|false XXX info ID or false on failure - */ - public function updateXXXInfo(string $movie, ?array $release = null): int|false - { - $result = $this->processMovie($movie); - - if ($result['status'] !== AdultProcessingResult::STATUS_MATCHED) { - return -2; - } - - $providerName = $result['provider']; - $movieData = $result['movieData']; - - if ($this->echoOutput) { - $fromStr = match ($providerName) { - 'aebn' => 'Adult Entertainment Broadcast Network', - 'ade' => 'Adult DVD Empire', - 'pop' => 'PopPorn', - 'adm' => 'Adult DVD Marketplace', - 'hotm' => 'HotMovies', - default => $providerName, - }; - cli()->primary('Fetching XXX info from: '.$fromStr); - } - - // Track provider usage - $this->stats['providers'][$providerName] = ($this->stats['providers'][$providerName] ?? 0) + 1; - - // Prepare the movie data for database storage - $cast = ! empty($movieData['cast']) ? implode(',', (array) $movieData['cast']) : ''; - $genres = ! empty($movieData['genres']) ? $this->getGenreID($movieData['genres']) : ''; - - $mov = [ - 'trailers' => ! empty($movieData['trailers']) ? serialize($movieData['trailers']) : '', - 'extras' => ! empty($movieData['extras']) ? serialize($movieData['extras']) : '', - 'productinfo' => ! empty($movieData['productinfo']) ? serialize($movieData['productinfo']) : '', - 'backdrop' => ! empty($movieData['backcover']) ? $movieData['backcover'] : 0, - 'cover' => ! empty($movieData['boxcover']) ? $movieData['boxcover'] : 0, - 'title' => ! empty($movieData['title']) ? html_entity_decode($movieData['title'], ENT_QUOTES, 'UTF-8') : '', - 'plot' => ! empty($movieData['synopsis']) ? html_entity_decode($movieData['synopsis'], ENT_QUOTES, 'UTF-8') : '', - 'tagline' => ! empty($movieData['tagline']) ? html_entity_decode($movieData['tagline'], ENT_QUOTES, 'UTF-8') : '', - 'genre' => ! empty($genres) ? html_entity_decode($genres, ENT_QUOTES, 'UTF-8') : '', - 'director' => ! empty($movieData['director']) ? html_entity_decode($movieData['director'], ENT_QUOTES, 'UTF-8') : '', - 'actors' => ! empty($cast) ? html_entity_decode($cast, ENT_QUOTES, 'UTF-8') : '', - 'directurl' => ! empty($movieData['directurl']) ? html_entity_decode($movieData['directurl'], ENT_QUOTES, 'UTF-8') : '', - 'classused' => $providerName, - ]; - - $cover = 0; - $backdrop = 0; - $xxxID = false; - - // Check if this movie already exists - $check = XxxInfo::query()->where('title', $mov['title'])->first(['id']); - - if ($check !== null && $check['id'] > 0) { - $xxxID = $check['id']; - - // Update BoxCover - if (! empty($mov['cover'])) { - $cover = $this->releaseImage->saveImage($xxxID.'-cover', $mov['cover'], $this->imgSavePath); - } - - // BackCover - if (! empty($mov['backdrop'])) { - $backdrop = $this->releaseImage->saveImage($xxxID.'-backdrop', $mov['backdrop'], $this->imgSavePath, 1920, 1024); - } - - // Update existing record - XxxInfo::query()->where('id', $check['id'])->update([ - 'title' => $mov['title'], - 'tagline' => $mov['tagline'], - 'plot' => "\x1f\x8b\x08\x00".gzcompress($mov['plot']), - 'genre' => substr($mov['genre'], 0, 64), - 'director' => $mov['director'], - 'actors' => $mov['actors'], - 'extras' => $mov['extras'], - 'productinfo' => $mov['productinfo'], - 'trailers' => $mov['trailers'], - 'directurl' => $mov['directurl'], - 'classused' => $mov['classused'], - 'cover' => empty($cover) ? 0 : $cover, - 'backdrop' => empty($backdrop) ? 0 : $backdrop, - ]); - } else { - // Insert new record - $xxxID = XxxInfo::query()->insertGetId([ - 'title' => $mov['title'], - 'tagline' => $mov['tagline'], - 'plot' => "\x1f\x8b\x08\x00".gzcompress($mov['plot']), - 'genre' => substr($mov['genre'], 0, 64), - 'director' => $mov['director'], - 'actors' => $mov['actors'], - 'extras' => $mov['extras'], - 'productinfo' => $mov['productinfo'], - 'trailers' => $mov['trailers'], - 'directurl' => $mov['directurl'], - 'classused' => $mov['classused'], - 'created_at' => now(), - 'updated_at' => now(), - ]); - - // Update BoxCover - if (! empty($mov['cover'])) { - $cover = $this->releaseImage->saveImage($xxxID.'-cover', $mov['cover'], $this->imgSavePath); - } - - // BackCover - if (! empty($mov['backdrop'])) { - $backdrop = $this->releaseImage->saveImage($xxxID.'-backdrop', $mov['backdrop'], $this->imgSavePath, 1920, 1024); - } - - XxxInfo::whereId($xxxID)->update(['cover' => $cover, 'backdrop' => $backdrop]); - } - - if ($this->echoOutput) { - cli()->primary( - ($xxxID !== false ? 'Added/updated XXX movie: '.$mov['title'] : 'Nothing to update for XXX movie: '.$mov['title']), - true - ); - } - - return $xxxID; - } - - /** - * Get releases to process. - * - * @return Collection - */ - protected function getReleasesToProcess(): \Illuminate\Database\Eloquent\Collection // @phpstan-ignore missingType.generics, return.phpDocType - { - return Release::query() - ->where(['xxxinfo_id' => 0]) - ->whereIn('categories_id', [ - Category::XXX_DVD, - Category::XXX_WMV, - Category::XXX_XVID, - Category::XXX_X264, - Category::XXX_SD, - Category::XXX_CLIPHD, - Category::XXX_CLIPSD, - Category::XXX_WEBDL, - Category::XXX_UHD, - Category::XXX_VR, - ]) - ->limit($this->movieQty) - ->get(['searchname', 'id']); - } - - /** - * Check if async processing can be used. - */ - protected function canUseAsync(): bool - { - return class_exists('Illuminate\Support\Facades\Concurrency') && - function_exists('pcntl_fork') && - ! defined('HHVM_VERSION'); - } - - /** - * Check if XXX info already exists in database. - * - * @return array - */ - protected function checkXXXInfoExists(string $releaseName): ?array - { - $result = XxxInfo::query()->where('title', 'like', '%'.$releaseName.'%')->first(['id', 'title']); - - return $result ? $result->toArray() : null; - } - - /** - * Update release with XXX info ID. - */ - protected function updateReleaseXxxId(int $releaseId, int $xxxInfoId): void - { - Release::query()->where('id', $releaseId)->update(['xxxinfo_id' => $xxxInfoId]); - } - - /** - * Get Genre ID from genre names. - * - * @param array $arr - */ - protected function getGenreID(array|string $arr): string - { - $ret = null; - - if (! is_array($arr)) { - $res = Genre::query()->where('title', $arr)->first(['id']); - if ($res !== null) { - return (string) $res['id']; - } - - return ''; - } - - foreach ($arr as $value) { - $res = Genre::query()->where('title', $value)->first(['id']); - if ($res !== null) { - $ret .= ','.$res['id']; - } else { - $ret .= ','.$this->insertGenre($value); - } - } - - return ltrim($ret, ','); - } - - /** - * Insert a new genre. - */ - protected function insertGenre(string $genre): int|string - { - return Genre::query()->insertGetId([ - 'title' => $genre, - 'type' => Category::XXX_ROOT, - 'disabled' => 0, - ]); - } - - /** - * Parse XXX search name from release name. - * - * @return string|false Cleaned title or false if couldn't parse - */ - protected function parseXXXSearchName(string $releaseName): string|false - { - $name = ''; - $followingList = '[^\w]((2160|1080|480|720)(p|i)|AC3D|Directors([^\w]CUT)?|DD5\.1|(DVD|BD|BR)(Rip)?|BluRay|divx|HDTV|iNTERNAL|LiMiTED|(Real\.)?Proper|RE(pack|Rip)|Sub\.?(fix|pack)|Unrated|WEB-DL|(x|H)[ ._-]?264|xvid|[Dd][Ii][Ss][Cc](\d+|\s*\d+|\.\d+)|XXX|BTS|DirFix|Trailer|WEBRiP|NFO|(19|20)\d\d)[^\w]'; - - if (preg_match('/([^\w]{2,})?(?P[\w .-]+?)'.$followingList.'/i', $releaseName, $hits)) { - $name = $hits['name']; - } - - if ($name !== '') { - $name = preg_replace('/'.$followingList.'/i', ' ', $name); - $name = preg_replace('/\(.*?\)|[._-]/i', ' ', $name); - $name = trim(preg_replace('/\s{2,}/', ' ', $name)); - $name = trim(preg_replace('/^Private\s(Specials|Blockbusters|Blockbuster|Sports|Gold|Lesbian|Movies|Classics|Castings|Fetish|Stars|Pictures|XXX|Private|Black\sLabel|Black)\s\d+/i', '', $name)); - $name = trim(preg_replace('/(brazilian|chinese|croatian|danish|deutsch|dutch|estonian|flemish|finnish|french|german|greek|hebrew|icelandic|italian|latin|nordic|norwegian|polish|portuguese|japenese|japanese|russian|serbian|slovenian|spanish|spanisch|swedish|thai|turkish)$/i', '', $name)); - - if (strlen($name) > 5 && - ! preg_match('/^\d+$/', $name) && - ! preg_match('/( File \d+ of \d+|\d+.\d+.\d+)/', $name) && - ! preg_match('/(E\d+)/', $name) && - ! preg_match('/\d\d\.\d\d.\d\d/', $name) - ) { - return $name; - } - } - - return false; - } - - /** - * Reset processing statistics. - */ - protected function resetStats(): void - { - $this->stats = [ - 'processed' => 0, - 'matched' => 0, - 'failed' => 0, - 'skipped' => 0, - 'duration' => 0.0, - 'providers' => [], - ]; - } - - /** - * Output processing statistics. - */ - protected function outputStats(): void - { - cli()->header("\n=== Adult Processing Statistics ==="); - cli()->primary('Processed: '.$this->stats['processed']); - cli()->primary('Matched: '.$this->stats['matched']); - cli()->primary('Failed: '.$this->stats['failed']); - cli()->primary('Skipped: '.$this->stats['skipped']); - cli()->primary(sprintf('Duration: %.2f seconds', $this->stats['duration'])); - - if (! empty($this->stats['providers'])) { - cli()->header("\nProvider Statistics:"); - foreach ($this->stats['providers'] as $provider => $count) { - cli()->primary(" {$provider}: {$count} matches"); - } - } - } - - /** - * Get processing statistics. - * - * @return array - */ - public function getStats(): array - { - return $this->stats; - } - - /** - * Get all registered pipes. - * - * @return Collection - */ - public function getPipes(): Collection - { - return $this->pipes; - } -} diff --git a/app/Services/AdultProcessing/AdultProcessingResult.php b/app/Services/AdultProcessing/AdultProcessingResult.php deleted file mode 100644 index d6c4fc0a3..000000000 --- a/app/Services/AdultProcessing/AdultProcessingResult.php +++ /dev/null @@ -1,146 +0,0 @@ - $debug - * @param array $movieData - */ - public function __construct( - public readonly string $status, - public readonly ?string $title = null, - public readonly ?string $providerName = null, - public readonly array $movieData = [], - public readonly array $debug = [], - ) {} - - /** - * Create a successful match result. - * - * @param array $debug - * @param array $movieData - */ - public static function matched( - string $title, - string $providerName, - array $movieData, - array $debug = [] - ): self { - return new self( - status: self::STATUS_MATCHED, - title: $title, - providerName: $providerName, - movieData: $movieData, - debug: $debug, - ); - } - - /** - * Create a not found result. - * - * @param array $debug - */ - public static function notFound(?string $providerName = null, array $debug = []): self - { - return new self( - status: self::STATUS_NOT_FOUND, - providerName: $providerName, - debug: $debug, - ); - } - - /** - * Create a failed result. - */ - public static function failed(string $reason = '', ?string $providerName = null): self - { - return new self( - status: self::STATUS_FAILED, - providerName: $providerName, - debug: ['reason' => $reason], - ); - } - - /** - * Create a skipped result. - */ - public static function skipped(string $reason = '', ?string $providerName = null): self - { - return new self( - status: self::STATUS_SKIPPED, - providerName: $providerName, - debug: ['reason' => $reason], - ); - } - - /** - * Create a pending result. - */ - public static function pending(): self - { - return new self(status: self::STATUS_PENDING); - } - - /** - * Check if the result is a successful match. - */ - public function isMatched(): bool - { - return $this->status === self::STATUS_MATCHED; - } - - /** - * Check if processing should continue to the next provider. - */ - public function shouldContinueProcessing(): bool - { - return ! $this->isMatched(); - } - - /** - * Get the box cover URL if available. - */ - public function getBoxCover(): ?string - { - return $this->movieData['boxcover'] ?? null; - } - - /** - * Get the back cover URL if available. - */ - public function getBackCover(): ?string - { - return $this->movieData['backcover'] ?? null; - } - - /** - * Get the synopsis if available. - */ - public function getSynopsis(): ?string - { - return $this->movieData['synopsis'] ?? null; - } - - /** - * Get the direct URL if available. - */ - public function getDirectUrl(): ?string - { - return $this->movieData['directurl'] ?? null; - } -} diff --git a/app/Services/AdultProcessing/AdultReleaseContext.php b/app/Services/AdultProcessing/AdultReleaseContext.php deleted file mode 100644 index 98818a209..000000000 --- a/app/Services/AdultProcessing/AdultReleaseContext.php +++ /dev/null @@ -1,46 +0,0 @@ - $release - */ - public static function fromRelease(array|object $release, string $cleanTitle): self - { - $data = is_array($release) ? $release : (array) $release; - - return new self( - releaseId: (int) ($data['id'] ?? 0), - searchName: $data['searchname'] ?? '', - cleanTitle: $cleanTitle, - guid: $data['guid'] ?? null, - ); - } - - /** - * Create from a movie title string. - */ - public static function fromTitle(string $title): self - { - return new self( - releaseId: 0, - searchName: $title, - cleanTitle: $title, - guid: null, - ); - } -} diff --git a/app/Services/AdultProcessing/AgeVerificationManager.php b/app/Services/AdultProcessing/AgeVerificationManager.php deleted file mode 100644 index 9353e5d39..000000000 --- a/app/Services/AdultProcessing/AgeVerificationManager.php +++ /dev/null @@ -1,397 +0,0 @@ - - */ - private array $cookieJars = []; - - /** - * Site-specific age verification configurations - * - * @var array - */ - private array $siteConfigs = [ - 'adultdvdempire.com' => [ - 'cookies' => [ - ['name' => 'age_verified', 'value' => '1'], - ['name' => 'age_gate_passed', 'value' => 'true'], - ['name' => 'over18', 'value' => '1'], - ['name' => 'ageConfirmed', 'value' => 'true'], - ['name' => 'isAdult', 'value' => 'true'], - ], - 'detection' => ['ageConfirmationButton', 'age-confirmation', 'confirm you are over'], - ], - 'adultdvdmarketplace.com' => [ - 'cookies' => [ - ['name' => 'age_verified', 'value' => '1'], - ['name' => 'over18', 'value' => 'yes'], - ['name' => 'ageConfirmed', 'value' => 'true'], - ], - 'detection' => ['age verification', 'are you 18'], - ], - 'straight.theater.aebn.net' => [ - 'cookies' => [ - ['name' => 'age_verified', 'value' => '1'], - ['name' => 'aebn_age_check', 'value' => 'passed'], - ['name' => 'over18', 'value' => 'true'], - ], - 'detection' => ['age verification', 'over 18'], - ], - 'hotmovies.com' => [ - 'cookies' => [ - ['name' => 'age_verified', 'value' => '1'], - ['name' => 'over18', 'value' => 'true'], - ['name' => 'ageConfirmed', 'value' => 'true'], - ['name' => 'hmAgeVerified', 'value' => '1'], - ], - 'detection' => ['age verification', 'enter'], - ], - 'popporn.com' => [ - 'cookies' => [ - ['name' => 'age_verified', 'value' => '1'], - ['name' => 'over_18', 'value' => 'yes'], - ['name' => 'ageVerified', 'value' => 'true'], - ['name' => 'popAgeConfirmed', 'value' => '1'], - ['name' => 'adultConsent', 'value' => 'true'], - // Note: etoken is dynamically set by the server, we can't pre-set it - ], - 'detection' => ['age verification', 'over 18', 'AgeConfirmation'], - 'redirectBypass' => true, // Indicates this site uses redirect-based verification - ], - ]; - - /** - * Constructor - */ - public function __construct(?string $cookieDir = null) - { - if ($cookieDir !== null) { - $this->cookieDir = $cookieDir; - } else { - $this->cookieDir = storage_path('app/cookies/adult_sites'); - } - - // Create cookie directory if it doesn't exist - if (! is_dir($this->cookieDir)) { - mkdir($this->cookieDir, 0755, true); - } - } - - /** - * Get cookie jar for a specific site - * Loads existing cookies or creates new jar - */ - public function getCookieJar(string $url): FileCookieJar - { - $domain = $this->extractDomain($url); - - if (! isset($this->cookieJars[$domain])) { - $cookieFile = $this->getCookieFilePath($domain); - $this->cookieJars[$domain] = new FileCookieJar($cookieFile, true); - - // If cookie file is new or empty, set age verification cookies - if (! file_exists($cookieFile) || filesize($cookieFile) < 10) { - $this->setAgeVerificationCookies($domain, $this->cookieJars[$domain]); - } - } - - return $this->cookieJars[$domain]; - } - - /** - * Make HTTP request with automatic age verification handling - * - * @param array $options - */ - public function makeRequest(string $url, array $options = []): string|false - { - $domain = $this->extractDomain($url); - $cookieJar = $this->getCookieJar($url); - - $client = new Client([ - 'cookies' => $cookieJar, - 'headers' => [ - 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', - 'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', - 'Accept-Language' => 'en-US,en;q=0.5', - 'Accept-Encoding' => 'gzip, deflate, br', - 'DNT' => '1', - 'Connection' => 'keep-alive', - 'Upgrade-Insecure-Requests' => '1', - ], - 'allow_redirects' => true, - 'verify' => false, // For development; set to true in production - ]); - - try { - $response = $client->get($url, $options); - $html = $response->getBody()->getContents(); - - // Check if we got an age verification page - if ($this->isAgeVerificationPage($html, $domain)) { - // Set age verification cookies and retry - $this->setAgeVerificationCookies($domain, $cookieJar); - $cookieJar->save($this->getCookieFilePath($domain)); - - // Retry request with new cookies - $response = $client->get($url, $options); - $html = $response->getBody()->getContents(); - } - - return $html; - - } catch (\Exception $e) { - error_log("Age Verification Manager: Request failed for {$url}: ".$e->getMessage()); - - return false; - } - } - - /** - * Check if response is an age verification page - */ - private function isAgeVerificationPage(string $html, string $domain): bool - { - if (! isset($this->siteConfigs[$domain])) { - return false; - } - - $detection = $this->siteConfigs[$domain]['detection']; - $htmlLower = strtolower($html); - - foreach ($detection as $keyword) { - if (stripos($htmlLower, strtolower($keyword)) !== false) { - return true; - } - } - - return false; - } - - /** - * Set age verification cookies for a domain - */ - private function setAgeVerificationCookies(string $domain, CookieJar $cookieJar): void - { - if (! isset($this->siteConfigs[$domain])) { - return; - } - - $cookies = $this->siteConfigs[$domain]['cookies']; - $expiry = time() + (365 * 24 * 60 * 60); // 1 year - - foreach ($cookies as $cookieData) { - $cookie = new SetCookie([ - 'Name' => $cookieData['name'], - 'Value' => $cookieData['value'], - 'Domain' => '.'.$domain, - 'Path' => '/', - 'Expires' => $expiry, - 'Secure' => true, - 'HttpOnly' => false, - ]); - - $cookieJar->setCookie($cookie); - } - - // Save cookies to file - if ($cookieJar instanceof FileCookieJar) { - $cookieJar->save($this->getCookieFilePath($domain)); - } - } - - /** - * Extract domain from URL - */ - private function extractDomain(string $url): string - { - $parsed = parse_url($url); - $host = $parsed['host'] ?? ''; - - // Remove www. prefix if present - $host = preg_replace('/^www\./', '', $host); - - // Map known subdomains to main domains - $domainMap = [ - 'straight.theater.aebn.net' => 'straight.theater.aebn.net', - 'adultdvdempire.com' => 'adultdvdempire.com', - 'adultdvdmarketplace.com' => 'adultdvdmarketplace.com', - 'hotmovies.com' => 'hotmovies.com', - 'popporn.com' => 'popporn.com', - ]; - - return $domainMap[$host] ?? $host; - } - - /** - * Force refresh cookies for a domain. - */ - public function refreshCookies(string $url): FileCookieJar - { - $domain = $this->extractDomain($url); - $cookieFile = $this->getCookieFilePath($domain); - - // Clear existing cookie jar - if (isset($this->cookieJars[$domain])) { - unset($this->cookieJars[$domain]); - } - - // Delete old cookie file if exists - if (file_exists($cookieFile)) { - unlink($cookieFile); - } - - // Create new jar with fresh cookies - $this->cookieJars[$domain] = new FileCookieJar($cookieFile, true); - $this->setAgeVerificationCookies($domain, $this->cookieJars[$domain]); - - return $this->cookieJars[$domain]; - } - - /** - * Get cookie file path for a domain - */ - private function getCookieFilePath(string $domain): string - { - $safeName = preg_replace('/[^a-z0-9_-]/', '_', strtolower($domain)); - - return $this->cookieDir.'/'.$safeName.'_cookies.json'; - } - - /** - * Clear cookies for a specific domain - */ - public function clearCookies(string $domain): bool - { - $cookieFile = $this->getCookieFilePath($domain); - - if (file_exists($cookieFile)) { - unlink($cookieFile); - unset($this->cookieJars[$domain]); - - return true; - } - - return false; - } - - /** - * Clear all stored cookies - */ - public function clearAllCookies(): int - { - $cleared = 0; - $files = glob($this->cookieDir.'/*_cookies.json'); - - foreach ($files as $file) { - if (unlink($file)) { - $cleared++; - } - } - - $this->cookieJars = []; - - return $cleared; - } - - /** - * Get list of domains with stored cookies - * - * @return array - */ - public function getStoredDomains(): array - { - $domains = []; - $files = glob($this->cookieDir.'/*_cookies.json'); - - foreach ($files as $file) { - $basename = basename($file, '_cookies.json'); - $domain = str_replace('_', '.', $basename); - $domains[] = $domain; - } - - return $domains; - } - - /** - * Check if cookies exist for a domain - * - * @return list - */ - public function hasCookies(string $domain): bool - { - $cookieFile = $this->getCookieFilePath($domain); - - return file_exists($cookieFile) && filesize($cookieFile) > 10; - } - - /** - * Get cookie statistics - * - * @return array - */ - public function getCookieStats(): array - { - $stats = [ - 'total_domains' => 0, - 'total_cookies' => 0, - 'domains' => [], - ]; - - foreach ($this->siteConfigs as $domain => $config) { - if ($this->hasCookies($domain)) { - $cookieJar = $this->getCookieJar('https://'.$domain); - $cookieCount = count($cookieJar); - - $stats['domains'][$domain] = [ - 'has_cookies' => true, - 'cookie_count' => $cookieCount, - 'file' => $this->getCookieFilePath($domain), - ]; - - $stats['total_domains']++; - $stats['total_cookies'] += $cookieCount; - } else { - $stats['domains'][$domain] = [ - 'has_cookies' => false, - 'cookie_count' => 0, - ]; - } - } - - return $stats; - } - - /** - * Get the cookie directory path - */ - public function getCookieDirectory(): string - { - return $this->cookieDir; - } -} diff --git a/app/Services/AdultProcessing/Pipes/AbstractAdultProviderPipe.php b/app/Services/AdultProcessing/Pipes/AbstractAdultProviderPipe.php deleted file mode 100644 index b00b07369..000000000 --- a/app/Services/AdultProcessing/Pipes/AbstractAdultProviderPipe.php +++ /dev/null @@ -1,913 +0,0 @@ - - */ - protected static array $lastRequestTime = []; - - /** - * Cache duration for search results in minutes. - */ - protected int $cacheDuration = 60; - - /** - * Whether to use caching for this provider. - */ - protected bool $useCache = true; - - public function __construct() - { - // Lazy load HtmlDomParser to avoid serialization issues - } - - /** - * Get the HtmlDomParser instance (lazy loaded). - */ - protected function getHtmlParser(): HtmlDomParser - { - if ($this->html === null) { - $this->html = new HtmlDomParser; - } - - return $this->html; - } - - /** - * Handle the adult movie processing request. - */ - public function handle(AdultProcessingPassable $passable, Closure $next): AdultProcessingPassable - { - // If we already have a match, skip processing - if ($passable->shouldStopProcessing()) { - return $next($passable); - } - - // Set the cookie from passable - $this->cookie = $passable->getCookie(); - - // Skip if this provider shouldn't process - if ($this->shouldSkip($passable)) { - $passable->updateResult( - AdultProcessingResult::skipped('Provider skipped', $this->getName()), - $this->getName() - ); - - return $next($passable); - } - - // Output processing message - if ($this->echoOutput) { - cli()->info('Checking '.$this->getDisplayName().' for movie info'); - } - - try { - // Apply rate limiting - $this->applyRateLimit(); - - // Attempt to process with this provider - $result = $this->process($passable); - - // Update the result - $passable->updateResult($result, $this->getName()); - } catch (\Exception $e) { - Log::error('Adult provider '.$this->getName().' failed: '.$e->getMessage(), [ - 'provider' => $this->getName(), - 'title' => $passable->getCleanTitle(), - 'exception' => get_class($e), - ]); - - $passable->updateResult( - AdultProcessingResult::failed($e->getMessage(), $this->getName()), - $this->getName() - ); - } - - return $next($passable); - } - - /** - * Apply rate limiting between requests to the same provider. - */ - protected function applyRateLimit(): void - { - $providerName = $this->getName(); - $now = microtime(true) * 1000; - - if (isset(self::$lastRequestTime[$providerName])) { - $elapsed = $now - self::$lastRequestTime[$providerName]; - if ($elapsed < $this->rateLimitDelay) { - usleep((int) (($this->rateLimitDelay - $elapsed) * 1000)); - } - } - - self::$lastRequestTime[$providerName] = microtime(true) * 1000; - } - - /** - * Get the priority of this provider (lower = higher priority). - */ - public function getPriority(): int - { - return $this->priority; - } - - /** - * Get the internal name of this provider. - */ - abstract public function getName(): string; - - /** - * Get the display name for user-facing output. - */ - abstract public function getDisplayName(): string; - - /** - * Get the base URL for the provider. - */ - abstract protected function getBaseUrl(): string; - - /** - * Attempt to process the movie through this provider. - */ - abstract protected function process(AdultProcessingPassable $passable): AdultProcessingResult; - - /** - * Search for a movie on this provider. - * - * @return array|false Returns array with 'title' and 'url' keys on success, false on failure - */ - abstract protected function search(string $movie): array|false; - - /** - * Get all movie information from the provider. - * - * @return array - */ - abstract protected function getMovieInfo(): array|false; - - /** - * Check if this provider should be skipped for the given passable. - */ - protected function shouldSkip(AdultProcessingPassable $passable): bool - { - return empty($passable->getCleanTitle()); - } - - /** - * Set echo output flag. - */ - public function setEchoOutput(bool $echo): self - { - $this->echoOutput = $echo; - - return $this; - } - - /** - * Get cached search result if available. - * - * @return array - */ - protected function getCachedSearch(string $movie): array|false|null - { - if (! $this->useCache) { - return null; - } - - $cacheKey = 'adult_search_'.$this->getName().'_'.md5(strtolower($movie)); - $cached = Cache::get($cacheKey); - - if ($cached !== null) { - if ($this->echoOutput) { - cli()->info('Using cached result for: '.$movie); - } - - return $cached; - } - - return null; - } - - /** - * Cache a search result. - * - * @param array $result - */ - protected function cacheSearchResult(string $movie, array|false $result): void - { - if (! $this->useCache) { - return; - } - - $cacheKey = 'adult_search_'.$this->getName().'_'.md5(strtolower($movie)); - Cache::put($cacheKey, $result, now()->addMinutes($this->cacheDuration)); - } - - /** - * Fetch raw HTML from a URL with retry support. - * - * @param array $postData - */ - protected function fetchHtml(string $url, ?string $cookie = null, ?array $postData = null): string|false - { - $attempt = 0; - $lastException = null; - $ageVerificationAttempted = false; - - while ($attempt < $this->maxRetries) { - try { - $attempt++; - $client = $this->getHttpClient(); - - $options = [ - 'headers' => $this->getDefaultHeaders(), - ]; - - // Add custom cookie if provided - if ($cookie) { - $options['headers']['Cookie'] = $cookie; - } - - // Handle POST data - if ($postData !== null) { - $options['form_params'] = $postData; - $response = $client->post($url, $options); - } else { - $response = $client->get($url, $options); - } - - $body = $response->getBody()->getContents(); - - // Check if we were redirected to an age verification page - $finalUrl = $response->getHeaderLine('X-Guzzle-Redirect-History'); - if (empty($finalUrl)) { - // Use the effective URI if available - $effectiveUri = $response->getHeader('X-Guzzle-Redirect-History'); - if (! empty($effectiveUri)) { - $finalUrl = end($effectiveUri); - } - } - - // Check for common error pages - if ($this->isErrorPage($body)) { - Log::warning('Received error page from '.$this->getName().': '.$url); - if ($attempt < $this->maxRetries) { - usleep($this->retryDelay * 1000); - - continue; - } - - return false; - } - - // Check for age verification requirement - if ($this->requiresAgeVerification($body)) { - // If we haven't tried age verification yet, refresh cookies and retry - if (! $ageVerificationAttempted) { - $ageVerificationAttempted = true; - - // Refresh cookies using the manager - $this->getAgeVerificationManager()->refreshCookies($this->getBaseUrl()); - - // Reset HTTP client to pick up new cookies - $this->httpClient = null; - $this->cookieJar = null; - - Log::info('Refreshed age verification cookies for '.$this->getName().', retrying...'); - - continue; - } - - $body = $this->handleAgeVerification($url, $body); - if ($body === false) { - return false; - } - } - - return $body; - - } catch (ConnectException $e) { - $lastException = $e; - Log::warning('Connection failed for '.$this->getName().' (attempt '.$attempt.'): '.$e->getMessage()); - - if ($attempt < $this->maxRetries) { - usleep($this->retryDelay * 1000 * $attempt); // Exponential backoff - } - } catch (RequestException $e) { - $lastException = $e; - $statusCode = $e->hasResponse() ? $e->getResponse()->getStatusCode() : 0; - - // Don't retry on 4xx client errors (except 429 rate limit) - if ($statusCode >= 400 && $statusCode < 500 && $statusCode !== 429) { - Log::error('HTTP '.$statusCode.' for '.$this->getName().': '.$url); - - return false; - } - - Log::warning('Request failed for '.$this->getName().' (attempt '.$attempt.'): '.$e->getMessage()); - - if ($attempt < $this->maxRetries) { - // Longer delay for rate limit errors - $delay = $statusCode === 429 ? $this->retryDelay * 5 : $this->retryDelay * $attempt; - usleep($delay * 1000); - } - } catch (\Exception $e) { - $lastException = $e; - Log::error('Unexpected error for '.$this->getName().': '.$e->getMessage()); - - if ($attempt < $this->maxRetries) { - usleep($this->retryDelay * 1000); - } - } - } - - if ($lastException) { - Log::error('All retry attempts failed for '.$this->getName().': '.$lastException->getMessage()); - } - - return false; - } - - /** - * Get default HTTP headers. - * - * @return array - */ - protected function getDefaultHeaders(): array - { - return [ - 'User-Agent' => $this->getRandomUserAgent(), - 'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8', - 'Accept-Language' => 'en-US,en;q=0.9', - 'Accept-Encoding' => 'gzip, deflate, br', - 'Cache-Control' => 'no-cache', - 'Pragma' => 'no-cache', - 'Sec-Fetch-Dest' => 'document', - 'Sec-Fetch-Mode' => 'navigate', - 'Sec-Fetch-Site' => 'none', - 'Sec-Fetch-User' => '?1', - 'Upgrade-Insecure-Requests' => '1', - ]; - } - - /** - * Get a random user agent string. - */ - protected function getRandomUserAgent(): string - { - $userAgents = [ - 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', - 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36', - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', - 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0', - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Safari/605.1.15', - 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0', - ]; - - return $userAgents[array_rand($userAgents)]; - } - - /** - * Check if the response is an error page. - */ - protected function isErrorPage(string $html): bool - { - $errorPatterns = [ - 'Access Denied', - 'Service Unavailable', - '503 Service', - '502 Bad Gateway', - 'temporarily unavailable', - 'maintenance mode', - 'rate limit exceeded', - ]; - - foreach ($errorPatterns as $pattern) { - if (stripos($html, $pattern) !== false) { - return true; - } - } - - return false; - } - - /** - * Check if the page requires age verification. - */ - protected function requiresAgeVerification(string $html): bool - { - // First check if this looks like a proper content page - // Content pages have actual movie info, cast, etc. - $contentIndicators = [ - '.*?DVD.*?', - 'product-info', - 'movie-details', - 'cast-list', - 'genre-list', - '"@type":\s*"Movie"', - '"@type":\s*"Product"', - ]; - - foreach ($contentIndicators as $pattern) { - // Note: Using # as delimiter to avoid issues with / in patterns like - if (preg_match('#'.$pattern.'#is', $html)) { - return false; // This is a content page, not an age verification page - } - } - - // Check for short page that might just be a redirect/age gate - if (strlen($html) < 500) { - return true; // Very short response likely means we got redirected - } - - // Now check for explicit age verification indicators - $agePatterns = [ - 'age verification', - 'are you 18', - 'are you over 18', - 'confirm your age', - 'enter your age', - 'must be 18', - 'age-gate', - 'ageGate', - 'AgeConfirmation', // PopPorn specific - 'ageConfirmationButton', // ADE specific - 'age-confirmation', // Generic - 'verify your age', - 'adult content warning', - 'I am 18 or older', - 'I am over 18', - 'this site contains adult', - ]; - - // Count how many patterns match - if multiple match on a short page, it's likely age verification - $matchCount = 0; - foreach ($agePatterns as $pattern) { - if (stripos($html, $pattern) !== false) { - $matchCount++; - // If the page is relatively short and has an age pattern, it's probably an age gate - if (strlen($html) < 10000) { - return true; - } - } - } - - // If multiple patterns match, it's likely an age verification page - return $matchCount >= 2; - } - - /** - * Handle age verification requirement. - */ - protected function handleAgeVerification(string $url, string $html): string|false - { - // First, try to use site-specific cookies from the AgeVerificationManager - $manager = $this->getAgeVerificationManager(); - $domain = parse_url($this->getBaseUrl(), PHP_URL_HOST); - $domain = preg_replace('/^www\./', '', $domain); - - // Re-initialize cookies from the manager and retry - if ($this->cookieJar) { - // The manager already handles setting cookies, but let's ensure they're fresh - Log::info('Attempting to handle age verification for '.$this->getName().' with domain: '.$domain); - } - - // Try to find and submit age verification form - $this->getHtmlParser()->loadHtml($html); - - // Look for common age verification form patterns - $forms = $this->getHtmlParser()->find('form'); - foreach ($forms as $form) { - $action = $form->action ?? ''; - $method = strtoupper($form->method ?? 'GET'); - - // Check if this looks like an age verification form - $formHtml = $form->innerHtml ?? ''; - if (stripos($formHtml, 'age') !== false || stripos($formHtml, '18') !== false || - stripos($formHtml, 'adult') !== false || stripos($formHtml, 'enter') !== false || - stripos($formHtml, 'confirm') !== false) { - // Try to submit the form with age confirmation - $postData = $this->extractAgeVerificationFormData($form); - - if (! empty($postData)) { - $submitUrl = $action; - if (! str_starts_with($submitUrl, 'http')) { - $submitUrl = $this->getBaseUrl().'/'.ltrim($submitUrl, '/'); - } - - // Submit the age verification - try { - $response = $this->getHttpClient()->request($method, $submitUrl, [ - 'form_params' => $postData, - 'headers' => $this->getDefaultHeaders(), - ]); - - $body = $response->getBody()->getContents(); - - // Check if we still get age verification after submit - if (! $this->requiresAgeVerification($body)) { - return $body; - } - } catch (\Exception $e) { - Log::warning('Age verification submission failed for '.$this->getName().': '.$e->getMessage()); - } - } - } - } - - // Look for JavaScript-based age verification (click to enter) - if (preg_match('/onclick\s*=\s*["\'].*?(enter|agree|confirm|over18|adult).*?["\']/i', $html) || - preg_match('/]*href\s*=\s*["\']([^"\']*)["\'][^>]*>(Enter|I am over 18|Agree|Enter Site|I Agree)/i', $html, $matches)) { - // Try to follow the link or simulate the click - if (! empty($matches[1])) { - $enterUrl = $matches[1]; - if (! str_starts_with($enterUrl, 'http')) { - $enterUrl = $this->getBaseUrl().'/'.ltrim($enterUrl, '/'); - } - - try { - $response = $this->getHttpClient()->get($enterUrl, [ - 'headers' => $this->getDefaultHeaders(), - ]); - $body = $response->getBody()->getContents(); - - if (! $this->requiresAgeVerification($body)) { - return $body; - } - } catch (\Exception $e) { - Log::warning('Age verification link follow failed for '.$this->getName().': '.$e->getMessage()); - } - } - } - - // If all else fails, try to just refetch the original URL - // (sometimes the cookies from previous attempts work) - try { - $response = $this->getHttpClient()->get($url, [ - 'headers' => $this->getDefaultHeaders(), - ]); - $body = $response->getBody()->getContents(); - - if (! $this->requiresAgeVerification($body)) { - return $body; - } - } catch (\Exception $e) { - Log::warning('Age verification retry failed for '.$this->getName().': '.$e->getMessage()); - } - - // If we couldn't handle age verification, log and return false - Log::warning('Could not handle age verification for '.$this->getName().': '.$url); - - return false; - } - - /** - * Extract form data for age verification submission. - * - * @return array - */ - protected function extractAgeVerificationFormData(mixed $form): array - { - $data = []; - - // Get all input fields - foreach ($form->find('input') as $input) { - $name = $input->name ?? ''; - $type = strtolower($input->type ?? 'text'); - $value = $input->value ?? ''; - - if (empty($name)) { - continue; - } - - // Handle different input types - switch ($type) { - case 'hidden': - $data[$name] = $value; - break; - case 'checkbox': - // Usually age verification checkboxes need to be checked - if (stripos($name, 'age') !== false || stripos($name, 'agree') !== false || stripos($name, 'confirm') !== false) { - $data[$name] = $value ?: '1'; - } - break; - case 'submit': - // Include submit button value if it has a name - if (! empty($value)) { - $data[$name] = $value; - } - break; - default: - // For text inputs that might be age/birthdate - if (stripos($name, 'age') !== false || stripos($name, 'year') !== false) { - $data[$name] = '1990'; // Default to a valid birth year - } - } - } - - // Handle select elements (for birthdate selection) - foreach ($form->find('select') as $select) { - $name = $select->name ?? ''; - if (empty($name)) { - continue; - } - - if (stripos($name, 'year') !== false) { - $data[$name] = '1990'; - } elseif (stripos($name, 'month') !== false) { - $data[$name] = '01'; - } elseif (stripos($name, 'day') !== false) { - $data[$name] = '01'; - } - } - - return $data; - } - - /** - * Get the age verification manager instance. - */ - protected function getAgeVerificationManager(): AgeVerificationManager - { - if ($this->ageVerificationManager === null) { - $this->ageVerificationManager = new AgeVerificationManager; - } - - return $this->ageVerificationManager; - } - - /** - * Get or create HTTP client with retry middleware. - */ - protected function getHttpClient(): Client - { - if ($this->httpClient === null) { - // Use the AgeVerificationManager to get proper cookie jar with age verification cookies - $this->cookieJar = $this->getAgeVerificationManager()->getCookieJar($this->getBaseUrl()); - - $this->httpClient = new Client([ - 'timeout' => 30, - 'connect_timeout' => 15, - 'verify' => false, - 'cookies' => $this->cookieJar, - 'allow_redirects' => [ - 'max' => 5, - 'strict' => false, - 'referer' => true, - 'track_redirects' => true, - ], - 'http_errors' => true, - ]); - } - - return $this->httpClient; - } - - /** - * Calculate similarity between two strings using multiple algorithms. - */ - protected function calculateSimilarity(string $searchTerm, string $resultTitle): float - { - // Clean up both strings for comparison - $cleanSearch = $this->cleanTitleForComparison($searchTerm); - $cleanResult = $this->cleanTitleForComparison($resultTitle); - - // Calculate similarity using multiple methods - similar_text($cleanSearch, $cleanResult, $similarTextPercent); - - // Also calculate Levenshtein distance based similarity - $maxLen = max(strlen($cleanSearch), strlen($cleanResult)); - if ($maxLen > 0) { - $levenshtein = levenshtein($cleanSearch, $cleanResult); - $levenshteinPercent = (1 - ($levenshtein / $maxLen)) * 100; - } else { - $levenshteinPercent = 0; - } - - // Use the higher of the two similarity scores - return max($similarTextPercent, $levenshteinPercent); - } - - /** - * Clean a title for comparison purposes. - */ - protected function cleanTitleForComparison(string $title): string - { - $title = strtolower($title); - $title = str_replace('/XXX/', '', $title); - - // Remove common adult movie prefixes/suffixes - $removePatterns = [ - '/\b(xxx|adult|porn|erotic|hd|4k|1080p|720p|dvdrip|webrip|bluray)\b/i', - '/\(.*?\)/', - '/\[.*?\]/', - '/[._-]+/', - '/\s+/', - ]; - - foreach ($removePatterns as $pattern) { - $title = preg_replace($pattern, ' ', $title); - } - - return trim($title); - } - - /** - * Extract movie information from the loaded HTML. - * - * @return array - */ - protected function extractCovers(): array - { - return []; - } - - /** - * @return array - */ - protected function extractSynopsis(): array - { - return []; - } - - /** - * @return array - */ - protected function extractCast(): array - { - return []; - } - - /** - * @return array - */ - protected function extractGenres(): array - { - return []; - } - - /** - * @return array - */ - protected function extractProductInfo(bool $extras = false): array - { - return []; - } - - /** - * @return array - */ - protected function extractTrailers(): array - { - return []; - } - - /** - * Output match success message. - */ - protected function outputMatch(string $title): void - { - if (! $this->echoOutput) { - return; - } - - cli()->primary('Found match on '.$this->getDisplayName().': '.$title); - } - - /** - * Output failure message. - */ - protected function outputNotFound(): void - { - if (! $this->echoOutput) { - return; - } - - cli()->notice('No match found on '.$this->getDisplayName()); - } - - /** - * Parse JSON-LD structured data from HTML. - * - * @return array - */ - protected function extractJsonLd(string $html): ?array - { - // Note: Using # as delimiter because pattern contains / in - if (preg_match_all('#]*type=["\']application/ld\+json["\'][^>]*>(.*?)#si', $html, $matches)) { - foreach ($matches[1] as $json) { - $data = json_decode(trim($json), true); - if (json_last_error() === JSON_ERROR_NONE && is_array($data)) { - // Handle both single object and array of objects - if (isset($data['@type'])) { - return $data; - } elseif (isset($data[0]['@type'])) { - return $data[0]; - } - } - } - } - - return null; - } - - /** - * Extract Open Graph meta data from HTML. - * - * @return array - */ - protected function extractOpenGraph(string $html): array - { - $og = []; - $this->getHtmlParser()->loadHtml($html); - - $metaTags = [ - 'og:title' => 'title', - 'og:description' => 'description', - 'og:image' => 'image', - 'og:url' => 'url', - ]; - - foreach ($metaTags as $property => $key) { - $meta = $this->getHtmlParser()->findOne('meta[property="'.$property.'"]'); - if ($meta && isset($meta->content)) { // @phpstan-ignore booleanAnd.leftAlwaysTrue - $og[$key] = trim($meta->content); - } - } - - return $og; - } -} diff --git a/app/Services/AdultProcessing/Pipes/AdePipe.php b/app/Services/AdultProcessing/Pipes/AdePipe.php deleted file mode 100644 index 920de35e9..000000000 --- a/app/Services/AdultProcessing/Pipes/AdePipe.php +++ /dev/null @@ -1,398 +0,0 @@ -getCleanTitle(); - - $searchResult = $this->search($movie); - - if ($searchResult === false) { - $this->outputNotFound(); - - return AdultProcessingResult::notFound($this->getName()); - } - - $this->title = $searchResult['title']; - $this->directUrl = $searchResult['url']; - - // Fetch the movie details page - $this->response = $this->fetchHtml($this->directUrl, $this->cookie); - - if ($this->response === false) { // @phpstan-ignore identical.alwaysFalse - return AdultProcessingResult::failed('Failed to fetch movie details page', $this->getName()); - } - - $this->getHtmlParser()->loadHtml($this->response); - - $movieInfo = $this->getMovieInfo(); - - if ($movieInfo === false) { - return AdultProcessingResult::notFound($this->getName()); - } - - $this->outputMatch($this->title); - - return AdultProcessingResult::matched( - $this->title, - $this->getName(), - $movieInfo - ); - } - - /** - * @return array - */ - protected function search(string $movie): array|false - { - if (empty($movie)) { - return false; - } - - // Initialize session with age verification cookies - $this->initializeSession(); - - $searchUrl = self::BASE_URL.self::SEARCH_URL.rawurlencode($movie); - $response = $this->fetchHtml($searchUrl, $this->cookie); - - if ($response === false) { - return false; - } - - $this->getHtmlParser()->loadHtml($response); - - // Try multiple search result selectors - $resultSelectors = [ - 'a[class=fancybox-button]', - 'div.card a.boxcover-link', - 'a[href*="/item/"]', - ]; - - $bestMatch = null; - $highestSimilarity = 0; - - foreach ($resultSelectors as $selector) { - $res = $this->getHtmlParser()->find($selector); - if (! empty($res)) { - foreach ($res as $ret) { - $title = $ret->title ?? $ret->getAttribute('title') ?? trim($ret->plaintext); - $url = trim($ret->href ?? ''); - - if (empty($title) || empty($url)) { - continue; - } - - $similarity = $this->calculateSimilarity($movie, $title); - - if ($similarity > $highestSimilarity) { - $highestSimilarity = $similarity; - $bestMatch = [ - 'title' => trim($title), - 'url' => str_starts_with($url, 'http') ? $url : self::BASE_URL.$url, - ]; - } - } - - // If we found results with this selector, don't try others - if ($bestMatch !== null) { - break; - } - } - } - - if ($bestMatch !== null && $highestSimilarity >= $this->minimumSimilarity) { - return $bestMatch; - } - - return false; - } - - /** - * @return array - */ - protected function getMovieInfo(): array|false - { - $results = []; - - if (! empty($this->directUrl)) { - if (! empty($this->title)) { - $results['title'] = $this->title; - } - $results['directurl'] = $this->directUrl; - } - - // Get all the movie data - $results = array_merge($results, $this->extractSynopsis()); - $results = array_merge($results, $this->extractProductInfo(true)); - $results = array_merge($results, $this->extractCast()); - $results = array_merge($results, $this->extractGenres()); - $results = array_merge($results, $this->extractCovers()); - $results = array_merge($results, $this->extractTrailers()); - - if (empty($results)) { - return false; - } - - return $results; - } - - /** - * @return array - */ - protected function extractTrailers(): array - { - $res = []; - - $trailersUrl = str_replace('/item/', '/item/trailers/', $this->directUrl); - $trailersResponse = $this->fetchHtml($trailersUrl, $this->cookie); - - if ($trailersResponse !== false) { - if (preg_match("/([\"|'])(?P[^\"']+.swf)([\"|'])/i", $trailersResponse, $hits)) { - $res['trailers']['url'] = self::BASE_URL.trim(trim($hits['swf']), '"'); - - if (preg_match('#(?:streamID:\s\")(?P[0-9A-Z]+)(?:\")#', $trailersResponse, $hits)) { - $res['trailers']['streamid'] = trim($hits['streamid']); - } - - if (preg_match('#(?:BaseStreamingUrl:\s\")(?P[\d]+\.[\d]+\.[\d]+\.[\d]+)(?:\")#', $trailersResponse, $hits)) { - $res['trailers']['baseurl'] = $hits['baseurl']; - } - } - } - - return $res; - } - - /** - * @return array - */ - protected function extractCovers(): array - { - $res = []; - - // Try multiple selectors for better reliability - $selectors = [ - 'div#Boxcover img[itemprop=image]', - 'img[itemprop=image]', - 'div#Boxcover img', - 'div.boxcover img', - ]; - - foreach ($selectors as $selector) { - $ret = $this->getHtmlParser()->findOne($selector); - if ($ret && isset($ret->src)) { // @phpstan-ignore booleanAnd.leftAlwaysTrue - // Get high-resolution covers - $res['boxcover'] = preg_replace('/[ms]\.jpg$/', 'h.jpg', $ret->src); - $res['backcover'] = preg_replace('/[ms]\.jpg$/', 'bh.jpg', $ret->src); - - return $res; - } - } - - return $res; - } - - /** - * @return array - */ - protected function extractSynopsis(): array - { - $res = []; - - // Try multiple selectors in priority order - $selectors = [ - 'meta[property="og:description"]' => 'content', - 'meta[name="description"]' => 'content', - 'div[itemprop="description"]' => 'plaintext', - 'p.synopsis' => 'plaintext', - ]; - - foreach ($selectors as $selector => $property) { - $meta = $this->getHtmlParser()->findOne($selector); - if ($meta && isset($meta->$property) && $meta->$property !== false && ! empty(trim($meta->$property))) { // @phpstan-ignore booleanAnd.leftAlwaysTrue - $res['synopsis'] = trim($meta->$property); - - return $res; - } - } - - return $res; - } - - /** - * @return array - */ - protected function extractCast(): array - { - $res = []; - $cast = []; - - // Try multiple selector strategies - $selectors = [ - 'div[itemprop="actor"] span[itemprop="name"]', - 'div.performer-list a', - 'a[href*="/performer/"]', - ]; - - foreach ($selectors as $selector) { - $elements = $this->getHtmlParser()->find($selector); - if (! empty($elements)) { - foreach ($elements as $a) { - if ($a->plaintext !== false && ! empty(trim($a->plaintext))) { - $cast[] = trim($a->plaintext); - } - } - - if (! empty($cast)) { - break; - } - } - } - - $res['cast'] = array_values(array_unique($cast)); - - return $res; - } - - /** - * @return array - */ - protected function extractGenres(): array - { - $res = []; - $genres = []; - - // Try multiple selector strategies - $selectors = [ - 'a[Label="Category"]', - 'div.categories a', - 'a[href*="/category/"]', - 'span[itemprop="genre"]', - ]; - - foreach ($selectors as $selector) { - $elements = $this->getHtmlParser()->find($selector); - if (! empty($elements)) { - foreach ($elements as $a) { - if ($a->plaintext !== false && ! empty(trim($a->plaintext))) { - $genres[] = trim($a->plaintext); - } - } - - if (! empty($genres)) { - break; - } - } - } - - $res['genres'] = array_values(array_unique($genres)); - - return $res; - } - - /** - * @return array - */ - protected function extractProductInfo(bool $extras = false): array - { - $res = []; - $dofeature = null; - - $tmpResponse = str_ireplace('Section ProductInfo', 'spdinfo', $this->response); - $tmpHtml = new \voku\helper\HtmlDomParser; - $tmpHtml->loadHtml($tmpResponse); - - if ($ret = $tmpHtml->findOne('div[class=spdinfo]')) { // @phpstan-ignore if.alwaysTrue - $productinfo = []; - $extrasData = []; - - $tmpResponse = trim($ret->outertext); - $ret = $tmpHtml->loadHtml($tmpResponse); - - foreach ($ret->find('text') as $strong) { - if (trim($strong->innertext) === 'Features') { - $dofeature = true; - } - if ($dofeature !== true) { - if (trim($strong->innertext) !== ' ') { - $productinfo[] = trim($strong->innertext); - } - } else { - if ($extras === true) { - $extrasData[] = trim($strong->innertext); - } - } - } - - array_shift($productinfo); - array_shift($productinfo); - $res['productinfo'] = array_chunk($productinfo, 2, false); - - if (! empty($extrasData)) { - $res['extras'] = $extrasData; - } - } - - return $res; - } - - /** - * Initialize session by visiting the site to establish cookies. - * ADE uses JavaScript-based age verification with cookies. - */ - protected function initializeSession(): void - { - try { - $client = $this->getHttpClient(); - - // Visit the homepage first to establish a session - $client->get(self::BASE_URL, [ - 'headers' => $this->getDefaultHeaders(), - 'allow_redirects' => true, - ]); - - usleep(300000); // 300ms delay - - } catch (\Exception $e) { - \Illuminate\Support\Facades\Log::debug('ADE session initialization: '.$e->getMessage()); - } - } -} diff --git a/app/Services/AdultProcessing/Pipes/AdmPipe.php b/app/Services/AdultProcessing/Pipes/AdmPipe.php deleted file mode 100644 index bfc07ed0f..000000000 --- a/app/Services/AdultProcessing/Pipes/AdmPipe.php +++ /dev/null @@ -1,299 +0,0 @@ -getCleanTitle(); - - $searchResult = $this->search($movie); - - if ($searchResult === false) { - $this->outputNotFound(); - - return AdultProcessingResult::notFound($this->getName()); - } - - $this->title = $searchResult['title']; - $this->directUrl = $searchResult['url']; - - // Fetch the movie details page - $this->response = $this->fetchHtml($this->directUrl, $this->cookie); - - if ($this->response === false) { // @phpstan-ignore identical.alwaysFalse - return AdultProcessingResult::failed('Failed to fetch movie details page', $this->getName()); - } - - $this->getHtmlParser()->loadHtml($this->response); - - $movieInfo = $this->getMovieInfo(); - - if ($movieInfo === false) { - return AdultProcessingResult::notFound($this->getName()); - } - - $this->outputMatch($this->title); - - return AdultProcessingResult::matched( - $this->title, - $this->getName(), - $movieInfo - ); - } - - /** - * @return array - */ - protected function search(string $movie): array|false - { - if (empty($movie)) { - return false; - } - - $searchUrl = self::BASE_URL.self::SEARCH_URL.urlencode($movie); - $response = $this->fetchHtml($searchUrl, $this->cookie); - - if ($response === false) { - return false; - } - - $this->getHtmlParser()->loadHtml($response); - $check = $this->getHtmlParser()->find('img[rel=license]'); - - if (empty($check)) { - return false; - } - - $bestMatch = null; - $highestSimilarity = 0; - - foreach ($check as $ret) { - if (! isset($ret->alt) || ! isset($ret->src)) { - continue; - } - - $title = trim($ret->alt, '"'); - $title = str_replace('/XXX/', '', $title); - - $similarity = $this->calculateSimilarity($movie, $title); - - if ($similarity > $highestSimilarity && preg_match('/\/(?\d+)\.jpg$/i', $ret->src, $hits)) { - $highestSimilarity = $similarity; - $bestMatch = [ - 'title' => trim($title), - 'sku' => $hits['sku'], - ]; - } - } - - if ($bestMatch !== null && $highestSimilarity >= $this->minimumSimilarity) { - return [ - 'title' => $bestMatch['title'], - 'url' => self::BASE_URL.'/dvd_view_'.$bestMatch['sku'].'.html', - ]; - } - - return false; - } - - /** - * @return array - */ - protected function getMovieInfo(): array|false - { - $results = []; - - if (! empty($this->directUrl)) { - if (! empty($this->title)) { - $results['title'] = $this->title; - } - $results['directurl'] = $this->directUrl; - } - - // Get all the movie data - $results = array_merge($results, $this->extractSynopsis()); - $results = array_merge($results, $this->extractProductInfo(true)); - $results = array_merge($results, $this->extractCast()); - $results = array_merge($results, $this->extractGenres()); - $results = array_merge($results, $this->extractCovers()); - - if (empty($results)) { - return false; - } - - return $results; - } - - /** - * @return array - */ - protected function extractCovers(): array - { - $res = []; - $baseUrl = 'https://www.adultdvdmarketplace.com/'; - - // Try fancybox link first - if ($ret = $this->getHtmlParser()->findOne('a[rel=fancybox-button]')) { // @phpstan-ignore if.alwaysTrue - if (isset($ret->href) && preg_match('/images\/.*[\d]+\.jpg$/i', $ret->href, $hits)) { - $res['boxcover'] = str_starts_with($hits[0], 'http') - ? $hits[0] - : $baseUrl.$hits[0]; - $res['backcover'] = str_ireplace('/front/', '/back/', $res['boxcover']); - - return $res; - } - } - - // Try license image - if ($ret = $this->getHtmlParser()->findOne('img[rel=license]')) { // @phpstan-ignore if.alwaysTrue - if (isset($ret->src) && preg_match('/images\/.*[\d]+\.jpg$/i', $ret->src, $hits)) { - $res['boxcover'] = str_starts_with($hits[0], 'http') - ? $hits[0] - : $baseUrl.$hits[0]; - - return $res; - } - } - - return $res; - } - - /** - * @return array - */ - protected function extractSynopsis(): array - { - $res = []; - $res['synopsis'] = 'N/A'; - - // Try to find Description heading - foreach ($this->getHtmlParser()->find('h3') as $heading) { - if (trim($heading->plaintext) === 'Description') { - $nextElement = $heading->next_sibling(); - if ($nextElement && ! empty(trim($nextElement->plaintext))) { - $res['synopsis'] = trim($nextElement->plaintext); - - return $res; - } - } - } - - // Fallback: Try meta description - $meta = $this->getHtmlParser()->findOne('meta[name="description"]'); - if ($meta && isset($meta->content) && ! empty(trim($meta->content))) { // @phpstan-ignore booleanAnd.leftAlwaysTrue - $res['synopsis'] = trim($meta->content); - } - - return $res; - } - - /** - * @return array - */ - protected function extractProductInfo(bool $extras = false): array - { - $res = []; - - foreach ($this->getHtmlParser()->find('ul.list-unstyled li') as $li) { - $category = explode(':', $li->plaintext); - switch (trim($category[0])) { - case 'Director': - $res['director'] = trim($category[1]); - break; - case 'Format': - case 'Studio': - case 'Released': - case 'SKU': - $res['productinfo'][trim($category[0])] = trim($category[1]); - } - } - - return $res; - } - - /** - * @return array - */ - protected function extractCast(): array - { - $res = []; - $cast = []; - - foreach ($this->getHtmlParser()->find('h3') as $heading) { - if (trim($heading->plaintext) === 'Cast') { - $next = $heading->nextSibling(); - while ($next) { - if ($next->nodeName === 'h3') { // @phpstan-ignore property.notFound - break; - } - if (isset($next->href) && preg_match('/search_performerid/', $next->href)) { - $cast[] = trim($next->plaintext); - } - $next = $next->nextSibling(); - } - } - } - - $res['cast'] = array_unique($cast); - - return $res; - } - - /** - * @return array - */ - protected function extractGenres(): array - { - $res = []; - $genres = []; - - foreach ($this->getHtmlParser()->find('ul.list-unstyled') as $li) { - $category = explode(':', $li->plaintext); - if (trim($category[0]) === 'Category') { - foreach (explode(',', $category[1]) as $genre) { - $genres[] = trim($genre); - } - $res['genres'] = $genres; - } - } - - return $res; - } -} diff --git a/app/Services/AdultProcessing/Pipes/AebnPipe.php b/app/Services/AdultProcessing/Pipes/AebnPipe.php deleted file mode 100644 index 52faf4495..000000000 --- a/app/Services/AdultProcessing/Pipes/AebnPipe.php +++ /dev/null @@ -1,576 +0,0 @@ - - */ - protected array $res = []; - - protected string $response = ''; - - /** - * @var array - */ - protected ?array $jsonLdData = null; - - public function getName(): string - { - return 'aebn'; - } - - public function getDisplayName(): string - { - return 'Adult Entertainment Broadcast Network'; - } - - protected function getBaseUrl(): string - { - return self::BASE_URL; - } - - protected function process(AdultProcessingPassable $passable): AdultProcessingResult - { - $movie = $passable->getCleanTitle(); - - // Check cache first - $cached = $this->getCachedSearch($movie); - if ($cached !== null) { - if ($cached === false) { - return AdultProcessingResult::notFound($this->getName()); - } - - return AdultProcessingResult::matched( - $cached['title'] ?? $movie, - $this->getName(), - $cached - ); - } - - $searchResult = $this->search($movie); - - if ($searchResult === false) { - $this->cacheSearchResult($movie, false); - $this->outputNotFound(); - - return AdultProcessingResult::notFound($this->getName()); - } - - $this->title = $searchResult['title']; - $this->directUrl = $searchResult['url']; - - // Fetch the movie details page - $this->response = $this->fetchHtml($this->directUrl, $this->cookie); - - if ($this->response === false) { // @phpstan-ignore identical.alwaysFalse - return AdultProcessingResult::failed('Failed to fetch movie details page', $this->getName()); - } - - // Try to extract JSON-LD data first - $this->jsonLdData = $this->extractJsonLd($this->response); - - $this->getHtmlParser()->loadHtml($this->response); - - $movieInfo = $this->getMovieInfo(); - - if ($movieInfo === false) { - $this->cacheSearchResult($movie, false); - - return AdultProcessingResult::notFound($this->getName()); - } - - // Cache the successful result - $this->cacheSearchResult($movie, $movieInfo); - - $this->outputMatch($this->title); - - return AdultProcessingResult::matched( - $this->title, - $this->getName(), - $movieInfo - ); - } - - /** - * @return array - */ - protected function search(string $movie): array|false - { - if (empty($movie)) { - return false; - } - - $searchUrl = self::BASE_URL.self::SEARCH_URL.urlencode($movie); - $response = $this->fetchHtml($searchUrl, $this->cookie); - - if ($response === false) { - return false; - } - - $this->getHtmlParser()->loadHtml($response); - - $bestMatch = null; - $highestSimilarity = 0; - $i = 1; - - // Try multiple container selectors for search results - $containerSelectors = [ - 'div.movie', - 'div.search-result', - 'div[class*="movie"]', - 'article.movie', - ]; - - $movies = []; - foreach ($containerSelectors as $containerSelector) { - $movies = $this->getHtmlParser()->find($containerSelector); - if (! empty($movies) && (is_countable($movies) ? count($movies) > 0 : true)) { - break; - } - } - - foreach ($movies as $mov) { - // Try multiple selector patterns for the title link - $selectors = [ - 'a#FTSMovieSearch_link_title_detail_'.$i, - 'a.title-link', - 'a[href*="/movie/"]', - 'h3 a', - 'a[title]', - ]; - - $ret = null; - foreach ($selectors as $selector) { - $ret = $mov->findOne($selector); - if ($ret && isset($ret->href)) { - break; - } - } - - if ($ret && isset($ret->href)) { - $title = $ret->title ?? trim($ret->plaintext ?? ''); - - if (! empty($title)) { - $similarity = $this->calculateSimilarity($movie, $title); - - if ($similarity > $highestSimilarity) { - $highestSimilarity = $similarity; - $bestMatch = [ - 'title' => trim($title), - 'url' => self::BASE_URL.html_entity_decode($ret->href), - 'similarity' => $similarity, - ]; - } - } - } - $i++; - } - - if ($bestMatch !== null && $highestSimilarity >= $this->minimumSimilarity) { - return $bestMatch; - } - - return false; - } - - /** - * @return array - */ - protected function getMovieInfo(): array|false - { - $results = []; - - if (! empty($this->directUrl)) { - if (! empty($this->title)) { - $results['title'] = $this->title; - } - $results['directurl'] = $this->directUrl; - } - - // Try to get data from JSON-LD first (most reliable) - if ($this->jsonLdData !== null) { - $results = array_merge($results, $this->extractFromJsonLd()); - } - - // Get all the movie data (HTML fallback) - $synopsis = $this->extractSynopsis(); - if (! empty($synopsis)) { - $results = array_merge($results, $synopsis); - } - - $productInfo = $this->extractProductInfo(true); - if (! empty($productInfo)) { - $results = array_merge($results, $productInfo); - } - - $cast = $this->extractCast(); - if (! empty($cast)) { - $results = array_merge($results, $cast); - } - - $genres = $this->extractGenres(); - if (! empty($genres)) { - $results = array_merge($results, $genres); - } - - $covers = $this->extractCovers(); - if (! empty($covers)) { - $results = array_merge($results, $covers); - } - - $trailers = $this->extractTrailers(); - if (! empty($trailers)) { - $results = array_merge($results, $trailers); - } - - if (empty($results) || (empty($results['title'] ?? '') && empty($results['boxcover'] ?? ''))) { - return false; - } - - return $results; - } - - /** - * Extract data from JSON-LD structured data. - * - * @return array - */ - protected function extractFromJsonLd(): array - { - $results = []; - - if ($this->jsonLdData === null) { - return $results; - } - - // Title - if (! empty($this->jsonLdData['name'])) { - $results['title'] = $this->jsonLdData['name']; - } - - // Synopsis/Description - if (! empty($this->jsonLdData['description'])) { - $results['synopsis'] = $this->jsonLdData['description']; - } - - // Image/Cover - if (! empty($this->jsonLdData['image'])) { - $image = is_array($this->jsonLdData['image']) ? ($this->jsonLdData['image'][0] ?? '') : $this->jsonLdData['image']; - if (! empty($image)) { - $results['boxcover'] = $image; - $results['backcover'] = str_ireplace(['xlf.jpg', 'front'], ['xlb.jpg', 'back'], $image); - } - } - - // Duration - if (! empty($this->jsonLdData['duration'])) { - $results['duration'] = $this->jsonLdData['duration']; - } - - // Director - if (! empty($this->jsonLdData['director'])) { - $director = $this->jsonLdData['director']; - if (is_array($director)) { - $results['director'] = $director['name'] ?? ($director[0]['name'] ?? ''); - } else { - $results['director'] = $director; - } - } - - // Actors - if (! empty($this->jsonLdData['actor'])) { - $actors = $this->jsonLdData['actor']; - $cast = []; - if (is_array($actors)) { - foreach ($actors as $actor) { - if (is_array($actor) && ! empty($actor['name'])) { - $cast[] = $actor['name']; - } elseif (is_string($actor)) { - $cast[] = $actor; - } - } - } - if (! empty($cast)) { - $results['cast'] = $cast; - } - } - - // Genre - if (! empty($this->jsonLdData['genre'])) { - $genres = $this->jsonLdData['genre']; - if (is_array($genres)) { - $results['genres'] = $genres; - } else { - $results['genres'] = [$genres]; - } - } - - return $results; - } - - /** - * @return array - */ - protected function extractTrailers(): array - { - $res = []; - - // Try multiple selectors - $selectors = [ - 'a[itemprop=trailer]', - 'a[href*="previewPlayer"]', - 'a.trailer-link', - ]; - - foreach ($selectors as $selector) { - $ret = $this->getHtmlParser()->find($selector, 0); - if ($ret && isset($ret->href) && preg_match('/movieId=(?\d+)/', trim($ret->href), $hits)) { - $movieid = $hits['movieid']; - $res['trailers']['url'] = self::BASE_URL.self::TRAILER_URL.$movieid; - - return $res; - } - } - - return $res; - } - - /** - * @return array - */ - protected function extractCovers(): array - { - $res = []; - - // Try multiple selectors - $selectors = [ - 'img[itemprop=thumbnailUrl]', - 'img[itemprop=image]', - 'div#md-boxCover img', - 'div.boxcover img', - 'img.boxcover', - 'img[src*="boxcover"]', - 'meta[property="og:image"]', - ]; - - foreach ($selectors as $selector) { - $ret = $this->getHtmlParser()->findOne($selector); - if ($ret) { // @phpstan-ignore if.alwaysTrue - $coverUrl = $ret->src ?? $ret->content ?? null; - - if (! empty($coverUrl)) { - // Ensure URL has protocol - if (str_starts_with($coverUrl, '//')) { - $coverUrl = 'https:'.$coverUrl; - } - - // Get high-resolution versions - $res['boxcover'] = str_ireplace(['160w.jpg', '120w.jpg', '_small', '_thumb'], ['xlf.jpg', 'xlf.jpg', '', ''], $coverUrl); - $res['backcover'] = str_ireplace(['160w.jpg', '120w.jpg', 'xlf.jpg', 'front'], ['xlb.jpg', 'xlb.jpg', 'xlb.jpg', 'back'], $res['boxcover']); - - return $res; - } - } - } - - return $res; - } - - /** - * @return array - */ - protected function extractGenres(): array - { - $res = []; - $genres = []; - - // Try multiple selectors - $selectors = [ - 'div.md-detailsCategories a[itemprop=genre]', - 'a[itemprop=genre]', - 'span[itemprop=genre]', - 'div.categories a', - 'a[href*="/category/"]', - ]; - - foreach ($selectors as $selector) { - $elements = $this->getHtmlParser()->find($selector); - if (! empty($elements)) { - foreach ($elements as $genre) { - $text = trim($genre->plaintext ?? ''); - if (! empty($text)) { - $genres[] = $text; - } - } - if (! empty($genres)) { - break; - } - } - } - - if (! empty($genres)) { - $res['genres'] = array_unique($genres); - } - - return $res; - } - - /** - * @return array - */ - protected function extractCast(): array - { - $res = []; - $cast = []; - - // Try multiple selectors - $selectors = [ - 'div.starsFull span[itemprop=name]', - 'span[itemprop=name]', - 'a[href*="/stars/"]', - 'div.cast a', - 'div.performers a', - ]; - - foreach ($selectors as $selector) { - $elements = $this->getHtmlParser()->find($selector); - if (! empty($elements)) { - foreach ($elements as $star) { - $text = trim($star->plaintext ?? ''); - if (! empty($text) && strlen($text) > 2) { - $cast[] = $text; - } - } - if (! empty($cast)) { - break; - } - } - } - - // Fallback: try detailsLink div - if (empty($cast)) { - $ret = $this->getHtmlParser()->findOne('div.detailsLink'); - if ($ret && ! ($ret instanceof \voku\helper\SimpleHtmlDomNodeBlank)) { // @phpstan-ignore booleanAnd.leftAlwaysTrue - foreach ($ret->find('span') as $star) { - $text = $star->plaintext ?? ''; - if (str_contains($text, '/More/') && str_contains($text, '/Stars/')) { - $cast[] = trim($text); - } - } - } - } - - if (! empty($cast)) { - $res['cast'] = array_unique($cast); - } - - return $res; - } - - /** - * @return array - */ - protected function extractProductInfo(bool $extras = false): array - { - $res = []; - - // Try multiple selectors - $selectors = [ - 'div#md-detailsLeft', - 'div.movie-details', - 'div.product-info', - ]; - - foreach ($selectors as $selector) { - $ret = $this->getHtmlParser()->find($selector, 0); - if ($ret) { - $productinfo = []; - foreach ($ret->find('div') as $div) { - foreach ($div->find('span') as $span) { - $text = rawurldecode($span->plaintext ?? ''); - $text = preg_replace('/ /', '', $text); - $text = trim($text); - if (! empty($text)) { - $productinfo[] = $text; - } - } - } - - if (! empty($productinfo)) { - if (false !== $key = array_search('Running Time:', $productinfo, false)) { - unset($productinfo[$key + 2]); - } - - if (false !== $key = array_search('Director:', $productinfo, false)) { - $res['director'] = $productinfo[$key + 1] ?? ''; - unset($productinfo[$key], $productinfo[$key + 1]); - } - - $res['productinfo'] = array_chunk(array_values($productinfo), 2, false); - break; - } - } - } - - return $res; - } - - /** - * @return array - */ - protected function extractSynopsis(): array - { - $res = []; - - // Try multiple selectors in order of preference - $selectors = [ - 'span[itemprop=about]', - 'span[itemprop=description]', - 'div[itemprop=description]', - 'div.movieDetailDescription', - 'div.synopsis', - 'p.description', - 'meta[name="description"]', - 'meta[property="og:description"]', - ]; - - foreach ($selectors as $selector) { - $ret = $this->getHtmlParser()->findOne($selector); - if ($ret) { // @phpstan-ignore if.alwaysTrue - $text = $ret->plaintext ?? $ret->content ?? ''; - if (! empty(trim($text))) { - $text = trim($text); - $text = preg_replace('/^Description:\s*/i', '', $text); - $res['synopsis'] = $text; - - return $res; - } - } - } - - return $res; - } -} diff --git a/app/Services/AdultProcessing/Pipes/Data18Pipe.php b/app/Services/AdultProcessing/Pipes/Data18Pipe.php deleted file mode 100644 index 40b464ec6..000000000 --- a/app/Services/AdultProcessing/Pipes/Data18Pipe.php +++ /dev/null @@ -1,525 +0,0 @@ - - */ - protected ?array $jsonLdData = null; - - public function getName(): string - { - return 'data18'; - } - - public function getDisplayName(): string - { - return 'Data18'; - } - - protected function getBaseUrl(): string - { - return self::BASE_URL; - } - - protected function process(AdultProcessingPassable $passable): AdultProcessingResult - { - $movie = $passable->getCleanTitle(); - - // Check cache first - $cached = $this->getCachedSearch($movie); - if ($cached !== null) { - if ($cached === false) { - return AdultProcessingResult::notFound($this->getName()); - } - - return AdultProcessingResult::matched( - $cached['title'] ?? $movie, - $this->getName(), - $cached - ); - } - - $searchResult = $this->search($movie); - - if ($searchResult === false) { - $this->cacheSearchResult($movie, false); - $this->outputNotFound(); - - return AdultProcessingResult::notFound($this->getName()); - } - - $this->title = $searchResult['title']; - $this->directUrl = $searchResult['url']; - - // Fetch the movie details page - $this->response = $this->fetchHtml($this->directUrl, $this->cookie); - - if ($this->response === false) { // @phpstan-ignore identical.alwaysFalse - return AdultProcessingResult::failed('Failed to fetch movie details page', $this->getName()); - } - - // Try to extract JSON-LD data first - $this->jsonLdData = $this->extractJsonLd($this->response); - - $this->getHtmlParser()->loadHtml($this->response); - - $movieInfo = $this->getMovieInfo(); - - if ($movieInfo === false) { - $this->cacheSearchResult($movie, false); - - return AdultProcessingResult::notFound($this->getName()); - } - - // Cache the successful result - $this->cacheSearchResult($movie, $movieInfo); - - $this->outputMatch($this->title); - - return AdultProcessingResult::matched( - $this->title, - $this->getName(), - $movieInfo - ); - } - - /** - * @return array - */ - protected function search(string $movie): array|false - { - if (empty($movie)) { - return false; - } - - $searchUrl = self::BASE_URL.self::SEARCH_URL.urlencode($movie); - $response = $this->fetchHtml($searchUrl, $this->cookie); - - if ($response === false) { - return false; - } - - $this->getHtmlParser()->loadHtml($response); - - $bestMatch = null; - $highestSimilarity = 0; - - // Try multiple container selectors for search results - $containerSelectors = [ - 'div.gen12', - 'div.movie-card', - 'div[class*="result"]', - 'a[href*="/movies/"]', - ]; - - foreach ($containerSelectors as $containerSelector) { - $results = $this->getHtmlParser()->find($containerSelector); - - if (! empty($results)) { - foreach ($results as $result) { - $link = null; - $title = ''; - - // If the container is a link itself - if (isset($result->href) && str_contains($result->href, '/movies/')) { - $link = $result; - $title = $result->title ?? trim($result->plaintext ?? ''); - } else { - // Find link within container - $link = $result->findOne('a[href*="/movies/"]'); - if ($link) { - $title = $link->title ?? trim($link->plaintext ?? ''); - } - } - - if ($link && isset($link->href) && ! empty($title)) { - $similarity = $this->calculateSimilarity($movie, $title); - - if ($similarity > $highestSimilarity) { - $highestSimilarity = $similarity; - $url = $link->href; - if (! str_starts_with($url, 'http')) { - $url = self::BASE_URL.$url; - } - $bestMatch = [ - 'title' => trim($title), - 'url' => $url, - 'similarity' => $similarity, - ]; - } - } - } - - if ($bestMatch !== null) { - break; - } - } - } - - if ($bestMatch !== null && $highestSimilarity >= $this->minimumSimilarity) { - return $bestMatch; - } - - return false; - } - - /** - * @return array - */ - protected function getMovieInfo(): array|false - { - $results = []; - - if (! empty($this->directUrl)) { - if (! empty($this->title)) { - $results['title'] = $this->title; - } - $results['directurl'] = $this->directUrl; - } - - // Try to get data from JSON-LD first (most reliable) - if ($this->jsonLdData !== null) { - $results = array_merge($results, $this->extractFromJsonLd()); - } - - // Get all the movie data (HTML fallback) - $synopsis = $this->extractSynopsis(); - if (! empty($synopsis)) { - $results = array_merge($results, $synopsis); - } - - $productInfo = $this->extractProductInfo(true); - if (! empty($productInfo)) { - $results = array_merge($results, $productInfo); - } - - $cast = $this->extractCast(); - if (! empty($cast)) { - $results = array_merge($results, $cast); - } - - $genres = $this->extractGenres(); - if (! empty($genres)) { - $results = array_merge($results, $genres); - } - - $covers = $this->extractCovers(); - if (! empty($covers)) { - $results = array_merge($results, $covers); - } - - if (empty($results) || (empty($results['title'] ?? '') && empty($results['boxcover'] ?? ''))) { - return false; - } - - return $results; - } - - /** - * Extract data from JSON-LD structured data. - * - * @return array - */ - protected function extractFromJsonLd(): array - { - $results = []; - - if ($this->jsonLdData === null) { - return $results; - } - - // Title - if (! empty($this->jsonLdData['name'])) { - $results['title'] = $this->jsonLdData['name']; - } - - // Synopsis/Description - if (! empty($this->jsonLdData['description'])) { - $results['synopsis'] = $this->jsonLdData['description']; - } - - // Image/Cover - if (! empty($this->jsonLdData['image'])) { - $image = is_array($this->jsonLdData['image']) ? ($this->jsonLdData['image'][0] ?? '') : $this->jsonLdData['image']; - if (! empty($image)) { - $results['boxcover'] = $image; - } - } - - // Duration - if (! empty($this->jsonLdData['duration'])) { - $results['duration'] = $this->jsonLdData['duration']; - } - - // Director - if (! empty($this->jsonLdData['director'])) { - $director = $this->jsonLdData['director']; - if (is_array($director)) { - $results['director'] = $director['name'] ?? ($director[0]['name'] ?? ''); - } else { - $results['director'] = $director; - } - } - - // Actors - if (! empty($this->jsonLdData['actor'])) { - $actors = $this->jsonLdData['actor']; - $cast = []; - if (is_array($actors)) { - foreach ($actors as $actor) { - if (is_array($actor) && ! empty($actor['name'])) { - $cast[] = $actor['name']; - } elseif (is_string($actor)) { - $cast[] = $actor; - } - } - } - if (! empty($cast)) { - $results['cast'] = $cast; - } - } - - // Genre - if (! empty($this->jsonLdData['genre'])) { - $genres = $this->jsonLdData['genre']; - if (is_array($genres)) { - $results['genres'] = $genres; - } else { - $results['genres'] = [$genres]; - } - } - - return $results; - } - - /** - * @return array - */ - protected function extractCovers(): array - { - $res = []; - - // Try multiple selectors - $selectors = [ - 'img[itemprop=image]', - 'img.cover', - 'img[src*="cover"]', - 'div.cover img', - 'a.cover img', - 'meta[property="og:image"]', - ]; - - foreach ($selectors as $selector) { - $ret = $this->getHtmlParser()->findOne($selector); - if ($ret) { // @phpstan-ignore if.alwaysTrue - $coverUrl = $ret->src ?? $ret->content ?? null; - - if (! empty($coverUrl)) { - if (str_starts_with($coverUrl, '//')) { - $coverUrl = 'https:'.$coverUrl; - } elseif (! str_starts_with($coverUrl, 'http')) { - $coverUrl = self::BASE_URL.'/'.ltrim($coverUrl, '/'); - } - - $res['boxcover'] = $coverUrl; - - // Try to find back cover - $backCover = str_replace(['front', '_f.', '_1.'], ['back', '_b.', '_2.'], $coverUrl); - if ($backCover !== $coverUrl) { - $res['backcover'] = $backCover; - } - - return $res; - } - } - } - - return $res; - } - - /** - * @return array - */ - protected function extractSynopsis(): array - { - $res = []; - - $selectors = [ - 'div[itemprop=description]', - 'span[itemprop=description]', - 'div.synopsis', - 'div.description', - 'p.synopsis', - 'meta[name="description"]', - 'meta[property="og:description"]', - ]; - - foreach ($selectors as $selector) { - $ret = $this->getHtmlParser()->findOne($selector); - if ($ret) { // @phpstan-ignore if.alwaysTrue - $text = $ret->plaintext ?? $ret->content ?? ''; - if (! empty(trim($text))) { - $res['synopsis'] = trim($text); - - return $res; - } - } - } - - return $res; - } - - /** - * @return array - */ - protected function extractCast(): array - { - $res = []; - $cast = []; - - $selectors = [ - 'a[href*="/name/"]', - 'a[href*="/pornstars/"]', - 'span[itemprop=actor] a', - 'div.cast a', - 'div.performers a', - ]; - - foreach ($selectors as $selector) { - $elements = $this->getHtmlParser()->find($selector); - if (! empty($elements)) { - foreach ($elements as $element) { - $name = trim($element->plaintext ?? ''); - if (! empty($name) && strlen($name) > 2) { - $cast[] = $name; - } - } - if (! empty($cast)) { - break; - } - } - } - - if (! empty($cast)) { - $res['cast'] = array_unique($cast); - } - - return $res; - } - - /** - * @return array - */ - protected function extractGenres(): array - { - $res = []; - $genres = []; - - $selectors = [ - 'a[href*="/category/"]', - 'a[href*="/genre/"]', - 'span[itemprop=genre]', - 'div.categories a', - 'div.tags a', - ]; - - foreach ($selectors as $selector) { - $elements = $this->getHtmlParser()->find($selector); - if (! empty($elements)) { - foreach ($elements as $element) { - $text = trim($element->plaintext ?? ''); - if (! empty($text) && strlen($text) > 1) { - $genres[] = $text; - } - } - if (! empty($genres)) { - break; - } - } - } - - if (! empty($genres)) { - $res['genres'] = array_unique($genres); - } - - return $res; - } - - /** - * @return array - */ - protected function extractProductInfo(bool $extras = false): array - { - $res = []; - - // Look for studio - $studioSelectors = [ - 'a[href*="/studio/"]', - 'a[href*="/studios/"]', - 'span.studio a', - ]; - - foreach ($studioSelectors as $selector) { - $studio = $this->getHtmlParser()->findOne($selector); - if ($studio) { // @phpstan-ignore if.alwaysTrue - $res['studio'] = trim($studio->plaintext ?? ''); - break; - } - } - - // Look for release date - $dateSelectors = [ - 'span[itemprop=datePublished]', - 'time[datetime]', - 'span.date', - ]; - - foreach ($dateSelectors as $selector) { - $date = $this->getHtmlParser()->findOne($selector); - if ($date) { // @phpstan-ignore if.alwaysTrue - $res['releasedate'] = $date->datetime ?? trim($date->plaintext ?? ''); - break; - } - } - - // Look for director - $directorSelectors = [ - 'a[href*="/director/"]', - 'span.director a', - ]; - - foreach ($directorSelectors as $selector) { - $director = $this->getHtmlParser()->findOne($selector); - if ($director) { // @phpstan-ignore if.alwaysTrue - $res['director'] = trim($director->plaintext ?? ''); - break; - } - } - - return $res; - } -} diff --git a/app/Services/AdultProcessing/Pipes/HotmoviesPipe.php b/app/Services/AdultProcessing/Pipes/HotmoviesPipe.php deleted file mode 100644 index 8a4059d09..000000000 --- a/app/Services/AdultProcessing/Pipes/HotmoviesPipe.php +++ /dev/null @@ -1,364 +0,0 @@ -getCleanTitle(); - - $searchResult = $this->search($movie); - - if ($searchResult === false) { - $this->outputNotFound(); - - return AdultProcessingResult::notFound($this->getName()); - } - - $this->title = $searchResult['title']; - $this->directUrl = $searchResult['url']; - - // Fetch the movie details page - $this->response = $this->fetchHtml($this->directUrl, $this->cookie); - - if ($this->response === false) { // @phpstan-ignore identical.alwaysFalse - return AdultProcessingResult::failed('Failed to fetch movie details page', $this->getName()); - } - - $this->getHtmlParser()->loadHtml($this->response); - - $movieInfo = $this->getMovieInfo(); - - if ($movieInfo === false) { - return AdultProcessingResult::notFound($this->getName()); - } - - $this->outputMatch($this->title); - - return AdultProcessingResult::matched( - $this->title, - $this->getName(), - $movieInfo - ); - } - - /** - * @return array - */ - protected function search(string $movie): array|false - { - if (empty($movie)) { - return false; - } - - // Initialize session with age verification - $this->initializeSession(); - - $searchUrl = self::BASE_URL.self::SEARCH_URL.urlencode($movie).self::EXTRA_SEARCH; - $response = $this->fetchHtml($searchUrl, $this->cookie); - - if ($response === false) { - return false; - } - - $this->getHtmlParser()->loadHtml($response); - - // Try multiple result selectors - $resultSelectors = [ - 'h3[class=title] a[title]', - 'h3.title a', - 'div.movie-title a', - ]; - - $bestMatch = null; - $highestSimilarity = 0; - - foreach ($resultSelectors as $selector) { - $elements = $this->getHtmlParser()->find($selector); - if (! empty($elements)) { - foreach ($elements as $ret) { - $title = $ret->title ?? $ret->plaintext ?? ''; - $url = $ret->href ?? ''; - - if (empty($title) || empty($url)) { - continue; - } - - $similarity = $this->calculateSimilarity($movie, $title); - - if ($similarity > $highestSimilarity) { - $highestSimilarity = $similarity; - $bestMatch = [ - 'title' => trim($title), - 'url' => str_starts_with($url, 'http') ? $url : self::BASE_URL.$url, - ]; - } - } - - // If we found results with this selector, don't try others - if ($bestMatch !== null) { - break; - } - } - } - - if ($bestMatch !== null && $highestSimilarity >= $this->minimumSimilarity) { - return $bestMatch; - } - - return false; - } - - /** - * @return array - */ - protected function getMovieInfo(): array|false - { - $results = []; - - if (! empty($this->directUrl)) { - if (! empty($this->title)) { - $results['title'] = $this->title; - } - $results['directurl'] = $this->directUrl; - } - - // Get all the movie data - $results = array_merge($results, $this->extractSynopsis()); - $results = array_merge($results, $this->extractProductInfo(true)); - $results = array_merge($results, $this->extractCast()); - $results = array_merge($results, $this->extractGenres()); - $results = array_merge($results, $this->extractCovers()); - - if (empty($results)) { - return false; - } - - return $results; - } - - /** - * @return array - */ - protected function extractSynopsis(): array - { - $res = []; - $res['synopsis'] = 'N/A'; - - // Try multiple selectors - $selectors = [ - '.video_description', - 'div.description', - 'div.synopsis', - 'meta[name="description"]', - ]; - - foreach ($selectors as $selector) { - $ret = $this->getHtmlParser()->findOne($selector); - if ($ret) { // @phpstan-ignore if.alwaysTrue - $text = $ret->innerText ?? $ret->plaintext ?? $ret->content ?? ''; - if (! empty(trim($text))) { - $res['synopsis'] = trim($text); - - return $res; - } - } - } - - return $res; - } - - /** - * @return array - */ - protected function extractProductInfo(bool $extras = false): array - { - $res = []; - $studio = false; - $director = false; - - if (($ret = $this->getHtmlParser()->find('div.page_video_info')) && ! empty($ret->find('text'))) { - $productinfo = []; - - foreach ($ret->find('text') as $e) { - $e = trim($e->plaintext); - $rArray = [',', '...', ' :']; - $e = str_replace($rArray, '', $e); - - if (stripos($e, 'Studio:') !== false) { - $studio = true; - } - - if (str_contains($e, 'Director:')) { - $director = true; - $e = null; - } - - if ($studio === true) { - if ((stripos($e, 'Custodian of Records') === false) && stripos($e, 'Description') === false) { - if ($director === true && ! empty($e)) { - $res['director'] = $e; - $e = null; - $director = false; - } - if (! empty($e)) { - $productinfo[] = $e; - } - } else { - break; - } - } - } - - $res['productinfo'] = array_chunk($productinfo, 2, false); - } - - return $res; - } - - /** - * @return array - */ - protected function extractCast(): array - { - $res = []; - $cast = []; - - // Prefer scoped search within stars container to avoid unrelated links - if ($container = $this->getHtmlParser()->findOne('.stars')) { // @phpstan-ignore if.alwaysTrue - foreach ($container->find('a[title]') as $e) { - $name = trim($e->title); // @phpstan-ignore property.notFound - $name = preg_replace('/\((.*)\)/', '', $name); - $name = trim($name); - if ($name !== '') { - $cast[] = $name; - } - } - } - - // Fallback: anchors that look like performer links - if (empty($cast)) { - foreach ($this->getHtmlParser()->find('a[href*="/performers/"]') as $e) { - $name = trim($e->plaintext); - if ($name !== '') { - $cast[] = $name; - } - } - } - - if (! empty($cast)) { - $res['cast'] = array_values(array_unique($cast)); - } - - return $res; - } - - /** - * @return array - */ - protected function extractGenres(): array - { - $res = []; - $genres = []; - - if ($ret = $this->getHtmlParser()->findOne('div.categories')) { // @phpstan-ignore if.alwaysTrue - foreach ($ret->find('a') as $e) { - if (str_contains($e->title, ' -> ')) { // @phpstan-ignore property.notFound - $e = explode(' -> ', $e->plaintext); - $genres[] = trim($e[1]); - } - } - $res['genres'] = $genres; - } - - return $res; - } - - /** - * @return array - */ - protected function extractCovers(): array - { - $res = []; - - // Try multiple selectors - $selectors = [ - 'img#cover', - 'div#large_cover img', - 'img.boxcover', - 'div.product-image img', - ]; - - foreach ($selectors as $selector) { - $ret = $this->getHtmlParser()->findOne($selector); - if ($ret && isset($ret->src)) { // @phpstan-ignore booleanAnd.leftAlwaysTrue - $res['boxcover'] = trim($ret->src); - $res['backcover'] = str_ireplace(['.cover', 'front'], ['.back', 'back'], trim($ret->src)); - - return $res; - } - } - - return $res; - } - - /** - * Initialize session by visiting the site to establish cookies. - * HotMovies uses cookie-based age verification. - */ - protected function initializeSession(): void - { - try { - $client = $this->getHttpClient(); - - // Visit the homepage first to establish a session - $client->get(self::BASE_URL, [ - 'headers' => $this->getDefaultHeaders(), - 'allow_redirects' => true, - ]); - - usleep(300000); // 300ms delay - - } catch (\Exception $e) { - \Illuminate\Support\Facades\Log::debug('HotMovies session initialization: '.$e->getMessage()); - } - } -} diff --git a/app/Services/AdultProcessing/Pipes/IafdPipe.php b/app/Services/AdultProcessing/Pipes/IafdPipe.php deleted file mode 100644 index 5fb92e5ba..000000000 --- a/app/Services/AdultProcessing/Pipes/IafdPipe.php +++ /dev/null @@ -1,518 +0,0 @@ - - */ - protected ?array $jsonLdData = null; - - public function getName(): string - { - return 'iafd'; - } - - public function getDisplayName(): string - { - return 'Internet Adult Film Database'; - } - - protected function getBaseUrl(): string - { - return self::BASE_URL; - } - - protected function process(AdultProcessingPassable $passable): AdultProcessingResult - { - $movie = $passable->getCleanTitle(); - - // Check cache first - $cached = $this->getCachedSearch($movie); - if ($cached !== null) { - if ($cached === false) { - return AdultProcessingResult::notFound($this->getName()); - } - - return AdultProcessingResult::matched( - $cached['title'] ?? $movie, - $this->getName(), - $cached - ); - } - - $searchResult = $this->search($movie); - - if ($searchResult === false) { - $this->cacheSearchResult($movie, false); - $this->outputNotFound(); - - return AdultProcessingResult::notFound($this->getName()); - } - - $this->title = $searchResult['title']; - $this->directUrl = $searchResult['url']; - - // Fetch the movie details page - $this->response = $this->fetchHtml($this->directUrl, $this->cookie); - - if ($this->response === false) { // @phpstan-ignore identical.alwaysFalse - return AdultProcessingResult::failed('Failed to fetch movie details page', $this->getName()); - } - - // Try to extract JSON-LD data first - $this->jsonLdData = $this->extractJsonLd($this->response); - - $this->getHtmlParser()->loadHtml($this->response); - - $movieInfo = $this->getMovieInfo(); - - if ($movieInfo === false) { - $this->cacheSearchResult($movie, false); - - return AdultProcessingResult::notFound($this->getName()); - } - - // Cache the successful result - $this->cacheSearchResult($movie, $movieInfo); - - $this->outputMatch($this->title); - - return AdultProcessingResult::matched( - $this->title, - $this->getName(), - $movieInfo - ); - } - - /** - * @return array - */ - protected function search(string $movie): array|false - { - if (empty($movie)) { - return false; - } - - $searchUrl = self::BASE_URL.self::SEARCH_URL.urlencode($movie); - $response = $this->fetchHtml($searchUrl, $this->cookie); - - if ($response === false) { - return false; - } - - $this->getHtmlParser()->loadHtml($response); - - $bestMatch = null; - $highestSimilarity = 0; - - // Look for movie results table - $movieResults = $this->getHtmlParser()->find('table#titleresult tr'); - - if (empty($movieResults)) { - // Try alternative selectors - $movieResults = $this->getHtmlParser()->find('div.panel-body a[href*="/title.rme"]'); - } - - foreach ($movieResults as $result) { - $link = null; - $title = ''; - - // Check if this is a table row - if ($result->tag === 'tr') { - $link = $result->findOne('a[href*="/title.rme"]'); - if ($link) { - $title = $link->title ?? trim($link->plaintext ?? ''); - } - } else { - // Direct link element - $link = $result; - $title = $link->title ?? trim($link->plaintext ?? ''); - } - - if ($link && isset($link->href) && ! empty($title)) { - $similarity = $this->calculateSimilarity($movie, $title); - - if ($similarity > $highestSimilarity) { - $highestSimilarity = $similarity; - $url = $link->href; - if (! str_starts_with($url, 'http')) { - $url = self::BASE_URL.'/'.ltrim($url, '/'); - } - $bestMatch = [ - 'title' => trim($title), - 'url' => $url, - 'similarity' => $similarity, - ]; - } - } - } - - if ($bestMatch !== null && $highestSimilarity >= $this->minimumSimilarity) { - return $bestMatch; - } - - return false; - } - - /** - * @return array - */ - protected function getMovieInfo(): array|false - { - $results = []; - - if (! empty($this->directUrl)) { - if (! empty($this->title)) { - $results['title'] = $this->title; - } - $results['directurl'] = $this->directUrl; - } - - // Try to get data from JSON-LD first (most reliable) - if ($this->jsonLdData !== null) { - $results = array_merge($results, $this->extractFromJsonLd()); - } - - // Get all the movie data (HTML fallback) - $synopsis = $this->extractSynopsis(); - if (! empty($synopsis)) { - $results = array_merge($results, $synopsis); - } - - $productInfo = $this->extractProductInfo(true); - if (! empty($productInfo)) { - $results = array_merge($results, $productInfo); - } - - $cast = $this->extractCast(); - if (! empty($cast)) { - $results = array_merge($results, $cast); - } - - $genres = $this->extractGenres(); - if (! empty($genres)) { - $results = array_merge($results, $genres); - } - - $covers = $this->extractCovers(); - if (! empty($covers)) { - $results = array_merge($results, $covers); - } - - if (empty($results) || (empty($results['title'] ?? '') && empty($results['boxcover'] ?? ''))) { - return false; - } - - return $results; - } - - /** - * Extract data from JSON-LD structured data. - * - * @return array - */ - protected function extractFromJsonLd(): array - { - $results = []; - - if ($this->jsonLdData === null) { - return $results; - } - - // Standard JSON-LD extraction - if (! empty($this->jsonLdData['name'])) { - $results['title'] = $this->jsonLdData['name']; - } - - if (! empty($this->jsonLdData['description'])) { - $results['synopsis'] = $this->jsonLdData['description']; - } - - if (! empty($this->jsonLdData['image'])) { - $image = is_array($this->jsonLdData['image']) ? ($this->jsonLdData['image'][0] ?? '') : $this->jsonLdData['image']; - if (! empty($image)) { - $results['boxcover'] = $image; - } - } - - if (! empty($this->jsonLdData['director'])) { - $director = $this->jsonLdData['director']; - if (is_array($director)) { - $results['director'] = $director['name'] ?? ($director[0]['name'] ?? ''); - } else { - $results['director'] = $director; - } - } - - if (! empty($this->jsonLdData['actor'])) { - $actors = $this->jsonLdData['actor']; - $cast = []; - if (is_array($actors)) { - foreach ($actors as $actor) { - if (is_array($actor) && ! empty($actor['name'])) { - $cast[] = $actor['name']; - } elseif (is_string($actor)) { - $cast[] = $actor; - } - } - } - if (! empty($cast)) { - $results['cast'] = $cast; - } - } - - if (! empty($this->jsonLdData['genre'])) { - $genres = $this->jsonLdData['genre']; - if (is_array($genres)) { - $results['genres'] = $genres; - } else { - $results['genres'] = [$genres]; - } - } - - return $results; - } - - /** - * @return array - */ - protected function extractCovers(): array - { - $res = []; - - // IAFD typically uses specific cover image selectors - $selectors = [ - 'div#titlecover img', - 'img#titlecover', - 'div.coverbox img', - 'img[src*="cover"]', - 'meta[property="og:image"]', - ]; - - foreach ($selectors as $selector) { - $ret = $this->getHtmlParser()->findOne($selector); - if ($ret) { // @phpstan-ignore if.alwaysTrue - $coverUrl = $ret->src ?? $ret->content ?? null; - - if (! empty($coverUrl)) { - if (str_starts_with($coverUrl, '//')) { - $coverUrl = 'https:'.$coverUrl; - } elseif (! str_starts_with($coverUrl, 'http')) { - $coverUrl = self::BASE_URL.'/'.ltrim($coverUrl, '/'); - } - - $res['boxcover'] = $coverUrl; - - return $res; - } - } - } - - return $res; - } - - /** - * @return array - */ - protected function extractSynopsis(): array - { - $res = []; - - $selectors = [ - 'div#synopsis', - 'div.synopsis', - 'td.syno', - 'p[class*="synopsis"]', - 'meta[name="description"]', - ]; - - foreach ($selectors as $selector) { - $ret = $this->getHtmlParser()->findOne($selector); - if ($ret) { // @phpstan-ignore if.alwaysTrue - $text = $ret->plaintext ?? $ret->content ?? ''; - if (! empty(trim($text))) { - $res['synopsis'] = trim($text); - - return $res; - } - } - } - - return $res; - } - - /** - * @return array - */ - protected function extractCast(): array - { - $res = []; - $cast = []; - - // IAFD has a specific cast table structure - $castTable = $this->getHtmlParser()->findOne('table#perfcast, div#perfcast'); - - if ($castTable) { // @phpstan-ignore if.alwaysTrue - $performers = $castTable->find('a[href*="/person.rme"]'); - foreach ($performers as $performer) { - $name = trim($performer->plaintext ?? ''); - if (! empty($name) && strlen($name) > 2) { - $cast[] = $name; - } - } - } - - // Fallback to general performer links - if (empty($cast)) { - $selectors = [ - 'a[href*="/person.rme"]', - 'a[href*="/performer/"]', - ]; - - foreach ($selectors as $selector) { - $elements = $this->getHtmlParser()->find($selector); - if (! empty($elements)) { - foreach ($elements as $element) { - $name = trim($element->plaintext ?? ''); - if (! empty($name) && strlen($name) > 2 && ! str_contains(strtolower($name), 'director')) { - $cast[] = $name; - } - } - if (! empty($cast)) { - break; - } - } - } - } - - if (! empty($cast)) { - $res['cast'] = array_unique($cast); - } - - return $res; - } - - /** - * @return array - */ - protected function extractGenres(): array - { - $res = []; - $genres = []; - - $selectors = [ - 'a[href*="/genre.rme"]', - 'div.genres a', - 'span.genre a', - ]; - - foreach ($selectors as $selector) { - $elements = $this->getHtmlParser()->find($selector); - if (! empty($elements)) { - foreach ($elements as $element) { - $text = trim($element->plaintext ?? ''); - if (! empty($text) && strlen($text) > 1) { - $genres[] = $text; - } - } - if (! empty($genres)) { - break; - } - } - } - - if (! empty($genres)) { - $res['genres'] = array_unique($genres); - } - - return $res; - } - - /** - * @return array - */ - protected function extractProductInfo(bool $extras = false): array - { - $res = []; - - // Look for studio - $studio = $this->getHtmlParser()->findOne('a[href*="/studio.rme"]'); - if ($studio) { // @phpstan-ignore if.alwaysTrue - $res['studio'] = trim($studio->plaintext ?? ''); - } - - // Look for distributor - $distributor = $this->getHtmlParser()->findOne('a[href*="/distrib.rme"]'); - if ($distributor) { // @phpstan-ignore if.alwaysTrue - $res['distributor'] = trim($distributor->plaintext ?? ''); - } - - // Look for release year - if (preg_match('/\((\d{4})\)/', $this->response, $yearMatch)) { - $res['year'] = $yearMatch[1]; - } - - // Look for director - $directorSelectors = [ - 'a[href*="/person.rme"][title*="director"]', - 'p:contains("Director") a', - ]; - - foreach ($directorSelectors as $selector) { - $director = $this->getHtmlParser()->findOne($selector); - if ($director) { // @phpstan-ignore if.alwaysTrue - $res['director'] = trim($director->plaintext ?? ''); - break; - } - } - - // Try to extract from info table - $infoRows = $this->getHtmlParser()->find('table.biodata tr, div.biodata p'); - foreach ($infoRows as $row) { - $text = $row->plaintext ?? ''; - if (stripos($text, 'Director:') !== false) { - $parts = explode(':', $text, 2); - if (count($parts) === 2) { - $res['director'] = trim($parts[1]); - } - } - if (stripos($text, 'Studio:') !== false) { - $parts = explode(':', $text, 2); - if (count($parts) === 2 && empty($res['studio'])) { - $res['studio'] = trim($parts[1]); - } - } - if (stripos($text, 'Minutes:') !== false || stripos($text, 'Runtime:') !== false) { - $parts = explode(':', $text, 2); - if (count($parts) === 2) { - $res['runtime'] = trim($parts[1]); - } - } - } - - return $res; - } -} diff --git a/app/Services/AdultProcessing/Pipes/PoppornPipe.php b/app/Services/AdultProcessing/Pipes/PoppornPipe.php deleted file mode 100644 index 2d6fc6253..000000000 --- a/app/Services/AdultProcessing/Pipes/PoppornPipe.php +++ /dev/null @@ -1,534 +0,0 @@ -getCleanTitle(); - - $searchResult = $this->search($movie); - - if ($searchResult === false) { - $this->outputNotFound(); - - return AdultProcessingResult::notFound($this->getName()); - } - - $this->title = $searchResult['title']; - $this->directUrl = $searchResult['url']; - - // Fetch the movie details page - $this->response = $this->fetchHtml($this->directUrl, $this->cookie); - - if ($this->response === false) { // @phpstan-ignore identical.alwaysFalse - return AdultProcessingResult::failed('Failed to fetch movie details page', $this->getName()); - } - - $this->getHtmlParser()->loadHtml($this->response); - - $movieInfo = $this->getMovieInfo(); - - if ($movieInfo === false) { - return AdultProcessingResult::notFound($this->getName()); - } - - $this->outputMatch($this->title); - - return AdultProcessingResult::matched( - $this->title, - $this->getName(), - $movieInfo - ); - } - - /** - * @return array - */ - protected function search(string $movie): array|false - { - if (empty($movie)) { - return false; - } - - // First, establish a session by visiting the AgeConfirmation endpoint to set cookies - $this->acceptAgeVerification(); - - $searchUrl = self::BASE_URL.self::SEARCH_ENDPOINT.urlencode($movie); - $response = $this->fetchHtml($searchUrl, $this->cookie); - - if (empty($response)) { - return false; - } - - $this->getHtmlParser()->loadHtml($response); - - $bestMatch = null; - $highestSimilarity = 0; - - // Try multiple selector patterns for search results - $resultSelectors = [ - 'div.product-info a, div.title a', - 'div.product-title a', - 'h3.product-title a', - ]; - - foreach ($resultSelectors as $selector) { - $results = $this->getHtmlParser()->find($selector); - - if (! empty($results)) { - foreach ($results as $result) { - $title = $result->title ?? $result->plaintext; - $url = $result->href; // @phpstan-ignore property.notFound - - if (! empty($title)) { - $similarity = $this->calculateSimilarity($movie, $title); - - if ($similarity > $highestSimilarity) { - $highestSimilarity = $similarity; - $bestMatch = [ - 'title' => trim($title), - 'url' => str_starts_with($url, 'http') ? $url : self::BASE_URL.$url, - ]; - } - } - } - - break; - } - } - - if ($bestMatch !== null && $highestSimilarity >= $this->minimumSimilarity) { - return $bestMatch; - } - - return false; - } - - /** - * @return array - */ - protected function getMovieInfo(): array|false - { - $results = []; - - if (! empty($this->directUrl)) { - if (! empty($this->title)) { - $results['title'] = $this->title; - } - $results['directurl'] = $this->directUrl; - } - - // Get all the movie data - $results = array_merge($results, $this->extractSynopsis()); - $results = array_merge($results, $this->extractProductInfo(true)); - $results = array_merge($results, $this->extractCast()); - $results = array_merge($results, $this->extractGenres()); - $results = array_merge($results, $this->extractCovers()); - $results = array_merge($results, $this->extractTrailers()); - - if (empty($results)) { - return false; - } - - return $results; - } - - /** - * @return array - */ - protected function extractCovers(): array - { - $res = []; - - // Method 1: Try structured data - if (preg_match('/"image":\s*"(.*?)"/is', $this->response, $match)) { - $res['boxcover'] = trim($match[1]); - // Try to determine backcover from boxcover pattern - if (stripos(trim($match[1]), '_aa') !== false) { - $res['backcover'] = str_ireplace('_aa', '_bb', trim($match[1])); - } else { - $res['backcover'] = str_ireplace('.jpg', '_b.jpg', trim($match[1])); - } - - return $res; - } - - // Method 2: Try multiple selectors - $selectors = [ - 'div[id=box-art], a[rel=box-art]', - 'img.front', - 'div.box-cover img', - 'div.product-image img', - ]; - - foreach ($selectors as $selector) { - if ($ret = $this->getHtmlParser()->findOne($selector)) { // @phpstan-ignore if.alwaysTrue - $res['boxcover'] = $ret->href ?? $ret->src; // @phpstan-ignore property.notFound - - // Try to determine backcover - if (stripos($res['boxcover'], '_aa') !== false) { - $res['backcover'] = str_ireplace('_aa', '_bb', $res['boxcover']); - } else { - $res['backcover'] = str_ireplace('.jpg', '_b.jpg', $res['boxcover']); - } - - return $res; - } - } - - return $res; // @phpstan-ignore deadCode.unreachable - } - - /** - * @return array - */ - protected function extractSynopsis(): array - { - $res = []; - - // Method 1: Try structured data - if (preg_match('/"description":\s*"(.*?)"/is', $this->response, $match)) { - $res['synopsis'] = trim(html_entity_decode(str_replace('\\u', '\\u', $match[1]))); - - return $res; - } - - // Method 2: Try multiple selectors - $selectors = [ - 'div[id=product-info] h3[class=highlight] + *', - 'div.product-description', - 'div.synopsis', - 'meta[name="description"]', - ]; - - foreach ($selectors as $selector) { - if ($ret = $this->getHtmlParser()->findOne($selector)) { // @phpstan-ignore if.alwaysTrue - $text = $ret->plaintext ?? $ret->content; // @phpstan-ignore property.notFound - - // Filter out "POPPORN EXCLUSIVE" text - if (stripos(trim($text), 'POPPORN EXCLUSIVE') !== false) { - if ($ret->next_sibling()) { - $text = trim($ret->next_sibling()->plaintext); - } - } - - if (! empty($text)) { - $res['synopsis'] = trim($text); - - return $res; - } - } - } - - return $res; - } - - /** - * @return array - */ - protected function extractTrailers(): array - { - $res = []; - - // Method 1: Try structured data - if (preg_match('/"contentUrl":\s*"(.*?)"/is', $this->response, $match)) { - $url = trim($match[1]); - if (! empty($url)) { - $res['trailers']['url'] = $url; - - return $res; - } - } - - // Method 2: Modern video embeds - $videoSelectors = [ - 'video source', - 'iframe[src*="trailer"]', - 'video[src]', - ]; - - foreach ($videoSelectors as $selector) { - $ret = $this->getHtmlParser()->findOne($selector); - if ($ret && isset($ret->src) && ! empty(trim($ret->src))) { // @phpstan-ignore booleanAnd.leftAlwaysTrue - $res['trailers']['url'] = trim($ret->src); - - return $res; - } - } - - return $res; - } - - /** - * @return array - */ - protected function extractProductInfo(bool $extras = false): array - { - $res = []; - $productInfo = []; - $director = ''; - - // Method 1: Try structured data - if (preg_match('/"director":\s*{[^}]*"name":\s*"(.*?)"/is', $this->response, $match)) { - $director = trim($match[1]); - } - - // Method 2: Look for product details in various formats - $selectors = [ - 'div#lside', - 'div.product-details', - 'div.product-info', - ]; - - foreach ($selectors as $selector) { - if ($ret = $this->getHtmlParser()->findOne($selector)) { // @phpstan-ignore if.alwaysTrue - // Extract country information - $country = false; - $rawInfo = []; - - foreach ($ret->find('text') as $e) { - $e = trim($e->innertext); - $e = str_replace([', ', '...', ' '], '', $e); - - if (stripos($e, 'Country:') !== false) { - $country = true; - } - - if ($country === true) { - if (stripos($e, 'addthis_config') === false) { - if (! empty($e)) { - $rawInfo[] = $e; - } - } else { - break; - } - } - } - - if (! empty($rawInfo)) { - $productInfo = array_chunk($rawInfo, 2, false); - break; - } - } - } - - $res['productinfo'] = $productInfo; - $res['director'] = $director; - - // Get extras if requested - if ($extras === true) { - $features = false; - $extrasData = []; - - $featureSelectors = [ - 'ul.stock-information', - 'div.features', - 'div.extras', - ]; - - foreach ($featureSelectors as $selector) { - if ($ret = $this->getHtmlParser()->findOne($selector)) { // @phpstan-ignore if.alwaysTrue - foreach ($ret->find('li') as $e) { - $text = trim($e->plaintext); - if ($text === 'Features:') { - $features = true; - - continue; - } - - if ($features === true && ! empty($text)) { - $extrasData[] = $text; - } - } - - if (! empty($extrasData)) { - $res['extras'] = $extrasData; - break; - } - } - } - } - - return $res; - } - - /** - * @return array - */ - protected function extractCast(): array - { - $res = []; - $cast = []; - $director = ''; - - // Method 1: Try structured data - if (preg_match_all('/"actor":\s*{[^}]*"name":\s*"(.*?)"/is', $this->response, $matches)) { - foreach ($matches[1] as $actor) { - $cast[] = trim($actor); - } - } - - if (preg_match('/"director":\s*{[^}]*"name":\s*"(.*?)"/is', $this->response, $match)) { - $director = trim($match[1]); - } - - // Method 2: Try multiple selectors - if (empty($cast)) { - $castSelectors = [ - 'div.cast a', - 'div.stars a', - 'div.performers a', - ]; - - foreach ($castSelectors as $selector) { - $elements = $this->getHtmlParser()->find($selector); - if (! empty($elements)) { - foreach ($elements as $element) { - $cast[] = trim($element->plaintext); - } - break; - } - } - } - - $res['cast'] = array_unique(array_filter($cast)); - $res['director'] = $director; - - return $res; - } - - /** - * @return array - */ - protected function extractGenres(): array - { - $res = []; - $genres = []; - - // Method 1: Try structured data - if (preg_match_all('/"genre":\s*"(.*?)"/is', $this->response, $matches)) { - foreach ($matches[1] as $genre) { - $genres[] = trim($genre); - } - } - - // Method 2: Try multiple selectors - if (empty($genres)) { - $selectors = [ - 'div[id=thekeywords] a', - 'p[class=keywords] a', - 'div.categories a', - 'div.tags a', - ]; - - foreach ($selectors as $selector) { - $elements = $this->getHtmlParser()->find($selector); - if (! empty($elements)) { - foreach ($elements as $e) { - $genres[] = trim($e->plaintext); - } - break; - } - } - } - - $res['genres'] = array_unique(array_filter($genres)); - - return $res; - } - - /** - * Accept age verification by visiting the confirmation endpoint. - * PopPorn uses a redirect-based age verification system. - */ - protected function acceptAgeVerification(): void - { - try { - // PopPorn requires visiting the AgeConfirmation endpoint with the URL you want to go to - // The confirmation sets a cookie that allows access - $client = $this->getHttpClient(); - - // PopPorn redirects to /AgeConfirmation?url2=/ on first visit - // We need to visit that page and follow through to set the etoken cookie - - // First, make a request that disables redirects to see where we're being sent - try { - $response = $client->get(self::BASE_URL.'/', [ - 'headers' => $this->getDefaultHeaders(), - 'allow_redirects' => false, - 'http_errors' => false, - ]); - - // Check for redirect to age confirmation - $statusCode = $response->getStatusCode(); - if ($statusCode === 302 || $statusCode === 301) { - $location = $response->getHeaderLine('Location'); - - // If redirected to AgeConfirmation, follow the flow - if (stripos($location, 'AgeConfirmation') !== false) { - // The redirect URL includes ?url2= parameter, we need to visit it - $ageConfirmUrl = $location; - if (! str_starts_with($ageConfirmUrl, 'http')) { - $ageConfirmUrl = self::BASE_URL.$ageConfirmUrl; - } - - // Visit the age confirmation page - $ageResponse = $client->get($ageConfirmUrl, [ - 'headers' => $this->getDefaultHeaders(), - 'allow_redirects' => true, - 'http_errors' => false, - ]); - - \Illuminate\Support\Facades\Log::debug('PopPorn age confirmation visited: '.$ageConfirmUrl); - } - } - } catch (\Exception $e) { - // Ignore redirect errors - } - - // Wait a moment to simulate human behavior - usleep(500000); // 500ms - - } catch (\Exception $e) { - // Log but don't fail - we'll try the search anyway - \Illuminate\Support\Facades\Log::debug('PopPorn age verification setup: '.$e->getMessage()); - } - } -} diff --git a/app/Services/PostProcessService.php b/app/Services/PostProcessService.php index 3e85f0f9e..30e64e8de 100644 --- a/app/Services/PostProcessService.php +++ b/app/Services/PostProcessService.php @@ -16,7 +16,6 @@ use dariusiii\rarinfo\Par2Info; * - NFO processing * - Movie/TV/Anime lookups * - Music/Books/Games/Console processing - * - XXX content processing * - Additional processing (RAR/ZIP contents, samples, etc.) */ final class PostProcessService @@ -51,8 +50,6 @@ final class PostProcessService private readonly AnimeProcessor $animeProcessor; - private readonly XXXProcessor $xxxProcessor; - public function __construct( ?NameFixingService $nameFixingService = null, ?Par2Info $par2Info = null, @@ -66,7 +63,6 @@ final class PostProcessService ?ConsolesProcessor $consolesProcessor = null, ?GamesProcessor $gamesProcessor = null, ?AnimeProcessor $animeProcessor = null, - ?XXXProcessor $xxxProcessor = null, ) { $this->echoOutput = (bool) config('nntmux.echocli'); $this->addPar2 = (bool) config('nntmux_settings.add_par2'); @@ -92,7 +88,6 @@ final class PostProcessService $this->consolesProcessor = $consolesProcessor ?? new ConsolesProcessor($this->echoOutput); $this->gamesProcessor = $gamesProcessor ?? new GamesProcessor($this->echoOutput); $this->animeProcessor = $animeProcessor ?? new AnimeProcessor($this->echoOutput); - $this->xxxProcessor = $xxxProcessor ?? new XXXProcessor($this->echoOutput); } /** @@ -110,7 +105,6 @@ final class PostProcessService $this->processGames(); $this->processAnime(); $this->processTv(); - $this->processXXX(); $this->processBooks(); } @@ -230,16 +224,6 @@ final class PostProcessService } } - /** - * Process XXX releases. - * - * @throws \Exception - */ - public function processXXX(): void - { - $this->xxxProcessor->process(); - } - /** * Process additional release data (RAR/ZIP contents, samples, media info). * diff --git a/app/Services/ReleaseRemoverService.php b/app/Services/ReleaseRemoverService.php index 044ae55fc..eb0d821db 100644 --- a/app/Services/ReleaseRemoverService.php +++ b/app/Services/ReleaseRemoverService.php @@ -835,7 +835,7 @@ class ReleaseRemoverService FROM releases r LEFT JOIN release_files rf ON r.id = rf.releases_id WHERE r.categories_id IN ({$categories}) - AND (r.imdbid NOT IN ('0000000', 0) OR xxxinfo_id > 0) + AND (r.imdbid NOT IN ('0000000', 0) OR r.categories_id BETWEEN ".Category::XXX_ROOT.' AND '.Category::XXX_OTHER.") AND r.nfostatus = 1 AND r.haspreview = 0 AND r.jpgstatus = 0 diff --git a/app/Services/Tmux/Tmux.php b/app/Services/Tmux/Tmux.php index 202937cb1..7c473ace7 100644 --- a/app/Services/Tmux/Tmux.php +++ b/app/Services/Tmux/Tmux.php @@ -191,7 +191,6 @@ class Tmux 'lookupbooks' => 'processbooks', 'lookupmusic' => 'processmusic', 'lookupgames' => 'processgames', - 'lookupxxx' => 'processxxx', 'lookupimdb' => 'processmovies', 'lookuptv' => 'processtvrage', 'lookupanidb' => 'processanime', @@ -311,12 +310,11 @@ class Tmux SUM(IF(categories_id BETWEEN %d AND %d AND consoleinfo_id IS NULL,1,0)) AS processconsole, SUM(IF(categories_id IN (%s) AND bookinfo_id IS NULL,1,0)) AS processbooks, SUM(IF(categories_id = %d AND gamesinfo_id = 0,1,0)) AS processgames, - SUM(IF(categories_id BETWEEN %d AND %d AND xxxinfo_id = 0,1,0)) AS processxxx, SUM(IF(1=1 %s,1,0)) AS processnfo, SUM(IF(isrenamed = %d AND predb_id = 0 AND passwordstatus >= 0 AND nfostatus > %d AND ((nfostatus = %d AND proc_nfo = %d) OR proc_files = %d OR proc_par2 = %d) AND categories_id IN (%s),1,0)) AS processrenames, SUM(IF(isrenamed = %d,1,0)) AS renamed, - SUM(IF(nfostatus = %20$d,1,0)) AS nfo, + SUM(IF(nfostatus = %19$d,1,0)) AS nfo, SUM(IF(predb_id > 0,1,0)) AS predb_matched, COUNT(DISTINCT(predb_id)) AS distinct_predb_matched FROM releases r', @@ -333,8 +331,6 @@ class Tmux Category::GAME_OTHER, $bookreqids, Category::PC_GAMES, - Category::XXX_ROOT, - Category::XXX_X264, NfoService::NfoQueryString(), NameFixingService::IS_RENAMED_NONE, NfoService::NFO_UNPROC, diff --git a/app/Services/Tmux/TmuxLayoutBuilder.php b/app/Services/Tmux/TmuxLayoutBuilder.php index 9258e4cfc..f73cf0c50 100644 --- a/app/Services/Tmux/TmuxLayoutBuilder.php +++ b/app/Services/Tmux/TmuxLayoutBuilder.php @@ -40,7 +40,6 @@ class TmuxLayoutBuilder 'postprocessing_tv' => '󰟴 TV/Anime', 'postprocessing_amazon' => ' Amazon', 'postprocessing_movies' => ' Movies', - 'postprocessing_xxx' => '󰞋 XXX', // IRC 'scrapeIRC' => '󰻞 IRC Scraper', @@ -125,7 +124,6 @@ class TmuxLayoutBuilder // Right side: After left splits, right side is now 2.3 $this->paneManager->selectPane('2.3'); $this->paneManager->setPaneTitle('2.3', $this->getPaneDisplayName('postprocessing_movies')); - $this->paneManager->splitVertical('2', '50%', $this->getPaneDisplayName('postprocessing_xxx')); // Window 3: IRC Scraper $this->createIRCScraperWindow(); @@ -171,7 +169,6 @@ class TmuxLayoutBuilder // Right side: After left splits, right side is now 2.3 $this->paneManager->selectPane('2.3'); $this->paneManager->setPaneTitle('2.3', $this->getPaneDisplayName('postprocessing_movies')); - $this->paneManager->splitVertical('2', '50%', $this->getPaneDisplayName('postprocessing_xxx')); // Window 3: IRC Scraper $this->createIRCScraperWindow(); diff --git a/app/Services/Tmux/TmuxOutput.php b/app/Services/Tmux/TmuxOutput.php index fdbf11185..f056b484e 100644 --- a/app/Services/Tmux/TmuxOutput.php +++ b/app/Services/Tmux/TmuxOutput.php @@ -359,16 +359,15 @@ class TmuxOutput extends Tmux 'XXX', sprintf( '%s(%s)', - number_format($this->runVar['counts']['now']['processxxx']), - $this->runVar['counts']['diff']['processxxx'] + '0', + '0' ), sprintf( '%s(%d%%)', - number_format($this->runVar['counts']['now']['xxx']), - $this->runVar['counts']['percent']['xxx'] + number_format($this->runVar['counts']['now']['xxx'] ?? 0), + $this->runVar['counts']['percent']['xxx'] ?? 0 ) ); - $buffer .= $this->_getSeparator(); $buffer .= sprintf( diff --git a/app/Services/Tmux/TmuxTaskRunner.php b/app/Services/Tmux/TmuxTaskRunner.php index f0593b474..c0f5304f4 100644 --- a/app/Services/Tmux/TmuxTaskRunner.php +++ b/app/Services/Tmux/TmuxTaskRunner.php @@ -319,7 +319,6 @@ class TmuxTaskRunner 'tv' => $this->runTvTask($runVar), 'movies' => $this->runMoviesTask($runVar), 'amazon' => $this->runAmazonTask($runVar), - 'xxx' => $this->runXXXTask($runVar), 'scraper' => $this->runIRCScraper($runVar), // Legacy mapping for backward compatibility 'nonamazon' => $this->runTvTask($runVar), @@ -779,32 +778,4 @@ class TmuxTaskRunner return $this->paneManager->respawnPane($pane, $fullCommand); } - - /** - * Run XXX post-processing - * - * @param array $runVar - */ - protected function runXXXTask(array $runVar): bool - { - $enabled = (int) ($runVar['settings']['processxxx'] ?? 0); - $pane = '2.4'; - - if ($enabled !== 1) { - return $this->disablePane($pane, 'Post-process XXX', 'disabled in settings'); - } - - $hasWork = (int) ($runVar['counts']['now']['processxxx'] ?? 0) > 0; - - if (! $hasWork) { - return $this->disablePane($pane, 'Post-process XXX', 'no XXX releases to process'); - } - - $niceness = Settings::settingValue('niceness') ?? 2; - $command = "nice -n{$niceness} ".PHP_BINARY.' artisan update:postprocess xxx true'; - $sleep = (int) ($runVar['settings']['post_timer_amazon'] ?? 300); - $command = $this->buildCommand($command, ['log_pane' => 'post_xxx', 'sleep' => $sleep]); - - return $this->paneManager->respawnPane($pane, $command); - } } diff --git a/app/Services/XXXProcessor.php b/app/Services/XXXProcessor.php deleted file mode 100644 index 4c3b0b5ab..000000000 --- a/app/Services/XXXProcessor.php +++ /dev/null @@ -1,38 +0,0 @@ -echooutput = $echooutput; - } - - public function process(): void - { - if ((int) Settings::settingValue('lookupxxx') === 1) { - $pipeline = new AdultProcessingPipeline([], $this->echooutput); - $pipeline->processXXXReleases(); - } - } - - /** - * Process a single movie title and return the result. - * - * @param string $movie Movie title to look up - * @param bool $debug Whether to include debug information - * @return array Processing result - */ - public function lookupMovie(string $movie, bool $debug = false): array - { - $pipeline = new AdultProcessingPipeline([], $this->echooutput); - - return $pipeline->processMovie($movie, $debug); - } -} diff --git a/app/Services/XxxBrowseService.php b/app/Services/XxxBrowseService.php deleted file mode 100644 index ba45b8aa1..000000000 --- a/app/Services/XxxBrowseService.php +++ /dev/null @@ -1,215 +0,0 @@ -showPasswords = app(ReleaseBrowseService::class)->showPasswords(); - } - - /** - * Get XXX releases with covers for xxx browse page. - * - * Uses three separate queries instead of GROUP_CONCAT: - * 1. COUNT query for total results (replaces SQL_CALC_FOUND_ROWS) - * 2. Paginated XXX entity list with only needed columns - * 3. Top 2 releases per XXX entity using ROW_NUMBER() window function - * - * @param array $cat - * @param array $excludedCats - */ - public function getXXXRange(int $page, array $cat, int $start, int $num, string $orderBy, int $maxAge = -1, array $excludedCats = []): mixed - { - $page = max(1, $page); - $start = max(0, $start); - - $catSrch = ''; - if (\count($cat) > 0 && $cat[0] !== -1) { // @phpstan-ignore offsetAccess.notFound - $catSrch = Category::getCategorySearch($cat); - } - $order = $this->getXXXOrder($orderBy); - $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_medium')); - - $browseBy = $this->getBrowseBy(); - $whereAge = $maxAge > 0 ? 'AND r.postdate > NOW() - INTERVAL '.$maxAge.' DAY ' : ''; - $whereExcluded = \count($excludedCats) > 0 ? ' AND r.categories_id NOT IN ('.implode(',', $excludedCats).')' : ''; - - $baseWhere = "xxx.title != '' " - ."AND r.passwordstatus {$this->showPasswords} " - .$browseBy.' ' - .$catSrch.' ' - .$whereAge - .$whereExcluded; - - $cacheKey = md5('xxx_range_'.$baseWhere.$order[0].$order[1].$start.$num.$page); // @phpstan-ignore offsetAccess.notFound - - $cached = Cache::get($cacheKey); - if ($cached !== null) { - return $cached; - } - - // Step 1: Count total distinct XXX entities matching filters - $countSql = 'SELECT COUNT(DISTINCT xxx.id) AS total ' - .'FROM xxxinfo xxx ' - .'INNER JOIN releases r ON xxx.id = r.xxxinfo_id ' - .'WHERE '.$baseWhere; - - $totalResult = DB::select($countSql); - $totalCount = $totalResult[0]->total ?? 0; - - if ($totalCount === 0) { - return collect(); - } - - // Step 2: Get paginated XXX entity list with only needed columns - $xxxSql = 'SELECT xxx.id, xxx.title, xxx.tagline, xxx.cover, xxx.genre, xxx.director, xxx.actors, ' - .'UNCOMPRESS(xxx.plot) AS plot, ' - .'MAX(r.postdate) AS latest_postdate, ' - .'COUNT(r.id) AS total_releases ' - .'FROM xxxinfo xxx ' - .'INNER JOIN releases r ON xxx.id = r.xxxinfo_id ' - .'WHERE '.$baseWhere.' ' - .'GROUP BY xxx.id, xxx.title, xxx.tagline, xxx.cover, xxx.genre, xxx.director, xxx.actors, xxx.plot ' - ."ORDER BY {$order[0]} {$order[1]} " // @phpstan-ignore offsetAccess.notFound - ."LIMIT {$num} OFFSET {$start}"; - - $xxxEntities = XxxInfo::fromQuery($xxxSql); - - if ($xxxEntities->isEmpty()) { - return collect(); - } - - // Build list of XXX IDs for release query - $xxxIds = $xxxEntities->pluck('id')->toArray(); - $inXxxIds = implode(',', array_map('intval', $xxxIds)); - - // Step 3: Get top 2 releases per XXX entity using ROW_NUMBER() - $releasesSql = 'SELECT ranked.id, ranked.xxxinfo_id, ranked.guid, ranked.searchname, ' - .'ranked.size, ranked.postdate, ranked.adddate, ranked.haspreview, ranked.grabs, ' - .'ranked.comments, ranked.totalpart, ranked.group_name, ranked.nfoid, ranked.failed_count ' - .'FROM ( ' - .'SELECT r.id, r.xxxinfo_id, r.guid, r.searchname, r.size, r.postdate, r.adddate, ' - .'r.haspreview, r.grabs, r.comments, r.totalpart, g.name AS group_name, ' - .'rn.releases_id AS nfoid, df.failed AS failed_count, ' - .'ROW_NUMBER() OVER (PARTITION BY r.xxxinfo_id ORDER BY r.postdate DESC) AS rn ' - .'FROM releases r ' - .'LEFT JOIN usenet_groups g ON g.id = r.groups_id ' - .'LEFT JOIN release_nfos rn ON rn.releases_id = r.id ' - .'LEFT JOIN dnzb_failures df ON df.release_id = r.id ' - ."WHERE r.xxxinfo_id IN ({$inXxxIds}) " - ."AND r.passwordstatus {$this->showPasswords} " - .$catSrch.' ' - .$whereAge - .$whereExcluded - .') ranked ' - .'WHERE ranked.rn <= 2 ' - .'ORDER BY ranked.xxxinfo_id, ranked.postdate DESC'; - - $releases = DB::select($releasesSql); - - // Group releases by xxxinfo_id for fast lookup - $releasesByXxx = []; - foreach ($releases as $release) { - $releasesByXxx[$release->xxxinfo_id][] = $release; - } - - // Attach releases to each XXX entity - foreach ($xxxEntities as $xxx) { - $xxx->releases = $releasesByXxx[$xxx->id] ?? []; // @phpstan-ignore assign.propertyReadOnly - } - - // Set total count on first item (matches existing pattern used by controllers) - if ($xxxEntities->isNotEmpty()) { - $xxxEntities[0]->_totalcount = $totalCount; // @phpstan-ignore property.notFound - } - - Cache::put($cacheKey, $xxxEntities, $expiresAt); - - return $xxxEntities; - } - - /** - * Get the order type the user requested on the xxx page. - * - * @return array - */ - protected function getXXXOrder(string $orderBy): array - { - $orderArr = explode('_', (($orderBy === '') ? 'r.postdate' : $orderBy)); - $orderField = match ($orderArr[0]) { - 'title' => 'xxx.title', - default => 'r.postdate', - }; - - return [$orderField, isset($orderArr[1]) && preg_match('/^asc|desc$/i', $orderArr[1]) ? $orderArr[1] : 'desc']; - } - - /** - * Order types for xxx page. - * - * @return array - */ - public function getXXXOrdering(): array - { - return ['title_asc', 'title_desc', 'name_asc', 'name_desc', 'size_asc', 'size_desc', 'posted_asc', 'posted_desc', 'cat_asc', 'cat_desc']; - } - - protected function getBrowseBy(): string - { - $browseBy = ' '; - foreach (['title', 'director', 'actors', 'genre', 'id'] as $bb) { - if (! empty($_REQUEST[$bb])) { - $bbv = stripslashes($_REQUEST[$bb]); - if ($bb === 'genre') { - $bbv = XxxInfo::getGenreID($bbv); - } - if ($bb === 'id') { - $browseBy .= ' AND xxx.'.$bb.'='.$bbv; - } else { - $browseBy .= ' AND xxx.'.$bb.' '.'LIKE '.escapeString('%'.$bbv.'%'); - } - } - } - - return $browseBy; - } - - /** - * Inserts Trailer Code by Class. - */ - public function insertSwf(string $whichClass, ?string $res): string - { - $ret = ''; - if (($whichClass === 'ade') && ! empty($res)) { - $trailers = unserialize($res, ['allowed_classes' => false]); - $ret .= ""; - $ret .= ""; - $ret .= ''; - - return $ret; - } - if (($whichClass === 'pop') && ! empty($res)) { - $trailers = unserialize($res, ['allowed_classes' => false]); - $ret .= ""; - - return $ret; - } - - return $ret; - } -} diff --git a/bootstrap/providers.php b/bootstrap/providers.php index 8c66860f3..a06762558 100644 --- a/bootstrap/providers.php +++ b/bootstrap/providers.php @@ -2,7 +2,6 @@ return [ App\Providers\AdditionalProcessingServiceProvider::class, - App\Providers\AdultProcessingServiceProvider::class, App\Providers\AppServiceProvider::class, App\Providers\CategorizationServiceProvider::class, App\Providers\ForumServiceProvider::class, diff --git a/database/migrations/2026_02_13_000000_drop_xxxinfo_and_releases_xxxinfo_id.php b/database/migrations/2026_02_13_000000_drop_xxxinfo_and_releases_xxxinfo_id.php new file mode 100644 index 000000000..c3549a593 --- /dev/null +++ b/database/migrations/2026_02_13_000000_drop_xxxinfo_and_releases_xxxinfo_id.php @@ -0,0 +1,51 @@ +dropIndex('ix_releases_xxxinfo_id'); + $table->dropColumn('xxxinfo_id'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('releases', function (Blueprint $table) { + $table->integer('xxxinfo_id')->default(0)->after('imdbid'); + $table->index('xxxinfo_id', 'ix_releases_xxxinfo_id'); + }); + + Schema::create('xxxinfo', function (Blueprint $table) { + $table->increments('id'); + $table->string('title', 1024); + $table->string('tagline', 1024); + $table->binary('plot')->nullable(); + $table->string('genre', 255); + $table->string('director', 255)->nullable(); + $table->string('actors', 2500); + $table->text('extras')->nullable(); + $table->text('productinfo')->nullable(); + $table->text('trailers')->nullable(); + $table->string('directurl', 2000); + $table->string('classused', 20)->default(''); + $table->boolean('cover')->default(false); + $table->boolean('backdrop')->default(false); + $table->timestamps(); + $table->unique('title', 'ix_xxxinfo_title'); + }); + } +}; diff --git a/database/schema/mariadb-schema.sql b/database/schema/mariadb-schema.sql index e2a3b777f..393e57439 100644 --- a/database/schema/mariadb-schema.sql +++ b/database/schema/mariadb-schema.sql @@ -893,7 +893,6 @@ CREATE TABLE `releases` ( `videos_id` int(10) unsigned NOT NULL DEFAULT 0 COMMENT 'FK to videos.id of the parent series.', `tv_episodes_id` int(11) NOT NULL DEFAULT 0 COMMENT 'FK to tv_episodes.id for the episode.', `imdbid` varchar(100) DEFAULT NULL, - `xxxinfo_id` int(11) NOT NULL DEFAULT 0, `musicinfo_id` int(11) DEFAULT NULL COMMENT 'FK to musicinfo.id', `consoleinfo_id` int(11) DEFAULT NULL COMMENT 'FK to consoleinfo.id', `gamesinfo_id` int(11) NOT NULL DEFAULT 0, @@ -938,7 +937,6 @@ CREATE TABLE `releases` ( KEY `ix_releases_videos_id` (`videos_id`), KEY `ix_releases_tv_episodes_id` (`tv_episodes_id`), KEY `ix_releases_imdbid` (`imdbid`), - KEY `ix_releases_xxxinfo_id` (`xxxinfo_id`), KEY `ix_releases_consoleinfo_id` (`consoleinfo_id`), KEY `ix_releases_gamesinfo_id` (`gamesinfo_id`), KEY `ix_releases_bookinfo_id` (`bookinfo_id`), @@ -1290,29 +1288,6 @@ CREATE TABLE `videos_aliases` ( PRIMARY KEY (`videos_id`,`title`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; -DROP TABLE IF EXISTS `xxxinfo`; - -CREATE TABLE `xxxinfo` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `title` varchar(1024) NOT NULL, - `tagline` varchar(1024) NOT NULL, - `plot` blob DEFAULT NULL, - `genre` varchar(255) NOT NULL, - `director` varchar(255) DEFAULT NULL, - `actors` varchar(2500) NOT NULL, - `extras` text DEFAULT NULL, - `productinfo` text DEFAULT NULL, - `trailers` text DEFAULT NULL, - `directurl` varchar(2000) NOT NULL, - `classused` varchar(20) NOT NULL DEFAULT '', - `cover` tinyint(1) NOT NULL DEFAULT 0, - `backdrop` tinyint(1) NOT NULL DEFAULT 0, - `created_at` timestamp NULL DEFAULT NULL, - `updated_at` timestamp NULL DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `ix_xxxinfo_title` (`title`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; - INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (1,'2014_01_16_195548_create_users_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (2,'2014_02_01_311070_create_firewall_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (3,'2017_11_29_223842_create_countries_table',1); @@ -1366,7 +1341,6 @@ INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (52,'2018_01_20_200 INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (53,'2018_01_20_200346_create_video_data_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (54,'2018_01_20_200353_create_videos_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (55,'2018_01_20_200403_create_videos_aliases_table',1); -INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (56,'2018_01_20_200417_create_xxxinfo_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (58,'2018_04_24_132758_create_cache_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (59,'2018_08_08_100000_create_telescope_entries_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (60,'2018_09_13_070520_add_verification_to_user_table',1); diff --git a/database/schema/mysql-schema.sql b/database/schema/mysql-schema.sql index e2a3b777f..393e57439 100644 --- a/database/schema/mysql-schema.sql +++ b/database/schema/mysql-schema.sql @@ -893,7 +893,6 @@ CREATE TABLE `releases` ( `videos_id` int(10) unsigned NOT NULL DEFAULT 0 COMMENT 'FK to videos.id of the parent series.', `tv_episodes_id` int(11) NOT NULL DEFAULT 0 COMMENT 'FK to tv_episodes.id for the episode.', `imdbid` varchar(100) DEFAULT NULL, - `xxxinfo_id` int(11) NOT NULL DEFAULT 0, `musicinfo_id` int(11) DEFAULT NULL COMMENT 'FK to musicinfo.id', `consoleinfo_id` int(11) DEFAULT NULL COMMENT 'FK to consoleinfo.id', `gamesinfo_id` int(11) NOT NULL DEFAULT 0, @@ -938,7 +937,6 @@ CREATE TABLE `releases` ( KEY `ix_releases_videos_id` (`videos_id`), KEY `ix_releases_tv_episodes_id` (`tv_episodes_id`), KEY `ix_releases_imdbid` (`imdbid`), - KEY `ix_releases_xxxinfo_id` (`xxxinfo_id`), KEY `ix_releases_consoleinfo_id` (`consoleinfo_id`), KEY `ix_releases_gamesinfo_id` (`gamesinfo_id`), KEY `ix_releases_bookinfo_id` (`bookinfo_id`), @@ -1290,29 +1288,6 @@ CREATE TABLE `videos_aliases` ( PRIMARY KEY (`videos_id`,`title`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; -DROP TABLE IF EXISTS `xxxinfo`; - -CREATE TABLE `xxxinfo` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `title` varchar(1024) NOT NULL, - `tagline` varchar(1024) NOT NULL, - `plot` blob DEFAULT NULL, - `genre` varchar(255) NOT NULL, - `director` varchar(255) DEFAULT NULL, - `actors` varchar(2500) NOT NULL, - `extras` text DEFAULT NULL, - `productinfo` text DEFAULT NULL, - `trailers` text DEFAULT NULL, - `directurl` varchar(2000) NOT NULL, - `classused` varchar(20) NOT NULL DEFAULT '', - `cover` tinyint(1) NOT NULL DEFAULT 0, - `backdrop` tinyint(1) NOT NULL DEFAULT 0, - `created_at` timestamp NULL DEFAULT NULL, - `updated_at` timestamp NULL DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `ix_xxxinfo_title` (`title`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; - INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (1,'2014_01_16_195548_create_users_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (2,'2014_02_01_311070_create_firewall_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (3,'2017_11_29_223842_create_countries_table',1); @@ -1366,7 +1341,6 @@ INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (52,'2018_01_20_200 INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (53,'2018_01_20_200346_create_video_data_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (54,'2018_01_20_200353_create_videos_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (55,'2018_01_20_200403_create_videos_aliases_table',1); -INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (56,'2018_01_20_200417_create_xxxinfo_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (58,'2018_04_24_132758_create_cache_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (59,'2018_08_08_100000_create_telescope_entries_table',1); INSERT INTO `migrations` (`id`, `migration`, `batch`) VALUES (60,'2018_09_13_070520_add_verification_to_user_table',1); diff --git a/manage_adult_cookies.php b/manage_adult_cookies.php deleted file mode 100644 index 5e94d13f7..000000000 --- a/manage_adult_cookies.php +++ /dev/null @@ -1,169 +0,0 @@ -#!/usr/bin/env php - 'Adult DVD Empire', - 'https://www.adultdvdmarketplace.com' => 'Adult DVD Marketplace', - 'https://straight.theater.aebn.net' => 'AEBN Theater', - 'https://www.hotmovies.com' => 'HotMovies', - 'https://www.popporn.com' => 'Popporn', - ]; - - foreach ($sites as $url => $name) { - echo "Setting up {$name}...\n"; - try { - $cookieJar = $manager->getCookieJar($url); - $count = count($cookieJar); - echo " ✓ Cookies initialized ({$count} cookies)\n"; - } catch (Exception $e) { - echo " ❌ Failed: {$e->getMessage()}\n"; - } - echo "\n"; - } - - echo 'Done! Cookies are saved to: '.$manager->getCookieDirectory()."\n"; - break; - - case 'stats': - echo "================================================================================\n"; - echo "Adult Site Cookie Statistics\n"; - echo "================================================================================\n\n"; - - $stats = $manager->getCookieStats(); - - echo "Total domains with cookies: {$stats['total_domains']}\n"; - echo "Total cookies stored: {$stats['total_cookies']}\n\n"; - - echo "Domain Details:\n"; - echo str_repeat('-', 80)."\n"; - - foreach ($stats['domains'] as $domain => $info) { - $status = $info['has_cookies'] ? '✓' : '❌'; - $cookies = $info['cookie_count']; - echo sprintf(" %s %-40s %d cookies\n", $status, $domain, $cookies); - - if ($info['has_cookies']) { - echo " File: {$info['file']}\n"; - } - } - - echo "\n"; - break; - - case 'clear': - if ($argument) { - echo "Clearing cookies for: {$argument}\n"; - if ($manager->clearCookies($argument)) { - echo "✓ Cookies cleared\n"; - } else { - echo "❌ No cookies found for this domain\n"; - } - } else { - echo "Clearing all adult site cookies...\n"; - $cleared = $manager->clearAllCookies(); - echo "✓ Cleared {$cleared} cookie file(s)\n"; - } - break; - - case 'test': - echo "================================================================================\n"; - echo "Testing Adult Site Access\n"; - echo "================================================================================\n\n"; - - $testSites = [ - 'https://www.adultdvdempire.com/dvd/search?q=test' => 'Adult DVD Empire', - 'https://www.adultdvdmarketplace.com' => 'Adult DVD Marketplace', - 'https://straight.theater.aebn.net' => 'AEBN Theater', - 'https://www.hotmovies.com' => 'HotMovies', - 'https://www.popporn.com' => 'Popporn', - ]; - - if ($argument) { - // Test specific site - $testSites = array_filter($testSites, function ($name, $url) use ($argument) { - return stripos($url, $argument) !== false; - }, ARRAY_FILTER_USE_BOTH); - } - - foreach ($testSites as $url => $name) { - echo "Testing {$name}...\n"; - try { - $response = $manager->makeRequest($url); - - if ($response === false) { - echo " ❌ Request failed\n"; - } else { - $responseLength = strlen($response); - echo " ✓ Response received ({$responseLength} bytes)\n"; - - // Check for age verification indicators - if (stripos($response, 'age') !== false && - (stripos($response, 'verification') !== false || - stripos($response, 'confirm') !== false)) { - echo " ⚠️ Age verification page detected\n"; - } else { - echo " ✓ Successfully bypassed age gate\n"; - } - } - } catch (Exception $e) { - echo " ❌ Error: {$e->getMessage()}\n"; - } - echo "\n"; - } - break; - - case 'help': - default: - echo "================================================================================\n"; - echo "Adult Site Cookie Manager\n"; - echo "================================================================================\n\n"; - - echo "Usage:\n"; - echo " php manage_adult_cookies.php [arguments]\n\n"; - - echo "Commands:\n"; - echo " init Initialize age verification cookies for all sites\n"; - echo " stats Show statistics about stored cookies\n"; - echo " clear [domain] Clear cookies (all or specific domain)\n"; - echo " test [domain] Test if cookies work for sites\n"; - echo " help Show this help message\n\n"; - - echo "Examples:\n"; - echo " php manage_adult_cookies.php init\n"; - echo " php manage_adult_cookies.php stats\n"; - echo " php manage_adult_cookies.php clear adultdvdempire.com\n"; - echo " php manage_adult_cookies.php test\n\n"; - - echo "Cookie Storage:\n"; - echo " Cookies are stored in: storage/app/cookies/adult_sites/\n"; - echo " Format: JSON files, one per domain\n"; - echo " Expiry: 1 year from creation\n\n"; - break; -} diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index a52621b86..d387ff2e8 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -390,18 +390,6 @@ parameters: count: 1 path: app/Models/UserActivityStat.php - - - message: '#^Method App\\Models\\XxxInfo\:\:getAllGenres\(\) should return array\ but returns list\.$#' - identifier: return.type - count: 1 - path: app/Models/XxxInfo.php - - - - message: '#^Method App\\Models\\XxxInfo\:\:getGenres\(\) should return array\ but returns App\\Models\\Genre\|null\.$#' - identifier: return.type - count: 2 - path: app/Models/XxxInfo.php - - message: '#^Method App\\Services\\AdditionalProcessing\\ArchiveExtractionService\:\:extractViaSevenZip\(\) should return list\ but returns array\{success\: false, files\: array\{\}, hasPassword\: false, passwordStatus\: 0\}\.$#' identifier: return.type @@ -462,18 +450,6 @@ parameters: count: 1 path: app/Services/AdditionalProcessing/NzbContentParser.php - - - message: '#^Method App\\Services\\AdultProcessing\\AgeVerificationManager\:\:getStoredDomains\(\) should return array\ but returns list\\.$#' - identifier: return.type - count: 1 - path: app/Services/AdultProcessing/AgeVerificationManager.php - - - - message: '#^PHPDoc tag @return with type list\ is incompatible with native type bool\.$#' - identifier: return.phpDocType - count: 1 - path: app/Services/AdultProcessing/AgeVerificationManager.php - - message: '#^Method App\\Services\\Archives\\SevenZipPartialParser\:\:getFilesByExtension\(\) should return array\\> but returns array\\.$#' identifier: return.type @@ -780,12 +756,6 @@ parameters: count: 1 path: app/Services/XrefService.php - - - message: '#^Method App\\Services\\XxxBrowseService\:\:getXXXOrder\(\) should return array\ but returns array\\.$#' - identifier: return.type - count: 1 - path: app/Services/XxxBrowseService.php - - message: '#^Method App\\Support\\UpdatePerformanceHelper\:\:checkSystemResources\(\) should return array\ but returns list\\.$#' identifier: return.type diff --git a/resources/views/admin/site/edit.blade.php b/resources/views/admin/site/edit.blade.php index 135c9ed4d..f89b51ab2 100644 --- a/resources/views/admin/site/edit.blade.php +++ b/resources/views/admin/site/edit.blade.php @@ -431,20 +431,6 @@

Whether to attempt to lookup game information from Amazon.

- -
- - -

Whether to attempt to lookup XXX information when processing binaries.

-
@@ -878,15 +864,6 @@

The maximum amount of books to process with amazon per run. This does not use an NNTP connection

-
- - -

The maximum amount of XXX to process per run.

-
-
-
- xxxview ?? 0)) ? 'checked' : '' }} - class="h-4 w-4 text-blue-600 dark:text-blue-400 focus:ring-blue-500 border-gray-300 dark:border-gray-600 rounded"> - -
@endif diff --git a/resources/views/details/index.blade.php b/resources/views/details/index.blade.php index de3305ebd..20a0de9f4 100644 --- a/resources/views/details/index.blade.php +++ b/resources/views/details/index.blade.php @@ -253,41 +253,6 @@ @endif - - @if(!empty($xxx)) - @php - $xxxData = is_object($xxx) ? get_object_vars($xxx) : $xxx; - $xxxTitle = $xxxData['title'] ?? ($xxx->title ?? null); - $xxxGenre = $xxxData['genre'] ?? ($xxx->genre ?? null); - $xxxActors = $xxxData['actors'] ?? ($xxx->actors ?? null); - @endphp -
-

- Adult Content Information -

-
- @if(!empty($xxxTitle)) -
-
Title
-
{{ $xxxTitle }}
-
- @endif - @if(!empty($xxxGenre)) -
-
Genre
-
{!! $xxxGenre !!}
-
- @endif - @if(!empty($xxxActors)) -
-
Actors
-
{!! $xxxActors !!}
-
- @endif -
-
- @endif - @if(!empty($music)) @php diff --git a/resources/views/profile/edit.blade.php b/resources/views/profile/edit.blade.php index 779808269..9dff4b5a3 100644 --- a/resources/views/profile/edit.blade.php +++ b/resources/views/profile/edit.blade.php @@ -183,11 +183,6 @@ class="rounded border-gray-300 dark:border-gray-600 text-blue-600 dark:text-blue-400 focus:ring-blue-500 mr-2"> Book Covers - diff --git a/resources/views/profile/index.blade.php b/resources/views/profile/index.blade.php index f36a61133..309d7a9f4 100644 --- a/resources/views/profile/index.blade.php +++ b/resources/views/profile/index.blade.php @@ -325,10 +325,6 @@ Book Covers -
- - XXX Covers -
diff --git a/resources/views/xxx/index.blade.php b/resources/views/xxx/index.blade.php index 4ebbe2b9d..35516ab40 100644 --- a/resources/views/xxx/index.blade.php +++ b/resources/views/xxx/index.blade.php @@ -7,276 +7,125 @@ @section('content')
-
+
- -
-
-
- -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
-
- -
- - - Clear + + - - - @if(count($results) > 0) -
-
-

- - {{ $catname ?? 'All' }} XXX -

- -
- - {{ $results->total() }} results found - -
- - -
- @foreach($results as $result) - @php - $releases = $result->releases ?? []; - $totalReleases = $result->total_releases ?? count($releases); - $maxReleases = 2; - $displayReleases = array_slice($releases, 0, $maxReleases); - $guid = !empty($displayReleases) ? $displayReleases[0]->guid : null; - $totalFailed = collect($releases)->sum(fn($r) => (int)($r->failed_count ?? 0)); - @endphp - -
-
- - - - -
-
-
-

{{ $result->title }}

- - @if($totalFailed > 0) -
- - {{ $totalFailed }} failed report{{ $totalFailed > 1 ? 's' : '' }} -
- @endif - -
- @if(!empty($result->genre)) -
- Genre: {!! makeFieldLinks((array) $result, 'genre', 'xxx') !!} -
- @endif - @if(!empty($result->actors)) -
- Actors: {!! makeFieldLinks((array) $result, 'actors', 'xxx') !!} -
- @endif - @if(!empty($result->director)) -
- Director: {!! makeFieldLinks((array) $result, 'director', 'xxx') !!} -
- @endif -
- - @if(isset($result->plot) && $result->plot) -

{{ $result->plot }}

- @endif -
-
- - - @if(!empty($displayReleases)) -
-

- Available Releases - @if($totalReleases > $maxReleases) - (Showing {{ $maxReleases }} of {{ $totalReleases }}) - @endif -

-
- @foreach($displayReleases as $release) - @if($release->searchname) -
-
- - - {{ $release->searchname }} - - - -
- @if(isset($release->size)) - - {{ number_format($release->size / 1073741824, 2) }} GB - - @endif - @if(isset($release->postdate)) - - {{ date('M d, Y H:i', strtotime($release->postdate)) }} - - @endif - @if(isset($release->grabs) && $release->grabs > 0) - - {{ $release->grabs }} grabs - - @endif - @if(isset($release->nfoid) && !empty($release->nfoid)) - - @endif - @if(isset($release->haspreview) && $release->haspreview == 1) - - @endif -
- - - -
-
- @endif - @endforeach -
-
- @endif -
-
-
@endforeach
+
+ Order by: + @foreach($ordering ?? [] as $ob) + + {{ str_replace('_', ' ', $ob) }} + + @endforeach +
+
+ + @if($results->count() > 0) +
+ {{ $results->total() }} results found +
+ +
+ + + + + + + + + + + + @foreach($results as $result) + + + + + + + + @endforeach + +
NameCategoryAddedSizeAction
+
+
+ +
+
+ + {{ $result->searchname }} + + @if(!empty($result->failed_count) && $result->failed_count > 0) + + Failed ({{ $result->failed_count }}) + + @endif + @if(!empty($result->group_name)) + {{ $result->group_name }} + @endif +
+
+
+ + {{ $result->category_name ?? 'Other' }} + + + {{ userDateDiffForHumans($result->adddate ?? null) }} + + {{ isset($result->size) ? number_format($result->size / 1073741824, 2) . ' GB' : '-' }} + + +
+
-
{{ $results->links() }}
@else - -
- +
+

No content found

-

Try adjusting your search filters or browse all content.

- +

Try a different category or browse all XXX.

+
Browse All XXX
@endif
- -{{-- All modals (NFO, preview, etc.) are included globally via layouts.main --}} @endsection - diff --git a/routes/web.php b/routes/web.php index 71d9189a1..298d31308 100644 --- a/routes/web.php +++ b/routes/web.php @@ -74,7 +74,7 @@ use App\Http\Controllers\TermsController; // Serve cover images from storage - Must be public (no auth required) Route::get('/covers/{type}/{filename}', [App\Http\Controllers\CoverController::class, 'show']) - ->where('type', 'anime|audio|audiosample|book|console|games|movies|music|preview|sample|tvrage|video|xxx') + ->where('type', 'anime|audio|audiosample|book|console|games|movies|music|preview|sample|tvrage|video') ->where('filename', '.*') ->name('covers.show'); diff --git a/storage/covers/xxx/.gitignore b/storage/covers/xxx/.gitignore deleted file mode 100644 index ba2606d59..000000000 --- a/storage/covers/xxx/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.gitignore -!.gitignore -!no-cover.jpg -!no-backdrop.jpg diff --git a/storage/covers/xxx/no-backdrop.jpg b/storage/covers/xxx/no-backdrop.jpg deleted file mode 100644 index efd5e95f2bb86694ac2aff8a0e3183bf72f515f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 306639 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 maQ1(tON=Oh{jwR&@ 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�#fNCtXn{PoM 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

(t0u= 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 >}*pEw{7ybAfJc@>5b>P$_Wdm!Zh)&9Ss| z=L~0O&sYF%On?AG(&6A<=6u~%QX}XiK3csgAaM5=;u#WkV*S>8N-3gp6L%9gIefw` zz$V)F5_}VZ>*Ay5=a@ysB174(2*Ifr*(p(cf$_`wH5iIA+w4_3C3zXvL(`U^x__UG`2$POLzRJ4?9d# z+g}Qp<;=42FH{N~bX%^YgK~^A1Qfwiu>Oy!WfANL%p{!K3ESnmRh8bOu=y}_ zYw0banhhAInY|e!v~Uj4xlF|}9~&c0;WgAnbT`?Z=;TvhZCnfbPg|wP3mlnmH1eJG zXUz0h2A%Ket$IA<8;h1Qq^|Z^7g#wVUC)MZRAtC#n7g%;qnGXEU2nTw{Yzt*=IQ0= zirhwUuzJDN#5nzMyA>AkD6Vmi-Sx`{(|l^|=AOP*&vV%q7XOX|7(-Gck9j#h)M8=| ze>P;*@n>}2D8g6+O2Ro?`BmHHAYUcw5?$UM$CSzyqQH)pPfU0&=+4>_>+3;e8qBlu zK~dRsPS&@Y<#HcI2HrS*2jk_j5M{5)697N8rbhpx<6hU}MkojVsf~qY+IlzkB?|2N zbb|fL3`Q=gu1PFq@W;dpxAyYLS3ogMf>jwZCR3Mw-u-MwOwNNH4%Ni!80&0wu*4sT zKe7izkS#{MW$Q-9nLji7Pih1-M@wAd=;hbvsw@C4Ya!km OsiN5PqoK!y-*L_#{ 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::class, $pipeline); - $this->assertCount(7, $pipeline->getPipes()); - } - - /** - * Test that pipes are ordered by priority. - */ - public function test_pipes_are_ordered_by_priority(): void - { - $pipeline = new AdultProcessingPipeline; - $pipes = $pipeline->getPipes()->values(); - - // AEBN should be first (priority 10) - $this->assertInstanceOf(AebnPipe::class, $pipes[0]); - // IAFD should be second (priority 15) - $this->assertInstanceOf(IafdPipe::class, $pipes[1]); - // Data18 should be third (priority 18) - $this->assertInstanceOf(Data18Pipe::class, $pipes[2]); - // PopPorn should be fourth (priority 20) - $this->assertInstanceOf(PoppornPipe::class, $pipes[3]); - // ADM should be fifth (priority 30) - $this->assertInstanceOf(AdmPipe::class, $pipes[4]); - // ADE should be sixth (priority 40) - $this->assertInstanceOf(AdePipe::class, $pipes[5]); - // HotMovies should be last (priority 50) - $this->assertInstanceOf(HotmoviesPipe::class, $pipes[6]); - } - - /** - * Test that a pipe can be added to the pipeline. - */ - public function test_can_add_pipe_to_pipeline(): void - { - $pipeline = new AdultProcessingPipeline([]); - - $this->assertCount(7, $pipeline->getPipes()); // Default pipes - - // Create a custom pipe with high priority - $customPipe = new class extends AbstractAdultProviderPipe - { - protected int $priority = 5; - - public function getName(): string - { - return 'custom'; - } - - public function getDisplayName(): string - { - return 'Custom Provider'; - } - - protected function getBaseUrl(): string - { - return 'https://example.com'; - } - - protected function process(AdultProcessingPassable $passable): AdultProcessingResult - { - return AdultProcessingResult::notFound($this->getName()); - } - - protected function search(string $movie): array|false - { - return false; - } - - protected function getMovieInfo(): array|false - { - return false; - } - }; - - $pipeline->addPipe($customPipe); - - $this->assertCount(8, $pipeline->getPipes()); - } - - /** - * Test AdultReleaseContext creation from title. - */ - public function test_release_context_from_title(): void - { - $context = AdultReleaseContext::fromTitle('Test Movie Title'); - - $this->assertEquals(0, $context->releaseId); - $this->assertEquals('Test Movie Title', $context->searchName); - $this->assertEquals('Test Movie Title', $context->cleanTitle); - $this->assertNull($context->guid); - } - - /** - * Test AdultReleaseContext creation from release array. - */ - public function test_release_context_from_release(): void - { - $release = [ - 'id' => 123, - 'searchname' => 'Test.Movie.Title.XXX.2023', - 'guid' => 'abc123', - ]; - - $context = AdultReleaseContext::fromRelease($release, 'Test Movie Title'); - - $this->assertEquals(123, $context->releaseId); - $this->assertEquals('Test.Movie.Title.XXX.2023', $context->searchName); - $this->assertEquals('Test Movie Title', $context->cleanTitle); - $this->assertEquals('abc123', $context->guid); - } - - /** - * Test AdultProcessingResult creation methods. - */ - public function test_processing_result_creation(): void - { - // Test matched result - $matchedResult = AdultProcessingResult::matched( - 'Test Movie', - 'aebn', - ['boxcover' => 'http://example.com/cover.jpg'] - ); - $this->assertEquals(AdultProcessingResult::STATUS_MATCHED, $matchedResult->status); - $this->assertTrue($matchedResult->isMatched()); - $this->assertFalse($matchedResult->shouldContinueProcessing()); - $this->assertEquals('http://example.com/cover.jpg', $matchedResult->getBoxCover()); - - // Test not found result - $notFoundResult = AdultProcessingResult::notFound('aebn'); - $this->assertEquals(AdultProcessingResult::STATUS_NOT_FOUND, $notFoundResult->status); - $this->assertFalse($notFoundResult->isMatched()); - $this->assertTrue($notFoundResult->shouldContinueProcessing()); - - // Test skipped result - $skippedResult = AdultProcessingResult::skipped('Provider unavailable', 'aebn'); - $this->assertEquals(AdultProcessingResult::STATUS_SKIPPED, $skippedResult->status); - $this->assertFalse($skippedResult->isMatched()); - - // Test pending result - $pendingResult = AdultProcessingResult::pending(); - $this->assertEquals(AdultProcessingResult::STATUS_PENDING, $pendingResult->status); - $this->assertFalse($pendingResult->isMatched()); - } - - /** - * Test AdultProcessingPassable behavior. - */ - public function test_processing_passable_behavior(): void - { - $context = AdultReleaseContext::fromTitle('Test Movie'); - $passable = new AdultProcessingPassable($context, true, 'test_cookie'); - - $this->assertEquals('Test Movie', $passable->getCleanTitle()); - $this->assertEquals('test_cookie', $passable->getCookie()); - $this->assertFalse($passable->shouldStopProcessing()); - - // Update with a matched result - $result = AdultProcessingResult::matched('Test Movie', 'aebn', []); - $passable->updateResult($result, 'aebn'); - - $this->assertTrue($passable->shouldStopProcessing()); - $this->assertEquals('aebn', $passable->result->providerName); - } - - /** - * Test individual pipe name and priority. - */ - public function test_pipe_names_and_priorities(): void - { - $aebn = new AebnPipe; - $this->assertEquals('aebn', $aebn->getName()); - $this->assertEquals('Adult Entertainment Broadcast Network', $aebn->getDisplayName()); - $this->assertEquals(10, $aebn->getPriority()); - - $popporn = new PoppornPipe; - $this->assertEquals('pop', $popporn->getName()); - $this->assertEquals('PopPorn', $popporn->getDisplayName()); - $this->assertEquals(20, $popporn->getPriority()); - - $adm = new AdmPipe; - $this->assertEquals('adm', $adm->getName()); - $this->assertEquals('Adult DVD Marketplace', $adm->getDisplayName()); - $this->assertEquals(30, $adm->getPriority()); - - $ade = new AdePipe; - $this->assertEquals('ade', $ade->getName()); - $this->assertEquals('Adult DVD Empire', $ade->getDisplayName()); - $this->assertEquals(40, $ade->getPriority()); - - $hotmovies = new HotmoviesPipe; - $this->assertEquals('hotm', $hotmovies->getName()); - $this->assertEquals('HotMovies', $hotmovies->getDisplayName()); - $this->assertEquals(50, $hotmovies->getPriority()); - } - - /** - * Test passable to array conversion with debug info. - */ - public function test_passable_to_array_with_debug(): void - { - $context = AdultReleaseContext::fromRelease([ - 'id' => 123, - 'searchname' => 'Test.Movie.XXX', - ], 'Test Movie'); - - $passable = new AdultProcessingPassable($context, true); - - $result = AdultProcessingResult::matched('Test Movie', 'aebn', [ - 'boxcover' => 'http://example.com/cover.jpg', - ]); - $passable->updateResult($result, 'aebn'); - - $array = $passable->toArray(); - - $this->assertEquals('matched', $array['status']); - $this->assertEquals('Test Movie', $array['title']); - $this->assertEquals('aebn', $array['provider']); - $this->assertArrayHasKey('debug', $array); - $this->assertEquals(123, $array['debug']['release_id']); - $this->assertEquals('Test.Movie.XXX', $array['debug']['search_name']); - $this->assertEquals('Test Movie', $array['debug']['clean_title']); - } - - /** - * Test that echo output can be disabled on pipes. - */ - public function test_pipe_echo_output_can_be_disabled(): void - { - $pipe = new AebnPipe; - $pipe->setEchoOutput(false); - - // This should not throw any exceptions - $this->assertInstanceOf(AebnPipe::class, $pipe); - } - - /** - * Test similarity calculation for title matching. - */ - public function test_title_similarity_calculation(): void - { - $pipe = new class extends AbstractAdultProviderPipe - { - public function getName(): string - { - return 'test'; - } - - public function getDisplayName(): string - { - return 'Test'; - } - - protected function getBaseUrl(): string - { - return ''; - } - - protected function process(AdultProcessingPassable $passable): AdultProcessingResult - { - return AdultProcessingResult::pending(); - } - - protected function search(string $movie): array|false - { - return false; - } - - protected function getMovieInfo(): array|false - { - return false; - } - - public function publicCalculateSimilarity(string $search, string $result): float - { - return $this->calculateSimilarity($search, $result); - } - }; - - // Exact match should be 100% - $similarity = $pipe->publicCalculateSimilarity('Test Movie', 'Test Movie'); - $this->assertGreaterThan(99, $similarity); - - // Similar titles should have high similarity - $similarity = $pipe->publicCalculateSimilarity('Test Movie', 'Test Movie 2023'); - $this->assertGreaterThanOrEqual(80, $similarity); - - // Different titles should have lower similarity - $similarity = $pipe->publicCalculateSimilarity('Test Movie', 'Completely Different Title'); - $this->assertLessThan(50, $similarity); - } -}