Passed
Push — master ( 179943...1193c4 )
by Darko
09:13
created

LocalDbPipe::getName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
namespace App\Services\TvProcessing\Pipes;
4
5
use App\Services\TvProcessing\TvProcessingPassable;
6
use App\Services\TvProcessing\TvProcessingResult;
7
use Blacklight\processing\tv\LocalDB;
8
use Blacklight\processing\tv\TV;
9
10
/**
11
 * Pipe for local database lookups.
12
 * Attempts to match releases against existing video data before hitting external APIs.
13
 */
14
class LocalDbPipe extends AbstractTvProviderPipe
15
{
16
    protected int $priority = 10;
17
    private ?LocalDB $localDb = null;
18
19
    public function getName(): string
20
    {
21
        return 'Local DB';
22
    }
23
24
    public function getStatusCode(): int
25
    {
26
        return 0; // PROCESS_TVDB - Local DB processes unmatched releases first
27
    }
28
29
    /**
30
     * Get or create the LocalDB instance.
31
     */
32
    private function getLocalDb(): LocalDB
33
    {
34
        if ($this->localDb === null) {
35
            $this->localDb = new LocalDB();
36
        }
37
        return $this->localDb;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->localDb could return the type null which is incompatible with the type-hinted return Blacklight\processing\tv\LocalDB. Consider adding an additional type-check to rule them out.
Loading history...
38
    }
39
40
    protected function process(TvProcessingPassable $passable): TvProcessingResult
41
    {
42
        $parsedInfo = $passable->getParsedInfo();
43
        $context = $passable->context;
44
45
        if ($parsedInfo === null || empty($parsedInfo['cleanname'])) {
46
            return TvProcessingResult::notFound($this->getName());
47
        }
48
49
        $cleanName = $parsedInfo['cleanname'];
50
        $localDb = $this->getLocalDb();
51
52
        // Try to find the show in our local database by title
53
        $videoId = $localDb->getByTitle($cleanName, TV::TYPE_TV, 0);
54
55
        if ($videoId === 0 || $videoId === false) {
56
            $this->outputNotFound($cleanName);
57
            return TvProcessingResult::notFound($this->getName(), ['title' => $cleanName]);
58
        }
59
60
        // Found a matching show in local DB
61
        $episodeId = false;
62
        $hasEpisodeNumbers = $this->hasEpisodeNumbers($parsedInfo);
63
        $hasAirdate = ! empty($parsedInfo['airdate']);
64
65
        if ($hasEpisodeNumbers || $hasAirdate) {
66
            // Try to find the specific episode
67
            $episodeId = $localDb->getBySeasonEp(
68
                $videoId,
69
                (int) ($parsedInfo['season'] ?? 0),
70
                (int) ($parsedInfo['episode'] ?? 0),
71
                $parsedInfo['airdate'] ?? ''
72
            );
73
        }
74
75
        if ($episodeId !== false && $episodeId > 0) {
76
            // Complete match - both show and episode found
77
            $localDb->setVideoIdFound($videoId, $context->releaseId, $episodeId);
0 ignored issues
show
Bug introduced by
It seems like $episodeId can also be of type true; however, parameter $episodeId of Blacklight\processing\tv\TV::setVideoIdFound() 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

77
            $localDb->setVideoIdFound($videoId, $context->releaseId, /** @scrutinizer ignore-type */ $episodeId);
Loading history...
78
79
            $this->outputMatch(
80
                $cleanName,
81
                $hasEpisodeNumbers ? (int) $parsedInfo['season'] : null,
82
                $hasEpisodeNumbers ? (int) $parsedInfo['episode'] : null,
83
                $hasAirdate ? $parsedInfo['airdate'] : null
84
            );
85
86
            return TvProcessingResult::matched($videoId, $episodeId, $this->getName());
0 ignored issues
show
Bug introduced by
It seems like $episodeId can also be of type true; however, parameter $episodeId of App\Services\TvProcessin...essingResult::matched() 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

86
            return TvProcessingResult::matched($videoId, /** @scrutinizer ignore-type */ $episodeId, $this->getName());
Loading history...
87
        }
88
89
        // Series matched but no specific episode located
90
        // Set video ID but mark episode as 0 (needs further lookup)
91
        $localDb->setVideoIdFound($videoId, $context->releaseId, 0);
92
93
        if ($this->echoOutput) {
94
            $this->colorCli->primaryOver('    → ');
95
            $this->colorCli->headerOver($this->truncateTitle($cleanName));
96
            if ($hasAirdate) {
97
                $this->colorCli->primaryOver(' | ');
98
                $this->colorCli->warningOver($parsedInfo['airdate']);
99
                $this->colorCli->headerOver(' → ');
100
                $this->colorCli->notice('Series matched, airdate not in local DB');
101
            } elseif ($hasEpisodeNumbers) {
102
                $this->colorCli->primaryOver(' S');
103
                $this->colorCli->warningOver(sprintf('%02d', (int) $parsedInfo['season']));
104
                $this->colorCli->primaryOver('E');
105
                $this->colorCli->warningOver(sprintf('%02d', (int) $parsedInfo['episode']));
106
                $this->colorCli->headerOver(' → ');
107
                $this->colorCli->notice('Series matched, episode not in local DB');
108
            } else {
109
                $this->colorCli->primaryOver(' → ');
110
                $this->colorCli->notice('Series matched (no episode info)');
111
            }
112
        }
113
114
        // Return not found so external APIs can try to get the episode
115
        return TvProcessingResult::notFound($this->getName(), [
116
            'video_id' => $videoId,
117
            'series_matched' => true,
118
            'episode_missing' => true,
119
        ]);
120
    }
121
122
    /**
123
     * Check if parsed info has valid episode numbers.
124
     */
125
    private function hasEpisodeNumbers(array $parsedInfo): bool
126
    {
127
        return isset($parsedInfo['season'], $parsedInfo['episode'])
128
            && $parsedInfo['episode'] !== 'all'
129
            && (int) $parsedInfo['season'] > 0
130
            && (int) $parsedInfo['episode'] > 0;
131
    }
132
}
133