Separate Blacklight/Releases into specific services

This commit is contained in:
DariusIII
2025-12-20 21:47:01 +01:00
parent a79f357173
commit 85b4904e6f
26 changed files with 1553 additions and 1109 deletions
+1 -1
View File
@@ -127,7 +127,7 @@ class Books
%s %s %s
GROUP BY boo.id
ORDER BY %s %s %s",
(new Releases)->showPasswords(),
app(\App\Services\Releases\ReleaseBrowseService::class)->showPasswords(),
$browseby,
$catsrch,
$exccatlist,
+1 -1
View File
@@ -163,7 +163,7 @@ class Console
%s %s %s
GROUP BY con.id
ORDER BY %s %s %s",
(new Releases)->showPasswords(),
app(\App\Services\Releases\ReleaseBrowseService::class)->showPasswords(),
$browseBy,
$catsrch,
$exccatlist,
+1 -1
View File
@@ -205,7 +205,7 @@ class Games
$order = $this->getGamesOrder($orderBy);
$gamesSql =
"SELECT SQL_CALC_FOUND_ROWS gi.id, GROUP_CONCAT(r.id ORDER BY r.postdate DESC SEPARATOR ',') AS grp_release_id FROM gamesinfo gi LEFT JOIN releases r ON gi.id = r.gamesinfo_id WHERE gi.title != '' AND gi.cover = 1 AND r.passwordstatus "
.(new Releases)->showPasswords().
.app(\App\Services\Releases\ReleaseBrowseService::class)->showPasswords().
$browseBy.
$catsrch.
$maxAge.
+1 -1
View File
@@ -129,7 +129,7 @@ class Movie
$this->imdburl = (int) Settings::settingValue('imdburl') !== 0;
$this->movieqty = Settings::settingValue('maximdbprocessed') !== '' ? (int) Settings::settingValue('maximdbprocessed') : 100;
$this->showPasswords = (new Releases)->showPasswords();
$this->showPasswords = app(\App\Services\Releases\ReleaseBrowseService::class)->showPasswords();
$this->echooutput = config('nntmux.echocli');
$this->imgSavePath = storage_path('covers/movies/');
+1 -1
View File
@@ -151,7 +151,7 @@ class Music
%s %s %s
GROUP BY m.id
ORDER BY %s %s %s",
(new Releases)->showPasswords(),
app(\App\Services\Releases\ReleaseBrowseService::class)->showPasswords(),
$browseby,
$catsrch,
$exccatlist,
+4 -3
View File
@@ -3,6 +3,7 @@
namespace Blacklight;
use App\Models\UsenetGroup;
use App\Services\Releases\ReleaseManagementService;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
@@ -17,7 +18,7 @@ class NZBExport
protected NZB $nzb;
protected Releases $releases;
protected ReleaseManagementService $releaseManagement;
protected bool $echoCLI;
@@ -30,7 +31,7 @@ class NZBExport
public function __construct()
{
$this->echoCLI = config('nntmux.echocli');
$this->releases = new Releases;
$this->releaseManagement = app(ReleaseManagementService::class);
$this->nzb = new NZB;
}
@@ -104,7 +105,7 @@ class NZBExport
foreach ($groups as $group) {
$currentExport = 0;
// Get all the releases based on the parameters.
$releases = $this->releases->getForExport($fromDate, $toDate, $group['id']);
$releases = $this->releaseManagement->getForExport($fromDate, $toDate, $group['id']);
$totalFound = \count($releases);
if ($totalFound === 0) {
if ($this->echoCLI) {
+4 -3
View File
@@ -5,6 +5,7 @@ namespace Blacklight;
use App\Enums\BlacklistConstants;
use App\Models\Category;
use App\Models\Settings;
use App\Services\Releases\ReleaseManagementService;
use Exception;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
@@ -41,7 +42,7 @@ class ReleaseRemover
protected bool $ignoreUserCheck = false;
protected string $method = '';
protected string $query = '';
protected Releases $releases;
protected ReleaseManagementService $releaseManagement;
protected array $result = [];
private NZB $nzb;
private ReleaseImage $releaseImage;
@@ -54,7 +55,7 @@ class ReleaseRemover
public function __construct()
{
$this->colorCLI = new ColorCLI;
$this->releases = new Releases;
$this->releaseManagement = app(ReleaseManagementService::class);
$this->nzb = new NZB;
$this->releaseImage = new ReleaseImage;
$this->echoCLI = config('nntmux.echocli');
@@ -844,7 +845,7 @@ class ReleaseRemover
$deletedCount = 0;
foreach ($this->result as $release) {
if ($this->delete) {
$this->releases->deleteSingle(['g' => $release->guid, 'i' => $release->id], $this->nzb, $this->releaseImage);
$this->releaseManagement->deleteSingle(['g' => $release->guid, 'i' => $release->id], $this->nzb, $this->releaseImage);
if ($this->echoCLI) {
$this->colorCLI->primary('Deleting: '.$this->method.': '.$release->searchname, true);
}
+1 -1
View File
@@ -48,7 +48,7 @@ class XXX
$this->colorCli = new ColorCLI;
$this->movieQty = Settings::settingValue('maxxxxprocessed') ?? 100;
$this->showPasswords = (new Releases)->showPasswords();
$this->showPasswords = app(\App\Services\Releases\ReleaseBrowseService::class)->showPasswords();
$this->echoOutput = config('nntmux.echocli');
$this->imgSavePath = storage_path('covers/xxx/');
$this->cookie = resource_path('tmp/xxx.cookie');
+4 -4
View File
@@ -3,9 +3,9 @@
namespace App\Console\Commands;
use App\Models\Release;
use App\Services\Releases\ReleaseManagementService;
use Blacklight\NZB;
use Blacklight\ReleaseImage;
use Blacklight\Releases;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\File;
@@ -80,20 +80,20 @@ class CleanNZB extends Command
{
// Setup
$nzb = new NZB;
$rel = new Releases;
$releaseManagement = app(ReleaseManagementService::class);
$checked = $deleted = 0;
$this->info('Getting list of releases from database to check if they have a corresponding NZB on disk');
$total = Release::count();
$this->alert("Total releases to check: $total");
Release::where('nzbstatus', 1)->chunkById((int) $this->option('chunksize'), function (Collection $releases) use ($delete, &$checked, &$deleted, $nzb, $rel) {
Release::where('nzbstatus', 1)->chunkById((int) $this->option('chunksize'), function (Collection $releases) use ($delete, &$checked, &$deleted, $nzb, $releaseManagement) {
echo 'Total done: '.$checked."\r";
foreach ($releases as $r) {
if (! $nzb->NZBPath($r->guid)) {
if ($delete) {
$rel->deleteSingle(['g' => $r->guid, 'i' => $r->id], $nzb, new ReleaseImage);
$releaseManagement->deleteSingle(['g' => $r->guid, 'i' => $r->id], $nzb, new ReleaseImage);
}
$deleted++;
$this->line("Deleted: $r->searchname -> $r->guid");
@@ -5,11 +5,19 @@ namespace App\Http\Controllers\Admin;
use App\Http\Controllers\BasePageController;
use App\Models\Category;
use App\Models\Release;
use Blacklight\Releases;
use App\Services\Releases\ReleaseManagementService;
use Illuminate\Http\Request;
class AdminReleasesController extends BasePageController
{
private ReleaseManagementService $releaseManagement;
public function __construct(ReleaseManagementService $releaseManagement)
{
parent::__construct();
$this->releaseManagement = $releaseManagement;
}
/**
* @throws \Exception
*/
@@ -88,8 +96,7 @@ class AdminReleasesController extends BasePageController
{
try {
if ($id) {
$releases = new Releases;
$releases->deleteMultiple($id);
$this->releaseManagement->deleteMultiple($id);
// Handle AJAX requests
if (request()->wantsJson() || request()->ajax()) {
+17 -6
View File
@@ -12,8 +12,9 @@ use App\Models\UsenetGroup;
use App\Models\User;
use App\Models\UserDownload;
use App\Models\UserRequest;
use App\Services\Releases\ReleaseBrowseService;
use App\Services\Releases\ReleaseSearchService;
use Blacklight\NZB;
use Blacklight\Releases;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
@@ -27,6 +28,17 @@ use Symfony\Component\HttpFoundation\StreamedResponse;
class ApiController extends BasePageController
{
private string $type;
private ReleaseSearchService $releaseSearchService;
private ReleaseBrowseService $releaseBrowseService;
public function __construct(
ReleaseSearchService $releaseSearchService,
ReleaseBrowseService $releaseBrowseService
) {
parent::__construct();
$this->releaseSearchService = $releaseSearchService;
$this->releaseBrowseService = $releaseBrowseService;
}
/**
* @return Application|\Illuminate\Foundation\Application|RedirectResponse|Redirector|StreamedResponse|void
@@ -119,7 +131,6 @@ class ApiController extends BasePageController
}
}
$releases = new Releases;
// Set Query Parameters based on Request objects
$outputXML = ! ($request->has('o') && $request->input('o') === 'json');
@@ -155,7 +166,7 @@ class ApiController extends BasePageController
];
if ($request->has('q')) {
$relData = $releases->search(
$relData = $this->releaseSearchService->search(
$searchArr,
$groupName,
-1,
@@ -172,7 +183,7 @@ class ApiController extends BasePageController
$minSize
);
} else {
$relData = $releases->getBrowseRange(
$relData = $this->releaseBrowseService->getBrowseRange(
1,
$categoryID,
$offset,
@@ -220,7 +231,7 @@ class ApiController extends BasePageController
$airDate = str_replace('/', '-', $year[0].'-'.$episode);
}
$relData = $releases->tvSearch(
$relData = $this->releaseSearchService->tvSearch(
$siteIdArr,
$series,
$episode,
@@ -248,7 +259,7 @@ class ApiController extends BasePageController
$tmdbId = $request->has('tmdbid') && $request->filled('tmdbid') ? (int) $request->input('tmdbid') : -1;
$traktId = $request->has('traktid') && $request->filled('traktid') ? (int) $request->input('traktid') : -1;
$relData = $releases->moviesSearch(
$relData = $this->releaseSearchService->moviesSearch(
$imdbId,
$tmdbId,
$traktId,
+16 -10
View File
@@ -10,10 +10,11 @@ use App\Models\Settings;
use App\Models\User;
use App\Models\UserDownload;
use App\Models\UserRequest;
use App\Services\Releases\ReleaseBrowseService;
use App\Services\Releases\ReleaseSearchService;
use App\Transformers\ApiTransformer;
use App\Transformers\CategoryTransformer;
use App\Transformers\DetailsTransformer;
use Blacklight\Releases;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
@@ -23,10 +24,17 @@ use Illuminate\Support\Facades\DB;
class ApiV2Controller extends BasePageController
{
private ApiController $api;
private ReleaseSearchService $releaseSearchService;
private ReleaseBrowseService $releaseBrowseService;
public function __construct()
{
$this->api = new ApiController;
public function __construct(
ApiController $api,
ReleaseSearchService $releaseSearchService,
ReleaseBrowseService $releaseBrowseService
) {
$this->api = $api;
$this->releaseSearchService = $releaseSearchService;
$this->releaseBrowseService = $releaseBrowseService;
}
public function capabilities(): JsonResponse
@@ -93,7 +101,7 @@ class ApiV2Controller extends BasePageController
];
// Perform search
$relData = (new Releases)->moviesSearch(
$relData = $this->releaseSearchService->moviesSearch(
$params['imdbId'],
$params['tmdbId'],
$params['traktId'],
@@ -137,7 +145,6 @@ class ApiV2Controller extends BasePageController
if ($request->missing('api_token') || $request->isNotFilled('api_token')) {
return response()->json(['error' => 'Missing parameter (api_token)'], 403);
}
$releases = new Releases;
$user = User::query()->where('api_token', $request->input('api_token'))->first();
$offset = $this->api->offset($request);
$catExclusions = User::getCategoryExclusionForApi($request);
@@ -150,7 +157,7 @@ class ApiV2Controller extends BasePageController
$limit = $this->api->limit($request);
if ($request->has('id')) {
$relData = $releases->apiSearch(
$relData = $this->releaseSearchService->apiSearch(
$request->input('id'),
$groupName,
$offset,
@@ -161,7 +168,7 @@ class ApiV2Controller extends BasePageController
$minSize
);
} else {
$relData = $releases->getBrowseRange(
$relData = $this->releaseBrowseService->getBrowseRange(
1,
$categoryID,
$offset,
@@ -202,7 +209,6 @@ class ApiV2Controller extends BasePageController
if ($request->missing('api_token') || $request->isNotFilled('api_token')) {
return response()->json(['error' => 'Missing parameter (api_token)'], 403);
}
$releases = new Releases;
$user = User::query()->where('api_token', $request->input('api_token'))->first();
if ($user === null) {
return response()->json(['error' => 'Invalid API Token'], 403);
@@ -242,7 +248,7 @@ class ApiV2Controller extends BasePageController
$airDate = str_replace('/', '-', $year[0].'-'.$episode);
}
$relData = $releases->apiTvSearch(
$relData = $this->releaseSearchService->apiTvSearch(
$siteIdArr,
$series,
$episode,
+4 -4
View File
@@ -4,7 +4,7 @@ namespace App\Http\Controllers\Api;
use App\Models\Category;
use App\Models\Release;
use Blacklight\Releases;
use App\Services\Releases\ReleaseBrowseService;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\Cache;
@@ -15,7 +15,7 @@ use Illuminate\Support\Facades\DB;
*/
class RSS extends ApiController
{
public Releases $releases;
public ReleaseBrowseService $releaseBrowseService;
/**
* @throws \Exception
@@ -23,7 +23,7 @@ class RSS extends ApiController
public function __construct()
{
parent::__construct();
$this->releases = new Releases;
$this->releaseBrowseService = app(ReleaseBrowseService::class);
}
/**
@@ -72,7 +72,7 @@ class RSS extends ApiController
%s %s %s %s
ORDER BY postdate DESC %s",
$cartSearch,
$this->releases->showPasswords(),
$this->releaseBrowseService->showPasswords(),
$catSearch,
($videosId > 0 ? sprintf('AND r.videos_id = %d %s', $videosId, ($catSearch === '' ? $catLimit : '')) : ''),
($aniDbID > 0 ? sprintf('AND r.anidbid = %d %s', $aniDbID, ($catSearch === '' ? $catLimit : '')) : ''),
+14 -10
View File
@@ -4,24 +4,30 @@ namespace App\Http\Controllers;
use App\Models\Category;
use App\Models\RootCategory;
use Blacklight\Releases;
use App\Services\Releases\ReleaseBrowseService;
use Illuminate\Http\Request;
class BrowseController extends BasePageController
{
private ReleaseBrowseService $releaseBrowseService;
public function __construct(ReleaseBrowseService $releaseBrowseService)
{
parent::__construct();
$this->releaseBrowseService = $releaseBrowseService;
}
/**
* @throws \Exception
*/
public function index(Request $request)
{
$releases = new Releases;
$ordering = $releases->getBrowseOrdering();
$ordering = $this->releaseBrowseService->getBrowseOrdering();
$orderBy = $request->has('ob') && ! empty($request->input('ob')) ? $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 = $releases->getBrowseRange($page, [-1], $offset, config('nntmux.items_per_page'), $orderBy, -1, $this->userdata->categoryexclusions, -1);
$rslt = $this->releaseBrowseService->getBrowseRange($page, [-1], $offset, config('nntmux.items_per_page'), $orderBy, -1, $this->userdata->categoryexclusions, -1);
$results = $this->paginate($rslt ?? [], $rslt[0]->_totalcount ?? 0, config('nntmux.items_per_page'), $page, $request->url(), $request->query());
// Build order by URLs
@@ -48,7 +54,6 @@ class BrowseController extends BasePageController
*/
public function show(Request $request, string $parentCategory, string $id = 'All')
{
$releases = new Releases;
$parentId = RootCategory::query()->where('title', $parentCategory)->value('id');
@@ -65,12 +70,12 @@ class BrowseController extends BasePageController
$catarray = [];
$catarray[] = $category;
$ordering = $releases->getBrowseOrdering();
$ordering = $this->releaseBrowseService->getBrowseOrdering();
$orderBy = $request->has('ob') && ! empty($request->input('ob')) ? $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 = $releases->getBrowseRange($page, $catarray, $offset, config('nntmux.items_per_page'), $orderBy, -1, $this->userdata->categoryexclusions, $grp);
$rslt = $this->releaseBrowseService->getBrowseRange($page, $catarray, $offset, config('nntmux.items_per_page'), $orderBy, -1, $this->userdata->categoryexclusions, $grp);
$results = $this->paginate($rslt ?? [], $rslt[0]->_totalcount ?? 0, config('nntmux.items_per_page'), $page, $request->url(), $request->query());
$covgroup = '';
@@ -139,12 +144,11 @@ class BrowseController extends BasePageController
*/
public function group(Request $request)
{
$releases = new Releases;
if ($request->has('g')) {
$group = $request->input('g');
$page = $request->has('page') && is_numeric($request->input('page')) ? $request->input('page') : 1;
$offset = ($page - 1) * config('nntmux.items_per_page');
$rslt = $releases->getBrowseRange($page, [-1], $offset, config('nntmux.items_per_page'), '', -1, $this->userdata->categoryexclusions, $group);
$rslt = $this->releaseBrowseService->getBrowseRange($page, [-1], $offset, config('nntmux.items_per_page'), '', -1, $this->userdata->categoryexclusions, $group);
$results = $this->paginate($rslt ?? [], $rslt[0]->_totalcount ?? 0, config('nntmux.items_per_page'), $page, $request->url(), $request->query());
$this->viewData = array_merge($this->viewData, [
+11 -4
View File
@@ -12,6 +12,7 @@ use App\Models\ReleaseRegex;
use App\Models\Settings;
use App\Models\UserDownload;
use App\Models\Video;
use App\Services\Releases\ReleaseSearchService;
use Blacklight\AniDB;
use Blacklight\Books;
use Blacklight\Console;
@@ -19,16 +20,22 @@ use Blacklight\Games;
use Blacklight\Movie;
use Blacklight\Music;
use Blacklight\ReleaseExtra;
use Blacklight\Releases;
use Blacklight\XXX;
use Illuminate\Http\Request;
class DetailsController extends BasePageController
{
private ReleaseSearchService $releaseSearchService;
public function __construct(ReleaseSearchService $releaseSearchService)
{
parent::__construct();
$this->releaseSearchService = $releaseSearchService;
}
public function show(Request $request, string $guid)
{
if ($guid !== null) {
$releases = new Releases;
$re = new ReleaseExtra;
$data = Release::getByGuid($guid);
$releaseRegex = '';
@@ -52,7 +59,7 @@ class DetailsController extends BasePageController
$reAudio = $re->getAudio($data['id']);
$reSubs = $re->getSubs($data['id']);
$comments = ReleaseComment::getComments($data['id']);
$similars = $releases->searchSimilar($data['id'], $data['searchname'], $this->userdata->categoryexclusions);
$similars = $this->releaseSearchService->searchSimilar($data['id'], $data['searchname'], $this->userdata->categoryexclusions);
$failed = DnzbFailure::getFailedCount($data['id']);
$downloadedBy = UserDownload::query()->with('user')->where('releases_id', $data['id'])->get(['users_id']);
@@ -121,7 +128,7 @@ class DetailsController extends BasePageController
$AniDBAPIArray = '';
if ($data['anidbid'] > 0) {
$AniDBAPIArray = (new AniDB)->getAnimeInfo($data['anidbid']);
// If we have anilist_id but missing details, fetch from AniList
if ($AniDBAPIArray && !empty($AniDBAPIArray->anilist_id)) {
$anilistId = is_object($AniDBAPIArray) ? $AniDBAPIArray->anilist_id : ($AniDBAPIArray['anilist_id'] ?? null);
+10 -2
View File
@@ -5,12 +5,20 @@ namespace App\Http\Controllers;
use App\Models\Category;
use App\Models\Settings;
use App\Models\UserMovie;
use App\Services\Releases\ReleaseBrowseService;
use Blacklight\Movie;
use Blacklight\Releases;
use Illuminate\Http\Request;
class MyMoviesController extends BasePageController
{
private ReleaseBrowseService $releaseBrowseService;
public function __construct(ReleaseBrowseService $releaseBrowseService)
{
parent::__construct();
$this->releaseBrowseService = $releaseBrowseService;
}
public function show(Request $request)
{
$mv = new Movie;
@@ -141,7 +149,7 @@ class MyMoviesController extends BasePageController
}
}
$ordering = (new Releases)->getBrowseOrdering();
$ordering = $this->releaseBrowseService->getBrowseOrdering();
$page = $request->has('page') && is_numeric($request->input('page')) ? $request->input('page') : 1;
+11 -5
View File
@@ -6,11 +6,19 @@ use App\Models\Category;
use App\Models\Settings;
use App\Models\UserSerie;
use App\Models\Video;
use Blacklight\Releases;
use App\Services\Releases\ReleaseBrowseService;
use Illuminate\Http\Request;
class MyShowsController extends BasePageController
{
private ReleaseBrowseService $releaseBrowseService;
public function __construct(ReleaseBrowseService $releaseBrowseService)
{
parent::__construct();
$this->releaseBrowseService = $releaseBrowseService;
}
public function show(Request $request)
{
$action = $request->input('action') ?? '';
@@ -168,15 +176,13 @@ class MyShowsController extends BasePageController
$shows = UserSerie::getShows($this->userdata->id);
$releases = new Releases;
$page = $request->has('page') && is_numeric($request->input('page')) ? $request->input('page') : 1;
$offset = ($page - 1) * config('nntmux.items_per_page');
$ordering = $releases->getBrowseOrdering();
$ordering = $this->releaseBrowseService->getBrowseOrdering();
$orderby = $request->has('ob') && \in_array($request->input('ob'), $ordering, false) ? $request->input('ob') : '';
$browseCount = $shows ? $shows->count() : 0;
$rslt = $releases->getShowsRange($shows ?? [], $offset, config('nntmux.items_per_page'), $orderby, -1, $this->userdata->categoryexclusions);
$rslt = $this->releaseBrowseService->getShowsRange($shows ?? [], $offset, config('nntmux.items_per_page'), $orderby, -1, $this->userdata->categoryexclusions);
$results = $this->paginate($rslt ?? [], $browseCount, config('nntmux.items_per_page'), $page, $request->url(), $request->query());
$this->viewData['covgroup'] = '';
+15 -8
View File
@@ -4,18 +4,26 @@ namespace App\Http\Controllers;
use App\Models\Category;
use App\Models\UsenetGroup;
use App\Services\Releases\ReleaseBrowseService;
use App\Services\Releases\ReleaseSearchService;
use App\Services\Search\Contracts\SearchServiceInterface;
use Blacklight\Releases;
use Illuminate\Http\Request;
class SearchController extends BasePageController
{
private SearchServiceInterface $searchService;
private ReleaseSearchService $releaseSearchService;
private ReleaseBrowseService $releaseBrowseService;
public function __construct(SearchServiceInterface $searchService)
{
public function __construct(
SearchServiceInterface $searchService,
ReleaseSearchService $releaseSearchService,
ReleaseBrowseService $releaseBrowseService
) {
parent::__construct();
$this->searchService = $searchService;
$this->releaseSearchService = $releaseSearchService;
$this->releaseBrowseService = $releaseBrowseService;
}
/**
@@ -23,7 +31,6 @@ class SearchController extends BasePageController
*/
public function search(Request $request)
{
$releases = new Releases;
$results = [];
@@ -32,7 +39,7 @@ class SearchController extends BasePageController
$searchType = 'advanced';
}
$ordering = $releases->getBrowseOrdering();
$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');
@@ -68,11 +75,11 @@ class SearchController extends BasePageController
}
$orderByUrls = [];
foreach ($releases->getBrowseOrdering() as $orderType) {
foreach ($this->releaseBrowseService->getBrowseOrdering() as $orderType) {
$orderByUrls['orderby'.$orderType] = url('/search?search='.htmlentities($searchString['searchname'], ENT_QUOTES | ENT_HTML5).'&t='.implode(',', $categoryID).'&ob='.$orderType);
}
$rslt = $releases->search(
$rslt = $this->releaseSearchService->search(
$searchString,
-1,
-1,
@@ -177,7 +184,7 @@ class SearchController extends BasePageController
'filename' => $searchVars['searchadvfilename'] === '' ? -1 : $searchVars['searchadvfilename'],
];
$rslt = $releases->search(
$rslt = $this->releaseSearchService->search(
$searchArr,
$searchVars['searchadvgroups'],
$searchVars['searchadvsizefrom'],
+10 -3
View File
@@ -5,19 +5,26 @@ namespace App\Http\Controllers;
use App\Models\TvEpisode;
use App\Models\UserSerie;
use App\Models\Video;
use Blacklight\Releases;
use App\Services\Releases\ReleaseSearchService;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
class SeriesController extends BasePageController
{
private ReleaseSearchService $releaseSearchService;
public function __construct(ReleaseSearchService $releaseSearchService)
{
parent::__construct();
$this->releaseSearchService = $releaseSearchService;
}
/**
* @throws \Exception
*/
public function index(Request $request, string $id = '')
{
$releases = new Releases;
if ($id && ctype_digit($id)) {
$category = -1;
@@ -33,7 +40,7 @@ class SeriesController extends BasePageController
$page = max($page, 1);
$offset = $seriesLimit > 0 ? ($page - 1) * $seriesLimit : 0;
$rel = $releases->tvSearch(['id' => $id], '', '', '', $offset, $seriesLimit, '', $catarray, -1);
$rel = $this->releaseSearchService->tvSearch(['id' => $id], '', '', '', $offset, $seriesLimit, '', $catarray, -1);
$show = Video::getByVideoID($id);
+2 -2
View File
@@ -400,11 +400,11 @@ class UsenetGroup extends Model
$res->get();
$releases = new Releases;
$releaseManagement = app(\App\Services\Releases\ReleaseManagementService::class);
$nzb = new NZB;
$releaseImage = new ReleaseImage;
foreach ($res as $row) {
$releases->deleteSingle(
$releaseManagement->deleteSingle(
[
'g' => $row['guid'],
'i' => $row['id'],
@@ -17,7 +17,6 @@ use App\Services\AdultProcessing\Pipes\IafdPipe;
use App\Services\AdultProcessing\Pipes\PoppornPipe;
use Blacklight\ColorCLI;
use Blacklight\ReleaseImage;
use Blacklight\Releases;
use Illuminate\Pipeline\Pipeline;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Concurrency;
@@ -74,7 +73,7 @@ class AdultProcessingPipeline
// 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 = (new Releases())->showPasswords();
$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;
+5 -5
View File
@@ -13,6 +13,7 @@ use App\Models\Release;
use App\Models\Settings;
use App\Models\UsenetGroup;
use App\Services\Categorization\CategorizationService;
use App\Services\Releases\ReleaseManagementService;
use App\Support\DTOs\ProcessReleasesSettings;
use App\Support\DTOs\ReleaseCreationResult;
use App\Support\DTOs\ReleaseDeleteStats;
@@ -22,7 +23,6 @@ use Blacklight\NNTP;
use Blacklight\NZB;
use Blacklight\ReleaseCleaning;
use Blacklight\ReleaseImage;
use Blacklight\Releases;
use DateTimeInterface;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
@@ -53,7 +53,7 @@ final class ReleaseProcessingService
private readonly ColorCLI $colorCLI;
private readonly NZB $nzb;
private readonly ReleaseCleaning $releaseCleaning;
private readonly Releases $releases;
private readonly ReleaseManagementService $releaseManagement;
private readonly ReleaseImage $releaseImage;
private readonly ReleaseCreationService $releaseCreationService;
private readonly CollectionCleanupService $collectionCleanupService;
@@ -63,7 +63,7 @@ final class ReleaseProcessingService
?ColorCLI $colorCLI = null,
?NZB $nzb = null,
?ReleaseCleaning $releaseCleaning = null,
?Releases $releases = null,
?ReleaseManagementService $releaseManagement = null,
?ReleaseImage $releaseImage = null,
?ReleaseCreationService $releaseCreationService = null,
?CollectionCleanupService $collectionCleanupService = null,
@@ -74,7 +74,7 @@ final class ReleaseProcessingService
$this->colorCLI = $colorCLI ?? new ColorCLI();
$this->nzb = $nzb ?? new NZB();
$this->releaseCleaning = $releaseCleaning ?? new ReleaseCleaning();
$this->releases = $releases ?? new Releases();
$this->releaseManagement = $releaseManagement ?? app(ReleaseManagementService::class);
$this->releaseImage = $releaseImage ?? new ReleaseImage();
$this->releaseCreationService = $releaseCreationService
@@ -1217,7 +1217,7 @@ final class ReleaseProcessingService
private function deleteSingleRelease(object $release): void
{
$this->releases->deleteSingle(
$this->releaseManagement->deleteSingle(
['g' => $release->guid, 'i' => $release->id],
$this->nzb,
$this->releaseImage
@@ -0,0 +1,411 @@
<?php
namespace App\Services\Releases;
use App\Models\Category;
use App\Models\Release;
use App\Models\Settings;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
/**
* Service for browsing and ordering releases on the frontend.
*/
class ReleaseBrowseService
{
private const CACHE_VERSION_KEY = 'releases:cache_version';
// RAR/ZIP Password indicator.
public const PASSWD_NONE = 0; // No password.
public const PASSWD_RAR = 1; // Definitely passworded.
public function __construct()
{
}
/**
* Used for Browse results.
*
* @return Collection|mixed
*/
public function getBrowseRange($page, $cat, $start, $num, $orderBy, int $maxAge = -1, array $excludedCats = [], int|string $groupName = -1, int $minSize = 0): mixed
{
$cacheVersion = $this->getCacheVersion();
$page = max(1, $page);
$start = max(0, $start);
$orderBy = $this->getBrowseOrder($orderBy);
$qry = sprintf(
"SELECT r.id, r.searchname, r.groups_id, r.guid, r.postdate, r.categories_id, r.size, r.totalpart, r.fromname, r.passwordstatus, r.grabs, r.comments, r.adddate, r.videos_id, r.tv_episodes_id, r.haspreview, r.jpgstatus, r.nfostatus, cp.title AS parent_category, c.title AS sub_category, r.group_name,
CONCAT(cp.title, ' > ', c.title) AS category_name,
CONCAT(cp.id, ',', c.id) AS category_ids,
df.failed AS failed,
rn.releases_id AS nfoid,
re.releases_id AS reid,
v.tvdb, v.trakt, v.tvrage, v.tvmaze, v.imdb, v.tmdb,
m.imdbid, m.tmdbid, m.traktid,
tve.title, tve.firstaired
FROM
(
SELECT r.id, r.searchname, r.guid, r.postdate, r.groups_id, r.categories_id, r.size, r.totalpart, r.fromname, r.passwordstatus, r.grabs, r.comments, r.adddate, r.videos_id, r.tv_episodes_id, r.haspreview, r.jpgstatus, r.nfostatus, g.name AS group_name, r.movieinfo_id
FROM releases r
LEFT JOIN usenet_groups g ON g.id = r.groups_id
WHERE r.passwordstatus %s
%s %s %s %s %s
ORDER BY %s %s %s
) r
LEFT JOIN categories c ON c.id = r.categories_id
LEFT JOIN root_categories cp ON cp.id = c.root_categories_id
LEFT OUTER JOIN videos v ON r.videos_id = v.id
LEFT OUTER JOIN tv_episodes tve ON r.tv_episodes_id = tve.id
LEFT OUTER JOIN movieinfo m ON m.id = r.movieinfo_id
LEFT OUTER JOIN video_data re ON re.releases_id = r.id
LEFT OUTER JOIN release_nfos rn ON rn.releases_id = r.id
LEFT OUTER JOIN dnzb_failures df ON df.release_id = r.id
GROUP BY r.id
ORDER BY %7\$s %8\$s",
$this->showPasswords(),
Category::getCategorySearch($cat),
($maxAge > 0 ? (' AND postdate > NOW() - INTERVAL '.$maxAge.' DAY ') : ''),
(\count($excludedCats) ? (' AND r.categories_id NOT IN ('.implode(',', $excludedCats).')') : ''),
((int) $groupName !== -1 ? sprintf(' AND g.name = %s ', escapeString($groupName)) : ''),
($minSize > 0 ? sprintf('AND r.size >= %d', $minSize) : ''),
$orderBy[0],
$orderBy[1],
($start === 0 ? ' LIMIT '.$num : ' LIMIT '.$num.' OFFSET '.$start)
);
$cacheKey = md5($cacheVersion.$qry.$page);
$releases = Cache::get($cacheKey);
if ($releases !== null) {
return $releases;
}
$sql = DB::select($qry);
if (\count($sql) > 0) {
$possibleRows = $this->getBrowseCount($cat, $maxAge, $excludedCats, $groupName);
$sql[0]->_totalcount = $sql[0]->_totalrows = $possibleRows;
}
$expiresAt = now()->addMinutes(config('nntmux.cache_expiry_medium'));
Cache::put($cacheKey, $sql, $expiresAt);
return $sql;
}
/**
* Used for pager on browse page.
*/
public function getBrowseCount(array $cat, int $maxAge = -1, array $excludedCats = [], int|string $groupName = ''): int
{
return $this->getPagerCount(sprintf(
'SELECT COUNT(r.id) AS count
FROM releases r
%s
WHERE r.passwordstatus %s
%s
%s %s %s ',
($groupName !== -1 ? 'LEFT JOIN usenet_groups g ON g.id = r.groups_id' : ''),
$this->showPasswords(),
($groupName !== -1 ? sprintf(' AND g.name = %s', escapeString($groupName)) : ''),
Category::getCategorySearch($cat),
($maxAge > 0 ? (' AND r.postdate > NOW() - INTERVAL '.$maxAge.' DAY ') : ''),
(\count($excludedCats) ? (' AND r.categories_id NOT IN ('.implode(',', $excludedCats).')') : '')
));
}
/**
* Get the passworded releases clause.
*/
public function showPasswords(): string
{
$show = (int) Settings::settingValue('showpasswordedrelease');
$setting = $show ?? 0;
return match ($setting) {
1 => '<= '.self::PASSWD_RAR,
default => '= '.self::PASSWD_NONE,
};
}
/**
* Use to order releases on site.
*/
public function getBrowseOrder(array|string $orderBy): array
{
$orderArr = explode('_', ($orderBy === '' ? 'posted_desc' : $orderBy));
$orderField = match ($orderArr[0]) {
'cat' => 'categories_id',
'name' => 'searchname',
'size' => 'size',
'files' => 'totalpart',
'stats' => 'grabs',
default => 'postdate',
};
return [$orderField, isset($orderArr[1]) && preg_match('/^(asc|desc)$/i', $orderArr[1]) ? $orderArr[1] : 'desc'];
}
/**
* Return ordering types usable on site.
*
* @return string[]
*/
public function getBrowseOrdering(): array
{
return [
'name_asc',
'name_desc',
'cat_asc',
'cat_desc',
'posted_asc',
'posted_desc',
'size_asc',
'size_desc',
'files_asc',
'files_desc',
'stats_asc',
'stats_desc',
];
}
/**
* @return \Illuminate\Cache\|\Illuminate\Database\Eloquent\Collection|mixed
*/
public function getShowsRange($userShows, $offset, $limit, $orderBy, int $maxAge = -1, array $excludedCats = [])
{
$orderBy = $this->getBrowseOrder($orderBy);
$sql = sprintf(
"SELECT r.id, r.searchname, r.guid, r.postdate, r.groups_id, r.categories_id, r.size, r.totalpart, r.fromname, r.passwordstatus, r.grabs, r.comments, r.adddate, r.videos_id, r.tv_episodes_id, r.haspreview, r.jpgstatus, cp.title AS parent_category, c.title AS sub_category,
CONCAT(cp.title, '->', c.title) AS category_name
FROM releases r
LEFT JOIN categories c ON c.id = r.categories_id
LEFT JOIN root_categories cp ON cp.id = c.root_categories_id
WHERE %s %s
AND r.categories_id BETWEEN %d AND %d
AND r.passwordstatus %s
%s
GROUP BY r.id
ORDER BY %s %s %s",
$this->uSQL($userShows, 'videos_id'),
(! empty($excludedCats) ? ' AND r.categories_id NOT IN ('.implode(',', $excludedCats).')' : ''),
Category::TV_ROOT,
Category::TV_OTHER,
$this->showPasswords(),
($maxAge > 0 ? sprintf(' AND r.postdate > NOW() - INTERVAL %d DAY ', $maxAge) : ''),
$orderBy[0],
$orderBy[1],
($offset === false ? '' : (' LIMIT '.$limit.' OFFSET '.$offset))
);
$expiresAt = now()->addMinutes(config('nntmux.cache_expiry_long'));
$result = Cache::get(md5($sql));
if ($result !== null) {
return $result;
}
$result = Release::fromQuery($sql);
Cache::put(md5($sql), $result, $expiresAt);
return $result;
}
public function getShowsCount($userShows, int $maxAge = -1, array $excludedCats = []): int
{
return $this->getPagerCount(
sprintf(
'SELECT r.id
FROM releases r
WHERE %s %s
AND r.categories_id BETWEEN %d AND %d
AND r.passwordstatus %s
%s',
$this->uSQL($userShows, 'videos_id'),
(\count($excludedCats) ? ' AND r.categories_id NOT IN ('.implode(',', $excludedCats).')' : ''),
Category::TV_ROOT,
Category::TV_OTHER,
$this->showPasswords(),
($maxAge > 0 ? sprintf(' AND r.postdate > NOW() - INTERVAL %d DAY ', $maxAge) : '')
)
);
}
/**
* Creates part of a query for some functions.
*/
public function uSQL(Collection|array $userQuery, string $type): string
{
$sql = '(1=2 ';
foreach ($userQuery as $query) {
$sql .= sprintf('OR (r.%s = %d', $type, $query->$type);
if (! empty($query->categories)) {
$catsArr = explode('|', $query->categories);
if (\count($catsArr) > 1) {
$sql .= sprintf(' AND r.categories_id IN (%s)', implode(',', $catsArr));
} else {
$sql .= sprintf(' AND r.categories_id = %d', $catsArr[0]);
}
}
$sql .= ') ';
}
$sql .= ') ';
return $sql;
}
public static function bumpCacheVersion(): void
{
$current = Cache::get(self::CACHE_VERSION_KEY, 1);
Cache::forever(self::CACHE_VERSION_KEY, $current + 1);
}
private function getCacheVersion(): int
{
return Cache::get(self::CACHE_VERSION_KEY, 1);
}
/**
* Get the count of releases for pager.
*
* @param string $query The query to get the count from.
*/
private function getPagerCount(string $query): int
{
$maxResults = (int) config('nntmux.max_pager_results');
$cacheExpiry = config('nntmux.cache_expiry_short');
// Generate cache key from original query
$cacheKey = 'pager_count_'.md5($query);
// Check cache first
$count = Cache::get($cacheKey);
if ($count !== null) {
return (int) $count;
}
// Check if this is already a COUNT query
if (preg_match('/SELECT\s+COUNT\s*\(/is', $query)) {
// It's already a COUNT query, just execute it
try {
$result = DB::select($query);
if (isset($result[0])) {
// Handle different possible column names
$count = $result[0]->count ?? $result[0]->total ?? 0;
// Check for COUNT(*) result without alias
if ($count === 0) {
foreach ($result[0] as $value) {
$count = (int) $value;
break;
}
}
} else {
$count = 0;
}
// Cap the count at max results if applicable
if ($maxResults > 0 && $count > $maxResults) {
$count = $maxResults;
}
// Cache the result
Cache::put($cacheKey, $count, now()->addMinutes($cacheExpiry));
return $count;
} catch (\Exception $e) {
return 0;
}
}
// For regular SELECT queries, optimize for counting
$countQuery = $query;
// Remove ORDER BY clause (not needed for COUNT)
$countQuery = preg_replace('/ORDER\s+BY\s+[^)]+$/is', '', $countQuery);
// Remove GROUP BY if it's only grouping by r.id
$countQuery = preg_replace('/GROUP\s+BY\s+r\.id\s*$/is', '', $countQuery);
// Check if query has DISTINCT in SELECT
$hasDistinct = preg_match('/SELECT\s+DISTINCT/is', $countQuery);
// Replace SELECT clause with COUNT
if ($hasDistinct || preg_match('/GROUP\s+BY/is', $countQuery)) {
// For queries with DISTINCT or GROUP BY, count distinct r.id
$countQuery = preg_replace(
'/SELECT\s+.+?\s+FROM/is',
'SELECT COUNT(DISTINCT r.id) as count FROM',
$countQuery
);
} else {
// For simple queries, use COUNT(*)
$countQuery = preg_replace(
'/SELECT\s+.+?\s+FROM/is',
'SELECT COUNT(*) as count FROM',
$countQuery
);
}
// Remove LIMIT/OFFSET from the count query
$countQuery = preg_replace('/LIMIT\s+\d+(\s+OFFSET\s+\d+)?$/is', '', $countQuery);
try {
// If max results is set and query might return too many results
if ($maxResults > 0) {
// First check if count would exceed max
$testQuery = sprintf('SELECT 1 FROM (%s) as test LIMIT %d',
preg_replace('/SELECT\s+COUNT.+?\s+FROM/is', 'SELECT 1 FROM', $countQuery),
$maxResults + 1
);
$testResult = DB::select($testQuery);
if (count($testResult) > $maxResults) {
Cache::put($cacheKey, $maxResults, now()->addMinutes($cacheExpiry));
return $maxResults;
}
}
// Execute the count query
$result = DB::select($countQuery);
$count = isset($result[0]) ? (int) $result[0]->count : 0;
// Cache the result
Cache::put($cacheKey, $count, now()->addMinutes($cacheExpiry));
return $count;
} catch (\Exception $e) {
// If optimization fails, try a simpler approach
try {
// Extract the core table and WHERE conditions
if (preg_match('/FROM\s+releases\s+r\s+(.+?)(?:ORDER\s+BY|LIMIT|$)/is', $query, $matches)) {
$conditions = $matches[1];
// Remove JOINs but keep WHERE
$conditions = preg_replace('/(?:LEFT\s+|INNER\s+)?(?:OUTER\s+)?JOIN\s+.+?(?=WHERE|LEFT|INNER|JOIN|$)/is', '', $conditions);
$fallbackQuery = sprintf('SELECT COUNT(*) as count FROM releases r %s', trim($conditions));
if ($maxResults > 0) {
$fallbackQuery = sprintf('SELECT COUNT(*) as count FROM (SELECT 1 FROM releases r %s LIMIT %d) as limited',
trim($conditions),
$maxResults
);
}
$result = DB::select($fallbackQuery);
$count = isset($result[0]) ? (int) $result[0]->count : 0;
Cache::put($cacheKey, $count, now()->addMinutes($cacheExpiry));
return $count;
}
} catch (\Exception $fallbackException) {
// Log the error for debugging
\Illuminate\Support\Facades\Log::error('getPagerCount failed', [
'query' => $query,
'error' => $fallbackException->getMessage(),
]);
}
return 0;
}
}
}
@@ -0,0 +1,190 @@
<?php
namespace App\Services\Releases;
use App\Models\Release;
use App\Services\Search\ManticoreSearchService;
use Blacklight\NZB;
use Blacklight\ReleaseImage;
use Elasticsearch;
use Elasticsearch\Common\Exceptions\Missing404Exception;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
/**
* Service for managing releases (delete, update, export).
*/
class ReleaseManagementService
{
private ManticoreSearchService $manticoreSearch;
public function __construct(
ManticoreSearchService $manticoreSearch
) {
$this->manticoreSearch = $manticoreSearch;
}
/**
* @throws \Exception
*/
public function deleteMultiple(int|array|string $list): void
{
$list = (array) $list;
$nzb = new NZB;
$releaseImage = new ReleaseImage;
foreach ($list as $identifier) {
$this->deleteSingle(['g' => $identifier, 'i' => false], $nzb, $releaseImage);
}
}
/**
* Deletes a single release by GUID, and all the corresponding files.
*
* @param array $identifiers ['g' => Release GUID(mandatory), 'id => ReleaseID(optional, pass
* false)]
*
* @throws \Exception
*/
public function deleteSingle(array $identifiers, NZB $nzb, ReleaseImage $releaseImage): void
{
// Delete NZB from disk.
$nzbPath = $nzb->NZBPath($identifiers['g']);
if (! empty($nzbPath)) {
File::delete($nzbPath);
}
// Delete images.
$releaseImage->delete($identifiers['g']);
if (config('nntmux.elasticsearch_enabled') === true) {
if ($identifiers['i'] === false) {
$identifiers['i'] = Release::query()->where('guid', $identifiers['g'])->first(['id']);
if ($identifiers['i'] !== null) {
$identifiers['i'] = $identifiers['i']['id'];
}
}
if ($identifiers['i'] !== null) {
$params = [
'index' => 'releases',
'id' => $identifiers['i'],
];
try {
Elasticsearch::delete($params);
} catch (Missing404Exception $e) {
// we do nothing here just catch the error, we don't care if release is missing from ES, we are deleting it anyway
}
}
} else {
// Delete from Manticore
if ($identifiers['i'] === false) {
$release = Release::query()->where('guid', $identifiers['g'])->first(['id']);
if ($release !== null) {
$identifiers['i'] = $release->id;
}
}
if (!empty($identifiers['i'])) {
$this->manticoreSearch->deleteRelease((int) $identifiers['i']);
}
}
// Delete from DB.
Release::whereGuid($identifiers['g'])->delete();
}
/**
* @return bool|int
*/
public function updateMulti($guids, $category, $grabs, $videoId, $episodeId, $anidbId, $imdbId)
{
if (! \is_array($guids) || \count($guids) < 1) {
return false;
}
$update = [
'categories_id' => $category === -1 ? 'categories_id' : $category,
'grabs' => $grabs,
'videos_id' => $videoId,
'tv_episodes_id' => $episodeId,
'anidbid' => $anidbId,
'imdbid' => $imdbId,
];
return Release::query()->whereIn('guid', $guids)->update($update);
}
/**
* @return Release[]|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Query\Builder[]|\Illuminate\Support\Collection
*/
public function getForExport(string $postFrom = '', string $postTo = '', string $groupID = '')
{
$query = Release::query()
->select(['r.searchname', 'r.guid', 'g.name as gname', DB::raw("CONCAT(cp.title,'_',c.title) AS catName")])
->from('releases as r')
->leftJoin('categories as c', 'c.id', '=', 'r.categories_id')
->leftJoin('root_categories as cp', 'cp.id', '=', 'c.root_categories_id')
->leftJoin('usenet_groups as g', 'g.id', '=', 'r.groups_id');
if ($groupID !== '') {
$query->where('r.groups_id', $groupID);
}
if ($postFrom !== '') {
$dateParts = explode('/', $postFrom);
if (\count($dateParts) === 3) {
$query->where('r.postdate', '>', $dateParts[2].'-'.$dateParts[1].'-'.$dateParts[0].'00:00:00');
}
}
if ($postTo !== '') {
$dateParts = explode('/', $postTo);
if (\count($dateParts) === 3) {
$query->where('r.postdate', '<', $dateParts[2].'-'.$dateParts[1].'-'.$dateParts[0].'23:59:59');
}
}
return $query->get();
}
/**
* @return mixed|string
*/
public function getEarliestUsenetPostDate(): mixed
{
$row = Release::query()->selectRaw("DATE_FORMAT(min(postdate), '%d/%m/%Y') AS postdate")->first();
return $row === null ? '01/01/2014' : $row['postdate'];
}
/**
* @return mixed|string
*/
public function getLatestUsenetPostDate(): mixed
{
$row = Release::query()->selectRaw("DATE_FORMAT(max(postdate), '%d/%m/%Y') AS postdate")->first();
return $row === null ? '01/01/2014' : $row['postdate'];
}
public function getReleasedGroupsForSelect(bool $blnIncludeAll = true): array
{
$groups = Release::query()
->selectRaw('DISTINCT g.id, g.name')
->leftJoin('usenet_groups as g', 'g.id', '=', 'releases.groups_id')
->get();
$temp_array = [];
if ($blnIncludeAll) {
$temp_array[-1] = '--All Groups--';
}
foreach ($groups as $group) {
$temp_array[$group['id']] = $group['name'];
}
return $temp_array;
}
}
File diff suppressed because it is too large Load Diff
@@ -402,6 +402,15 @@ class ManticoreSearchService implements SearchServiceInterface
return [];
}
if (config('app.debug')) {
Log::debug('ManticoreSearch::searchIndexes called', [
'rt_index' => $rt_index,
'searchString' => $searchString,
'column' => $column,
'searchArray' => $searchArray,
]);
}
// Create cache key for search results
$cacheKey = md5(serialize([
'index' => $rt_index,
@@ -412,6 +421,12 @@ class ManticoreSearchService implements SearchServiceInterface
$cached = Cache::get($cacheKey);
if ($cached !== null) {
if (config('app.debug')) {
Log::debug('ManticoreSearch::searchIndexes returning cached result', [
'cacheKey' => $cacheKey,
'cached_ids_count' => count($cached['id'] ?? []),
]);
}
return $cached;
}
@@ -430,11 +445,17 @@ class ManticoreSearchService implements SearchServiceInterface
if (! empty($terms)) {
$searchExpr = implode(' ', $terms);
} else {
if (config('app.debug')) {
Log::debug('ManticoreSearch::searchIndexes no terms after escaping searchArray');
}
return [];
}
} elseif (! empty($searchString)) {
$escapedSearch = self::escapeString($searchString);
if (empty($escapedSearch)) {
if (config('app.debug')) {
Log::debug('ManticoreSearch::searchIndexes escapedSearch is empty');
}
return [];
}