Completed
Push — master ( 2515f9...556e6f )
by Stanislav
03:05
created

WeburgDownload::getTorrentsUrls()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 31
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

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