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) { |
|
|
|
|
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) { |
|
|
|
|
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' => 'Комментариев: (\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
|
|
|
|
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.