1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Popstas\Transmission\Console\Command; |
4
|
|
|
|
5
|
|
|
use Popstas\Transmission\Console\WeburgClient; |
6
|
|
|
use Symfony\Component\Console\Helper\ProgressBar; |
7
|
|
|
use Symfony\Component\Console\Input\ArrayInput; |
8
|
|
|
use Symfony\Component\Console\Input\InputInterface; |
9
|
|
|
use Symfony\Component\Console\Input\InputOption; |
10
|
|
|
use Symfony\Component\Console\Output\OutputInterface; |
11
|
|
|
|
12
|
|
|
class WeburgDownload extends Command |
13
|
|
|
{ |
14
|
|
View Code Duplication |
protected function configure() |
|
|
|
|
15
|
|
|
{ |
16
|
|
|
parent::configure(); |
17
|
|
|
$this |
18
|
|
|
->setName('weburg-download') |
19
|
|
|
->setAliases(['wd']) |
20
|
|
|
->setDescription('Download torrents from weburg.net') |
21
|
|
|
->addOption('download-torrents-dir', null, InputOption::VALUE_OPTIONAL, 'Torrents destination directory') |
22
|
|
|
->addOption('days', null, InputOption::VALUE_OPTIONAL, 'Max age of series torrent') |
23
|
|
|
->addOption('popular', null, InputOption::VALUE_NONE, 'Download only popular') |
24
|
|
|
->addOption('series', null, InputOption::VALUE_NONE, 'Download only tracked series') |
25
|
|
|
->addArgument('movie-id', null, 'Movie ID or URL') |
26
|
|
|
->setHelp(<<<EOT |
27
|
|
|
## Download torrents from Weburg.net |
28
|
|
|
|
29
|
|
|
You can automatically download popular torrents from http://weburg.net/movies/new out of the box, use command: |
30
|
|
|
``` |
31
|
|
|
transmission-cli weburg-download --download-torrents-dir=/path/to/torrents/directory |
32
|
|
|
``` |
33
|
|
|
|
34
|
|
|
or define `download-torrents-dir` in config and just: |
35
|
|
|
``` |
36
|
|
|
transmission-cli weburg-download |
37
|
|
|
``` |
38
|
|
|
|
39
|
|
|
You can automatically download new series, for add series to tracked list see `transmission-cli weburg-series-add`. |
40
|
|
|
It is pretty simple: |
41
|
|
|
``` |
42
|
|
|
transmission-cli weburg-series-add http://weburg.net/series/info/12345 |
43
|
|
|
``` |
44
|
|
|
|
45
|
|
|
After that command `weburg-download` also will download series from list for last day. |
46
|
|
|
If you don't want to download popular torrents, but only new series, use command: |
47
|
|
|
``` |
48
|
|
|
transmission-cli weburg-download --download-torrents-dir=/path/to/torrents/directory --series |
49
|
|
|
``` |
50
|
|
|
|
51
|
|
|
## Add downloaded torrents to Transmission |
52
|
|
|
|
53
|
|
|
After download all torrents, command call `torrent-add` command for each transmission-host from config. |
54
|
|
|
If was defined `--transmission-host` option, then `torrent-add` will called only for this host. |
55
|
|
|
EOT |
56
|
|
|
); |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
protected function execute(InputInterface $input, OutputInterface $output) |
60
|
|
|
{ |
61
|
|
|
$config = $this->getApplication()->getConfig(); |
62
|
|
|
$weburgClient = $this->getApplication()->getWeburgClient(); |
63
|
|
|
|
64
|
|
|
try { |
65
|
|
|
list($torrentsDir, $downloadDir) = $this->getTorrentsDirectory($input); |
66
|
|
|
|
67
|
|
|
$daysMax = $config->overrideConfig($input, 'days', 'weburg-series-max-age'); |
68
|
|
|
$allowedMisses = $config->get('weburg-series-allowed-misses'); |
69
|
|
|
|
70
|
|
|
$movieArgument = $input->getArgument('movie-id'); |
71
|
|
|
if (isset($movieArgument)) { |
72
|
|
|
$torrentsUrls = $this->getMovieTorrentsUrls( |
73
|
|
|
$weburgClient, |
74
|
|
|
$movieArgument, |
75
|
|
|
$daysMax, |
76
|
|
|
$allowedMisses |
77
|
|
|
); |
78
|
|
|
} else { |
79
|
|
|
$torrentsUrls = $this->getTorrentsUrls( |
80
|
|
|
$input, |
81
|
|
|
$output, |
82
|
|
|
$weburgClient, |
83
|
|
|
$downloadDir, |
84
|
|
|
$daysMax, |
85
|
|
|
$allowedMisses |
86
|
|
|
); |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
$this->dryRun($input, $output, function () use ( |
90
|
|
|
$input, |
91
|
|
|
$output, |
92
|
|
|
$weburgClient, |
93
|
|
|
$torrentsDir, |
94
|
|
|
$torrentsUrls |
95
|
|
|
) { |
96
|
|
|
$downloadedFiles = []; |
97
|
|
|
foreach ($torrentsUrls as $torrentUrl) { |
98
|
|
|
$downloadedFiles[] = $weburgClient->downloadTorrent($torrentUrl, $torrentsDir); |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
$this->addTorrents($input, $output, $downloadedFiles); |
102
|
|
|
}, 'dry-run, don\'t really download'); |
103
|
|
|
|
104
|
|
|
} catch (\RuntimeException $e) { |
105
|
|
|
$output->writeln($e->getMessage()); |
106
|
|
|
return 1; |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
return 0; |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
private function getTorrentsUrls( |
113
|
|
|
InputInterface $input, |
114
|
|
|
OutputInterface $output, |
115
|
|
|
WeburgClient $weburgClient, |
116
|
|
|
$downloadDir, |
117
|
|
|
$daysMax, |
118
|
|
|
$allowedMisses |
119
|
|
|
) { |
120
|
|
|
$torrentsUrls = []; |
121
|
|
|
|
122
|
|
|
if (!$input->getOption('popular') && !$input->getOption('series')) { |
123
|
|
|
$input->setOption('popular', true); |
124
|
|
|
$input->setOption('series', true); |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
if ($input->getOption('popular')) { |
128
|
|
|
$torrentsUrls = array_merge( |
129
|
|
|
$torrentsUrls, |
130
|
|
|
$this->getPopularTorrentsUrls($output, $weburgClient, $downloadDir) |
131
|
|
|
); |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
if ($input->getOption('series')) { |
135
|
|
|
$torrentsUrls = array_merge( |
136
|
|
|
$torrentsUrls, |
137
|
|
|
$this->getTrackedSeriesUrls($output, $weburgClient, $daysMax, $allowedMisses) |
138
|
|
|
); |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
return $torrentsUrls; |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
public function getPopularTorrentsUrls(OutputInterface $output, WeburgClient $weburgClient, $downloadDir) |
145
|
|
|
{ |
146
|
|
|
$torrentsUrls = []; |
147
|
|
|
|
148
|
|
|
$config = $this->getApplication()->getConfig(); |
149
|
|
|
$logger = $this->getApplication()->getLogger(); |
150
|
|
|
|
151
|
|
|
$moviesIds = $weburgClient->getMoviesIds(); |
152
|
|
|
|
153
|
|
|
$output->writeln("\nDownloading popular torrents"); |
154
|
|
|
|
155
|
|
|
$progress = new ProgressBar($output, count($moviesIds)); |
156
|
|
|
$progress->start(); |
157
|
|
|
|
158
|
|
|
foreach ($moviesIds as $movieId) { |
159
|
|
|
$progress->setMessage('Check movie ' . $movieId . '...'); |
160
|
|
|
$progress->advance(); |
161
|
|
|
|
162
|
|
|
$downloadedLogfile = $downloadDir . '/' . $movieId; |
163
|
|
|
|
164
|
|
|
$isDownloaded = file_exists($downloadedLogfile); |
165
|
|
|
if ($isDownloaded) { |
166
|
|
|
continue; |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
$movieInfo = $weburgClient->getMovieInfoById($movieId); |
170
|
|
|
foreach (array_keys($movieInfo) as $infoField) { |
171
|
|
|
if (!isset($movieInfo[$infoField])) { |
172
|
|
|
$logger->warning('Cannot find ' . $infoField . ' in movie ' . $movieId); |
173
|
|
|
} |
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
$isTorrentPopular = $weburgClient->isTorrentPopular( |
177
|
|
|
$movieInfo, |
178
|
|
|
$config->get('download-comments-min'), |
179
|
|
|
$config->get('download-imdb-min'), |
180
|
|
|
$config->get('download-kinopoisk-min'), |
181
|
|
|
$config->get('download-votes-min') |
182
|
|
|
); |
183
|
|
|
|
184
|
|
|
if ($isTorrentPopular) { |
185
|
|
|
$progress->setMessage('Download movie ' . $movieId . '...'); |
186
|
|
|
|
187
|
|
|
$movieUrls = $weburgClient->getMovieTorrentUrlsById($movieId); |
188
|
|
|
$torrentsUrls = array_merge($torrentsUrls, $movieUrls); |
189
|
|
|
$logger->info('Download movie ' . $movieId . ': ' . $movieInfo['title']); |
190
|
|
|
|
191
|
|
|
file_put_contents( |
192
|
|
|
$downloadedLogfile, |
193
|
|
|
date('Y-m-d H:i:s') . "\n" . implode("\n", $torrentsUrls) |
194
|
|
|
); |
195
|
|
|
} |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
$progress->finish(); |
199
|
|
|
|
200
|
|
|
return $torrentsUrls; |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
/** |
204
|
|
|
* @param OutputInterface $output |
205
|
|
|
* @param WeburgClient $weburgClient |
206
|
|
|
* @param $daysMax |
207
|
|
|
* @param $allowedMisses |
208
|
|
|
* @return array |
209
|
|
|
*/ |
210
|
|
|
public function getTrackedSeriesUrls(OutputInterface $output, WeburgClient $weburgClient, $daysMax, $allowedMisses) |
211
|
|
|
{ |
212
|
|
|
$torrentsUrls = []; |
213
|
|
|
|
214
|
|
|
$config = $this->getApplication()->getConfig(); |
215
|
|
|
|
216
|
|
|
$seriesIds = $config->get('weburg-series-list'); |
217
|
|
|
if (!$seriesIds) { |
218
|
|
|
return []; |
219
|
|
|
} |
220
|
|
|
|
221
|
|
|
$output->writeln("\nDownloading tracked series"); |
222
|
|
|
|
223
|
|
|
$progress = new ProgressBar($output, count($seriesIds)); |
224
|
|
|
$progress->start(); |
225
|
|
|
|
226
|
|
|
foreach ($seriesIds as $seriesId) { |
227
|
|
|
$progress->setMessage('Check series ' . $seriesId . '...'); |
228
|
|
|
$progress->advance(); |
229
|
|
|
|
230
|
|
|
$movieInfo = $weburgClient->getMovieInfoById($seriesId); |
231
|
|
|
$seriesUrls = $weburgClient->getSeriesTorrents($seriesId, $movieInfo['hashes'], $daysMax, $allowedMisses); |
232
|
|
|
$torrentsUrls = array_merge($torrentsUrls, $seriesUrls); |
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
$progress->finish(); |
236
|
|
|
|
237
|
|
|
return $torrentsUrls; |
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
/** |
241
|
|
|
* @param WeburgClient $weburgClient |
242
|
|
|
* @param $movieId |
243
|
|
|
* @param $daysMax |
244
|
|
|
* @param $allowedMisses |
245
|
|
|
* @return array |
246
|
|
|
*/ |
247
|
|
|
public function getMovieTorrentsUrls(WeburgClient $weburgClient, $movieId, $daysMax, $allowedMisses) |
248
|
|
|
{ |
249
|
|
|
$torrentsUrls = []; |
250
|
|
|
$logger = $this->getApplication()->getLogger(); |
251
|
|
|
|
252
|
|
|
$movieId = $weburgClient->cleanMovieId($movieId); |
253
|
|
|
if (!$movieId) { |
254
|
|
|
throw new \RuntimeException($movieId . ' seems not weburg movie ID or URL'); |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
$movieInfo = $weburgClient->getMovieInfoById($movieId); |
258
|
|
|
$logger->info('Search series ' . $movieId); |
259
|
|
|
if (!empty($movieInfo['hashes'])) { |
260
|
|
|
$seriesUrls = $weburgClient->getSeriesTorrents($movieId, $movieInfo['hashes'], $daysMax, $allowedMisses); |
261
|
|
|
$torrentsUrls = array_merge($torrentsUrls, $seriesUrls); |
262
|
|
|
|
263
|
|
|
if (count($seriesUrls)) { |
264
|
|
|
$logger->info('Download series ' . $movieId . ': ' |
265
|
|
|
. $movieInfo['title'] . ' (' . count($seriesUrls) . ')'); |
266
|
|
|
} |
267
|
|
|
} else { |
268
|
|
|
$torrentsUrls = array_merge($torrentsUrls, $weburgClient->getMovieTorrentUrlsById($movieId)); |
269
|
|
|
} |
270
|
|
|
|
271
|
|
|
return $torrentsUrls; |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
/** |
275
|
|
|
* @param InputInterface $input |
276
|
|
|
* @return array |
277
|
|
|
* @throws \RuntimeException |
278
|
|
|
*/ |
279
|
|
|
private function getTorrentsDirectory(InputInterface $input) |
280
|
|
|
{ |
281
|
|
|
$config = $this->getApplication()->getConfig(); |
282
|
|
|
|
283
|
|
|
$torrentsDir = $config->overrideConfig($input, 'download-torrents-dir'); |
284
|
|
|
if (!$torrentsDir) { |
285
|
|
|
throw new \RuntimeException('Destination directory not defined. ' |
286
|
|
|
.'Use command with --download-torrents-dir=/path/to/dir parameter ' |
287
|
|
|
.'or define destination directory \'download-torrents-dir\' in config file.'); |
288
|
|
|
} |
289
|
|
|
|
290
|
|
|
if (!file_exists($torrentsDir)) { |
291
|
|
|
throw new \RuntimeException('Destination directory not exists: ' . $torrentsDir); |
292
|
|
|
} |
293
|
|
|
|
294
|
|
|
$downloadDir = $torrentsDir . '/downloaded'; |
295
|
|
|
if (!file_exists($downloadDir)) { |
296
|
|
|
mkdir($downloadDir, 0777); |
297
|
|
|
} |
298
|
|
|
|
299
|
|
|
return [$torrentsDir, $downloadDir]; |
300
|
|
|
} |
301
|
|
|
|
302
|
|
|
private function addTorrents(InputInterface $input, OutputInterface $output, array $torrentFiles) |
303
|
|
|
{ |
304
|
|
|
$config = $this->getApplication()->getConfig(); |
305
|
|
|
$hosts = []; |
306
|
|
|
|
307
|
|
|
if (empty($input->getOption('transmission-host'))) { |
308
|
|
|
$transmissionConnects = $config->get('transmission'); |
309
|
|
|
foreach ($transmissionConnects as $transmissionConnect) { |
310
|
|
|
$hosts[] = $transmissionConnect['host']; |
311
|
|
|
} |
312
|
|
|
} else { |
313
|
|
|
$hosts[] = $config->get('transmission-host'); |
314
|
|
|
} |
315
|
|
|
|
316
|
|
|
foreach ($hosts as $host) { |
317
|
|
|
$command = $this->getApplication()->find('torrent-add'); |
318
|
|
|
$arguments = array( |
319
|
|
|
'command' => 'torrent-add', |
320
|
|
|
'torrent-files' => $torrentFiles, |
321
|
|
|
'--transmission-host' => $host |
322
|
|
|
); |
323
|
|
|
|
324
|
|
|
$addInput = new ArrayInput($arguments); |
325
|
|
|
$output->writeln("\nAdd torrents to " . $host); |
326
|
|
|
$command->run($addInput, $output); |
327
|
|
|
} |
328
|
|
|
} |
329
|
|
|
} |
330
|
|
|
|
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.