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

TvMazePipe::process()   F

Complexity

Conditions 30
Paths 3658

Size

Total Lines 123
Code Lines 67

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 67
c 1
b 0
f 0
dl 0
loc 123
rs 0
cc 30
nc 3658
nop 1

How to fix   Long Method    Complexity   

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
namespace App\Services\TvProcessing\Pipes;
4
5
use App\Services\TvProcessing\TvProcessingPassable;
6
use App\Services\TvProcessing\TvProcessingResult;
7
use Blacklight\processing\tv\TVMaze;
8
9
/**
10
 * Pipe for TVMaze API lookups.
11
 */
12
class TvMazePipe extends AbstractTvProviderPipe
13
{
14
    protected int $priority = 30;
15
    private ?TVMaze $tvmaze = null;
16
17
    public function getName(): string
18
    {
19
        return 'TVMaze';
20
    }
21
22
    public function getStatusCode(): int
23
    {
24
        return -1; // PROCESS_TVMAZE
25
    }
26
27
    /**
28
     * Get or create the TVMaze instance.
29
     */
30
    private function getTvMaze(): TVMaze
31
    {
32
        if ($this->tvmaze === null) {
33
            $this->tvmaze = new TVMaze();
34
        }
35
        return $this->tvmaze;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->tvmaze could return the type null which is incompatible with the type-hinted return Blacklight\processing\tv\TVMaze. Consider adding an additional type-check to rule them out.
Loading history...
36
    }
37
38
    protected function process(TvProcessingPassable $passable): TvProcessingResult
39
    {
40
        $parsedInfo = $passable->getParsedInfo();
41
        $context = $passable->context;
42
43
        if ($parsedInfo === null || empty($parsedInfo['cleanname'])) {
44
            return TvProcessingResult::notFound($this->getName());
45
        }
46
47
        $cleanName = $parsedInfo['cleanname'];
48
49
        // Check if we've already failed this title
50
        if ($this->isInTitleCache($cleanName)) {
51
            $this->outputSkipped($cleanName);
52
            return TvProcessingResult::skipped('previously failed', $this->getName());
53
        }
54
55
        $tvmaze = $this->getTvMaze();
56
        $siteId = false;
57
58
        // Find the Video ID if it already exists
59
        $videoId = $tvmaze->getByTitle($cleanName, TVMaze::TYPE_TV, TVMaze::SOURCE_TVMAZE);
60
61
        if ($videoId !== 0) {
62
            $siteId = $tvmaze->getSiteByID('tvmaze', $videoId);
63
        }
64
65
        if ($videoId === 0) {
66
            // Not in local DB, search TVMaze
67
            $this->outputSearching($cleanName);
68
69
            $tvmazeShow = $tvmaze->getShowInfo((string) $cleanName);
70
71
            if (is_array($tvmazeShow)) {
72
                // Check if we have a valid country
73
                if (isset($parsedInfo['country']) && strlen($parsedInfo['country']) === 2) {
74
                    $tvmazeShow['country'] = $parsedInfo['country'];
75
                }
76
                $videoId = $tvmaze->add($tvmazeShow);
77
                $siteId = (int) $tvmazeShow['tvmaze'];
78
            }
79
        } else {
80
            $this->outputFoundInDb($cleanName);
81
        }
82
83
        if ((int) $videoId === 0 || (int) $siteId === 0) {
84
            // Show not found
85
            $this->addToTitleCache($cleanName);
86
            $this->outputNotFound($cleanName);
87
            return TvProcessingResult::notFound($this->getName(), ['title' => $cleanName]);
88
        }
89
90
        // Fetch poster if we have one
91
        if (! empty($tvmazeShow['poster'] ?? '')) {
92
            $tvmaze->getPoster($videoId);
93
        }
94
95
        // Process episode
96
        $seriesNo = ! empty($parsedInfo['season']) ? preg_replace('/^S0*/i', '', (string) $parsedInfo['season']) : '';
97
        $episodeNo = ! empty($parsedInfo['episode']) ? preg_replace('/^E0*/i', '', (string) $parsedInfo['episode']) : '';
98
        $hasAirdate = ! empty($parsedInfo['airdate']);
99
100
        if ($episodeNo === 'all') {
101
            // Full season release
102
            $tvmaze->setVideoIdFound($videoId, $context->releaseId, 0);
103
            $this->outputFullSeason($cleanName);
104
            return TvProcessingResult::matched($videoId, 0, $this->getName(), ['full_season' => true]);
105
        }
106
107
        // Download all episodes if new show to reduce API/bandwidth usage
108
        if (! $tvmaze->countEpsByVideoID($videoId)) {
109
            $tvmaze->getEpisodeInfo($siteId, -1, -1);
110
        }
111
112
        // Check if we have the episode for this video ID
113
        $episode = $tvmaze->getBySeasonEp($videoId, $seriesNo, $episodeNo, $parsedInfo['airdate'] ?? '');
114
115
        if ($episode === false) {
116
            if ($seriesNo !== '' && $episodeNo !== '') {
117
                // Try to get episode from TVMaze
118
                $tvmazeEpisode = $tvmaze->getEpisodeInfo($siteId, (int) $seriesNo, (int) $episodeNo);
119
120
                if ($tvmazeEpisode) {
0 ignored issues
show
introduced by
$tvmazeEpisode is a non-empty array, thus is always true.
Loading history...
Bug Best Practice introduced by
The expression $tvmazeEpisode of type array<string,integer|string> is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
121
                    $episode = $tvmaze->addEpisode($videoId, $tvmazeEpisode);
122
                }
123
            }
124
125
            if ($episode === false && $hasAirdate) {
126
                // Refresh episode cache and attempt airdate match
127
                $tvmaze->getEpisodeInfo($siteId, -1, -1);
128
                $episode = $tvmaze->getBySeasonEp($videoId, 0, 0, $parsedInfo['airdate']);
129
            }
130
        }
131
132
        if ($episode !== false && is_numeric($episode) && $episode > 0) {
133
            // Success!
134
            $tvmaze->setVideoIdFound($videoId, $context->releaseId, $episode);
135
            $this->outputMatch(
136
                $cleanName,
137
                $seriesNo !== '' ? (int) $seriesNo : null,
138
                $episodeNo !== '' ? (int) $episodeNo : null,
139
                $hasAirdate ? $parsedInfo['airdate'] : null
140
            );
141
            return TvProcessingResult::matched($videoId, (int) $episode, $this->getName());
142
        }
143
144
        // Episode not found
145
        $tvmaze->setVideoIdFound($videoId, $context->releaseId, 0);
146
147
        if ($this->echoOutput) {
148
            $this->colorCli->primaryOver('    → ');
149
            $this->colorCli->alternateOver($this->truncateTitle($cleanName));
150
            if ($hasAirdate) {
151
                $this->colorCli->primaryOver(' | ');
152
                $this->colorCli->warningOver($parsedInfo['airdate']);
153
            }
154
            $this->colorCli->primaryOver(' → ');
155
            $this->colorCli->warning('Episode not found');
156
        }
157
158
        return TvProcessingResult::notFound($this->getName(), [
159
            'video_id' => $videoId,
160
            'episode_not_found' => true,
161
        ]);
162
    }
163
164
    /**
165
     * Output full season match message.
166
     */
167
    private function outputFullSeason(string $title): void
168
    {
169
        if (! $this->echoOutput) {
170
            return;
171
        }
172
173
        $this->colorCli->primaryOver('    → ');
174
        $this->colorCli->headerOver($this->truncateTitle($title));
175
        $this->colorCli->primaryOver(' → ');
176
        $this->colorCli->primary('Full Season matched');
177
    }
178
}
179
180