Completed
Branch dev (4bcb34)
by Darko
13:52
created

XXX   F

Complexity

Total Complexity 106

Size/Duplication

Total Lines 731
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 731
rs 1.263
c 0
b 0
f 0
wmc 106

16 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 17 5
A getAllGenres() 0 14 3
C parseXXXSearchName() 0 32 8
D getXXXRange() 0 117 14
A getXXXInfo() 0 3 1
B getBrowseBy() 0 19 6
A getXXXOrdering() 0 3 1
B update() 0 32 4
A checkXXXInfoExists() 0 3 1
A getGenres() 0 11 2
B getGenreID() 0 23 5
B getXXXOrder() 0 14 6
B processXXXReleases() 0 56 8
F updateXXXInfo() 0 147 35
B insertSwf() 0 25 5
A insertGenre() 0 8 2

How to fix   Complexity   

Complex Class

Complex classes like XXX often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use XXX, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Blacklight;
4
5
use App\Models\Genre;
6
use Blacklight\db\DB;
7
use App\Models\Release;
8
use App\Models\XxxInfo;
9
use App\Models\Category;
10
use App\Models\Settings;
11
use Illuminate\Support\Carbon;
12
use Blacklight\processing\adult\ADE;
13
use Blacklight\processing\adult\ADM;
14
use Blacklight\processing\adult\AEBN;
15
use Illuminate\Support\Facades\Cache;
16
use Blacklight\processing\adult\Popporn;
17
use Blacklight\processing\adult\Hotmovies;
18
19
/**
20
 * Class XXX.
21
 */
22
class XXX
23
{
24
    /**
25
     * @var \Blacklight\db\DB
26
     */
27
    public $pdo;
28
29
    /**
30
     * What scraper class did we use -- used for template and trailer information.
31
     *
32
     * @var string
33
     */
34
    protected $whichclass = '';
35
36
    /**
37
     * Current title being passed through various sites/api's.
38
     *
39
     * @var string
40
     */
41
    protected $currentTitle = '';
42
43
    /**
44
     * @var bool
45
     */
46
    protected $echooutput;
47
48
    /**
49
     * @var string
50
     */
51
    protected $imgSavePath;
52
53
    /**
54
     * @var \Blacklight\ReleaseImage
55
     */
56
    protected $releaseImage;
57
58
    /**
59
     * @var
60
     */
61
    protected $currentRelID;
62
63
    /**
64
     * @var int|null|string
65
     */
66
    protected $movieqty;
67
68
    /**
69
     * @var string
70
     */
71
    protected $showPasswords;
72
73
    protected $cookie;
74
75
    /**
76
     * @var array|bool|int|string
77
     */
78
    public $catWhere;
79
80
    /**
81
     * @param array $options Echo to cli / Class instances.
82
     *
83
     * @throws \Exception
84
     */
85
    public function __construct(array $options = [])
86
    {
87
        $defaults = [
88
            'Echo'         => false,
89
            'ReleaseImage' => null,
90
            'Settings'     => null,
91
        ];
92
        $options += $defaults;
93
94
        $this->pdo = ($options['Settings'] instanceof DB ? $options['Settings'] : new DB());
95
        $this->releaseImage = ($options['ReleaseImage'] instanceof ReleaseImage ? $options['ReleaseImage'] : new ReleaseImage());
96
97
        $this->movieqty = Settings::settingValue('..maxxxxprocessed') !== '' ? (int) Settings::settingValue('..maxxxxprocessed') : 100;
0 ignored issues
show
Bug introduced by
'..maxxxxprocessed' of type string is incompatible with the type boolean|array expected by parameter $setting of App\Models\Settings::settingValue(). ( Ignorable by Annotation )

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

97
        $this->movieqty = Settings::settingValue(/** @scrutinizer ignore-type */ '..maxxxxprocessed') !== '' ? (int) Settings::settingValue('..maxxxxprocessed') : 100;
Loading history...
98
        $this->showPasswords = Releases::showPasswords();
99
        $this->echooutput = ($options['Echo'] && config('nntmux.echocli'));
100
        $this->imgSavePath = NN_COVERS.'xxx'.DS;
0 ignored issues
show
Bug introduced by
The constant Blacklight\DS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
101
        $this->cookie = NN_TMP.'xxx.cookie';
0 ignored issues
show
Bug introduced by
The constant Blacklight\NN_TMP was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
102
    }
103
104
    /**
105
     * Get info for a xxx id.
106
     *
107
     * @param $xxxid
108
     * @return \Illuminate\Database\Query\Builder|static
109
     */
110
    public function getXXXInfo($xxxid)
111
    {
112
        return XxxInfo::query()->where('id', $xxxid)->selectRaw(' *, UNCOMPRESS(plot) as plot')->first();
0 ignored issues
show
Bug Best Practice introduced by
The expression return App\Models\XxxInf...lot) as plot')->first() also could return the type App\Models\XxxInfo which is incompatible with the documented return type Illuminate\Database\Query\Builder|Blacklight\XXX.
Loading history...
113
    }
