WeburgClient   A
last analyzed

Complexity

Total Complexity 38

Size/Duplication

Total Lines 289
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 38
lcom 1
cbo 3
dl 0
loc 289
rs 9.36
c 0
b 0
f 0

18 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A getMovieInfoById() 0 8 1
A getMovieTorrentUrlsById() 0 7 1
A getSeriesTorrents() 0 24 4
A getMoviesIds() 0 18 3
A getMovieIdByQuery() 0 10 4
A movieQuery() 0 14 1
A getMovieUrl() 0 4 1
A getUrl() 0 17 2
A getUrlBody() 0 6 1
A downloadTorrent() 0 14 1
A isTorrentPopular() 0 7 4
A cleanMovieId() 0 9 3
A getMovieTorrentUrl() 0 6 2
A getMovieInfo() 0 22 4
A checkTorrentDate() 0 10 3
A getInfoUrls() 0 6 1
A getTorrentsUrls() 0 7 1
1
<?php
2
3
namespace Popstas\Transmission\Console;
4
5
use GuzzleHttp\ClientInterface;
6
use GuzzleHttp\Cookie\CookieJar;
7
use GuzzleHttp\Exception\GuzzleException;
8
use Psr\Http\Message\ResponseInterface;
9
use Psr\Http\Message\StreamInterface;
10
use RuntimeException;
11
12
class WeburgClient
13
{
14
    /**
15
     * @var ClientInterface
16
     */
17
    private $httpClient;
18
19
    private $requestDelay;
20
21
    /**
22
     * WeburgClient constructor.
23
     * @param ClientInterface $httpClient
24
     * @param int $requestDelay
25
     */
26
    public function __construct(ClientInterface $httpClient, $requestDelay = 0)
27
    {
28
        $this->httpClient = $httpClient;
29
        $this->requestDelay = $requestDelay;
30
    }
31
32
    /**
33
     * @param $movieId
34
     * @return array
35
     * @throws GuzzleException
36
     */
37
    public function getMovieInfoById($movieId)
38
    {
39
        $movieUrl = $this->getMovieUrl($movieId);
40
        $body = $this->getUrlBody($movieUrl);
41
        $body = iconv('WINDOWS-1251', 'UTF-8', $body);
42
        $info = $this->getMovieInfo($body);
43
        return $info;
44
    }
45
46
    /**
47
     * @param $movieId
48
     * @return array urls of movie (not series)
49
     * @throws GuzzleException
50
     */
51
    public function getMovieTorrentUrlsById($movieId)
52
    {
53
        $torrentUrl = $this->getMovieTorrentUrl($movieId);
54
        $body = $this->getUrlBody($torrentUrl);
55
        $torrentsUrls = $this->getTorrentsUrls($body);
56
        return $torrentsUrls;
57
    }
58
59
    /**
60
     * @param $movieId
61
     * @param $hashes array hashes of torrents from movieInfo
62
     * @param int $daysMax torrents older last days will not matched
63
     * @param int $allowedMisses after x misses next checks will broken
64
     * @return array urls of matched torrent files
65
     * @throws GuzzleException
66
     */
67
    public function getSeriesTorrents($movieId, $hashes, $daysMax = 1, $allowedMisses = 0)
68
    {
69
        $torrentsUrls = [];
70
        $timestampFrom = strtotime('-' . $daysMax . 'days');
71
72
        $hashes = array_reverse($hashes);
73
        foreach ($hashes as $hash) {
74
            if ($allowedMisses < 0) {
75
                break;
76
            }
77
78
            $torrentUrl = $this->getMovieTorrentUrl($movieId, $hash);
79
            $body = $this->getUrlBody($torrentUrl);
80
81
            if ($this->checkTorrentDate($body, $timestampFrom) === false) {
82
                $allowedMisses--;
83
                continue;
84
            }
85
86
            $torrentsUrls = array_merge($torrentsUrls, $this->getTorrentsUrls($body));
87
        }
88
89
        return $torrentsUrls;
90
    }
91
92
    /**
93
     * @param string $moviesUrl
94
     * @return array
95
     * @throws GuzzleException
96
     */
97
    public function getMoviesIds($moviesUrl = 'https://weburg.net/movies/new/?clever_title=1&template=0&last=0')
98
    {
99
        if (!$moviesUrl) {
100
            $moviesUrl = 'https://weburg.net/movies/new/?clever_title=1&template=0&last=0';
101
        }
102
        $jsonRaw = $this->getUrlBody($moviesUrl, [
103
            'Content-Type'     => 'text/html; charset=utf-8',
104
            'User-Agent'       => 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:27.0) Gecko/20100101 Firefox/27.0',
105
            'X-Requested-With' => 'XMLHttpRequest',
106
        ]);
107
108
        $moviesJson = @json_decode($jsonRaw);
109
        $html = $moviesJson ? $moviesJson->items : strval($jsonRaw);
110
111
        $moviesIds = $this->getInfoUrls($html);
112
113
        return $moviesIds;
114
    }
115
116
    /**
117
     * @param $q
118
     * @return bool|string
119
     * @throws GuzzleException
120
     */
121
    public function getMovieIdByQuery($q)
122
    {
123
        $results = $this->movieQuery($q);
124
125
        if ($results && $results[0] && $results[0]->object_id) {
126
            return $results[0]->object_id;
127
        }
128
129
        return false;
130
    }
131
132
    /**
133
     * @param $q
134
     * @return mixed
135
     * @throws GuzzleException
136
     */
137
    public function movieQuery($q)
