Completed
Push — master ( 556e6f...7229c3 )
by Stanislav
02:21
created

WeburgDownload::addTorrents()   B

Complexity

Conditions 4
Paths 5

Size

Total Lines 27
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 27
rs 8.5806
cc 4
eloc 18
nc 5
nop 3
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()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
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