114
115
    /**
116
     * Get XXX releases with covers for xxx browse page.
117
     *
118
     * @param       $cat
119
     * @param       $start
120
     * @param       $num
121
     * @param       $orderBy
122
     * @param       $maxAge
123
     * @param array $excludedCats
124
     *
125
     * @return array
126
     * @throws \Exception
127
     */
128
    public function getXXXRange($cat, $start, $num, $orderBy, $maxAge = -1, array $excludedCats = []): array
129
    {
130
        $catsrch = '';
131
        if (\count($cat) > 0 && $cat[0] !== -1) {
132
            $catsrch = Category::getCategorySearch($cat);
133
        }
134
135
        $order = $this->getXXXOrder($orderBy);
136
137
        $expiresAt = Carbon::now()->addSeconds(config('nntmux.cache_expiry_medium'));
138
139
        $xxxmoviesSql =
140
            sprintf(
141
                "
142
				SELECT SQL_CALC_FOUND_ROWS
143
					xxx.id,
144
					GROUP_CONCAT(r.id ORDER BY r.postdate DESC SEPARATOR ',') AS grp_release_id
145
				FROM xxxinfo xxx
146
				LEFT JOIN releases r ON xxx.id = r.xxxinfo_id
147
				WHERE r.nzbstatus = 1
148
				AND xxx.title != ''
149
				AND r.passwordstatus %s
150
				%s %s %s %s
151
				GROUP BY xxx.id
152
				ORDER BY %s %s %s",
153
                $this->showPasswords,
154
                $this->getBrowseBy(),
155
                $catsrch,
156
                (
157
                    $maxAge > 0
158
                    ? 'AND r.postdate > NOW() - INTERVAL '.$maxAge.'DAY '
159
                    : ''
160
                ),
161
                (\count($excludedCats) > 0 ? ' AND r.categories_id NOT IN ('.implode(',', $excludedCats).')' : ''),
162
                $order[0],
163
                $order[1],
164
                ($start === false ? '' : ' LIMIT '.$num.' OFFSET '.$start)
165
           );
166
167
        $xxxmoviesCache = Cache::get(md5($xxxmoviesSql));
168
        if ($xxxmoviesCache !== null) {
169
            $xxxmovies = $xxxmoviesCache;
170
        } else {
171
            $xxxmovies = $this->pdo->queryCalc($xxxmoviesSql);
172
            Cache::put(md5($xxxmoviesSql), $xxxmovies, $expiresAt);
173
        }
174
175
        $xxxIDs = $releaseIDs = false;
176
177
        if (\is_array($xxxmovies['result'])) {
178
            foreach ($xxxmovies['result'] as $xxx => $id) {
179
                $xxxIDs[] = $id['id'];
180
                $releaseIDs[] = $id['grp_release_id'];
181
            }
182
        }
183
184
        $sql = sprintf(
185
            "
186
			SELECT
187
				GROUP_CONCAT(r.id ORDER BY r.postdate DESC SEPARATOR ',') AS grp_release_id,
188
				GROUP_CONCAT(r.rarinnerfilecount ORDER BY r.postdate DESC SEPARATOR ',') AS grp_rarinnerfilecount,
189
				GROUP_CONCAT(r.haspreview ORDER BY r.postdate DESC SEPARATOR ',') AS grp_haspreview,
190
				GROUP_CONCAT(r.passwordstatus ORDER BY r.postdate DESC SEPARATOR ',') AS grp_release_password,
191
				GROUP_CONCAT(r.guid ORDER BY r.postdate DESC SEPARATOR ',') AS grp_release_guid,
192
				GROUP_CONCAT(rn.releases_id ORDER BY r.postdate DESC SEPARATOR ',') AS grp_release_nfoid,
193
				GROUP_CONCAT(g.name ORDER BY r.postdate DESC SEPARATOR ',') AS grp_release_grpname,
194
				GROUP_CONCAT(r.searchname ORDER BY r.postdate DESC SEPARATOR '#') AS grp_release_name,
195
				GROUP_CONCAT(r.postdate ORDER BY r.postdate DESC SEPARATOR ',') AS grp_release_postdate,
196
				GROUP_CONCAT(r.size ORDER BY r.postdate DESC SEPARATOR ',') AS grp_release_size,
197
				GROUP_CONCAT(r.totalpart ORDER BY r.postdate DESC SEPARATOR ',') AS grp_release_totalparts,
198
				GROUP_CONCAT(r.comments ORDER BY r.postdate DESC SEPARATOR ',') AS grp_release_comments,
199
				GROUP_CONCAT(r.grabs ORDER BY r.postdate DESC SEPARATOR ',') AS grp_release_grabs,
200
				GROUP_CONCAT(df.failed ORDER BY r.postdate DESC SEPARATOR ',') AS grp_release_failed,
201
				GROUP_CONCAT(cp.title, ' > ', c.title ORDER BY r.postdate DESC SEPARATOR ',') AS grp_release_catname,
202
			xxx.*, UNCOMPRESS(xxx.plot) AS plot,
203
			g.name AS group_name,
204
			rn.releases_id AS nfoid
205
			FROM releases r
206
			LEFT OUTER JOIN groups g ON g.id = r.groups_id
207
			LEFT OUTER JOIN release_nfos rn ON rn.releases_id = r.id
208
			LEFT OUTER JOIN dnzb_failures df ON df.release_id = r.id
209
			LEFT OUTER JOIN categories c ON c.id = r.categories_id
210
			LEFT OUTER JOIN categories cp ON cp.id = c.parentid
211
			INNER JOIN xxxinfo xxx ON xxx.id = r.xxxinfo_id
212
			WHERE r.nzbstatus = 1
213
			AND xxx.id IN (%s)
214
			AND xxx.title != ''
215
			AND r.passwordstatus %s
216
			%s %s %s %s
217
			GROUP BY xxx.id
218
			ORDER BY %s %s",
219
            (\is_array($xxxIDs) ? implode(',', $xxxIDs) : -1),
0 ignored issues
show
introduced by
The condition is_array($xxxIDs) is always false.
Loading history...
220
            $this->showPasswords,
221
            $this->getBrowseBy(),
222
            $catsrch,
223
            (
224
                $maxAge > 0
225
                ? 'AND r.postdate > NOW() - INTERVAL '.$maxAge.'DAY '
226
                : ''
227
            ),
228
            (\count($excludedCats) > 0 ? ' AND r.categories_id NOT IN ('.implode(',', $excludedCats).')' : ''),
229
            $order[0],
230
            $order[1]
231
        );
232
        $return = Cache::get(md5($sql));
233
        if ($return !== null) {
234
            return $return;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $return returns the type Illuminate\Contracts\Cache\Repository which is incompatible with the type-hinted return array.
Loading history...
235
        }
236
237
        $return = $this->pdo->query($sql);
238
        if (! empty($return)) {
239
            $return[0]['_totalcount'] = $xxxmovies['total'] ?? 0;
240
        }
241
242
        Cache::put(md5($sql), $return, $expiresAt);
243
244
        return $return;
245
    }