138
    {
139
        $resultUrl = 'https://weburg.net/ajax/autocomplete/search/main?' . http_build_query(['q' => $q]);
140
141
        $jsonRaw = $this->getUrlBody($resultUrl, [
142
            'Content-Type' => 'text/html; charset=utf-8',
143
            'User-Agent'   => 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:27.0) Gecko/20100101 Firefox/27.0',
144
            // 'X-Requested-With' => 'XMLHttpRequest',
145
        ]);
146
147
        $resultJson = json_decode($jsonRaw);
148
149
        return $resultJson;
150
    }
151
152
    public static function getMovieUrl($movieId)
153
    {
154
        return 'https://weburg.net/movies/info/' . $movieId;
155
    }
156
157
    /**
158
     * @param $url
159
     * @param array $headers
160
     * @return ResponseInterface
161
     * @throws RuntimeException
162
     * @throws GuzzleException
163
     */
164
    private function getUrl($url, $headers = [])
165
    {
166
        $jar = new CookieJar();
167
168
        $res = $this->httpClient->request('GET', $url, [
169
            'headers' => $headers,
170
            'cookies' => $jar,
171
        ]);
172
173
        if ($res->getStatusCode() != 200) {
174
            throw new RuntimeException('Error ' . $res->getStatusCode() . 'while get url ' . $url);
175
        }
176
177
        sleep($this->requestDelay);
178
179
        return $res;
180
    }
181
182
    /**
183
     * @param string $url
184
     * @param array $headers
185
     * @return StreamInterface
186
     * @throws RuntimeException
187
     * @throws GuzzleException
188
     */
189
    public function getUrlBody($url, $headers = [])
190
    {
191
        $res = $this->getUrl($url, $headers);
192
        $body = $res->getBody();
193
        return $body;
194
    }
195
196
    /**
197
     * @param $url
198
     * @param $torrentsDir
199
     * @return string path to downloaded file
200
     * @throws RuntimeException
201
     * @throws GuzzleException
202
     */
203
    public function downloadTorrent($url, $torrentsDir)
204
    {
205
        $res = $this->getUrl($url);
206
        $torrentBody = $res->getBody();
207
208
        $disposition = $res->getHeader('content-disposition');
209
        preg_match('/filename="(.*?)"/', $disposition[0], $res);
210
        $filename = $res[1];
211
212
        $filePath = $torrentsDir . '/' . $filename;
213
        file_put_contents($filePath, $torrentBody);
214
215
        return $filePath;
216
    }
217
218
    public function isTorrentPopular($movieInfo, $commentsMin, $imdbMin, $kinopoiskMin, $votesMin)
219
    {
220
        return $movieInfo['comments'] >= $commentsMin
221
            || $movieInfo['rating_imdb'] >= $imdbMin
222
            || $movieInfo['rating_kinopoisk'] >= $kinopoiskMin
223
            || $movieInfo['rating_votes'] >= $votesMin;
224
    }
225
226
    public function cleanMovieId($idOrUrl)
227
    {
228
        if (preg_match('/^\d+$/', $idOrUrl)) {
229
            return $idOrUrl;
230
        }
231
        preg_match('/^https?:\/\/weburg\.net\/(series|movies)\/info\/(\d+)$/', $idOrUrl, $res);
232
        $movieId = count($res) ? $res[2] : null;
233
        return $movieId;
234
    }
235
236
    private static function getMovieTorrentUrl($movieId, $hash = '')
237
    {
238
        return 'https://weburg.net/ajax/download/movie?'
239
            . ($hash ? 'hash=' . $hash . '&' : '')
240
            . 'obj_id=' . $movieId;
241
    }
242
243
    private static function getMovieInfo($body)
244
    {
245
        $info = [];
246
247
        $checks = [
248
            'title'            => '<title>(.*?)( — Weburg)?( — Вебург)?<\/title>',
249
            'comments'         => 'Комментариев:&nbsp;(\d+)',
250
            'rating_kinopoisk' => 'external-ratings-link_type_kinopoisk.*?>(\d+\.\d+)',
251
            'rating_imdb'      => 'external-ratings-link_type_imdb.*?>(\d+\.\d+)',
252
            'rating_votes'     => 'count-votes" value="([0-9]+)"',
253
        ];
254
255
        foreach ($checks as $name => $regexp) {
256
            preg_match('/' . $regexp . '/mis', $body, $res);
257
            $info[$name] = count($res) ? $res[1] : null;
258
        }
259
260
        preg_match_all('/js-search-button.*?hash="(.*?)"/mis', $body, $res);
261
        $info['hashes'] = count($res) ? $res[1] : null;
262
263
        return $info;
264
    }
265
266
    /**
267
     * @param $body
268
     * @param $fromTimestamp
269
     * @return bool|string date if matched, false if not
270
     */
271
    private static function checkTorrentDate($body, $fromTimestamp)
272
    {
273
        preg_match('/(\d{2})\.(\d{2})\.(\d{4})/mis', $body, $res);
274
        if (empty($res)) {
275
            return false;
276
        }
277
278
        $torrentTimestamp = mktime(0, 0, 0, $res[2], $res[1], $res[3]);
279
        return $torrentTimestamp >= $fromTimestamp ? $res[0] : false;
280
    }
281
282
    private static function getInfoUrls($body)
283
    {
284
        preg_match_all('/\/movies\/info\/([0-9]+)/', $body, $res);
285
        $moviesIds = array_unique($res[1]);
286
        return $moviesIds;
287
    }
288
289
    /**
290
     * @param $body
291
     * @return array
292
     */
293
    private static function getTorrentsUrls($body)
294
    {
295
        preg_match_all('/(http:\/\/.*?gettorrent.*?)"/', $body, $res);
296
        $torrentsUrls = $res[1];
297
        $torrentsUrls = array_unique($torrentsUrls);
298
        return $torrentsUrls;
299
    }
300
}
301