NameFixingService::fixNamesWithMedia()   A
last analyzed

Complexity

Conditions 4
Paths 6

Size

Total Lines 51
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 40
dl 0
loc 51
rs 9.28
c 1
b 0
f 0
cc 4
nc 6
nop 5

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace App\Services\NameFixing;
6
7
use App\Facades\Search;
8
use App\Models\Category;
9
use App\Models\Release;
10
use App\Services\NameFixing\Extractors\FileNameExtractor;
11
use App\Services\NameFixing\Extractors\NfoNameExtractor;
12
use App\Services\NNTP\NNTPService;
13
14
/**
15
 * Main service for name fixing operations.
16
 *
17
 * Orchestrates the various name fixing sources (NFO, Files, CRC, SRR, etc.)
18
 * and handles the overall processing flow.
19
 */
20
class NameFixingService
21
{
22
    // Constants for name fixing status
23
    public const PROC_NFO_NONE = 0;
24
25
    public const PROC_NFO_DONE = 1;
26
27
    public const PROC_FILES_NONE = 0;
28
29
    public const PROC_FILES_DONE = 1;
30
31
    public const PROC_PAR2_NONE = 0;
32
33
    public const PROC_PAR2_DONE = 1;
34
35
    public const PROC_UID_NONE = 0;
36
37
    public const PROC_UID_DONE = 1;
38
39
    public const PROC_HASH16K_NONE = 0;
40
41
    public const PROC_HASH16K_DONE = 1;
42
43
    public const PROC_SRR_NONE = 0;
44
45
    public const PROC_SRR_DONE = 1;
46
47
    public const PROC_CRC_NONE = 0;
48
49
    public const PROC_CRC_DONE = 1;
50
51
    // Constants for overall rename status
52
    public const IS_RENAMED_NONE = 0;
53
54
    public const IS_RENAMED_DONE = 1;
55
56
    protected ReleaseUpdateService $updateService;
57
58
    protected NameCheckerService $checkerService;
59
60
    protected NfoNameExtractor $nfoExtractor;
61
62
    protected FileNameExtractor $fileExtractor;
63
64
    protected FileNameCleaner $fileNameCleaner;
65
66
    protected FilePrioritizer $filePrioritizer;
67
68
    protected bool $echoOutput;
69
70
    protected string $othercats;
71
72
    protected string $timeother;
73
74
    protected string $timeall;
75
76
    protected string $fullother;
77
78
    protected string $fullall;
79
80
    protected int $_totalReleases = 0;
81
82
    public function __construct(
83
        ?ReleaseUpdateService $updateService = null,
84
        ?NameCheckerService $checkerService = null,
85
        ?NfoNameExtractor $nfoExtractor = null,
86
        ?FileNameExtractor $fileExtractor = null,
87
        ?FileNameCleaner $fileNameCleaner = null,
88
        ?FilePrioritizer $filePrioritizer = null
89
    ) {
90
        $this->updateService = $updateService ?? new ReleaseUpdateService;
91
        $this->checkerService = $checkerService ?? new NameCheckerService;
92
        $this->nfoExtractor = $nfoExtractor ?? new NfoNameExtractor;
93
        $this->fileExtractor = $fileExtractor ?? new FileNameExtractor;
94
        $this->fileNameCleaner = $fileNameCleaner ?? new FileNameCleaner;
95
        $this->filePrioritizer = $filePrioritizer ?? new FilePrioritizer;
96
        $this->echoOutput = config('nntmux.echocli');
97
98
        $this->othercats = implode(',', Category::OTHERS_GROUP);
99
        $this->timeother = sprintf(' AND rel.adddate > (NOW() - INTERVAL 6 HOUR) AND rel.categories_id IN (%s) GROUP BY rel.id ORDER BY postdate DESC', $this->othercats);
100
        $this->timeall = ' AND rel.adddate > (NOW() - INTERVAL 6 HOUR) GROUP BY rel.id ORDER BY postdate DESC';
101
        $this->fullother = sprintf(' AND rel.categories_id IN (%s) GROUP BY rel.id', $this->othercats);
102
        $this->fullall = '';
103
    }
104
105
    /**
106
     * Fix names using NFO content.
107
     */
108
    public function fixNamesWithNfo(int $time, bool $echo, int $cats, bool $nameStatus, bool $show): void
109
    {
110
        $this->echoStartMessage($time, '.nfo files');
111
        $type = 'NFO, ';
112
113
        $preId = false;
114
        if ($cats === 3) {
115
            $query = sprintf(
116
                'SELECT rel.id AS releases_id, rel.fromname
117
                FROM releases rel
118
                INNER JOIN release_nfos nfo ON (nfo.releases_id = rel.id)
119
                WHERE rel.predb_id = 0'
120
            );
121
            $cats = 2;
122
            $preId = true;
123
        } else {
124
            $query = sprintf(
125
                'SELECT rel.id AS releases_id, rel.fromname
126
                FROM releases rel
127
                INNER JOIN release_nfos nfo ON (nfo.releases_id = rel.id)
128
                WHERE (rel.isrenamed = %d OR rel.categories_id IN (%d, %d))
129
                AND rel.predb_id = 0
130
                AND rel.proc_nfo = %d',
131
                self::IS_RENAMED_NONE,
132
                Category::OTHER_MISC,
133
                Category::OTHER_HASHED,
134
                self::PROC_NFO_NONE
135
            );
136
        }
137
138
        $releases = $this->getReleases($time, $cats, $query);
139
        $total = $releases->count();
140
141
        if ($total > 0) {
142
            $this->_totalReleases = $total;
143
            cli()->info(number_format($total).' releases to process.');
144
145
            foreach ($releases as $rel) {
146
                $releaseRow = Release::fromQuery(
147
                    sprintf(
148
                        'SELECT nfo.releases_id AS nfoid, rel.groups_id, rel.fromname, rel.categories_id, rel.name, rel.searchname,
149
                            UNCOMPRESS(nfo) AS textstring, rel.id AS releases_id
150
                        FROM releases rel
151
                        INNER JOIN release_nfos nfo ON (nfo.releases_id = rel.id)
152
                        WHERE rel.id = %d LIMIT 1',
153
                        $rel->releases_id
154
                    )
155
                );
156
157
                $this->updateService->incrementChecked();
158
159
                // Ignore encrypted NFOs
160
                if (preg_match('/^=newz\[NZB\]=\w+/', $releaseRow[0]->textstring)) {
161
                    $this->updateService->updateSingleColumn('proc_nfo', self::PROC_NFO_DONE, $rel->releases_id);
162
163
                    continue;
164
                }
165
166
                $this->updateService->reset();
167
168
                // Try NFO extraction
169
                $nfoResult = $this->nfoExtractor->extractFromNfo($releaseRow[0]->textstring);
170
                if ($nfoResult !== null) {
171
                    $this->updateService->updateRelease(
172
                        $releaseRow[0],
173
                        $nfoResult->newName,
174
                        'nfoCheck: '.$nfoResult->method,
175
                        $echo,
176
                        $type,
177
                        $nameStatus,
178
                        $show
179
                    );
180
                }
181
182
                // If NFO extraction didn't work, try pattern checkers
183
                if (! $this->updateService->matched) {
184
                    $this->checkWithPatternMatchers($releaseRow[0], $echo, $type, $nameStatus, $show, $preId);
185
                }
186
187
                $this->echoRenamed($show);
188
            }
189
            $this->echoFoundCount($echo, ' NFO\'s');
190
        } else {
191
            cli()->info('Nothing to fix.');
192
        }
193
    }
194
195
    /**
196
     * Fix names using file names.
197
     */
198
    public function fixNamesWithFiles(int $time, bool $echo, int $cats, bool $nameStatus, bool $show): void
199
    {
200
        $this->echoStartMessage($time, 'file names');
201
        $type = 'Filenames, ';
202
203
        $preId = false;
0 ignored issues
show
Unused Code introduced by
The assignment to $preId is dead and can be removed.
Loading history...
204
        if ($cats === 3) {
205
            $query = sprintf(
206
                'SELECT rf.name AS textstring, rel.categories_id, rel.name, rel.searchname, rel.fromname, rel.groups_id,
207
                    rf.releases_id AS fileid, rel.id AS releases_id
208
                FROM releases rel
209
                INNER JOIN release_files rf ON rf.releases_id = rel.id
210
                WHERE predb_id = 0'
211
            );
212
            $cats = 2;
213
            $preId = true;
214
        } else {
215
            $query = sprintf(
216
                'SELECT rf.name AS textstring, rel.categories_id, rel.name, rel.searchname, rel.fromname, rel.groups_id,
217
                    rf.releases_id AS fileid, rel.id AS releases_id
218
                FROM releases rel
219
                INNER JOIN release_files rf ON rf.releases_id = rel.id
220
                WHERE (rel.isrenamed = %d OR rel.categories_id IN (%d, %d))
221
                AND rel.predb_id = 0
222
                AND proc_files = %d',
223
                self::IS_RENAMED_NONE,
224
                Category::OTHER_MISC,
225
                Category::OTHER_HASHED,
226
                self::PROC_FILES_NONE
227
            );
228
        }
229
230
        $releases = $this->getReleases($time, $cats, $query);
231
        $total = $releases->count();
232
233
        if ($total > 0) {
234
            $this->_totalReleases = $total;
235
            cli()->info(number_format($total).' file names to process.');
236
237
            // Group files by release
238
            $releaseFiles = [];
239
            foreach ($releases as $release) {
240
                $releaseId = $release->releases_id;
241
                if (! isset($releaseFiles[$releaseId])) {
242
                    $releaseFiles[$releaseId] = [
243
                        'release' => $release,
244
                        'files' => [],
245
                    ];
246
                }
247
                $releaseFiles[$releaseId]['files'][] = $release->textstring;
248
            }
249
250
            foreach ($releaseFiles as $releaseId => $data) {
251
                $this->updateService->reset();
252
                $this->updateService->incrementChecked();
253
254
                // Prioritize files for matching
255
                $prioritizedFiles = $this->filePrioritizer->prioritizeForMatching($data['files']);
256
257
                foreach ($prioritizedFiles as $filename) {
258
                    $release = clone $data['release'];
259
                    $release->textstring = $filename;
260
261
                    // Try file name extraction
262
                    $fileResult = $this->fileExtractor->extractFromFile($filename);
263
                    if ($fileResult !== null) {
264
                        $this->updateService->updateRelease(
265
                            $release,
266
                            $fileResult->newName,
267
                            'fileCheck: '.$fileResult->method,
268
                            $echo,
269
                            $type,
270
                            $nameStatus,
271
                            $show
272
                        );
273
                    }
274
275
                    // If not matched, try PreDB search
276
                    if (! $this->updateService->matched) {
277
                        $this->preDbFileCheck($release, $echo, $type, $nameStatus, $show);
278
                    }
279
280
                    if (! $this->updateService->matched) {
281
                        $this->preDbTitleCheck($release, $echo, $type, $nameStatus, $show);
282
                    }
283
284
                    if ($this->updateService->matched) {
285
                        break;
286
                    }
287
                }
288
289
                $this->echoRenamed($show);
290
            }
291
292
            $this->echoFoundCount($echo, ' files');
293
        } else {
294
            cli()->info('Nothing to fix.');
295
        }
296
    }
297
298
    /**
299
     * Fix names using SRR files.
300
     */
301
    public function fixNamesWithSrr(int $time, bool $echo, int $cats, bool $nameStatus, bool $show): void
302
    {
303
        $this->echoStartMessage($time, 'SRR file names');
304
        $type = 'SRR, ';
305
306
        if ($cats === 3) {
307
            $query = sprintf(
308
                'SELECT rf.name AS textstring, rel.categories_id, rel.name, rel.searchname, rel.fromname, rel.groups_id,
309
                    rf.releases_id AS fileid, rel.id AS releases_id
310
                FROM releases rel
311
                INNER JOIN release_files rf ON (rf.releases_id = rel.id)
312
                WHERE predb_id = 0
313
                AND (rf.name LIKE %s OR rf.name LIKE %s)',
314
                escapeString('%.srr'),
315
                escapeString('%.srs')
316
            );
317
            $cats = 2;
318
        } else {
319
            $query = sprintf(
320
                'SELECT rf.name AS textstring, rel.categories_id, rel.name, rel.searchname, rel.fromname, rel.groups_id,
321
                    rf.releases_id AS fileid, rel.id AS releases_id
322
                FROM releases rel
323
                INNER JOIN release_files rf ON (rf.releases_id = rel.id)
324
                WHERE (rel.isrenamed = %d OR rel.categories_id IN (%d, %d))
325
                AND rel.predb_id = 0
326
                AND (rf.name LIKE %s OR rf.name LIKE %s)
327
                AND rel.proc_srr = %d',
328
                self::IS_RENAMED_NONE,
329
                Category::OTHER_MISC,
330
                Category::OTHER_HASHED,
331
                escapeString('%.srr'),
332
                escapeString('%.srs'),
333
                self::PROC_SRR_NONE
334
            );
335
        }
336
337
        $releases = $this->getReleases($time, $cats, $query);
338
        $total = $releases->count();
339
340
        if ($total > 0) {
341
            $this->_totalReleases = $total;
342
            cli()->info(number_format($total).' srr file extensions to process.');
343
344
            foreach ($releases as $release) {
345
                $this->updateService->reset();
346
                $this->updateService->incrementChecked();
347
348
                $this->srrNameCheck($release, $echo, $type, $nameStatus, $show);
349
                $this->echoRenamed($show);
350
            }
351
352
            $this->echoFoundCount($echo, ' files');
353
        } else {
354
            cli()->info('Nothing to fix.');
355
        }
356
    }
357
358
    /**
359
     * Fix names using CRC32 hashes.
360
     */
361
    public function fixNamesWithCrc(int $time, bool $echo, int $cats, bool $nameStatus, bool $show): void
362
    {
363
        $this->echoStartMessage($time, 'CRC32');
364
        $type = 'CRC32, ';
365
366
        $preId = false;
367
        if ($cats === 3) {
368
            $query = sprintf(
369
                'SELECT rf.crc32 AS textstring, rf.name AS filename, rel.categories_id, rel.name, rel.searchname, rel.fromname, rel.groups_id, rel.size as relsize,
370
                    rf.releases_id AS fileid, rel.id AS releases_id
371
                FROM releases rel
372
                INNER JOIN release_files rf ON rf.releases_id = rel.id
373
                WHERE predb_id = 0
374
                AND rf.crc32 != \'\'
375
                AND rf.crc32 IS NOT NULL'
376
            );
377
            $cats = 2;
378
            $preId = true;
379
        } else {
380
            $query = sprintf(
381
                'SELECT rf.crc32 AS textstring, rf.name AS filename, rel.categories_id, rel.name, rel.searchname, rel.fromname, rel.groups_id, rel.size as relsize,
382
                    rf.releases_id AS fileid, rel.id AS releases_id
383
                FROM releases rel
384
                INNER JOIN release_files rf ON rf.releases_id = rel.id
385
                WHERE (rel.isrenamed = %d OR rel.categories_id IN (%d, %d))
386
                AND rel.predb_id = 0
387
                AND rel.proc_crc32 = %d
388
                AND rf.crc32 != \'\'
389
                AND rf.crc32 IS NOT NULL',
390
                self::IS_RENAMED_NONE,
391
                Category::OTHER_MISC,
392
                Category::OTHER_HASHED,
393
                self::PROC_CRC_NONE
394
            );
395
        }
396
397
        $releases = $this->getReleases($time, $cats, $query);
398
        $total = $releases->count();
399
400
        if ($total > 0) {
401
            $this->_totalReleases = $total;
402
            cli()->info(number_format($total).' CRC32\'s to process.');
403
404
            // Group by release
405
            $releasesCrc = [];
406
            foreach ($releases as $release) {
407
                $releaseId = $release->releases_id;
408
                if (! isset($releasesCrc[$releaseId])) {
409
                    $releasesCrc[$releaseId] = [
410
                        'release' => $release,
411
                        'crcs' => [],
412
                    ];
413
                }
414
                if (! empty($release->textstring)) {
415
                    $priority = $this->filePrioritizer->getCrcPriority($release->filename ?? '');
416
                    $releasesCrc[$releaseId]['crcs'][$priority][] = $release->textstring;
417
                }
418
            }
419
420
            foreach ($releasesCrc as $releaseId => $data) {
421
                $this->updateService->reset();
422
                $this->updateService->incrementChecked();
423
424
                ksort($data['crcs']);
425
                foreach ($data['crcs'] as $crcs) {
426
                    foreach ($crcs as $crc) {
427
                        $release = clone $data['release'];
428
                        $release->textstring = $crc;
429
430
                        $this->crcCheck($release, $echo, $type, $nameStatus, $show, $preId);
431
432
                        if ($this->updateService->matched) {
433
                            break 2;
434
                        }
435
                    }
436
                }
437
438
                $this->echoRenamed($show);
439
            }
440
441
            $this->echoFoundCount($echo, ' crc32\'s');
442
        } else {
443
            cli()->info('Nothing to fix.');
444
        }
445
    }
446
447
    /**
448
     * Fix names using Media info unique IDs.
449
     */
450
    public function fixNamesWithMedia(int $time, bool $echo, int $cats, bool $nameStatus, bool $show): void
451
    {
452
        $type = 'UID, ';
453
        $this->echoStartMessage($time, 'mediainfo Unique_IDs');
454
455
        if ($cats === 3) {
456
            $query = sprintf(
457
                'SELECT rel.id AS releases_id, rel.size AS relsize, rel.groups_id, rel.fromname, rel.categories_id,
458
                    rel.name, rel.name AS textstring, rel.predb_id, rel.searchname,
459
                    ru.unique_id AS uid
460
                FROM releases rel
461
                LEFT JOIN media_infos ru ON ru.releases_id = rel.id
462
                WHERE ru.releases_id IS NOT NULL
463
                AND rel.predb_id = 0'
464
            );
465
            $cats = 2;
466
        } else {
467
            $query = sprintf(
468
                'SELECT rel.id AS releases_id, rel.size AS relsize, rel.groups_id, rel.fromname, rel.categories_id,
469
                    rel.name, rel.name AS textstring, rel.predb_id, rel.searchname,
470
                    ru.unique_id AS uid
471
                FROM releases rel
472
                LEFT JOIN media_infos ru ON ru.releases_id = rel.id
473
                WHERE ru.releases_id IS NOT NULL
474
                AND (rel.isrenamed = %d OR rel.categories_id IN (%d, %d))
475
                AND rel.predb_id = 0
476
                AND rel.proc_uid = %d',
477
                self::IS_RENAMED_NONE,
478
                Category::OTHER_MISC,
479
                Category::OTHER_HASHED,
480
                self::PROC_UID_NONE
481
            );
482
        }
483
484
        $releases = $this->getReleases($time, $cats, $query);
485
        $total = $releases->count();
486
487
        if ($total > 0) {
488
            $this->_totalReleases = $total;
489
            cli()->info(number_format($total).' unique ids to process.');
490
491
            foreach ($releases as $rel) {
492
                $this->updateService->reset();
493
                $this->updateService->incrementChecked();
494
                $this->uidCheck($rel, $echo, $type, $nameStatus, $show);
495
                $this->echoRenamed($show);
496
            }
497
498
            $this->echoFoundCount($echo, ' UID\'s');
499
        } else {
500
            cli()->info('Nothing to fix.');
501
        }
502
    }
503
504
    /**
505
     * Fix names using PAR2 hash_16K.
506
     */
507
    public function fixNamesWithParHash(int $time, bool $echo, int $cats, bool $nameStatus, bool $show): void
508
    {
509
        $type = 'PAR2 hash, ';
510
        $this->echoStartMessage($time, 'PAR2 hash_16K');
511
512
        if ($cats === 3) {
513
            $query = sprintf(
514
                'SELECT rel.id AS releases_id, rel.size AS relsize, rel.groups_id, rel.fromname, rel.categories_id,
515
                    rel.name, rel.name AS textstring, rel.predb_id, rel.searchname,
516
                    IFNULL(ph.hash, \'\') AS hash
517
                FROM releases rel
518
                LEFT JOIN par_hashes ph ON ph.releases_id = rel.id
519
                WHERE ph.hash != \'\'
520
                AND rel.predb_id = 0'
521
            );
522
            $cats = 2;
523
        } else {
524
            $query = sprintf(
525
                'SELECT rel.id AS releases_id, rel.size AS relsize, rel.groups_id, rel.fromname, rel.categories_id,
526
                    rel.name, rel.name AS textstring, rel.predb_id, rel.searchname,
527
                    IFNULL(ph.hash, \'\') AS hash
528
                FROM releases rel
529
                LEFT JOIN par_hashes ph ON ph.releases_id = rel.id
530
                WHERE (rel.isrenamed = %d OR rel.categories_id IN (%d, %d))
531
                AND rel.predb_id = 0
532
                AND ph.hash != \'\'
533
                AND rel.proc_hash16k = %d',
534
                self::IS_RENAMED_NONE,
535
                Category::OTHER_MISC,
536
                Category::OTHER_HASHED,
537
                self::PROC_HASH16K_NONE
538
            );
539
        }
540
541
        $releases = $this->getReleases($time, $cats, $query);
542
        $total = $releases->count();
543
544
        if ($total > 0) {
545
            $this->_totalReleases = $total;
546
            cli()->info(number_format($total).' hash_16K to process.');
547
548
            foreach ($releases as $rel) {
549
                $this->updateService->reset();
550
                $this->updateService->incrementChecked();
551
                $this->hashCheck($rel, $echo, $type, $nameStatus, $show);
552
                $this->echoRenamed($show);
553
            }
554
555
            $this->echoFoundCount($echo, ' hashes');
556
        } else {
557
            cli()->info('Nothing to fix.');
558
        }
559
    }
560
561
    /**
562
     * Check with pattern matchers (TV, Movie, Game, App).
563
     */
564
    protected function checkWithPatternMatchers(object $release, bool $echo, string $type, bool $nameStatus, bool $show, bool $preId): void
565
    {
566
        // Check for PreDB match first
567
        $preDbMatch = $this->updateService->checkPreDbMatch($release, $release->textstring);
568
        if ($preDbMatch !== null) {
569
            $this->updateService->updateRelease(
570
                $release,
571
                $preDbMatch['title'],
572
                'preDB: Match',
573
                $echo,
574
                $type,
575
                $nameStatus,
576
                $show,
577
                $preDbMatch['id']
578
            );
579
580
            return;
581
        }
582
583
        if ($preId) {
584
            return;
585
        }
586
587
        // Try pattern checkers
588
        $result = $this->checkerService->check($release, $release->textstring);
589
        if ($result !== null) {
590
            $this->updateService->updateRelease(
591
                $release,
592
                $result->newName,
593
                $result->getFormattedMethod(),
594
                $echo,
595
                $type,
596
                $nameStatus,
597
                $show
598
            );
599
        }
600
    }
601
602
    /**
603
     * Check SRR file for release name.
604
     */
605
    protected function srrNameCheck(object $release, bool $echo, string $type, bool $nameStatus, bool $show): bool
606
    {
607
        $extractedName = null;
608
609
        if (preg_match('/^(.+)\.srr$/i', $release->textstring, $hit)) {
610
            $extractedName = $hit[1];
611
        } elseif (preg_match('/^(.+)\.srs$/i', $release->textstring, $hit)) {
612
            $extractedName = $hit[1];
613
        }
614
615
        if ($extractedName !== null) {
616
            if (preg_match('/[\\\\\/]([^\\\\\/]+)$/', $extractedName, $pathMatch)) {
617
                $extractedName = $pathMatch[1];
618
            }
619
620
            if (preg_match(ReleaseUpdateService::PREDB_REGEX, $extractedName)) {
621
                $this->updateService->updateRelease(
622
                    $release,
623
                    $extractedName,
624
                    'fileCheck: SRR extension',
625
                    $echo,
626
                    $type,
627
                    $nameStatus,
628
                    $show
629
                );
630
631
                return true;
632
            }
633
        }
634
635
        $this->updateService->updateSingleColumn('proc_srr', self::PROC_SRR_DONE, $release->releases_id);
636
637
        return false;
638
    }
639
640
    /**
641
     * Check CRC32 for matches.
642
     */
643
    protected function crcCheck(object $release, bool $echo, string $type, bool $nameStatus, bool $show, bool $preId): bool
0 ignored issues
show
Unused Code introduced by
The parameter $preId is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

643
    protected function crcCheck(object $release, bool $echo, string $type, bool $nameStatus, bool $show, /** @scrutinizer ignore-unused */ bool $preId): bool

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
644
    {
645
        if ($release->textstring === '') {
646
            $this->updateService->updateSingleColumn('proc_crc32', self::PROC_CRC_DONE, $release->releases_id);
647
648
            return false;
649
        }
650
651
        $result = Release::fromQuery(
652
            sprintf(
653
                'SELECT rf.crc32, rel.categories_id, rel.name, rel.searchname, rel.fromname, rel.groups_id, rel.size as relsize, rel.predb_id as predb_id,
654
                    rf.releases_id AS fileid, rel.id AS releases_id
655
                FROM releases rel
656
                LEFT JOIN release_files rf ON rf.releases_id = rel.id
657
                WHERE rel.predb_id > 0
658
                AND rf.crc32 = %s',
659
                escapeString($release->textstring)
660
            )
661
        );
662
663
        foreach ($result as $res) {
664
            $floor = round(($res->relsize - $release->relsize) / $res->relsize * 100, 1);
665
            if ($floor >= -5 && $floor <= 5) {
666
                $this->updateService->updateRelease(
667
                    $release,
668
                    $res->searchname,
669
                    'crcCheck: CRC32',
670
                    $echo,
671
                    $type,
672
                    $nameStatus,
673
                    $show,
674
                    $res->predb_id
675
                );
676
677
                return true;
678
            }
679
        }
680
681
        $this->updateService->updateSingleColumn('proc_crc32', self::PROC_CRC_DONE, $release->releases_id);
682
683
        return false;
684
    }
685
686
    /**
687
     * Check UID for matches.
688
     */
689
    protected function uidCheck(object $release, bool $echo, string $type, bool $nameStatus, bool $show): bool
690
    {
691
        if (empty($release->uid)) {
692
            $this->updateService->updateSingleColumn('proc_uid', self::PROC_UID_DONE, $release->releases_id);
693
694
            return false;
695
        }
696
697
        $result = Release::fromQuery(sprintf(
698
            'SELECT r.id AS releases_id, r.size AS relsize, r.name AS textstring, r.searchname, r.fromname, r.predb_id
699
            FROM releases r
700
            LEFT JOIN media_infos ru ON ru.releases_id = r.id
701
            WHERE ru.releases_id IS NOT NULL
702
            AND ru.unique_id = %s
703
            AND ru.releases_id != %d
704
            AND (r.predb_id > 0 OR r.anidbid > 0 OR r.fromname = %s)',
705
            escapeString($release->uid),
706
            $release->releases_id,
707
            escapeString('[email protected] (EF)')
708
        ));
709
710
        foreach ($result as $res) {
711
            $floor = round(($res->relsize - $release->relsize) / $res->relsize * 100, 1);
712
            if ($floor >= -10 && $floor <= 10) {
713
                $this->updateService->updateRelease(
714
                    $release,
715
                    $res->searchname,
716
                    'uidCheck: Unique_ID',
717
                    $echo,
718
                    $type,
719
                    $nameStatus,
720
                    $show,
721
                    $res->predb_id
722
                );
723
724
                return true;
725
            }
726
        }
727
728
        $this->updateService->updateSingleColumn('proc_uid', self::PROC_UID_DONE, $release->releases_id);
729
730
        return false;
731
    }
732
733
    /**
734
     * Check PAR2 hash for matches.
735
     */
736
    protected function hashCheck(object $release, bool $echo, string $type, bool $nameStatus, bool $show): bool
737
    {
738
        $result = Release::fromQuery(sprintf(
739
            'SELECT r.id AS releases_id, r.size AS relsize, r.name AS textstring, r.searchname, r.fromname, r.predb_id
740
            FROM releases r
741
            LEFT JOIN par_hashes ph ON ph.releases_id = r.id
742
            WHERE ph.hash = %s
743
            AND ph.releases_id != %d
744
            AND (r.predb_id > 0 OR r.anidbid > 0)',
745
            escapeString($release->hash),
746
            $release->releases_id
747
        ));
748
749
        foreach ($result as $res) {
750
            $floor = round(($res->relsize - $release->relsize) / $res->relsize * 100, 1);
751
            if ($floor >= -5 && $floor <= 5) {
752
                $this->updateService->updateRelease(
753
                    $release,
754
                    $res->searchname,
755
                    'hashCheck: PAR2 hash_16K',
756
                    $echo,
757
                    $type,
758
                    $nameStatus,
759
                    $show,
760
                    $res->predb_id
761
                );
762
763
                return true;
764
            }
765
        }
766
767
        $this->updateService->updateSingleColumn('proc_hash16k', self::PROC_HASH16K_DONE, $release->releases_id);
768
769
        return false;
770
    }
771
772
    /**
773
     * Check PreDB for filename matches.
774
     */
775
    protected function preDbFileCheck(object $release, bool $echo, string $type, bool $nameStatus, bool $show): bool
776
    {
777
        $fileName = $this->fileNameCleaner->cleanForMatching($release->textstring);
778
779
        if (empty($fileName)) {
780
            return false;
781
        }
782
783
        $results = Search::searchPredb($fileName);
784
        foreach ($results as $hit) {
785
            if (! empty($hit)) {
786
                $hitData = is_array($hit) ? $hit : (array) $hit;
787
                $this->updateService->updateRelease(
788
                    $release,
789
                    $hitData['title'] ?? '',
790
                    'PreDb: Filename match',
791
                    $echo,
792
                    $type,
793
                    $nameStatus,
794
                    $show,
795
                    $hitData['id'] ?? null
796
                );
797
798
                return true;
799
            }
800
        }
801
802
        return false;
803
    }
804
805
    /**
806
     * Check PreDB for title matches.
807
     */
808
    protected function preDbTitleCheck(object $release, bool $echo, string $type, bool $nameStatus, bool $show): bool
809
    {
810
        $fileName = $this->fileNameCleaner->cleanForMatching($release->textstring);
811
812
        if (empty($fileName)) {
813
            return false;
814
        }
815
816
        $results = Search::searchPredb($fileName);
817
        foreach ($results as $hit) {
818
            if (! empty($hit)) {
819
                $hitData = is_array($hit) ? $hit : (array) $hit;
820
                $this->updateService->updateRelease(
821
                    $release,
822
                    $hitData['title'] ?? '',
823
                    'PreDb: Title match',
824
                    $echo,
825
                    $type,
826
                    $nameStatus,
827
                    $show,
828
                    $hitData['id'] ?? null
829
                );
830
831
                return true;
832
            }
833
        }
834
835
        return false;
836
    }
837
838
    /**
839
     * Get releases based on time and category parameters.
840
     */
841
    protected function getReleases(int $time, int $cats, string $query, int $limit = 0): \Illuminate\Database\Eloquent\Collection|bool
842
    {
843
        $releases = false;
844
        $queryLimit = ($limit === 0) ? '' : ' LIMIT '.$limit;
845
846
        if ($time === 1 && $cats === 1) {
847
            $releases = Release::fromQuery($query.$this->timeother.$queryLimit);
848
        }
849
        if ($time === 1 && $cats === 2) {
850
            $releases = Release::fromQuery($query.$this->timeall.$queryLimit);
851
        }
852
        if ($time === 2 && $cats === 1) {
853
            $releases = Release::fromQuery($query.$this->fullother.$queryLimit);
854
        }
855
        if ($time === 2 && $cats === 2) {
856
            $releases = Release::fromQuery($query.$this->fullall.$queryLimit);
857
        }
858
859
        return $releases;
860
    }
861
862
    /**
863
     * Echo start message.
864
     */
865
    protected function echoStartMessage(int $time, string $type): void
866
    {
867
        cli()->info(
868
            sprintf(
869
                'Fixing search names %s using %s.',
870
                ($time === 1 ? 'in the past 6 hours' : 'since the beginning'),
871
                $type
872
            )
873
        );
874
    }
875
876
    /**
877
     * Echo found count.
878
     */
879
    protected function echoFoundCount(bool $echo, string $type): void
880
    {
881
        $stats = $this->updateService->getStats();
882
        if ($echo === true) {
883
            cli()->info(
884
                PHP_EOL.
885
                number_format($stats['fixed']).
886
                ' releases have had their names changed out of: '.
887
                number_format($stats['checked']).
888
                $type.'.'
889
            );
890
        } else {
891
            cli()->info(
892
                PHP_EOL.
893
                number_format($stats['fixed']).
894
                ' releases could have their names changed. '.
895
                number_format($stats['checked']).
896
                $type.' were checked.'
897
            );
898
        }
899
    }
900
901
    /**
902
     * Echo renamed progress.
903
     */
904
    protected function echoRenamed(bool $show): void
905
    {
906
        $stats = $this->updateService->getStats();
907
908
        // Show milestone message every 500 releases
909
        if ($stats['checked'] % 500 === 0 && $stats['checked'] > 0) {
910
            cli()->alternate(PHP_EOL.number_format($stats['checked']).' files processed.'.PHP_EOL);
911
        }
912
913
        // Show active counter on the same line (overwrites previous)
914
        if ($show === true) {
915
            $percent = $this->_totalReleases > 0
916
                ? round(($stats['checked'] / $this->_totalReleases) * 100, 1)
917
                : 0;
918
919
            // Use carriage return to overwrite the same line
920
            echo "\rRenamed: ".number_format($stats['fixed']).
921
                 ' | Processed: '.number_format($stats['checked']).
922
                 '/'.number_format($this->_totalReleases).
923
                 ' ('.$percent.'%)    ';
924
        }
925
    }
926
927
    /**
928
     * Get the update service.
929
     */
930
    public function getUpdateService(): ReleaseUpdateService
931
    {
932
        return $this->updateService;
933
    }
934
935
    /**
936
     * Get the checker service.
937
     */
938
    public function getCheckerService(): NameCheckerService
939
    {
940
        return $this->checkerService;
941
    }
942
943
    /**
944
     * Fix names using PAR2 files (requires NNTP connection).
945
     */
946
    public function fixNamesWithPar2(int $time, bool $echo, int $cats, bool $nameStatus, bool $show, NNTPService $nntp): void
0 ignored issues
show
Unused Code introduced by
The parameter $nntp is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

946
    public function fixNamesWithPar2(int $time, bool $echo, int $cats, bool $nameStatus, bool $show, /** @scrutinizer ignore-unused */ NNTPService $nntp): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
947
    {
948
        $this->echoStartMessage($time, 'par2 files');
949
950
        if ($cats === 3) {
951
            $query = sprintf(
952
                'SELECT rel.id AS releases_id, rel.guid, rel.groups_id, rel.fromname
953
                FROM releases rel
954
                WHERE rel.predb_id = 0'
955
            );
956
            $cats = 2;
957
        } else {
958
            $query = sprintf(
959
                'SELECT rel.id AS releases_id, rel.guid, rel.groups_id, rel.fromname
960
                FROM releases rel
961
                WHERE (rel.isrenamed = %d OR rel.categories_id IN (%d, %d))
962
                AND rel.predb_id = 0
963
                AND rel.proc_par2 = %d',
964
                self::IS_RENAMED_NONE,
965
                Category::OTHER_MISC,
966
                Category::OTHER_HASHED,
967
                self::PROC_PAR2_NONE
968
            );
969
        }
970
971
        $releases = $this->getReleases($time, $cats, $query);
972
        $total = $releases ? $releases->count() : 0;
973
974
        if ($total > 0) {
975
            $this->_totalReleases = $total;
976
            cli()->info(number_format($total).' releases to process.');
977
            $nzbContentsService = app(\App\Services\Nzb\NzbContentsService::class);
978
979
            foreach ($releases as $release) {
980
                if ($nzbContentsService->checkPar2($release->guid, $release->releases_id, $release->groups_id, (int) $nameStatus, (int) $show)) {
981
                    $this->updateService->fixed++;
982
                }
983
984
                $this->updateService->incrementChecked();
985
                $this->echoRenamed($show);
986
            }
987
            $this->echoFoundCount($echo, ' files');
988
        } else {
989
            cli()->info('Nothing to fix.');
990
        }
991
    }
992
993
    /**
994
     * Fix XXX release names using specific file names.
995
     */
996
    public function fixXXXNamesWithFiles(int $time, bool $echo, int $cats, bool $nameStatus, bool $show): void
997
    {
998
        $this->echoStartMessage($time, 'file names');
999
        $type = 'Filenames, ';
1000
1001
        if ($cats === 3) {
1002
            $query = sprintf(
1003
                'SELECT rf.name AS textstring, rel.categories_id, rel.name, rel.searchname, rel.fromname, rel.groups_id,
1004
                    rf.releases_id AS fileid, rel.id AS releases_id
1005
                FROM releases rel
1006
                INNER JOIN release_files rf ON rf.releases_id = rel.id
1007
                WHERE predb_id = 0'
1008
            );
1009
            $cats = 2;
1010
        } else {
1011
            $query = sprintf(
1012
                'SELECT rf.name AS textstring, rel.categories_id, rel.name, rel.searchname, rel.fromname, rel.groups_id,
1013
                    rf.releases_id AS fileid, rel.id AS releases_id
1014
                FROM releases rel
1015
                INNER JOIN release_files rf ON rf.releases_id = rel.id
1016
                WHERE (rel.isrenamed = %d OR rel.categories_id IN (%d, %d))
1017
                AND rel.predb_id = 0
1018
                AND rf.name LIKE %s',
1019
                self::IS_RENAMED_NONE,
1020
                Category::OTHER_MISC,
1021
                Category::OTHER_HASHED,
1022
                escapeString('%SDPORN%')
1023
            );
1024
        }
1025
1026
        $releases = $this->getReleases($time, $cats, $query);
1027
        $total = $releases ? $releases->count() : 0;
1028
1029
        if ($total > 0) {
1030
            $this->_totalReleases = $total;
1031
            cli()->info(number_format($total).' xxx file names to process.');
1032
1033
            foreach ($releases as $release) {
1034
                $this->updateService->reset();
1035
                $this->xxxNameCheck($release, $echo, $type, $nameStatus, $show);
1036
                $this->updateService->incrementChecked();
1037
                $this->echoRenamed($show);
1038
            }
1039
            $this->echoFoundCount($echo, ' files');
1040
        } else {
1041
            cli()->info('Nothing to fix.');
1042
        }
1043
    }
1044
1045
    /**
1046
     * Fix release names using mediainfo movie_name.
1047
     */
1048
    public function fixNamesWithMediaMovieName(int $time, bool $echo, int $cats, bool $nameStatus, bool $show): void
1049
    {
1050
        $type = 'Mediainfo, ';
1051
        $this->echoStartMessage($time, 'Mediainfo movie_name');
1052
1053
        if ($cats === 3) {
1054
            $query = sprintf(
1055
                'SELECT rel.id AS releases_id, rel.name, rel.name AS textstring, rel.predb_id, rel.searchname, rel.fromname, rel.groups_id, rel.categories_id, rel.id AS releases_id, rf.movie_name as movie_name
1056
                FROM releases rel
1057
                INNER JOIN media_infos rf ON rf.releases_id = rel.id
1058
                WHERE rel.predb_id = 0'
1059
            );
1060
            $cats = 2;
1061
        } else {
1062
            $query = sprintf(
1063
                'SELECT rel.id AS releases_id, rel.name, rel.name AS textstring, rel.predb_id, rel.searchname, rel.fromname, rel.groups_id, rel.categories_id, rel.id AS releases_id, rf.movie_name as movie_name, rf.file_name as file_name
1064
                FROM releases rel
1065
                INNER JOIN media_infos rf ON rf.releases_id = rel.id
1066
                WHERE rel.isrenamed = %d
1067
                AND rel.predb_id = 0',
1068
                self::IS_RENAMED_NONE
1069
            );
1070
            if ($cats === 2) {
1071
                $query .= PHP_EOL.'AND rel.categories_id IN ('.Category::OTHER_MISC.','.Category::OTHER_HASHED.')';
1072
            }
1073
        }
1074
1075
        $releases = $this->getReleases($time, $cats, $query);
1076
        $total = $releases ? $releases->count() : 0;
1077
1078
        if ($total > 0) {
1079
            $this->_totalReleases = $total;
1080
            cli()->info(number_format($total).' mediainfo movie names to process.');
1081
1082
            foreach ($releases as $rel) {
1083
                $this->updateService->incrementChecked();
1084
                $this->updateService->reset();
1085
                $this->mediaMovieNameCheck($rel, $echo, $type, $nameStatus, $show);
1086
                $this->echoRenamed($show);
1087
            }
1088
            $this->echoFoundCount($echo, ' MediaInfo\'s');
1089
        } else {
1090
            cli()->info('Nothing to fix.');
1091
        }
1092
    }
1093
1094
    /**
1095
     * Check for XXX release name.
1096
     */
1097
    protected function xxxNameCheck(object $release, bool $echo, string $type, bool $nameStatus, bool $show): bool
1098
    {
1099
        if (preg_match('/^.+?SDPORN/i', $release->textstring, $hit)) {
1100
            $this->updateService->updateRelease($release, $hit[0], 'fileCheck: XXX SDPORN', $echo, $type, $nameStatus, $show);
1101
1102
            return true;
1103
        }
1104
1105
        $this->updateService->updateSingleColumn('proc_files', self::PROC_FILES_DONE, $release->releases_id);
1106
1107
        return false;
1108
    }
1109
1110
    /**
1111
     * Check mediainfo movie_name for release name.
1112
     */
1113
    protected function mediaMovieNameCheck(object $release, bool $echo, string $type, bool $nameStatus, bool $show): bool
1114
    {
1115
        $newName = '';
1116
1117
        if (! empty($release->movie_name)) {
1118
            if (preg_match(ReleaseUpdateService::PREDB_REGEX, $release->movie_name, $hit)) {
1119
                $newName = $hit[1];
1120
            } elseif (preg_match('/(.+),(\sRMZ\.cr)?$/i', $release->movie_name, $hit)) {
1121
                $newName = $hit[1];
1122
            } else {
1123
                $newName = $release->movie_name;
1124
            }
1125
        }
1126
1127
        if ($newName !== '') {
1128
            $this->updateService->updateRelease($release, $newName, 'MediaInfo: Movie Name', $echo, $type, $nameStatus, $show, $release->predb_id ?? 0);
1129
1130
            return true;
1131
        }
1132
1133
        $this->updateService->updateSingleColumn('proc_uid', self::PROC_UID_DONE, $release->releases_id);
1134
1135
        return false;
1136
    }
1137
1138
    /**
1139
     * Check the array using regex for a clean name.
1140
     *
1141
     * @throws \Exception
1142
     */
1143
    public function checkName(object $release, bool $echo, string $type, bool $nameStatus, bool $show, bool $preId = false): bool
1144
    {
1145
        // Check PreDB first
1146
        $preDbMatch = $this->updateService->checkPreDbMatch($release, $release->textstring);
1147
        if ($preDbMatch !== null) {
1148
            $this->updateService->updateRelease($release, $preDbMatch['title'], 'preDB: Match', $echo, $type, $nameStatus, $show, $preDbMatch['id']);
1149
1150
            return true;
1151
        }
1152
1153
        if ($preId) {
1154
            return $this->updateService->matched;
1155
        }
1156
1157
        // Route to appropriate checker based on type
1158
        switch ($type) {
1159
            case 'PAR2, ':
1160
                $result = $this->fileExtractor->extractFromFile($release->textstring);
1161
                if ($result !== null) {
1162
                    $this->updateService->updateRelease($release, $result->newName, 'fileCheck: '.$result->method, $echo, $type, $nameStatus, $show);
1163
                }
1164
                break;
1165
1166
            case 'NFO, ':
1167
                $result = $this->nfoExtractor->extractFromNfo($release->textstring);
1168
                if ($result !== null) {
1169
                    $this->updateService->updateRelease($release, $result->newName, 'nfoCheck: '.$result->method, $echo, $type, $nameStatus, $show);
1170
                }
1171
                break;
1172
1173
            case 'Filenames, ':
1174
                // Try PreDB file check
1175
                if (! $this->updateService->matched) {
1176
                    $this->preDbFileCheck($release, $echo, $type, $nameStatus, $show);
1177
                }
1178
                // Try PreDB title check
1179
                if (! $this->updateService->matched) {
1180
                    $this->preDbTitleCheck($release, $echo, $type, $nameStatus, $show);
1181
                }
1182
                // Try file name extraction
1183
                if (! $this->updateService->matched) {
1184
                    $result = $this->fileExtractor->extractFromFile($release->textstring);
1185
                    if ($result !== null) {
1186
                        $this->updateService->updateRelease($release, $result->newName, 'fileCheck: '.$result->method, $echo, $type, $nameStatus, $show);
1187
                    }
1188
                }
1189
                break;
1190
1191
            default:
1192
                // Use pattern checker service
1193
                $result = $this->checkerService->check($release, $release->textstring);
1194
                if ($result !== null) {
1195
                    $this->updateService->updateRelease($release, $result->newName, $result->getFormattedMethod(), $echo, $type, $nameStatus, $show);
1196
                }
1197
        }
1198
1199
        // Update processing flags if not matched
1200
        if ($nameStatus === true && ! $this->updateService->matched) {
1201
            $this->updateProcessingFlags($type, $release->releases_id);
1202
        }
1203
1204
        return $this->updateService->matched;
1205
    }
1206
1207
    /**
1208
     * Update processing flags based on type.
1209
     */
1210
    protected function updateProcessingFlags(string $type, int $releaseId): void
1211
    {
1212
        switch ($type) {
1213
            case 'NFO, ':
1214
                $this->updateService->updateSingleColumn('proc_nfo', self::PROC_NFO_DONE, $releaseId);
1215
                break;
1216
            case 'Filenames, ':
1217
                $this->updateService->updateSingleColumn('proc_files', self::PROC_FILES_DONE, $releaseId);
1218
                break;
1219
            case 'PAR2, ':
1220
                $this->updateService->updateSingleColumn('proc_par2', self::PROC_PAR2_DONE, $releaseId);
1221
                break;
1222
            case 'PAR2 hash, ':
1223
                $this->updateService->updateSingleColumn('proc_hash16k', self::PROC_HASH16K_DONE, $releaseId);
1224
                break;
1225
            case 'SRR, ':
1226
                $this->updateService->updateSingleColumn('proc_srr', self::PROC_SRR_DONE, $releaseId);
1227
                break;
1228
            case 'UID, ':
1229
            case 'Mediainfo, ':
1230
                $this->updateService->updateSingleColumn('proc_uid', self::PROC_UID_DONE, $releaseId);
1231
                break;
1232
            case 'CRC32, ':
1233
                $this->updateService->updateSingleColumn('proc_crc32', self::PROC_CRC_DONE, $releaseId);
1234
                break;
1235
        }
1236
    }
1237
1238
    /**
1239
     * Match a release filename to a PreDB filename or title.
1240
     *
1241
     * @throws \Exception
1242
     */
1243
    public function matchPreDbFiles(object $release, bool $echo, bool $nameStatus, bool $show): int
1244
    {
1245
        $matching = 0;
1246
1247
        $files = explode('||', $release->filename ?? '');
1248
        $prioritizedFiles = $this->filePrioritizer->prioritizeForPreDb($files);
1249
1250
        foreach ($prioritizedFiles as $fileName) {
1251
            $cleanedFileName = $this->fileNameCleaner->cleanForMatching($fileName);
1252
1253
            if (empty($cleanedFileName) || strlen($cleanedFileName) < 8) {
1254
                continue;
1255
            }
1256
1257
            $preMatch = $this->preMatch($cleanedFileName);
1258
            if ($preMatch[0] === true) {
1259
                $results = Search::searchPredb($preMatch[1]);
1260
1261
                if (! empty($results)) {
1262
                    foreach ($results as $result) {
1263
                        if (! empty($result)) {
1264
                            $resultData = is_array($result) ? $result : (array) $result;
1265
                            $preFtMatch = $this->preMatch($resultData['filename'] ?? '');
1266
                            if ($preFtMatch[0] === true) {
1267
                                if ($resultData['title'] !== $release->searchname) {
1268
                                    $this->updateService->updateRelease($release, $resultData['title'], 'file matched source: '.($resultData['source'] ?? ''), $echo, 'PreDB file match, ', $nameStatus, $show);
1269
                                } else {
1270
                                    $this->updateService->updateSingleColumn('predb_id', $resultData['id'] ?? 0, $release->releases_id);
1271
                                }
1272
                                $matching++;
1273
1274
                                return $matching;
1275
                            }
1276
                        }
1277
                    }
1278
                }
1279
            }
1280
        }
1281
1282
        return $matching;
1283
    }
1284
1285
    /**
1286
     * Pre-match check for filename patterns.
1287
     */
1288
    protected function preMatch(string $fileName): array
1289
    {
1290
        $result = preg_match('/(\d{2}\.\d{2}\.\d{2})+([\w\-.]+[\w]$)/i', $fileName, $hit);
1291
1292
        return [$result === 1, $hit[0] ?? ''];
1293
    }
1294
1295
    /**
1296
     * Check if a release name looks like a season pack.
1297
     */
1298
    public function isSeasonPack(string $name): bool
1299
    {
1300
        // Season pack pattern: S01 without E01
1301
        return (bool) preg_match('/S\d{1,2}(?!E\d)/i', $name);
1302
    }
1303
1304
    /**
1305
     * Reset the update service state.
1306
     */
1307
    public function reset(): void
1308
    {
1309
        $this->updateService->reset();
1310
    }
1311
1312
    /**
1313
     * Retrieves releases and their file names to attempt PreDB matches.
1314
     *
1315
     * @throws \Exception
1316
     */
1317
    public function getPreFileNames(array $args = []): void
1318
    {
1319
        $show = isset($args[2]) && $args[2] === 'show';
1320
1321
        if (isset($args[1]) && is_numeric($args[1])) {
1322
            $limit = 'LIMIT '.$args[1];
1323
            $orderBy = 'ORDER BY r.id DESC';
1324
        } else {
1325
            $orderBy = 'ORDER BY r.id ASC';
1326
            $limit = 'LIMIT 1000000';
1327
        }
1328
1329
        cli()->info(PHP_EOL.'Match PreFiles '.($args[1] ?? 'all').' Started at '.now());
1330
        cli()->info('Matching predb filename to cleaned release_files.name.');
1331
1332
        $counter = $counted = 0;
1333
        $timeStart = now();
1334
1335
        $query = Release::fromQuery(
1336
            sprintf(
1337
                "SELECT r.id AS releases_id, r.name, r.searchname,
1338
                    r.fromname, r.groups_id, r.categories_id,
1339
                    GROUP_CONCAT(rf.name ORDER BY LENGTH(rf.name) DESC SEPARATOR '||') AS filename
1340
                FROM releases r
1341
                INNER JOIN release_files rf ON r.id = rf.releases_id
1342
                WHERE rf.name IS NOT NULL
1343
                AND r.predb_id = 0
1344
                AND r.categories_id IN (%s)
1345
                AND r.isrenamed = 0
1346
                GROUP BY r.id
1347
                %s %s",
1348
                implode(',', Category::OTHERS_GROUP),
1349
                $orderBy,
1350
                $limit
1351
            )
1352
        );
1353
1354
        if ($query->isNotEmpty()) {
1355
            $total = $query->count();
1356
1357
            if ($total > 0) {
1358
                cli()->info(PHP_EOL.number_format($total).' releases to process.');
1359
1360
                foreach ($query as $row) {
1361
                    $success = $this->matchPreDbFiles($row, true, true, $show);
1362
                    if ($success === 1) {
1363
                        $counted++;
1364
                    }
1365
                    if ($show === false) {
1366
                        cli()->info('Renamed Releases: ['.number_format($counted).'] '.(new ColorCLI)->percentString(++$counter, $total));
0 ignored issues
show
Bug introduced by
The type App\Services\NameFixing\ColorCLI was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
1367
                    }
1368
                }
1369
                cli()->info(PHP_EOL.'Renamed '.number_format($counted).' releases in '.now()->diffInSeconds($timeStart, true).' seconds.');
1370
            } else {
1371
                cli()->info('Nothing to do.');
1372
            }
1373
        }
1374
    }
1375
}
1376