246
247
    /**
248
     * Get the order type the user requested on the movies page.
249
     *
250
     * @param $orderBy
251
     *
252
     * @return array
253
     */
254
    protected function getXXXOrder($orderBy): array
255
    {
256
        $orderArr = explode('_', (($orderBy === '') ? 'MAX(r.postdate)' : $orderBy));
257
        switch ($orderArr[0]) {
258
            case 'title':
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
259
                $orderField = 'xxx.title';
260
                break;
261
            case 'posted':
262
            default:
263
                $orderField = 'MAX(r.postdate)';
264
                break;
265
        }
266
267
        return [$orderField, isset($orderArr[1]) && preg_match('/^asc|desc$/i', $orderArr[1]) ? $orderArr[1] : 'desc'];
268
    }
269
270
    /**
271
     * Order types for xxx page.
272
     *
273
     * @return array
274
     */
275
    public function getXXXOrdering(): array
276
    {
277
        return ['title_asc', 'title_desc', 'name_asc', 'name_desc', 'size_asc', 'size_desc', 'posted_asc', 'posted_desc', 'cat_asc', 'cat_desc'];
278
    }
279
280
    /**
281
     * @return string
282
     */
283
    protected function getBrowseBy(): string
284
    {
285
        $browseBy = ' ';
286
        $browseByArr = ['title', 'director', 'actors', 'genre', 'id'];
287
        foreach ($browseByArr as $bb) {
288
            if (isset($_REQUEST[$bb]) && ! empty($_REQUEST[$bb])) {
289
                $bbv = stripslashes($_REQUEST[$bb]);
290
                if ($bb === 'genre') {
291
                    $bbv = $this->getGenreID($bbv);
292
                }
293
                if ($bb === 'id') {
294
                    $browseBy .= 'AND xxx.'.$bb.'='.$bbv;
295
                } else {
296
                    $browseBy .= 'AND xxx.'.$bb.' '.$this->pdo->likeString($bbv, true, true);
297
                }
298
            }
299
        }
300
301
        return $browseBy;
302
    }
