Completed
Push — master ( ee378a...71008e )
by Stanislav
02:40
created

WeburgClient::getSeriesTorrents()   B

Complexity

Conditions 4
Paths 2

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 1
Metric Value
c 3
b 1
f 1
dl 0
loc 24
rs 8.6845
cc 4
eloc 14
nc 2
nop 4
1
<?php
2
3
namespace Popstas\Transmission\Console;
4
5
use GuzzleHttp\ClientInterface;
6
use GuzzleHttp\Cookie\CookieJar;
7
8
class WeburgClient
9
{
10
    /**
11
     * @var ClientInterface
12
     */
13
    private $httpClient;
14
15
    private $requestDelay;
16
17
    public function __construct(ClientInterface $httpClient, $requestDelay = 0)
18
    {
19
        $this->httpClient = $httpClient;
20
        $this->requestDelay = $requestDelay;
21
    }
22
23
    public function getMovieInfoById($movieId)
24
    {
25
        $movieUrl = $this->getMovieUrl($movieId);
26
        $body = $this->getUrlBody($movieUrl);
27
        $body = iconv('WINDOWS-1251', 'UTF-8', $body);
28
        $info = $this->getMovieInfo($body);
29
        return $info;
30
    }
31
32
    /**
33
     * @param $movieId
34
     * @return array urls of movie (not series)
35
     */
36
    public function getMovieTorrentUrlsById($movieId)
37
    {
38
        $torrentUrl = $this->getMovieTorrentUrl($movieId);
39
        $body = $this->getUrlBody($torrentUrl);
40
        $torrentsUrls = $this->getTorrentsUrls($body);
41
        return $torrentsUrls;
42
    }
43
44
    /**
45
     * @param $movieId
46
     * @param $hashes array hashes of torrents from movieInfo
47
     * @param int $daysMax torrents older last days will not matched
48
     * @param int $allowedMisses after x misses next checks will broken
49
     * @return array urls of matched torrent files
50
     */
51
    public function getSeriesTorrents($movieId, $hashes, $daysMax = 1, $allowedMisses = 0)
52
    {
53
        $torrentsUrls = [];
54
        $timestampFrom = strtotime('-' . $daysMax . 'days');
55
56
        $hashes = array_reverse($hashes);
57
        foreach ($hashes as $hash) {
58
            if ($allowedMisses < 0) {
59
                break;
60
            }
61
62
            $torrentUrl = $this->getMovieTorrentUrl($movieId, $hash);
63
            $body = $this->getUrlBody($torrentUrl);
64
65
            if (!$this->checkTorrentDate($body, $timestampFrom)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->checkTorrentDate($body, $timestampFrom) of type false|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
66
                $allowedMisses--;
67
                continue;
68
            }
69
70
            $torrentsUrls = array_merge($torrentsUrls, $this->getTorrentsUrls($body));
71
        }
72
73
        return $torrentsUrls;
74
    }
75
76
    public function getMoviesIds()
77
    {
78
        $moviesUrl = 'http://weburg.net/movies/new/?clever_title=1&template=0&last=0';
79
80
        $jsonRaw = $this->getUrlBody($moviesUrl, [
81
            'Content-Type'     => 'text/html; charset=utf-8',
82
            'User-Agent'       => 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:27.0) Gecko/20100101 Firefox/27.0',
83
            'X-Requested-With' => 'XMLHttpRequest',
84
        ]);
85
86
        $moviesJson = json_decode($jsonRaw);
87
88
        $moviesIds = $this->getInfoUrls($moviesJson->items);
89
90
        return $moviesIds;
91
    }
92
93
    public function getMovieUrl($movieId)
94
    {
95
        return 'http://weburg.net/movies/info/' . $movieId;
96
    }
97
98
    /**
99
     * @param $url
100
     * @param array $headers
101
     * @return \Psr\Http\Message\ResponseInterface
102
     * @throws \RuntimeException
103
     */
104
    private function getUrl($url, $headers = [])
105
    {
106
        $jar = new CookieJar();
107
108
        $res = $this->httpClient->request('GET', $url, [
109
            'headers' => $headers,
110
            'cookies' => $jar,
111
        ]);
112
113
        if ($res->getStatusCode() != 200) {
114
            throw new \RuntimeException('Error ' . $res->getStatusCode() . 'while get url ' . $url);
115
        }
116
117
        sleep($this->requestDelay);
118
119
        return $res;
120
    }
