Completed
Push — master ( f277c1...6f7267 )
by Stanislav
02:15
created

StatsSend::getDatabase()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 35
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 35
rs 8.439
cc 5
eloc 23
nc 8
nop 1
1
<?php
2
3
namespace Popstas\Transmission\Console\Command;
4
5
use GuzzleHttp\Exception\ConnectException;
6
use InfluxDB;
7
use Martial\Transmission\API\Argument\Torrent;
8
use Symfony\Component\Console\Input\InputInterface;
9
use Symfony\Component\Console\Input\InputOption;
10
use Symfony\Component\Console\Output\OutputInterface;
11
12
class StatsSend extends Command
13
{
14
    /**
15
     * @var InfluxDB\Client $influxDb
16
     */
17
    private $influxDb;
18
19
    protected function configure()
20
    {
21
        parent::configure();
22
        $this
23
            ->setName('stats-send')
24
            ->setAliases(['ss'])
25
            ->setDescription('Send metrics to InfluxDB')
26
            ->addOption('influxdb-host', null, InputOption::VALUE_OPTIONAL, 'InfluxDb host')
27
            ->addOption('influxdb-port', null, InputOption::VALUE_OPTIONAL, 'InfluxDb port')
28
            ->addOption('influxdb-user', null, InputOption::VALUE_OPTIONAL, 'InfluxDb user')
29
            ->addOption('influxdb-password', null, InputOption::VALUE_OPTIONAL, 'InfluxDb password')
30
            ->addOption('influxdb-database', null, InputOption::VALUE_OPTIONAL, 'InfluxDb database')
31
            ->addOption('transmission-host', null, InputOption::VALUE_OPTIONAL, 'Transmission host')
32
            ->setHelp(<<<EOT
33
The <info>stats-send</info> sends upload ever for every torrent to InfluxDB.
34
EOT
35
            );
36
    }
37
38
    protected function execute(InputInterface $input, OutputInterface $output)
39
    {
40
        $config = $this->getApplication()->getConfig();
41
        $logger = $this->getApplication()->getLogger();
42
        $client = $this->getApplication()->getClient();
43
44
        $obsoleteList = $client->getObsoleteTorrents();
45
        if (!empty($obsoleteList)) {
46
            $output->writeln('<comment>Found obsolete torrents,
47
                              remove it using transmission-cli torrent-remove-duplicates</comment>');
48
            return 1;
49
        }
50
51
        try {
52
            $database = $this->getDatabase($input);
53
        } catch (\Exception $e) {
54
            $logger->critical($e->getMessage());
55
            return 1;
56
        }
57
58
        $points = [];
59
60
        $torrentList = $client->getTorrentData();
61
62
        $transmissionHost = $config->overrideConfig($input, 'transmission-host');
63
64
        foreach ($torrentList as $torrent) {
65
            $point = new InfluxDB\Point(
66
                'uploaded',
67
                $torrent[Torrent\Get::UPLOAD_EVER],
68
                [
69
                    'host'         => $transmissionHost,
70
                    'torrent_name' => $torrent[Torrent\Get::NAME],
71
                ],
72
                [],
73
                time()
74
            );
75
            $points[] = $point;
76
            $logger->debug('Send point: {point}', ['point' => $point]);
77
        }
78
79
        if (!$input->getOption('dry-run')) {
80
            $isSuccess = $database->writePoints($points, InfluxDB\Database::PRECISION_SECONDS);
81
            $logger->info('InfluxDB write ' . ($isSuccess ? 'success' : 'failed'));
82
        } else {
83
            $logger->info('dry-run, don\'t really send points');
84
        }
85
86
        return 0;
87
    }
88
89
    /**
90
     * @return InfluxDB\Client $influxDb
91
     */
92
    public function getInfluxDb()
93
    {
94
        return $this->influxDb;
95
    }
96
97
    /**
98
     * @param InfluxDB\Client $influxDb
99
     */
100
    public function setInfluxDb($influxDb)
101
    {
102
        $this->influxDb = $influxDb;
103
    }
104
105
    public function createInfluxDb($host, $port, $user, $password)
106
    {
107
        $logger = $this->getApplication()->getLogger();
108
109
        $connect = ['host' => $host, 'port' => $port, 'user' => $user, 'password' => $password];
110
111
        $influxDb = new InfluxDB\Client(
112
            $connect['host'],
113
            $connect['port'],
114
            $connect['user'],
115
            $connect['password']
116
        );
117
        $logger->debug('Connect InfluxDB using: {user}:{password}@{host}:{port}', $connect);
118
119
        return $influxDb;
120
    }
121
122
    /**
123
     * @param InputInterface $input
124
     * @return InfluxDB\Database|bool
125
     * @throws InfluxDB\Database\Exception
126
     */
127
    private function getDatabase(InputInterface $input)
128
    {
129
        $config = $this->getApplication()->getConfig();
130
        $logger = $this->getApplication()->getLogger();
131
132
        $influxDb = $this->getInfluxDb();
133
        if (!isset($influxDb)) {
134
            $this->setInfluxDb($this->createInfluxDb(
135
                $config->overrideConfig($input, 'influxdb-host'),
136
                $config->overrideConfig($input, 'influxdb-port'),
137
                $config->overrideConfig($input, 'influxdb-user'),
138
                $config->overrideConfig($input, 'influxdb-password')
139
            ));
140
            $influxDb = $this->getInfluxDb();
141
        }
142
143
        $databaseName = $config->overrideConfig($input, 'influxdb-database');
144
        if (!$databaseName) {
145
            throw new \RuntimeException('InfluxDb database not defined');
146
        }
147
148
        $database = $influxDb->selectDB($databaseName);
149
150
        try {
151
            $databaseExists = $database->exists();
152
        } catch (ConnectException $e) {
153
            throw new \RuntimeException('InfluxDb connection error: ' . $e->getMessage());
154
        }
155
        if (!$databaseExists) {
156
            $logger->info('Database ' . $databaseName . ' not exists, creating');
157
            $database->create();
158
        }
159
        
160
        return $database;
161
    }
162
}
163