303
304
    /**
305
     * Update XXX Information from getXXXCovers.php in misc/testing/PostProc.
306
     *
307
     * @param string $id
308
     * @param string $title
309
     * @param string $tagLine
310
     * @param string $plot
311
     * @param string $genre
312
     * @param string $director
313
     * @param string $actors
314
     * @param string $extras
315
     * @param string $productInfo
316
     * @param string $trailers
317
     * @param string $directUrl
318
     * @param string $classUsed
319
     * @param string $cover
320
     * @param string $backdrop
321
     */
322
    public function update(
323
        $id = '',
324
        $title = '',
325
        $tagLine = '',
326
        $plot = '',
327
        $genre = '',
328
        $director = '',
329
        $actors = '',
330
        $extras = '',
331
        $productInfo = '',
332
        $trailers = '',
333
        $directUrl = '',
334
        $classUsed = '',
335
        $cover = '',
336
        $backdrop = ''
337
    ): void {
338
        if (! empty($id)) {
339
            XxxInfo::query()->where('id', $id)->update(
340
                [
341
                    'title' => $title,
342
                    'tagline' => $tagLine,
343
                    'plot' => "\x1f\x8b\x08\x00".gzcompress($plot),
344
                    'genre' => substr($genre, 0, 64),
345
                    'director' => $director,
346
                    'actors' => $actors,
347
                    'extras' => $extras,
348
                    'productinfo' => $productInfo,
349
                    'trailers'=> $trailers,
350
                    'directurl' => $directUrl,
351
                    'classused' => $classUsed,
352
                    'cover' => empty($cover) ? 0 : $cover,
353
                    'backdrop' => empty($backdrop) ? 0 : $backdrop,
354
                ]
355
            );
356
        }
357
    }
358
359
    /**
360
     * Get all genres for search-filter.tpl.
361
     *
362
     *
363
     * @param bool $activeOnly
364
     * @return array
365
     */
366
    public function getAllGenres($activeOnly = false): array
367
    {
368
        $ret = [];
369
        if ($activeOnly) {
370
            $res = Genre::query()->where(['disabled' => 0, 'type' => Category::XXX_ROOT])->orderBy('title')->get(['title']);
371
        } else {
372
            $res = Genre::query()->where(['type' => Category::XXX_ROOT])->orderBy('title')->get(['title']);
373
        }
374
375
        foreach ($res as $arr => $value) {
376
            $ret[] = $value['title'];
377
        }
378
379
        return $ret;
380
    }
381
382
    /**
383
     * @param bool $activeOnly
384
     * @param null $gid
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $gid is correct as it would always require null to be passed?
Loading history...
385
     * @return mixed
386
     */
387
    public function getGenres($activeOnly = false, $gid = null)
388
    {
389
        if ($activeOnly) {
390
            return Genre::query()->where(['disabled' => 0, 'type' => Category::XXX_ROOT])->when($gid !== null, function ($query) use ($gid) {
391
                return $query->where('id', $gid);
392
            })->orderBy('title')->first(['title']);
393
        }
394
395
        return Genre::query()->where(['type' => Category::XXX_ROOT])->when($gid !== null, function ($query) use ($gid) {
396
            return $query->where('id', $gid);
397
        })->orderBy('title')->first(['title']);
398
    }
399
400
    /**
401
     * Get Genre id's Of the title.
402
     *
403
     * @param $arr - Array or String
404
     *
405
     * @return string - If array .. 1,2,3,4 if string .. 1
406
     */
