Completed
Push — master ( 2eb0da...31e203 )
by Stanislav
02:21
created

TorrentListUtils::printTorrentsTable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 12
rs 9.4285
cc 1
eloc 9
nc 1
nop 3
1
<?php
2
3
namespace Popstas\Transmission\Console\Helpers;
4
5
use Martial\Transmission\API\Argument\Torrent;
6
use Symfony\Component\Console\Helper\Table;
7
use Symfony\Component\Console\Helper\TableSeparator;
8
use Symfony\Component\Console\Output\OutputInterface;
9
10
class TorrentListUtils
11
{
12
    public static function getTorrentsSize(array $torrentList, $fieldName = Torrent\Get::TOTAL_SIZE)
13
    {
14
        $torrentSize = 0;
15
        foreach ($torrentList as $torrent) {
16
            $torrentSize += $torrent[$fieldName];
17
        }
18
        return $torrentSize;
19
    }
20
21
    public static function getTorrentsField(array $torrentList, $fieldName)
22
    {
23
        $fields = [];
24
        foreach ($torrentList as $torrent) {
25
            $fields[] = $torrent[$fieldName];
26
        }
27
        return $fields;
28
    }
29
30
    /**
31
     * @param array $torrentList
32
     *
33
     * @param array $filters
34
     * filters[
35
     * - age
36
     * - age_min
37
     * - age_max
38
     * ]
39
     *
40
     * @return array
41
     */
42
    public static function filterTorrents(array $torrentList, array $filters)
43
    {
44
        $filters += ['age_min' => 0, 'age_max' => 99999, 'name' => ''];
45
        $filters['name'] = str_replace(['/', '.', '*'], ['\/', '\.', '.*?'], $filters['name']);
46
47
        if (isset($filters['age'])) {
48
            $filters = self::parseAgeFilter($filters['age']) + $filters;
49
        }
50
51
        return array_filter($torrentList, function ($torrent) use ($filters) {
52
            $age = TorrentUtils::getTorrentAgeInDays($torrent);
53
            if ($age < $filters['age_min'] || $age > $filters['age_max']) {
54
                return false;
55
            }
56
            if (isset($torrent[Torrent\Get::NAME])
57
                && !preg_match('/' . $filters['name'] . '/i', $torrent[Torrent\Get::NAME])
58
            ) {
59
                return false;
60
            }
61
            return true;
62
        });
63
    }
64
65
    private static function parseAgeFilter($age)
66
    {
67
        $filters = [];
68
        preg_match_all('/([<>])\s?(\d+)/', $age, $results, PREG_SET_ORDER);
69
        if ($results) {
70
            foreach ($results as $result) {
71
                $ageOperator = $result[1];
72
                $ageValue = $result[2];
73
                if ($ageOperator == '<') {
74
                    $filters['age_max'] = $ageValue - 1;
75
                }
76
                if ($ageOperator == '>') {
77
                    $filters['age_min'] = $ageValue + 1;
78
                }
79
            }
80
        }
81
        return $filters;
82
    }
83
84
    public static function sortRowsByColumnNumber(array $rows, $columnNumber)
85
    {
86
        $rowsSorted = $rows;
87
        $columnsTotal = count(end($rows));
88
89
        $sortOrder = $columnNumber > 0 ? 1 : -1;
90
91
        $columnIndex = max(1, min(
92
            $columnsTotal,
93
            abs($columnNumber)
94
        )) - 1;
95
96
        usort($rowsSorted, function ($first, $second) use ($columnIndex, $sortOrder) {
97
            return $first[$columnIndex] > $second[$columnIndex] ? $sortOrder : $sortOrder * -1;
98
        });
99
100
        return $rowsSorted;
101
    }
102
103
    public static function buildTableData(array $torrentList)
104
    {
105
        $headers = ['Name', 'Id', 'Age', 'Size', 'Uploaded', 'Per day'];
106
        $rows = [];
107
108
        foreach ($torrentList as $torrent) {
109
            $age = TorrentUtils::getTorrentAgeInDays($torrent);
110
            $perDay = $age ? TorrentUtils::getSizeInGb($torrent[Torrent\Get::UPLOAD_EVER] / $age) : 0;
111
112
            $rows[] = [
113
                $torrent[Torrent\Get::NAME],
114
                $torrent[Torrent\Get::ID],
115
                $age,
116
                TorrentUtils::getSizeInGb($torrent[Torrent\Get::TOTAL_SIZE]),
117
                TorrentUtils::getSizeInGb($torrent[Torrent\Get::UPLOAD_EVER]),
118
                $perDay,
119
            ];
120
        }
121
122
        $totals = [
123
            'Total',
124
            '',
125
            '',
126
            TorrentUtils::getSizeInGb(self::getTorrentsSize($torrentList, Torrent\Get::TOTAL_SIZE)),
127
            TorrentUtils::getSizeInGb(self::getTorrentsSize($torrentList, Torrent\Get::UPLOAD_EVER)),
128
            ''
129
        ];
130
131
        return [
132
            'headers' => $headers,
133
            'rows' => $rows,
134
            'totals' => $totals
135
        ];
136
    }
137
138
    public static function printTorrentsTable(array $torrentList, OutputInterface $output, $sortColumnNumber = 1)
139
    {
140
        $data = self::buildTableData($torrentList);
141
        $data['rows'] = self::sortRowsByColumnNumber($data['rows'], $sortColumnNumber);
142
143
        $table = new Table($output);
144
        $table->setHeaders($data['headers']);
145
        $table->setRows($data['rows']);
146
        $table->addRow(new TableSeparator());
147
        $table->addRow($data['totals']);
148
        $table->render();
149
    }
150
151
    public static function getObsoleteTorrents(array $torrentList)
152
    {
153
        $all = [];
154
        $obsolete = [];
155
156
        foreach ($torrentList as $torrent) {
157
            $name = $torrent[Torrent\Get::NAME];
158
            if (!isset($all[$name])) {
159
                $all[$name] = $torrent;
160
                continue;
161
            }
162
163
            $obs = self::detectObsoleteTorrent($all[$name], $torrent);
164
            if ($obs) {
165
                $obsolete[] = $obs;
166
                if ($obs[Torrent\Get::ID] !== $torrent[Torrent\Get::ID]) {
167
                    $all[$name] = $torrent;
168
                }
169
            }
170
        }
171
172
        return $obsolete;
173
    }
174
175
    private static function detectObsoleteTorrent($torrentInList, $torrentNotInList)
176
    {
177
        if ($torrentInList[Torrent\Get::DOWNLOAD_DIR] !== $torrentNotInList[Torrent\Get::DOWNLOAD_DIR]) {
178
            return false;
179
        }
180
181
        return $torrentInList[Torrent\Get::TOTAL_SIZE] < $torrentNotInList[Torrent\Get::TOTAL_SIZE] ?
182
            $torrentInList : $torrentNotInList;
183
    }
184
}
185