Issues (569)

app/Console/Commands/UpdateBinaries.php (1 issue)

Severity
1
<?php
2
3
declare(strict_types=1);
4
5
namespace App\Console\Commands;
6
7
use App\Models\Settings;
8
use App\Models\UsenetGroup;
9
use Blacklight\Binaries;
10
use Blacklight\ColorCLI;
11
use Blacklight\NNTP;
12
use Illuminate\Console\Command;
13
use Illuminate\Support\Facades\Log;
14
15
class UpdateBinaries extends Command
16
{
17
    /**
18
     * The name and signature of the console command.
19
     *
20
     * @var string
21
     */
22
    protected $signature = 'update:binaries
23
                            {group? : Group name to update (optional, processes all if omitted)}
24
                            {max? : Maximum headers to download}';
25
26
    /**
27
     * The console command description.
28
     *
29
     * @var string
30
     */
31
    protected $description = 'Update binaries for a specific group or all groups';
32
33
    private ColorCLI $colorCLI;
34
35
    private bool $echoCLI;
36
37
    /**
38
     * Execute the console command.
39
     */
40
    public function handle(): int
41
    {
42
        $this->colorCLI = new ColorCLI();
43
        $this->echoCLI = (bool) config('nntmux.echocli');
44
45
        $groupName = $this->argument('group');
46
        $max = $this->argument('max');
47
48
        $maxHeaders = is_numeric($max) && $max > 0
49
            ? (int) $max
50
            : ((int) Settings::settingValue('max_headers_iteration') ?: 1000000);
51
52
        $startTime = now()->toImmutable();
53
54
        try {
55
            $this->outputBanner();
56
57
            $nntp = $this->getNntp();
58
            $binaries = new Binaries(['NNTP' => $nntp]);
0 ignored issues
show
The call to Blacklight\Binaries::__construct() has too many arguments starting with array('NNTP' => $nntp). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

58
            $binaries = /** @scrutinizer ignore-call */ new Binaries(['NNTP' => $nntp]);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
59
60
            if ($groupName && !is_numeric($groupName)) {
61
                $this->outputHeader('Updating Single Group');
62
                $this->outputInfo("Group: {$groupName}");
63
                $this->outputInfo('Max headers: ' . number_format($maxHeaders));
64
                $this->updateSingleGroup($binaries, $groupName, $maxHeaders);
65
            } else {
66
                $this->outputHeader('Updating All Groups');
67
                $this->outputInfo('Max headers: ' . number_format($maxHeaders));
68
                $binaries->updateAllGroups($maxHeaders);
69
            }
70
71
            $this->outputSummary($startTime);
72
73
            return self::SUCCESS;
74
        } catch (\Throwable $e) {
75
            Log::error($e->getMessage());
76
            $this->colorCLI->error('Error: ' . $e->getMessage());
77
78
            return self::FAILURE;
79
        }
80
    }
81
82
    /**
83
     * Update a single group.
84
     */
85
    private function updateSingleGroup(Binaries $binaries, string $groupName, int $maxHeaders): void
86
    {
87
        $group = UsenetGroup::getByName($groupName);
88
89
        if ($group === null) {
90
            throw new \RuntimeException("Group not found: {$groupName}");
91
        }
92
93
        $binaries->updateGroup($group->toArray(), $maxHeaders);
94
    }
95
96
    /**
97
     * Get NNTP connection.
98
     */
99
    private function getNntp(): NNTP
100
    {
101
        $nntp = new NNTP();
102
103
        if ($nntp->doConnect() !== true) {
104
            throw new \RuntimeException('Unable to connect to usenet.');
105
        }
106
107
        return $nntp;
108
    }
109
110
    /**
111
     * Output the banner.
112
     */
113
    private function outputBanner(): void
114
    {
115
        if (!$this->echoCLI) {
116
            return;
117
        }
118
119
        echo PHP_EOL;
120
        $this->colorCLI->header('NNTmux Binary Update');
121
        $this->colorCLI->info('Started: ' . now()->format('Y-m-d H:i:s'));
122
    }
123
124
    /**
125
     * Output a section header.
126
     */
127
    private function outputHeader(string $title): void
128
    {
129
        if (!$this->echoCLI) {
130
            return;
131
        }
132
133
        echo PHP_EOL;
134
        $this->colorCLI->header(strtoupper($title));
135
        $this->colorCLI->header(str_repeat('-', strlen($title)));
136
    }
137
138
    /**
139
     * Output an info line.
140
     */
141
    private function outputInfo(string $message): void
142
    {
143
        if (!$this->echoCLI) {
144
            return;
145
        }
146
147
        $this->colorCLI->info("  {$message}");
148
    }
149
150
    /**
151
     * Output the summary.
152
     */
153
    private function outputSummary(\DateTimeInterface $startTime): void
154
    {
155
        if (!$this->echoCLI) {
156
            return;
157
        }
158
159
        $elapsed = now()->diffInSeconds($startTime, true);
160
        $timeStr = $this->formatElapsedTime($elapsed);
161
162
        echo PHP_EOL;
163
        $this->colorCLI->header('COMPLETE');
164
        $this->colorCLI->header('--------');
165
        $this->colorCLI->info("  Total time: {$timeStr}");
166
        echo PHP_EOL;
167
    }
168
169
    /**
170
     * Format elapsed time.
171
     */
172
    private function formatElapsedTime(int|float $seconds): string
173
    {
174
        if ($seconds < 1) {
175
            return sprintf('%dms', (int) ($seconds * 1000));
176
        }
177
178
        if ($seconds < 60) {
179
            return sprintf('%.1fs', $seconds);
180
        }
181
182
        $minutes = floor($seconds / 60);
183
        $remainingSeconds = $seconds % 60;
184
185
        if ($minutes < 60) {
186
            return sprintf('%dm %ds', $minutes, (int) $remainingSeconds);
187
        }
188
189
        $hours = floor($minutes / 60);
190
        $remainingMinutes = $minutes % 60;
191
192
        return sprintf('%dh %dm', $hours, $remainingMinutes);
193
    }
194
}
195