0 ignored issues
show
Documentation Bug introduced by
The doc comment - at position 0 could not be parsed: Unknown type name '-' at position 0 in -.
Loading history...
407
    protected function getGenreID($arr): string
408
    {
409
        $ret = null;
410
411
        if (! \is_array($arr)) {
412
            $res = Genre::query()->where('title', $arr)->first(['id']);
413
            if ($res !== null) {
414
                return $res['id'];
415
            }
416
        }
417
418
        foreach ($arr as $key => $value) {
419
            $res = Genre::query()->where('title', $value)->first(['id']);
420
            if ($res !== null) {
421
                $ret .= ','.$res['id'];
422
            } else {
423
                $ret .= ','.$this->insertGenre($value);
424
            }
425
        }
426
427
        $ret = ltrim($ret, ',');
428
429
        return $ret;
430
    }
431
432
    /**
433
     * Inserts Genre and returns last affected row (Genre ID).
434
     *
435
     *
436
     * @param $genre
437
     * @return int|string
438
     */
439
    private function insertGenre($genre)
440
    {
441
        $res = '';
442
        if ($genre !== null) {
443
            $res = Genre::query()->insert(['title' => $genre, 'type' => Category::XXX_ROOT, 'disabled' => 0]);
444
        }
445
446
        return $res;
447
    }
448
449
    /**
450
     * Inserts Trailer Code by Class.
451
     *
452
     * @param $whichclass
453
     * @param $res
454
     *
455
     * @return string
456
     */
457
    public function insertSwf($whichclass, $res): string
458
    {
459
        $ret = '';
460
        if ($whichclass === 'ade') {
461
            if (! empty($res)) {
462
                $trailers = unserialize($res, 'ade');
0 ignored issues
show
Bug introduced by
'ade' of type string is incompatible with the type null|array expected by parameter $options of unserialize(). ( Ignorable by Annotation )

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

462
                $trailers = unserialize($res, /** @scrutinizer ignore-type */ 'ade');
Loading history...
463
                $ret .= "<object width='360' height='240' type='application/x-shockwave-flash' id='EmpireFlashPlayer' name='EmpireFlashPlayer' data='".$trailers['url']."'>";
464
                $ret .= "<param name='flashvars' value= 'streamID=".$trailers['streamid'].'&amp;autoPlay=false&amp;BaseStreamingUrl='.$trailers['baseurl']."'>";
465
                $ret .= '</object>';
466
467
                return $ret;
468
            }
469
        }
470
        if ($whichclass === 'pop') {
471
            if (! empty($res)) {
472
                $trailers = unserialize($res, 'pop');
473
                $ret .= "<embed id='trailer' width='480' height='360'";
474
                $ret .= "flashvars='".$trailers['flashvars']."' allowfullscreen='true' allowscriptaccess='always' quality='high' name='trailer' style='undefined'";
475
                $ret .= "src='".$trailers['baseurl']."' type='application/x-shockwave-flash'>";
476
477
                return $ret;
478
            }
479
        }
480
481
        return $ret;
482
    }
483
484
    /**
485
     * @param $movie
486
     *
487
     * @return false|int|string
488
     * @throws \Exception
489
     */
490
    public function updateXXXInfo($movie)
