Completed
Push — master ( eee7e2...2d86d4 )
by Stanislav
02:42
created

WeburgDownload::execute()   B

Complexity

Conditions 4
Paths 9

Size

Total Lines 30
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 9
Bugs 2 Features 1
Metric Value
c 9
b 2
f 1
dl 0
loc 30
rs 8.5806
cc 4
eloc 19
nc 9
nop 2
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
    protected function configure()
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
The <info>weburg-download</info> scans weburg.net top page and downloads popular torrents.
27
EOT
28
            );
29
    }
30
31
    protected function execute(InputInterface $input, OutputInterface $output)
32
    {
33
        $config = $this->getApplication()->getConfig();
34
        $weburgClient = $this->getApplication()->getWeburgClient();
35
36
        try {
37
            list($torrentsDir, $downloadDir) = $this->getTorrentsDirectory($input);
38
39
            $daysMax = $config->overrideConfig($input, 'days', 'weburg-series-max-age');
40
41
            $movieArgument = $input->getArgument('movie-id');
42
            if (isset($movieArgument)) {
43
                $torrentsUrls = $this->getMovieTorrentsUrls($weburgClient, $movieArgument, $daysMax);
44
            } else {
45
                $torrentsUrls = $this->getTorrentsUrls($input, $output, $weburgClient, $downloadDir, $daysMax);
46
            }
47
48
            $this->dryRun($input, $output, function () use ($weburgClient, $torrentsDir, $torrentsUrls) {
49
                foreach ($torrentsUrls as $torrentUrl) {
50
                    $weburgClient->downloadTorrent($torrentUrl, $torrentsDir);
51
                }
52
            }, 'dry-run, don\'t really download');
53
54
        } catch (\RuntimeException $e) {
55
            $output->writeln($e->getMessage());
56
            return 1;
57
        }
58
59
        return 0;
60
    }
61
62
    private function getTorrentsUrls(
63
        InputInterface $input,
64
        OutputInterface $output,
65
        WeburgClient $weburgClient,
66
        $downloadDir,
67
        $daysMax
68
    ) {
69
        $torrentsUrls = [];
70
71
        if (!$input->getOption('popular') && !$input->getOption('series')) {
72
            $input->setOption('popular', true);
73
            $input->setOption('series', true);
74
        }
75
76
        if ($input->getOption('popular')) {
77
            $torrentsUrls = array_merge(
78
                $torrentsUrls,
79
                $this->getPopularTorrentsUrls($output, $weburgClient, $downloadDir)
80
            );
81
        }
82
83
        if ($input->getOption('series')) {
84
            $torrentsUrls = array_merge(
85
                $torrentsUrls,
86
                $this->getTrackedSeriesUrls($output, $weburgClient, $daysMax)
87
            );
88
        }
89
90
        return $torrentsUrls;
91
    }
92
93
    public function getPopularTorrentsUrls(OutputInterface $output, WeburgClient $weburgClient, $downloadDir)
94
    {
95
        $torrentsUrls = [];
96
97
        $config = $this->getApplication()->getConfig();
98
        $logger = $this->getApplication()->getLogger();
99
100
        $moviesIds = $weburgClient->getMoviesIds();
101
102
        $output->writeln("Downloading popular torrents");
103
104
        $progress = new ProgressBar($output, count($moviesIds));
105
        $progress->start();
106
107
        foreach ($moviesIds as $movieId) {
108
            $progress->setMessage('Check movie ' . $movieId . '...');
109
            $progress->advance();
110
111
            $downloadedLogfile = $downloadDir . '/' . $movieId;
112
113
            $isDownloaded = file_exists($downloadedLogfile);
114
            if ($isDownloaded) {
115
                continue;
116
            }
117
118
            $movieInfo = $weburgClient->getMovieInfoById($movieId);
119
            foreach (array_keys($movieInfo) as $infoField) {
120
                if (!isset($movieInfo[$infoField])) {
121
                    $logger->warning('Cannot find ' . $infoField . ' in movie ' . $movieId);
122
                }
123
            }
124
125
            $isTorrentPopular = $weburgClient->isTorrentPopular(
126
                $movieInfo,
127
                $config->get('download-comments-min'),
128
                $config->get('download-imdb-min'),
129
                $config->get('download-kinopoisk-min'),
130
                $config->get('download-votes-min')
131
            );
132
133
            if ($isTorrentPopular) {
134
                $progress->setMessage('Download movie ' . $movieId . '...');
135
136
                $movieUrls = $weburgClient->getMovieTorrentUrlsById($movieId);
137
                $torrentsUrls = array_merge($torrentsUrls, $movieUrls);
138
                $logger->info('Download movie ' . $movieId . ': ' . $movieInfo['title']);
139
140
                file_put_contents(
141
                    $downloadedLogfile,
142
                    date('Y-m-d H:i:s') . "\n" . implode("\n", $torrentsUrls)
143
                );
144
            }
145
        }
146
147
        $progress->finish();
148
149
        return $torrentsUrls;
150
    }
