Completed
Push — master ( f277c1...6f7267 )
by Stanislav
02:15
created

WeburgClient::getMovieInfo()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 22
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
c 3
b 1
f 0
dl 0
loc 22
rs 8.9197
cc 4
eloc 14
nc 6
nop 1
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
    public function __construct(ClientInterface $httpClient)
16
    {
17
        $this->httpClient = $httpClient;
18
    }
19
20
    public function getMovieInfoById($movieId)
21
    {
22
        $movieUrl = $this->getMovieUrl($movieId);
23
        $body = $this->getUrlBody($movieUrl);
24
        $body = iconv('WINDOWS-1251', 'UTF-8', $body);
25
        $info = $this->getMovieInfo($body);
26
        return $info;
27
    }
28
29
    /**
30
     * @param $movieId
31
     * @return array urls of movie (not series)
32
     */
33
    public function getMovieTorrentUrlsById($movieId)
34
    {
35
        $torrentUrl = $this->getMovieTorrentUrl($movieId);
36
        $body = $this->getUrlBody($torrentUrl);
37
        $torrentsUrls = $this->getTorrentsUrls($body);
38
        return $torrentsUrls;
39
    }
40
41
    /**
42
     * @param $movieId
43
     * @param $hashes array hashes of torrents from movieInfo
44
     * @param int $daysMax torrents older last days will not matched
45
     * @return array urls of matched torrent files
46
     */
47
    public function getSeriesTorrents($movieId, $hashes, $daysMax = 1)
48
    {
49
        $torrentsUrls = [];
50
        $timestampFrom = strtotime('-' . $daysMax . 'days');
51
52
        $hashes = array_reverse($hashes);
53
        foreach ($hashes as $hash) {
54
            $torrentUrl = $this->getMovieTorrentUrl($movieId, $hash);
55
            $body = $this->getUrlBody($torrentUrl);
56
57
            if (!$this->checkTorrentDate($body, $timestampFrom)) {
58
                break;
59
            }
60
            $torrentsUrls = array_merge($torrentsUrls, $this->getTorrentsUrls($body));
61
        }
62
63
        return $torrentsUrls;
64
    }
65
66
    public function getMoviesIds()
67
    {
68
        $moviesUrl = 'http://weburg.net/movies/new/?clever_title=1&template=0&last=0';
69
70
        $jsonRaw = $this->getUrlBody($moviesUrl, [
71
            'Content-Type'     => 'text/html; charset=utf-8',
72
            'User-Agent'       => 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:27.0) Gecko/20100101 Firefox/27.0',
73
            'X-Requested-With' => 'XMLHttpRequest',
74
        ]);
75
76
        $moviesJson = json_decode($jsonRaw);
77
78
        $moviesIds = $this->getInfoUrls($moviesJson->items);
79
80
        return $moviesIds;
81
    }
82
83
    public function getMovieUrl($movieId)
84
    {
85
        return 'http://weburg.net/movies/info/' . $movieId;
86
    }
87
88
    public function getUrlBody($url, $headers = [])
89
    {
90
        $jar = new CookieJar();
91
92
        $res = $this->httpClient->request('GET', $url, [
93
            'headers' => $headers,
94
            'cookies' => $jar,
95
        ]);
96
97
        // TODO: it should return 200 or not 200 code, never 0
98 View Code Duplication
        if ($res->getStatusCode() != 200) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
99
            throw new \RuntimeException('Error ' . $res->getStatusCode() . 'while get url ' . $url);
100
        }
101
102
        $body = $res->getBody();
103
104
        return $body;
105
    }
106
107
    public function isTorrentPopular($movieInfo, $commentsMin, $imdbMin, $kinopoiskMin, $votesMin)
108
    {
109
        return $movieInfo['comments'] >= $commentsMin
110
        || $movieInfo['rating_imdb'] >= $imdbMin
111
        || $movieInfo['rating_kinopoisk'] >= $kinopoiskMin
112
        || $movieInfo['rating_votes'] >= $votesMin;
113
    }
114
115
    public function downloadTorrent($url, $torrentsDir)
116
    {
117
        $jar = new CookieJar();
118
119
        $res = $this->httpClient->request('GET', $url, ['cookies' => $jar]);
120
121 View Code Duplication
        if ($res->getStatusCode() != 200) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
122
            throw new \RuntimeException('Error ' . $res->getStatusCode() . 'while get url ' . $url);
123
        }
124
125
        $torrentBody = $res->getBody();
126
127
        $disposition = $res->getHeader('content-disposition');
128
        preg_match('/filename="(.*?)"/', $disposition[0], $res);
129
        $filename = $res[1];
130
131
        $filePath = $torrentsDir . '/' . $filename;
132
        file_put_contents($filePath, $torrentBody);
133
    }
134
135
    public function cleanMovieId($idOrUrl)
136
    {
137
        if (preg_match('/^\d+$/', $idOrUrl)) {
138
            return $idOrUrl;
139
        }
140
        preg_match('/^http:\/\/weburg\.net\/(series|movies)\/info\/(\d+)$/', $idOrUrl, $res);
141
        $movieId = count($res) ? $res[2] : null;
142
        return $movieId;
143
    }
144
145
    private function getMovieTorrentUrl($movieId, $hash = '')
146
    {
147
        return 'http://weburg.net/ajax/download/movie?'
148
        . ($hash ? 'hash=' . $hash . '&' : '')
149
        . 'obj_id=' . $movieId;
150
    }
151
152
    private function getMovieInfo($body)
153
    {
154
        $info = [];
155
156
        $checks = [
157
            'title'            => '<title>(.*?) — Weburg<\/title>',
158
            'comments'         => 'Комментариев:&nbsp;(\d+)',
159
            'rating_kinopoisk' => 'external-ratings-link_type_kinopoisk.*?>(\d+\.\d+)',
160
            'rating_imdb'      => 'external-ratings-link_type_imdb.*?>(\d+\.\d+)',
161
            'rating_votes'     => 'count-votes" value="([0-9]+)"',
162
        ];
163
164
        foreach ($checks as $name => $regexp) {
165
            preg_match('/' . $regexp . '/mis', $body, $res);
166
            $info[$name] = count($res) ? $res[1] : null;
167
        }
168
169
        preg_match_all('/js-search-button.*?hash="(.*?)"/mis', $body, $res);
170
        $info['hashes'] = count($res) ? $res[1] : null;
171
172
        return $info;
173
    }
174
175
    /**
176
     * @param $body
177
     * @param $fromTimestamp
178
     * @return bool|string date if matched, false if not
179
     */
180
    private function checkTorrentDate($body, $fromTimestamp)
181
    {
182
        preg_match('/(\d{2})\.(\d{2})\.(\d{4})/mis', $body, $res);
183
        if (empty($res)) {
184
            return false;
185
        }
186
187
        $torrentTimestamp = mktime(0, 0, 0, $res[2], $res[1], $res[3]);
188
        return $torrentTimestamp >= $fromTimestamp ? $res[0] : false;
189
    }
190
191
    private function getInfoUrls($body)
192
    {
193
        preg_match_all('/\/movies\/info\/([0-9]+)/', $body, $res);
194
        $moviesIds = array_unique($res[1]);
195
        return $moviesIds;
196
    }
197
198
    /**
199
     * @param $body
200
     * @return array
201
     */
202
    private function getTorrentsUrls($body)
203
    {
204
        preg_match_all('/(http:\/\/.*?gettorrent.*?)"/', $body, $res);
205
        $torrentsUrls = $res[1];
206
        $torrentsUrls = array_unique($torrentsUrls);
207
        return $torrentsUrls;
208
    }
209
}
210