491
    {
492
        $cover = $backdrop = 0;
493
        $xxxID = -2;
494
        $this->whichclass = 'aebn';
495
        $mov = new AEBN();
496
        $mov->cookie = $this->cookie;
0 ignored issues
show
Bug introduced by
The property cookie does not seem to exist on Blacklight\processing\adult\AEBN.
Loading history...
497
        ColorCLI::doEcho(ColorCLI::info('Checking AEBN for movie info'), true);
498
        $res = $mov->processSite($movie);
499
500
        if ($res === false) {
501
            $this->whichclass = 'pop';
502
            $mov = new Popporn();
503
            $mov->cookie = $this->cookie;
504
            ColorCLI::doEcho(ColorCLI::info('Checking PopPorn for movie info'), true);
505
            $res = $mov->processSite($movie);
506
        }
507
508
        if ($res === false) {
509
            $this->whichclass = 'adm';
510
            $mov = new ADM();
511
            $mov->cookie = $this->cookie;
512
            ColorCLI::doEcho(ColorCLI::info('Checking ADM for movie info'), true);
513
            $res = $mov->processSite($movie);
514
        }
515
516
        if ($res === false) {
517
            $this->whichclass = 'ade';
518
            $mov = new ADE();
519
            ColorCLI::doEcho(ColorCLI::info('Checking ADE for movie info'), true);
520
            $res = $mov->processSite($movie);
521
        }
522
523
        if ($res === false) {
524
            $this->whichclass = 'hotm';
525
            $mov = new Hotmovies();
526
            $mov->cookie = $this->cookie;
527
            ColorCLI::doEcho(ColorCLI::info('Checking HotMovies for movie info'), true);
528
            $res = $mov->processSite($movie);
529
        }
530
531
        // If a result is true getAll information.
532
        if ($res) {
533
            if ($this->echooutput) {
534
                switch ($this->whichclass) {
535
                    case 'aebn':
536
                        $fromstr = 'Adult Entertainment Broadcast Network';
537
                        break;
538
                    case 'ade':
539
                        $fromstr = 'Adult DVD Empire';
540
                        break;
541
                    case 'pop':
542
                        $fromstr = 'PopPorn';
543
                        break;
544
                    case 'adm':
545
                        $fromstr = 'Adult DVD Marketplace';
546
                        break;
547
                    case 'hotm':
548
                        $fromstr = 'HotMovies';
549
                        break;
550
                    default:
551
                        $fromstr = '';
552
                }
553
                ColorCLI::doEcho(ColorCLI::primary('Fetching XXX info from: '.$fromstr), true);
554
            }
555
            $res = $mov->getAll();
556
        } else {
557
            // Nothing was found, go ahead and set to -2
558
            return -2;
559
        }
560
561
        $res['cast'] = ! empty($res['cast']) ? implode(',', $res['cast']) : '';
562
        $res['genres'] = ! empty($res['genres']) ? $this->getGenreID($res['genres']) : '';
563
564
        $mov = [
565
            'trailers'    => ! empty($res['trailers']) ? serialize($res['trailers']) : '',
566
            'extras'      => ! empty($res['extras']) ? serialize($res['extras']) : '',
567
            'productinfo' => ! empty($res['productinfo']) ? serialize($res['productinfo']) : '',
568
            'backdrop'    => ! empty($res['backcover']) ? $res['backcover'] : 0,
569
            'cover'       => ! empty($res['boxcover']) ? $res['boxcover'] : 0,
570
            'title'       => ! empty($res['title']) ? html_entity_decode($res['title'], ENT_QUOTES, 'UTF-8') : '',
571
            'plot'        => ! empty($res['synopsis']) ? html_entity_decode($res['synopsis'], ENT_QUOTES, 'UTF-8') : '',
572
            'tagline'     => ! empty($res['tagline']) ? html_entity_decode($res['tagline'], ENT_QUOTES, 'UTF-8') : '',
573
            'genre'       => ! empty($res['genres']) ? html_entity_decode($res['genres'], ENT_QUOTES, 'UTF-8') : '',
574
            'director'    => ! empty($res['director']) ? html_entity_decode($res['director'], ENT_QUOTES, 'UTF-8') : '',
575
            'actors'      => ! empty($res['cast']) ? html_entity_decode($res['cast'], ENT_QUOTES, 'UTF-8') : '',
576
            'directurl'   => ! empty($res['directurl']) ? html_entity_decode($res['directurl'], ENT_QUOTES, 'UTF-8') : '',
577
            'classused'   => $this->whichclass,
578
        ];
579
580
        $check = XxxInfo::query()->where('title', $mov['title'])->first(['id']);
581
582
        if ($check !== null && $check['id'] > 0) {
583
            $xxxID = $check['id'];
584
585
            // Update BoxCover.
586
            if (! empty($mov['cover'])) {
587
                $cover = $this->releaseImage->saveImage($xxxID.'-cover', $mov['cover'], $this->imgSavePath);
588
            }
589
590
            // BackCover.
591
            if (! empty($mov['backdrop'])) {
592
                $backdrop = $this->releaseImage->saveImage($xxxID.'-backdrop', $mov['backdrop'], $this->imgSavePath, 1920, 1024);
593
            }
594
595
            // Update Current XXX Information
596
            $this->update($check['id'], $mov['title'], $mov['tagline'], $mov['plot'], $mov['genre'], $mov['director'], $mov['actors'], $mov['extras'], $mov['productinfo'], $mov['trailers'], $mov['directurl'], $mov['classused'], $cover, $backdrop);
0 ignored issues
show
Bug introduced by
It seems like $check['id'] can also be of type Illuminate\Database\Eloq...uent\Relations\Relation and Illuminate\Database\Eloquent\Relations\Relation; however, parameter $id of Blacklight\XXX::update() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

596
            $this->update(/** @scrutinizer ignore-type */ $check['id'], $mov['title'], $mov['tagline'], $mov['plot'], $mov['genre'], $mov['director'], $mov['actors'], $mov['extras'], $mov['productinfo'], $mov['trailers'], $mov['directurl'], $mov['classused'], $cover, $backdrop);
Loading history...
597
        }
598
599
        // Insert New XXX Information
600
        if ($check === null) {
601
            $xxxID = XxxInfo::query()->insertGetId(
602
                [
603
                    'title' => $mov['title'],
604
                    'tagline' => $mov['tagline'],
605
                    'plot' => "\x1f\x8b\x08\x00".gzcompress($mov['plot']),
606
                    'genre' => substr($mov['genre'], 0, 64),
607
                    'director' => $mov['director'],
608
                    'actors' => $mov['actors'],
609
                    'extras' => $mov['extras'],
610
                    'productinfo' => $mov['productinfo'],
611
                    'trailers' => $mov['trailers'],
612
                    'directurl' => $mov['directurl'],
613
                    'classused' => $mov['classused'],
614
                    'created_at' => Carbon::now(),
615
                    'updated_at' => Carbon::now(),
616
                ]
617
            );
618
            // Update BoxCover.
619
            if (! empty($mov['cover'])) {
620
                $cover = $this->releaseImage->saveImage($xxxID.'-cover', $mov['cover'], $this->imgSavePath);
621
            }
622
623
            // BackCover.
624
            if (! empty($mov['backdrop'])) {
625
                $backdrop = $this->releaseImage->saveImage($xxxID.'-backdrop', $mov['backdrop'], $this->imgSavePath, 1920, 1024);
626
            }
627
628
            XxxInfo::query()->where('id', $xxxID)->update(['cover' => $cover, 'backdrop' => $backdrop]);
629
        }
630
631
        if ($this->echooutput) {
632
            ColorCLI::doEcho(
633
                ColorCLI::headerOver(($xxxID !== false ? 'Added/updated XXX movie: '.ColorCLI::primary($mov['title']) : 'Nothing to update for XXX movie: '.ColorCLI::primary($mov['title']))), true);
634
        }
635
636
        return $xxxID;
637
    }