151
152
    /**
153
     * @param OutputInterface $output
154
     * @param WeburgClient $weburgClient
155
     * @param $daysMax
156
     * @return array
157
     */
158
    public function getTrackedSeriesUrls(OutputInterface $output, WeburgClient $weburgClient, $daysMax)
159
    {
160
        $torrentsUrls = [];
161
162
        $config = $this->getApplication()->getConfig();
163
164
        $seriesIds = $config->get('weburg-series-list');
165
        if (!$seriesIds) {
166
            return [];
167
        }
168
169
        $output->writeln("Downloading tracked series");
170
171
        $progress = new ProgressBar($output, count($seriesIds));
172
        $progress->start();
173
174
        foreach ($seriesIds as $seriesId) {
175
            $progress->setMessage('Check series ' . $seriesId . '...');
176
            $progress->advance();
177
178
            $movieInfo = $weburgClient->getMovieInfoById($seriesId);
179
            $seriesUrls = $weburgClient->getSeriesTorrents($seriesId, $movieInfo['hashes'], $daysMax);
180
            $torrentsUrls = array_merge($torrentsUrls, $seriesUrls);
181
        }
182
183
        $progress->finish();
184
185
        return $torrentsUrls;
186
    }
187
188
    /**
189
     * @param WeburgClient $weburgClient
190
     * @param $movieId
191
     * @param $daysMax
192
     * @return array
193
     * @throws \RuntimeException
194
     */
195
    public function getMovieTorrentsUrls(WeburgClient $weburgClient, $movieId, $daysMax)
196
    {
197
        $torrentsUrls = [];
198
        $logger = $this->getApplication()->getLogger();
199
200
        $movieId = $weburgClient->cleanMovieId($movieId);
201
        if (!$movieId) {
202
            throw new \RuntimeException($movieId . ' seems not weburg movie ID or URL');
203
        }
204
205
        $movieInfo = $weburgClient->getMovieInfoById($movieId);
206
        $logger->info('Search series ' . $movieId);
207
        if (!empty($movieInfo['hashes'])) {
208
            $seriesUrls = $weburgClient->getSeriesTorrents($movieId, $movieInfo['hashes'], $daysMax);
209
            $torrentsUrls = array_merge($torrentsUrls, $seriesUrls);
210
211
            if (count($seriesUrls)) {
212
                $logger->info('Download series ' . $movieId . ': '
213
                    . $movieInfo['title'] . ' (' . count($seriesUrls) . ')');
214
            }
215
        } else {
216
            $torrentsUrls = array_merge($torrentsUrls, $weburgClient->getMovieTorrentUrlsById($movieId));
217
        }
218
219
        return $torrentsUrls;
220
    }
221
222
    /**
223
     * @param InputInterface $input
224
     * @return array
225
     * @throws \RuntimeException
226
     */
227
    private function getTorrentsDirectory(InputInterface $input)
228
    {
229
        $config = $this->getApplication()->getConfig();
230
231
        $torrentsDir = $config->overrideConfig($input, 'download-torrents-dir');
232
        if (!$torrentsDir) {
233
            throw new \RuntimeException('Destination directory not defined. '
234
                .'Use command with --download-torrents-dir=/path/to/dir parameter '
235
                .'or define destination directory \'download-torrents-dir\' in config file.');
236
        }
237
238
        if (!file_exists($torrentsDir)) {
239
            throw new \RuntimeException('Destination directory not exists: ' . $torrentsDir);
240
        }
241
242
        $downloadDir = $torrentsDir . '/downloaded';
243
        if (!file_exists($downloadDir)) {
244
            mkdir($downloadDir, 0777);
245
        }
246
247
        return [$torrentsDir, $downloadDir];
248
    }
249
}
250