121
122
    /**
123
     * @param $url
124
     * @param array $headers
125
     * @return \Psr\Http\Message\StreamInterface
126
     * @throws \RuntimeException
127
     */
128
    public function getUrlBody($url, $headers = [])
129
    {
130
        $res = $this->getUrl($url, $headers);
131
        $body = $res->getBody();
132
        return $body;
133
    }
134
135
    /**
136
     * @param $url
137
     * @param $torrentsDir
138
     * @throws \RuntimeException
139
     */
140
    public function downloadTorrent($url, $torrentsDir)
141
    {
142
        $res = $this->getUrl($url);
143
        $torrentBody = $res->getBody();
144
145
        $disposition = $res->getHeader('content-disposition');
146
        preg_match('/filename="(.*?)"/', $disposition[0], $res);
147
        $filename = $res[1];
148
149
        $filePath = $torrentsDir . '/' . $filename;
150
        file_put_contents($filePath, $torrentBody);
151
    }
152
153
    public function isTorrentPopular($movieInfo, $commentsMin, $imdbMin, $kinopoiskMin, $votesMin)
154
    {
155
        return $movieInfo['comments'] >= $commentsMin
156
        || $movieInfo['rating_imdb'] >= $imdbMin
157
        || $movieInfo['rating_kinopoisk'] >= $kinopoiskMin
158
        || $movieInfo['rating_votes'] >= $votesMin;
159
    }
160
161
    public function cleanMovieId($idOrUrl)
162
    {
163
        if (preg_match('/^\d+$/', $idOrUrl)) {
164
            return $idOrUrl;
165
        }
166
        preg_match('/^http:\/\/weburg\.net\/(series|movies)\/info\/(\d+)$/', $idOrUrl, $res);
167
        $movieId = count($res) ? $res[2] : null;
168
        return $movieId;
169
    }
170
171
    private function getMovieTorrentUrl($movieId, $hash = '')
172
    {
173
        return 'http://weburg.net/ajax/download/movie?'
174
        . ($hash ? 'hash=' . $hash . '&' : '')
175
        . 'obj_id=' . $movieId;
176
    }
177
178
    private function getMovieInfo($body)
179
    {
180
        $info = [];
181
182
        $checks = [
183
            'title'            => '<title>(.*?) — Weburg<\/title>',
184
            'comments'         => 'Комментариев:&nbsp;(\d+)',
185
            'rating_kinopoisk' => 'external-ratings-link_type_kinopoisk.*?>(\d+\.\d+)',
186
            'rating_imdb'      => 'external-ratings-link_type_imdb.*?>(\d+\.\d+)',
187
            'rating_votes'     => 'count-votes" value="([0-9]+)"',
188
        ];
189
190
        foreach ($checks as $name => $regexp) {
191
            preg_match('/' . $regexp . '/mis', $body, $res);
192
            $info[$name] = count($res) ? $res[1] : null;
193
        }
194
195
        preg_match_all('/js-search-button.*?hash="(.*?)"/mis', $body, $res);
196
        $info['hashes'] = count($res) ? $res[1] : null;
197
198
        return $info;
199
    }
200
201
    /**
202
     * @param $body
203
     * @param $fromTimestamp
204
     * @return bool|string date if matched, false if not
205
     */
206
    private function checkTorrentDate($body, $fromTimestamp)
207
    {
208
        preg_match('/(\d{2})\.(\d{2})\.(\d{4})/mis', $body, $res);
209
        if (empty($res)) {
210
            return false;
211
        }
212
213
        $torrentTimestamp = mktime(0, 0, 0, $res[2], $res[1], $res[3]);
214
        return $torrentTimestamp >= $fromTimestamp ? $res[0] : false;
215
    }
216
217
    private function getInfoUrls($body)
218
    {
219
        preg_match_all('/\/movies\/info\/([0-9]+)/', $body, $res);
220
        $moviesIds = array_unique($res[1]);
221
        return $moviesIds;
222
    }
223
224
    /**
225
     * @param $body
226
     * @return array
227
     */
228
    private function getTorrentsUrls($body)
229
    {
230
        preg_match_all('/(http:\/\/.*?gettorrent.*?)"/', $body, $res);
231
        $torrentsUrls = $res[1];
232
        $torrentsUrls = array_unique($torrentsUrls);
233
        return $torrentsUrls;
234
    }
235
}
236