638
639
    /**
640
     * Process XXX releases where xxxinfo is 0.
641
     *
642
     * @throws \Exception
643
     */
644
    public function processXXXReleases(): void
645
    {
646
        $res = Release::query()
647
            ->where(['nzbstatus' => 1, 'xxxinfo_id' => 0])
648
            ->whereIn(
649
                'categories_id',
650
            [
651
                Category::XXX_DVD,
652
                Category::XXX_WMV,
653
                Category::XXX_XVID,
654
                Category::XXX_X264,
655
                Category::XXX_SD,
656
                Category::XXX_CLIPHD,
657
                Category::XXX_CLIPSD,
658
                Category::XXX_WEBDL,
659
            ]
660
            )
661
            ->limit($this->movieqty)
0 ignored issues
show
Bug introduced by
It seems like $this->movieqty can also be of type string; however, parameter $value of Illuminate\Database\Query\Builder::limit() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

661
            ->limit(/** @scrutinizer ignore-type */ $this->movieqty)
Loading history...
662
            ->get(['searchname', 'id']);
663
664
        $movieCount = \count($res);
665
666
        if ($movieCount > 0) {
667
            if ($this->echooutput) {
668
                ColorCLI::doEcho(ColorCLI::header('Processing '.$movieCount.' XXX releases.'), true);
669
            }
670
671
            // Loop over releases.
672
            foreach ($res as $arr) {
673
                $idcheck = -2;
674
675
                // Try to get a name.
676
                if ($this->parseXXXSearchName($arr['searchname']) !== false) {
677
                    $check = $this->checkXXXInfoExists($this->currentTitle);
678
                    if ($check === null) {
679
                        $this->currentRelID = $arr['id'];
680
                        if ($this->echooutput) {
681
                            ColorCLI::doEcho(ColorCLI::primaryOver('Looking up: ').ColorCLI::headerOver($this->currentTitle), true);
682
                        }
683
684
                        ColorCLI::doEcho(ColorCLI::info('Local match not found, checking web!'), true);
685
                        $idcheck = $this->updateXXXInfo($this->currentTitle);
686
                    } else {
687
                        ColorCLI::doEcho(ColorCLI::info('Local match found for XXX Movie: '.ColorCLI::headerOver($this->currentTitle)), true);
688
                        $idcheck = (int) $check['id'];
689
                    }
690
                } else {
691
                    ColorCLI::doEcho('.', true);
692
                }
693
                Release::query()
694
                    ->where('id', $arr['id'])
695
                    ->whereIn('categories_id', [Category::XXX_DVD, Category::XXX_WMV, Category::XXX_XVID, Category::XXX_X264, Category::XXX_SD, Category::XXX_CLIPHD, Category::XXX_CLIPSD, Category::XXX_WEBDL])
696
                    ->update(['xxxinfo_id' => $idcheck]);
697
            }
698
        } elseif ($this->echooutput) {
699
            ColorCLI::doEcho(ColorCLI::header('No xxx releases to process.'), true);
700
        }
701
    }
