TmuxTaskRunner::runPostProcessAdditional()   B
last analyzed

Complexity

Conditions 10
Paths 19

Size

Total Lines 58
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 32
c 3
b 0
f 0
dl 0
loc 58
rs 7.6666
cc 10
nc 19
nop 1

How to fix   Long Method    Complexity   

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 App\Services\Tmux;
4
5
use App\Models\Settings;
6
use Blacklight\ColorCLI;
7
8
/**
9
 * Service for running tasks in tmux panes
10
 */
11
class TmuxTaskRunner
12
{
13
    protected TmuxPaneManager $paneManager;
14
15
    protected ColorCLI $colorCli;
16
17
    protected string $sessionName;
18
19
    public function __construct(string $sessionName)
20
    {
21
        $this->sessionName = $sessionName;
22
        $this->paneManager = new TmuxPaneManager($sessionName);
23
        $this->colorCli = new ColorCLI;
24
    }
25
26
    /**
27
     * Get niceness value from settings or config with sensible default
28
     */
29
    protected function getNiceness(): int
30
    {
31
        // Try to get from settings first
32
        $niceness = Settings::settingValue('niceness');
33
34
        // If empty string or null, try config
35
        if (empty($niceness) && $niceness !== 0 && $niceness !== '0') {
36
            $niceness = config('nntmux.niceness');
37
        }
38
39
        // If still empty, use system default
40
        if (empty($niceness) && $niceness !== 0 && $niceness !== '0') {
41
            $niceness = 10; // Standard nice default
42
        }
43
44
        return (int) $niceness;
45
    }
46
47
    /**
48
     * Run a task in a specific pane
49
     */
50
    public function runTask(string $taskName, array $config): bool
51
    {
52
        $pane = $config['pane'] ?? null;
53
        $command = $config['command'] ?? null;
54
        $enabled = $config['enabled'] ?? true;
55
        $workAvailable = $config['work_available'] ?? true;
56
57
        if (! $pane || ! $command) {
58
            return false;
59
        }
60
61
        // Check if task is enabled and has work
62
        if (! $enabled) {
63
            return $this->disablePane($pane, $taskName, 'disabled in settings');
64
        }
65
66
        if (! $workAvailable) {
67
            return $this->disablePane($pane, $taskName, 'no work available');
68
        }
69
70
        // Respawn the pane with the command
71
        return $this->paneManager->respawnPane($pane, $command);
72
    }
73
74
    /**
75
     * Disable a pane with a message
76
     */
77
    protected function disablePane(string $pane, string $taskName, string $reason): bool
78
    {
79
        $color = $this->getRandomColor();
80
        $message = "echo -e \"\033[38;5;{$color}m\n{$taskName} has been disabled: {$reason}\"";
81
82
        return $this->paneManager->respawnPane($pane, $message, kill: true);
83
    }
84
85
    /**
86
     * Build a command with logging
87
     */
88
    public function buildCommand(string $baseCommand, array $options = []): string
89
    {
90
        $parts = [$baseCommand];
91
92
        // Add sleep timer at the end if specified
93
        if (isset($options['sleep'])) {
94
            $sleepCommand = $this->buildSleepCommand($options['sleep']);
95
            $parts[] = 'date +"%Y-%m-%d %T"';
96
            $parts[] = $sleepCommand;
97
        }
98
99
        // Add logging if enabled
100
        if (isset($options['log_pane'])) {
101
            $logFile = $this->getLogFile($options['log_pane']);
102
            $command = implode('; ', $parts);
103
104
            return "{$command} 2>&1 | tee -a {$logFile}";
105
        }
106
107
        return implode('; ', $parts);
108
    }
109
110
    /**
111
     * Build sleep command
112
     */
113
    protected function buildSleepCommand(int $seconds): string
114
    {
115
        $niceness = $this->getNiceness();
116
        $sleepScript = base_path('app/Services/Tmux/Scripts/showsleep.php');
117
118
        if (file_exists($sleepScript)) {
119
            return "nice -n{$niceness} php {$sleepScript} {$seconds}";
120
        }
121
122
        return "sleep {$seconds}";
123
    }
124
125
    /**
126
     * Get log file path for a pane
127
     */
128
    protected function getLogFile(string $paneName): string
129
    {
130
        $logsEnabled = (int) Settings::settingValue('write_logs') === 1;
131
132
        if (! $logsEnabled) {
133
            return '/dev/null';
134
        }
135
136
        $logDir = config('tmux.paths.logs', storage_path('logs/tmux'));
137
138
        if (! is_dir($logDir)) {
139
            mkdir($logDir, 0755, true);
140
        }
141
142
        $date = now()->format('Y_m_d');
143
144
        return "{$logDir}/{$paneName}-{$date}.log";
145
    }
146
147
    /**
148
     * Get a random color for terminal output
149
     */
150
    protected function getRandomColor(): int
151
    {
152
        $start = (int) Settings::settingValue('colors_start') ?? 0;
153
        $end = (int) Settings::settingValue('colors_end') ?? 255;
154
        $exclude = Settings::settingValue('colors_exc') ?? '';
155
156
        if (empty($exclude)) {
157
            return random_int($start, $end);
158
        }
159
160
        $exceptions = array_map('intval', explode(',', $exclude));
161
        sort($exceptions);
162
163
        $number = random_int($start, $end - count($exceptions));
164
165
        foreach ($exceptions as $exception) {
166
            if ($number >= $exception) {
167
                $number++;
168
            } else {
169
                break;
170
            }
171
        }
172
173
        return $number;
174
    }
175
176
    /**
177
     * Run the IRC scraper
178
     */
179
    public function runIRCScraper(array $config): bool
180
    {
181
        $runScraper = (int) ($config['constants']['run_ircscraper'] ?? 0);
182
        $pane = '3.0';
183
184
        if ($runScraper !== 1) {
185
            return $this->disablePane($pane, 'IRC Scraper', 'disabled in settings');
186
        }
187
188
        $niceness = $this->getNiceness();
189
        $artisan = base_path('artisan');
190
        $command = "nice -n{$niceness} php {$artisan} irc:scrape";
191
        $command = $this->buildCommand($command, ['log_pane' => 'scraper']);
192
193
        return $this->paneManager->respawnPane($pane, $command);
194
    }
195
196
    /**
197
     * Run binaries update
198
     */
199
    public function runBinariesUpdate(array $config): bool
200
    {
201
        $enabled = (int) ($config['settings']['binaries_run'] ?? 0);
202
        $killswitch = $config['killswitch']['pp'] ?? false;
203
        $pane = '0.1';
204
205
        if (! $enabled) {
206
            return $this->disablePane($pane, 'Update Binaries', 'disabled in settings');
207
        }
208
209
        if ($killswitch) {
210
            return $this->disablePane($pane, 'Update Binaries', 'postprocess kill limit exceeded');
211
        }
212
213
        $artisanCommand = match ((int) $enabled) {
214
            1 => 'multiprocessing:safe binaries',
215
            default => null,
216
        };
217
218
        if (! $artisanCommand) {
219
            return false;
220
        }
221
222
        $niceness = $this->getNiceness();
223
        $command = "nice -n{$niceness} ".PHP_BINARY." artisan {$artisanCommand}";
224
        $sleep = (int) ($config['settings']['bins_timer'] ?? 60);
225
        $command = $this->buildCommand($command, ['log_pane' => 'binaries', 'sleep' => $sleep]);
226
227
        return $this->paneManager->respawnPane($pane, $command);
228
    }
229
230
    /**
231
     * Run backfill
232
     */
233
    public function runBackfill(array $config): bool
234
    {
235
        $enabled = (int) ($config['settings']['backfill'] ?? 0);
236
        $collKillswitch = $config['killswitch']['coll'] ?? false;
237
        $ppKillswitch = $config['killswitch']['pp'] ?? false;
238
        $pane = '0.2';
239
240
        if (! $enabled) {
241
            return $this->disablePane($pane, 'Backfill', 'disabled in settings');
242
        }
243
244
        if ($collKillswitch || $ppKillswitch) {
245
            return $this->disablePane($pane, 'Backfill', 'kill limit exceeded');
246
        }
247
248
        $artisanCommand = match ((int) $enabled) {
249
            1 => 'multiprocessing:backfill',
250
            4 => 'multiprocessing:safe backfill',
251
            default => null,
252
        };
253
254
        if (! $artisanCommand) {
255
            return false;
256
        }
257
258
        // Calculate sleep time (progressive if enabled)
259
        $baseSleep = (int) ($config['settings']['back_timer'] ?? 600);
260
        $collections = (int) ($config['counts']['now']['collections_table'] ?? 0);
261
        $progressive = (int) ($config['settings']['progressive'] ?? 0);
262
263
        $sleep = ($progressive === 1 && floor($collections / 500) > $baseSleep)
264
            ? floor($collections / 500)
265
            : $baseSleep;
266
267
        $niceness = $this->getNiceness();
268
        $command = "nice -n{$niceness} ".PHP_BINARY." artisan {$artisanCommand}";
269
        $command = $this->buildCommand($command, ['log_pane' => 'backfill', 'sleep' => $sleep]);
270
271
        return $this->paneManager->respawnPane($pane, $command);
272
    }
273
274
    /**
275
     * Run releases update
276
     */
277
    public function runReleasesUpdate(array $config): bool
278
    {
279
        $enabled = (int) ($config['settings']['releases_run'] ?? 0);
280
        $pane = $config['pane'] ?? '0.3';
281
282
        if (! $enabled) {
283
            return $this->disablePane($pane, 'Update Releases', 'disabled in settings');
284
        }
285
286
        $niceness = $this->getNiceness();
287
        $command = "nice -n{$niceness} ".PHP_BINARY.' artisan multiprocessing:releases';
288
        $sleep = (int) ($config['settings']['rel_timer'] ?? 60);
289
        $command = $this->buildCommand($command, ['log_pane' => 'releases', 'sleep' => $sleep]);
290
291
        return $this->paneManager->respawnPane($pane, $command);
292
    }
293
294
    /**
295
     * Run a specific pane task based on task name
296
     *
297
     * @param  string  $taskName  The name of the task to run
298
     * @param  array  $config  Configuration for the task (target pane, etc.)
299
     * @param  array  $runVar  Runtime variables and settings
300
     * @return bool Success status
301
     */
302
    public function runPaneTask(string $taskName, array $config, array $runVar): bool
0 ignored issues
show
Unused Code introduced by
The parameter $config is not used and could be removed. ( Ignorable by Annotation )

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

302
    public function runPaneTask(string $taskName, /** @scrutinizer ignore-unused */ array $config, array $runVar): bool

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
303
    {
304
        $sequential = (int) ($runVar['constants']['sequential'] ?? 0);
305
306
        return match ($taskName) {
307
            'main' => $this->runMainTask($sequential, $runVar),
308
            'fixnames' => $this->runFixNamesTask($runVar),
309
            'removecrap' => $this->runRemoveCrapTask($runVar),
310
            'ppadditional' => $this->runPostProcessAdditional($runVar),
311
            'tv' => $this->runTvTask($runVar),
312
            'movies' => $this->runMoviesTask($runVar),
313
            'amazon' => $this->runAmazonTask($runVar),
314
            'xxx' => $this->runXXXTask($runVar),
315
            'scraper' => $this->runIRCScraper($runVar),
316
            // Legacy mapping for backward compatibility
317
            'nonamazon' => $this->runTvTask($runVar),
318
            default => false,
319
        };
320
    }
321
322
    /**
323
     * Run main task (varies by sequential mode)
324
     */
325
    protected function runMainTask(int $sequential, array $runVar): bool
326
    {
327
        return match ($sequential) {
328
            0 => $this->runMainNonSequential($runVar),
329
            1 => $this->runMainBasic($runVar),
330
            2 => $this->runMainSequential($runVar),
331
            default => false,
332
        };
333
    }
334
335
    /**
336
     * Run main non-sequential task (binaries, backfill, releases)
337
     */
338
    protected function runMainNonSequential(array $runVar): bool
339
    {
340
        // This runs in pane 0.1, 0.2, 0.3
341
        // For now, delegate to existing methods
342
        $this->runBinariesUpdate($runVar);
343
        $this->runBackfill($runVar);
344
        $this->runReleasesUpdate(array_merge($runVar, ['pane' => '0.3']));
345
346
        return true;
347
    }
348
349
    /**
350
     * Run main basic sequential task (just releases)
351
     */
352
    protected function runMainBasic(array $runVar): bool
353
    {
354
        return $this->runReleasesUpdate(array_merge($runVar, ['pane' => '0.1']));
355
    }
356
357
    /**
358
     * Run main full sequential task
359
     */
360
    protected function runMainSequential(array $runVar): bool
0 ignored issues
show
Unused Code introduced by
The parameter $runVar is not used and could be removed. ( Ignorable by Annotation )

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

360
    protected function runMainSequential(/** @scrutinizer ignore-unused */ array $runVar): bool

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
361
    {
362
        // Full sequential mode - runs group:update-all for each group
363
        $pane = '0.1';
364
365
        $niceness = $this->getNiceness();
366
        $artisan = base_path('artisan');
367
        $command = "nice -n{$niceness} php {$artisan} group:update-all";
368
        $command = $this->buildCommand($command, ['log_pane' => 'sequential']);
369
370
        return $this->paneManager->respawnPane($pane, $command);
371
    }
372
373
    /**
374
     * Run fix release names task
375
     */
376
    protected function runFixNamesTask(array $runVar): bool
377
    {
378
        $enabled = (int) ($runVar['settings']['fix_names'] ?? 0);
379
        $work = (int) ($runVar['counts']['now']['processrenames'] ?? 0);
380
        $pane = '1.0';
381
382
        if ($enabled !== 1) {
383
            return $this->disablePane($pane, 'Fix Release Names', 'disabled in settings');
384
        }
385
386
        if ($work === 0) {
387
            return $this->disablePane($pane, 'Fix Release Names', 'no releases to process');
388
        }
389
390
        $artisan = base_path('artisan');
391
        $log = $this->getLogFile('fixnames');
392
393
        // Run multiple fix-names passes
394
        $commands = [];
395
        foreach ([3, 5, 7, 9, 11, 13, 15, 17, 19] as $level) {
396
            $commands[] = "php {$artisan} releases:fix-names {$level} --update --category=other --set-status --show 2>&1 | tee -a {$log}";
397
        }
398
399
        $sleep = (int) ($runVar['settings']['fix_timer'] ?? 300);
400
        $allCommands = implode('; ', $commands);
401
        $sleepCommand = $this->buildSleepCommand($sleep);
402
        $fullCommand = "{$allCommands}; date +'%Y-%m-%d %T'; {$sleepCommand}";
403
404
        return $this->paneManager->respawnPane($pane, $fullCommand);
405
    }
406
407
    /**
408
     * Run remove crap releases task
409
     */
410
    protected function runRemoveCrapTask(array $runVar): bool
411
    {
412
        $option = $runVar['settings']['fix_crap_opt'] ?? 'Disabled';
413
        $pane = '1.1';
414
415
        // Handle disabled state
416
        if ($option === 'Disabled' || $option === 0 || $option === '0') {
417
            return $this->disablePane($pane, 'Remove Crap', 'disabled in settings');
418
        }
419
420
        $niceness = $this->getNiceness();
421
        $artisan = base_path('artisan');
422
        $sleep = (int) ($runVar['settings']['crap_timer'] ?? 300);
423
424
        // Handle 'All' mode - run all types with 2 hour time limit
425
        if ($option === 'All') {
426
            $command = "nice -n{$niceness} php {$artisan} releases:remove-crap --time=2 --delete";
427
            $command = $this->buildCommand($command, ['log_pane' => 'removecrap', 'sleep' => $sleep]);
428
429
            return $this->paneManager->respawnPane($pane, $command);
430
        }
431
432
        // Handle 'Custom' mode - run all selected types sequentially
433
        if ($option === 'Custom') {
434
            $selectedTypes = $runVar['settings']['fix_crap'] ?? '';
435
436
            // Convert numeric 0 or empty values to empty string
437
            if (empty($selectedTypes) || $selectedTypes === 0 || $selectedTypes === '0') {
438
                return $this->disablePane($pane, 'Remove Crap', 'no crap types selected');
439
            }
440
441
            $types = is_array($selectedTypes) ? $selectedTypes : explode(',', $selectedTypes);
442
443
            // Trim whitespace and filter out empty values and '0'
444
            $types = array_map('trim', $types);
445
            $types = array_filter($types, fn ($type) => ! empty($type) && $type !== '0');
446
447
            // Re-index array to ensure sequential keys
448
            $types = array_values($types);
449
450
            if (empty($types)) {
451
                return $this->disablePane($pane, 'Remove Crap', 'no crap types selected');
452
            }
453
454
            // Get state to determine if this is first run
455
            $stateFile = storage_path('tmux/removecrap_state.json');
456
            $state = $this->loadCrapState($stateFile);
457
            $isFirstRun = $state['first_run'] ?? true;
458
459
            // Determine time limit: full on first run, 4 hours otherwise
460
            $time = $isFirstRun ? 'full' : '4';
0 ignored issues
show
introduced by
The condition $isFirstRun is always true.
Loading history...
461
462
            // Build commands for all enabled types to run sequentially
463
            $log = $this->getLogFile('removecrap');
464
            $commands = [];
465
            foreach ($types as $type) {
466
                $commands[] = "echo \"\nRunning removeCrapReleases for {$type}\"; nice -n{$niceness} php {$artisan} releases:remove-crap --type={$type} --time={$time} --delete 2>&1 | tee -a {$log}";
467
            }
468
469
            // Join all commands with semicolons and add final timestamp and sleep
470
            $allCommands = implode('; ', $commands);
471
            $sleepCommand = $this->buildSleepCommand($sleep);
472
            $fullCommand = "{$allCommands}; date +'%Y-%m-%d %T'; {$sleepCommand}";
473
474
            // Mark that we're not on the first run anymore for next cycle
475
            $this->saveCrapState($stateFile, [
476
                'first_run' => false,
477
                'types' => $types,
478
            ]);
479
480
            return $this->paneManager->respawnPane($pane, $fullCommand);
481
        }
482
483
        // Default fallback - disabled
484
        return $this->disablePane($pane, 'Remove Crap', 'invalid configuration');
485
    }
486
487
    /**
488
     * Load crap removal state
489
     */
490
    protected function loadCrapState(string $file): array
491
    {
492
        if (! file_exists($file)) {
493
            return ['first_run' => true];
494
        }
495
496
        $content = file_get_contents($file);
497
        $state = json_decode($content, true);
498
499
        return $state ?: ['first_run' => true];
500
    }
501
502
    /**
503
     * Save crap removal state
504
     */
505
    protected function saveCrapState(string $file, array $state): void
506
    {
507
        $dir = dirname($file);
508
        if (! is_dir($dir)) {
509
            mkdir($dir, 0755, true);
510
        }
511
512
        file_put_contents($file, json_encode($state, JSON_PRETTY_PRINT));
513
    }
514
515
    /**
516
     * Run post-process additional task
517
     */
518
    protected function runPostProcessAdditional(array $runVar): bool
519
    {
520
        $postSetting = (int) ($runVar['settings']['post'] ?? 0);
521
        $pane = '2.0';
522
523
        // Check if post processing is enabled (1 = additional, 2 = nfo, 3 = both)
524
        if ($postSetting === 0) {
525
            return $this->disablePane($pane, 'Post-process Additional', 'disabled in settings');
526
        }
527
528
        $hasWork = (int) ($runVar['counts']['now']['work'] ?? 0) > 0;
529
        $hasNfo = (int) ($runVar['counts']['now']['processnfo'] ?? 0) > 0;
530
531
        $niceness = Settings::settingValue('niceness') ?? 2;
532
        $log = $this->getLogFile('post_additional');
533
        $sleep = (int) ($runVar['settings']['post_timer'] ?? 300);
534
535
        $commands = [];
536
537
        // Build commands based on post setting value
538
        if ($postSetting === 1) {
539
            // Post = 1: Additional processing only
540
            if ($hasWork) {
541
                $commands[] = "nice -n{$niceness} ".PHP_BINARY." artisan update:postprocess additional true 2>&1 | tee -a {$log}";
542
            }
543
        } elseif ($postSetting === 2) {
544
            // Post = 2: NFO processing only
545
            if ($hasNfo) {
546
                $commands[] = "nice -n{$niceness} ".PHP_BINARY." artisan update:postprocess nfo true 2>&1 | tee -a {$log}";
547
            }
548
        } elseif ($postSetting === 3) {
549
            // Post = 3: Both additional and NFO
550
            if ($hasWork) {
551
                $commands[] = "nice -n{$niceness} ".PHP_BINARY." artisan update:postprocess additional true 2>&1 | tee -a {$log}";
552
            }
553
            if ($hasNfo) {
554
                $commands[] = "nice -n{$niceness} ".PHP_BINARY." artisan update:postprocess nfo true 2>&1 | tee -a {$log}";
555
            }
556
        }
557
558
        // If no work available, disable the pane
559
        if (empty($commands)) {
560
            $reason = match ($postSetting) {
561
                1 => 'no additional work to process',
562
                2 => 'no NFOs to process',
563
                3 => 'no additional work or NFOs to process',
564
                default => 'invalid post setting value',
565
            };
566
567
            return $this->disablePane($pane, 'Post-process Additional', $reason);
568
        }
569
570
        // Build the full command with all parts
571
        $allCommands = implode('; ', $commands);
572
        $sleepCommand = $this->buildSleepCommand($sleep);
573
        $fullCommand = "{$allCommands}; date +'%Y-%m-%d %T'; {$sleepCommand}";
574
575
        return $this->paneManager->respawnPane($pane, $fullCommand);
576
    }
577
578
    /**
579
     * Run TV/Anime post-processing
580
     */
581
    protected function runTvTask(array $runVar): bool
582
    {
583
        $enabled = (int) ($runVar['settings']['post_non'] ?? 0);
584
        $pane = '2.1';
585
586
        if ($enabled !== 1) {
587
            return $this->disablePane($pane, 'Post-process TV/Anime', 'disabled in settings');
588
        }
589
590
        $niceness = $this->getNiceness();
591
        $log = $this->getLogFile('post_tv');
592
        $artisan = PHP_BINARY.' artisan';
593
        $commands = [];
594
595
        // TV processing - Check work count before adding to queue
596
        $processTv = (int) ($runVar['settings']['processtvrage'] ?? 0);
597
        $hasTvWork = (int) ($runVar['counts']['now']['processtv'] ?? 0) > 0;
598
        if ($processTv > 0) {
599
            if ($hasTvWork) {
600
                $commands[] = "nice -n{$niceness} {$artisan} update:postprocess tv 2>&1 | tee -a {$log}";
601
            } else {
602
                // Log that TV processing was skipped due to no work
603
                if ($this->echooutput ?? true) {
0 ignored issues
show
Bug Best Practice introduced by
The property echooutput does not exist on App\Services\Tmux\TmuxTaskRunner. Did you maybe forget to declare it?
Loading history...
604
                    $this->colorCli->notice('Skipping TV processing - no work available');
605
                }
606
            }
607
        }
608
609
        // Anime processing
610
        $processAnime = (int) ($runVar['settings']['processanime'] ?? 0);
611
        $hasAnimeWork = (int) ($runVar['counts']['now']['processanime'] ?? 0) > 0;
612
        if ($processAnime > 0 && $hasAnimeWork) {
613
            $commands[] = "nice -n{$niceness} {$artisan} update:postprocess anime true 2>&1 | tee -a {$log}";
614
        }
615
616
        // If no work available for any enabled type, disable the pane
617
        if (empty($commands)) {
618
            $enabledTypes = [];
619
            if ($processTv > 0) {
620
                $enabledTypes[] = 'TV';
621
            }
622
            if ($processAnime > 0) {
623
                $enabledTypes[] = 'Anime';
624
            }
625
626
            if (empty($enabledTypes)) {
627
                return $this->disablePane($pane, 'Post-process TV/Anime', 'no types enabled (TV/Anime)');
628
            }
629
630
            $typesList = implode(', ', $enabledTypes);
631
632
            return $this->disablePane($pane, 'Post-process TV/Anime', "no work for enabled types ({$typesList})");
633
        }
634
635
        $sleep = (int) ($runVar['settings']['post_timer_non'] ?? 300);
636
        $allCommands = implode('; ', $commands);
637
        $sleepCommand = $this->buildSleepCommand($sleep);
638
        $fullCommand = "{$allCommands}; date +'%Y-%m-%d %T'; {$sleepCommand}";
639
640
        return $this->paneManager->respawnPane($pane, $fullCommand);
641
    }
642
643
    /**
644
     * Run Movies post-processing
645
     */
646
    protected function runMoviesTask(array $runVar): bool
647
    {
648
        $enabled = (int) ($runVar['settings']['post_non'] ?? 0);
649
        $pane = '2.3';
650
651
        if ($enabled !== 1) {
652
            return $this->disablePane($pane, 'Post-process Movies', 'disabled in settings');
653
        }
654
655
        $niceness = $this->getNiceness();
656
        $log = $this->getLogFile('post_movies');
657
        $artisan = PHP_BINARY.' artisan';
658
659
        // Movies processing - Uses single-process command
660
        $processMovies = (int) ($runVar['settings']['processmovies'] ?? 0);
661
        $hasMoviesWork = (int) ($runVar['counts']['now']['processmovies'] ?? 0) > 0;
662
663
        if ($processMovies === 0) {
664
            return $this->disablePane($pane, 'Post-process Movies', 'disabled in settings');
665
        }
666
667
        if (! $hasMoviesWork) {
668
            return $this->disablePane($pane, 'Post-process Movies', 'no work available');
669
        }
670
671
        $sleep = (int) ($runVar['settings']['post_timer_non'] ?? 300);
672
        $command = "nice -n{$niceness} {$artisan} update:postprocess movies true 2>&1 | tee -a {$log}";
673
        $sleepCommand = $this->buildSleepCommand($sleep);
674
        $fullCommand = "{$command}; date +'%Y-%m-%d %T'; {$sleepCommand}";
675
676
        return $this->paneManager->respawnPane($pane, $fullCommand);
677
    }
678
679
    /**
680
     * Legacy method for backward compatibility - now just calls runTvTask
681
     * @deprecated Use runTvTask() instead
682
     */
683
    protected function runNonAmazonTask(array $runVar): bool
684
    {
685
        return $this->runTvTask($runVar);
686
    }
687
688
    /**
689
     * Run Amazon post-processing (Books, Music, Games, Console)
690
     */
691
    protected function runAmazonTask(array $runVar): bool
692
    {
693
        $enabled = (int) ($runVar['settings']['post_amazon'] ?? 0);
694
        $pane = '2.2';
695
696
        if ($enabled !== 1) {
697
            return $this->disablePane($pane, 'Post-process Amazon', 'disabled in settings');
698
        }
699
700
        $hasWork = (int) ($runVar['counts']['now']['processmusic'] ?? 0) > 0
701
            || (int) ($runVar['counts']['now']['processbooks'] ?? 0) > 0
702
            || (int) ($runVar['counts']['now']['processconsole'] ?? 0) > 0
703
            || (int) ($runVar['counts']['now']['processgames'] ?? 0) > 0;
704
705
        if (! $hasWork) {
706
            return $this->disablePane($pane, 'Post-process Amazon', 'no music/books/games to process');
707
        }
708
709
        $niceness = Settings::settingValue('niceness') ?? 2;
710
        $log = $this->getLogFile('post_amazon');
711
        $artisan = PHP_BINARY.' artisan';
712
        $commands = [];
713
714
        // Books processing
715
        $processBooks = (int) ($runVar['settings']['processbooks'] ?? 0);
716
        $hasBooksWork = (int) ($runVar['counts']['now']['processbooks'] ?? 0) > 0;
717
        if ($processBooks > 0 && $hasBooksWork) {
718
            $commands[] = "nice -n{$niceness} {$artisan} update:postprocess book 2>&1 | tee -a {$log}";
719
        }
720
721
        // Music processing
722
        $processMusic = (int) ($runVar['settings']['processmusic'] ?? 0);
723
        $hasMusicWork = (int) ($runVar['counts']['now']['processmusic'] ?? 0) > 0;
724
        if ($processMusic > 0 && $hasMusicWork) {
725
            $commands[] = "nice -n{$niceness} {$artisan} update:postprocess music 2>&1 | tee -a {$log}";
726
        }
727
728
        // Console processing
729
        $processConsole = (int) ($runVar['settings']['processconsole'] ?? 0);
730
        $hasConsoleWork = (int) ($runVar['counts']['now']['processconsole'] ?? 0) > 0;
731
        if ($processConsole > 0 && $hasConsoleWork) {
732
            $commands[] = "nice -n{$niceness} {$artisan} update:postprocess console 2>&1 | tee -a {$log}";
733
        }
734
735
        // Games processing
736
        $processGames = (int) ($runVar['settings']['processgames'] ?? 0);
737
        $hasGamesWork = (int) ($runVar['counts']['now']['processgames'] ?? 0) > 0;
738
        if ($processGames > 0 && $hasGamesWork) {
739
            $commands[] = "nice -n{$niceness} {$artisan} update:postprocess games 2>&1 | tee -a {$log}";
740
        }
741
742
        // If no commands were added (no work available), disable the pane
743
        if (empty($commands)) {
744
            return $this->disablePane($pane, 'Post-process Amazon', 'no work available for any enabled type');
745
        }
746
747
        $sleep = (int) ($runVar['settings']['post_timer_amazon'] ?? 300);
748
        $allCommands = implode('; ', $commands);
749
        $sleepCommand = $this->buildSleepCommand($sleep);
750
        $fullCommand = "{$allCommands}; date +'%Y-%m-%d %T'; {$sleepCommand}";
751
752
        return $this->paneManager->respawnPane($pane, $fullCommand);
753
    }
754
755
    /**
756
     * Run XXX post-processing
757
     */
758
    protected function runXXXTask(array $runVar): bool
759
    {
760
        $enabled = (int) ($runVar['settings']['processxxx'] ?? 0);
761
        $pane = '2.4';
762
763
        if ($enabled !== 1) {
764
            return $this->disablePane($pane, 'Post-process XXX', 'disabled in settings');
765
        }
766
767
        $hasWork = (int) ($runVar['counts']['now']['processxxx'] ?? 0) > 0;
768
769
        if (! $hasWork) {
770
            return $this->disablePane($pane, 'Post-process XXX', 'no XXX releases to process');
771
        }
772
773
        $niceness = Settings::settingValue('niceness') ?? 2;
774
        $command = "nice -n{$niceness} ".PHP_BINARY.' artisan update:postprocess xxx true';
775
        $sleep = (int) ($runVar['settings']['post_timer_amazon'] ?? 300);
776
        $command = $this->buildCommand($command, ['log_pane' => 'post_xxx', 'sleep' => $sleep]);
777
778
        return $this->paneManager->respawnPane($pane, $command);
779
    }
780
}
781