Completed
Push — master ( 53645a...5b6666 )
by Stanislav
02:22
created

WeburgDownload::execute()   C

Complexity

Conditions 9
Paths 46

Size

Total Lines 50
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

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