702
703
    /**
704
     * Checks xxxinfo to make sure releases exist.
705
     *
706
     * @param $releaseName
707
     * @return \Illuminate\Database\Eloquent\Model|null|static
708
     */
709
    protected function checkXXXInfoExists($releaseName)
710
    {
711
        return XxxInfo::query()->where('title', 'like', '%'.$releaseName.'%')->first(['id', 'title']);
712
    }
713
714
    /**
715
     * Cleans up a searchname to make it easier to scrape.
716
     *
717
     * @param string $releaseName
718
     *
719
     * @return bool
720
     */
721
    protected function parseXXXSearchName($releaseName): bool
722
    {
723
        $name = '';
724
        $followingList = '[^\w]((2160|1080|480|720)(p|i)|AC3D|Directors([^\w]CUT)?|DD5\.1|(DVD|BD|BR)(Rip)?|BluRay|divx|HDTV|iNTERNAL|LiMiTED|(Real\.)?Proper|RE(pack|Rip)|Sub\.?(fix|pack)|Unrated|WEB-DL|(x|H)[-._ ]?264|xvid|[Dd][Ii][Ss][Cc](\d+|\s*\d+|\.\d+)|XXX|BTS|DirFix|Trailer|WEBRiP|NFO|(19|20)\d\d)[^\w]';
725
726
        if (preg_match('/([^\w]{2,})?(?P<name>[\w .-]+?)'.$followingList.'/i', $releaseName, $matches)) {
727
            $name = $matches['name'];
728
        }
729
730
        // Check if we got something.
731
        if ($name !== '') {
732
733
            // If we still have any of the words in $followingList, remove them.
734
            $name = preg_replace('/'.$followingList.'/i', ' ', $name);
735
            // Remove periods, underscored, anything between parenthesis.
736
            $name = preg_replace('/\(.*?\)|[-._]/i', ' ', $name);
737
            // Finally remove multiple spaces and trim leading spaces.
738
            $name = trim(preg_replace('/\s{2,}/', ' ', $name));
739
            // Remove Private Movies {d} from name better matching.
740
            $name = trim(preg_replace('/^Private\s(Specials|Blockbusters|Blockbuster|Sports|Gold|Lesbian|Movies|Classics|Castings|Fetish|Stars|Pictures|XXX|Private|Black\sLabel|Black)\s\d+/i', '', $name));
741
            // Remove Foreign Words at the end of the name.
742
            $name = trim(preg_replace('/(brazilian|chinese|croatian|danish|deutsch|dutch|estonian|flemish|finnish|french|german|greek|hebrew|icelandic|italian|latin|nordic|norwegian|polish|portuguese|japenese|japanese|russian|serbian|slovenian|spanish|spanisch|swedish|thai|turkish)$/i', '', $name));
743
744
            // Check if the name is long enough and not just numbers and not file (d) of (d) and does not contain Episodes and any dated 00.00.00 which are site rips..
745
            if (\strlen($name) > 5 && ! preg_match('/^\d+$/', $name) && ! preg_match('/( File \d+ of \d+|\d+.\d+.\d+)/', $name) && ! preg_match('/(E\d+)/', $name) && ! preg_match('/\d\d\.\d\d.\d\d/', $name)) {
746
                $this->currentTitle = $name;
747
748
                return true;
749
            }
750
        }
751
752
        return false;
753
    }
754
}
755