Completed
Push — master ( f1c66f...84c3a4 )
by Stanislav
02:11
created

StatsGet::execute()   C

Complexity

Conditions 7
Paths 75

Size

Total Lines 75
Code Lines 52

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 1 Features 2
Metric Value
c 6
b 1
f 2
dl 0
loc 75
rs 6.5862
cc 7
eloc 52
nc 75
nop 2

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Popstas\Transmission\Console\Command;
4
5
use InfluxDB;
6
use Martial\Transmission\API\Argument\Torrent;
7
use Popstas\Transmission\Console\Helpers\TableUtils;
8
use Popstas\Transmission\Console\Helpers\TorrentListUtils;
9
use Popstas\Transmission\Console\Helpers\TorrentUtils;
10
use Symfony\Component\Console\Input\ArrayInput;
11
use Symfony\Component\Console\Input\InputInterface;
12
use Symfony\Component\Console\Input\InputOption;
13
use Symfony\Component\Console\Output\OutputInterface;
14
15
class StatsGet extends Command
16
{
17
    protected function configure()
18
    {
19
        parent::configure();
20
        $this
21
            ->setName('stats-get')
22
            ->setAliases(['sg'])
23
            ->setDescription('Get metrics from InfluxDB')
24
            ->addOption('name', null, InputOption::VALUE_OPTIONAL, 'Sort by torrent name (regexp)')
25
            ->addOption('age', null, InputOption::VALUE_OPTIONAL, 'Sort by torrent age, ex. \'>1 <5\'')
26
            ->addOption('profit', null, InputOption::VALUE_OPTIONAL, 'Filter by profit')
27
            ->addOption('days', null, InputOption::VALUE_OPTIONAL, 'Show stats for last days', 7)
28
            ->addOption('sort', null, InputOption::VALUE_OPTIONAL, 'Sort by column number', 4)
29
            ->addOption('limit', null, InputOption::VALUE_OPTIONAL, 'Limit torrent list')
30
            ->addOption('rm', null, InputOption::VALUE_NONE, 'Remove filtered torrents')
31
            ->addOption('soft', null, InputOption::VALUE_NONE, 'Remove only from Transmission, not delete data')
32
            ->addOption('yes', 'y', InputOption::VALUE_NONE, 'Don\'t ask confirmation')
33
            ->addOption('transmission-host', null, InputOption::VALUE_OPTIONAL, 'Transmission host')
34
            ->setHelp(<<<EOT
35
The <info>stats-get</info> sends upload ever for every torrent to InfluxDB.
36
EOT
37
            );
38
    }
39
40
    protected function execute(InputInterface $input, OutputInterface $output)
41
    {
42
        $config = $this->getApplication()->getConfig();
43
        $logger = $this->getApplication()->getLogger();
44
        $client = $this->getApplication()->getClient();
45
46
        try {
47
            $influxDbClient = $this->getApplication()->getInfluxDbClient(
48
                $config->get('influxdb-host'),
49
                $config->get('influxdb-port'),
50
                $config->get('influxdb-user'),
51
                $config->get('influxdb-password'),
52
                $config->get('influxdb-database')
53
            );
54
55
            $lastDays = (int)$input->getOption('days') ? (int)$input->getOption('days') : 0;
56
            $limit = (int)$input->getOption('limit') ? (int)$input->getOption('limit') : 0;
57
58
            $torrentList = $client->getTorrentData();
59
60
            $torrentList = TorrentListUtils::filterTorrents($torrentList, [
61
                'age' => $input->getOption('age'),
62
                'name' => $input->getOption('name'),
63
            ]);
64
65
            $transmissionHost = $config->overrideConfig($input, 'transmission-host');
66
67
            $rows = [];
68
69
            foreach ($torrentList as $torrent) {
70
                $perDay = $torrent['age'] ?
71
                    TorrentUtils::getSizeInGb($torrent[Torrent\Get::UPLOAD_EVER] / $torrent['age']) : 0;
72
                $uploaded = $influxDbClient->getTorrentSum($torrent, 'uploaded_last', $transmissionHost, $lastDays);
73
74
                $profit = round($uploaded / $torrent[Torrent\Get::TOTAL_SIZE], 2);
75
76
                $rows[] = [
77
                    $torrent[Torrent\Get::NAME],
78
                    $torrent[Torrent\Get::ID],
79
                    $torrent['age'],
80
                    TorrentUtils::getSizeInGb($torrent[Torrent\Get::TOTAL_SIZE]),
81
                    TorrentUtils::getSizeInGb($uploaded) . ' GB',
82
                    $perDay,
83
                    $profit
84
                ];
85
            }
86
        } catch (\Exception $e) {
87
            $logger->critical($e->getMessage());
88
            return 1;
89
        }
90
91
        $rows = TableUtils::filterRows($rows, [
92
            '6' => ['type' => 'numeric', 'value' => $input->getOption('profit')]
93
        ]);
94
95
        TableUtils::printTable([
96
            'headers' => ['Name', 'Id', 'Age', 'Size', 'Uploaded', 'Per day', 'Profit'],
97
            'rows' => $rows,
98
            'totals' => [
99
                '',
100
                '',
101
                '',
102
                '', // TODO: cannot sum rendered size or unfiltered torrentList
103
                TorrentListUtils::sumArrayField($rows, 4),
104
                TorrentListUtils::sumArrayField($rows, 5),
105
                TorrentListUtils::sumArrayField($rows, 6),
106
            ]
107
        ], $output, $input->getOption('sort'), $limit);
108
109
        if ($input->getOption('rm')) {
110
            return $this->removeTorrents($input, $output, $rows);
111
        }
112
113
        return 0;
114
    }
115
116
    private function removeTorrents(InputInterface $input, OutputInterface $output, array $rows)
117
    {
118
        $limit = (int)$input->getOption('limit') ? (int)$input->getOption('limit') : 0;
119
120
        $rows = TableUtils::sortRowsByColumnNumber($rows, $input->getOption('sort'));
121
122
        if ($limit && $limit < count($rows)) {
123
            $rows = array_slice($rows, 0, $limit);
124
        }
125
126
        $torrentIds = TorrentListUtils::getArrayField($rows, 1);
127
        $command = $this->getApplication()->find('torrent-remove');
128
        $arguments = array(
129
            'command'     => 'torrent-remove',
130
            'torrent-ids' => $torrentIds,
131
            '--dry-run'   => $input->getOption('dry-run'),
132
            '--yes'       => $input->getOption('yes'),
133
            '--soft'      => $input->getOption('soft'),
134
        );
135
136
        $removeInput = new ArrayInput($arguments);
137
        return $command->run($removeInput, $output);
138
    }
139
}
140