Files
newznab-tmux/app/Console/Commands/TmuxMonitorCommand.php
T
2025-11-01 19:42:03 +01:00

187 lines
5.3 KiB
PHP

<?php
namespace App\Console\Commands;
use App\Models\Collection;
use App\Models\Settings;
use App\Services\Tmux\TmuxMonitorService;
use App\Services\Tmux\TmuxTaskRunner;
use Blacklight\ColorCLI;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class TmuxMonitorCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'tmux:monitor
{--session= : Tmux session name}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Monitor and manage tmux processing panes';
private TmuxMonitorService $monitor;
private TmuxTaskRunner $taskRunner;
private ColorCLI $colorCli;
/**
* Execute the console command.
*/
public function handle(): int
{
$this->colorCli = new ColorCLI;
try {
// Reset old collections
$this->resetOldCollections();
$sessionName = $this->option('session') ?? Settings::settingValue('tmux_session') ?? 'newznab';
// Initialize services
$this->monitor = new TmuxMonitorService;
$this->taskRunner = new TmuxTaskRunner($sessionName);
// Initialize monitor
$runVar = $this->monitor->initializeMonitor();
$this->colorCli->header('Starting Tmux Monitor');
$this->info("Monitoring session: {$sessionName}");
// Main monitoring loop
while ($this->monitor->shouldContinue()) {
// Collect statistics
$runVar = $this->monitor->collectStatistics();
// Update display
$this->monitor->updateDisplay();
// Run pane tasks if tmux is running
if ((int) ($runVar['settings']['is_running'] ?? 0) === 1) {
$this->runPaneTasks($runVar);
} else {
$this->info('Tmux is not running. Waiting...');
}
// Increment iteration and sleep
$this->monitor->incrementIteration();
sleep(10);
}
$this->info('Monitor stopped by exit flag');
return Command::SUCCESS;
} catch (\Exception $e) {
$this->error('Monitor failed: '.$e->getMessage());
$this->error($e->getTraceAsString());
return Command::FAILURE;
}
}
/**
* Reset old collections based on delay time
*/
private function resetOldCollections(): void
{
$delayTime = Settings::settingValue('delaytime') ?? 2;
$this->colorCli->header('Resetting expired collections. This may take some time...');
try {
DB::transaction(function () use ($delayTime) {
Collection::query()
->where('dateadded', '<', now()->subHours($delayTime))
->update(['dateadded' => now()]);
}, 10);
$this->info('Collections reset complete');
} catch (\Exception $e) {
$this->error('Failed to reset collections: '.$e->getMessage());
}
}
/**
* Run tasks in panes based on configuration
*/
private function runPaneTasks(array $runVar): void
{
$sequential = (int) ($runVar['constants']['sequential'] ?? 0);
// Define pane tasks based on sequential mode
$paneTasks = $this->getPaneTasks($sequential);
foreach ($paneTasks as $taskName => $config) {
try {
$this->taskRunner->runPaneTask($taskName, $config, $runVar);
} catch (\Exception $e) {
$this->error("Failed to run {$taskName}: ".$e->getMessage());
}
}
}
/**
* Get pane tasks based on sequential mode
*/
private function getPaneTasks(int $sequential): array
{
return match ($sequential) {
1 => $this->getSequentialBasicTasks(),
2 => $this->getSequentialFullTasks(),
default => $this->getStandardTasks(),
};
}
/**
* Get standard (non-sequential) tasks
*/
private function getStandardTasks(): array
{
return [
'main' => ['target' => '0.1'], // Handles binaries, backfill, and releases
'fixnames' => ['target' => '1.0'],
'removecrap' => ['target' => '1.1'],
'ppadditional' => ['target' => '2.0'],
'nonamazon' => ['target' => '2.1'],
'amazon' => ['target' => '2.2'],
'scraper' => ['target' => '3.0'],
];
}
/**
* Get sequential basic tasks
*/
private function getSequentialBasicTasks(): array
{
return [
'main' => ['target' => '0.1'],
'amazon' => ['target' => '2.2'],
'scraper' => ['target' => '3.0'],
'fixnames' => ['target' => '1.0'],
'removecrap' => ['target' => '1.1'],
'ppadditional' => ['target' => '2.0'],
'nonamazon' => ['target' => '2.1'],
];
}
/**
* Get sequential full tasks
*/
private function getSequentialFullTasks(): array
{
return [
'main' => ['target' => '0.1'],
'amazon' => ['target' => '0.2'],
'scraper' => ['target' => '3.0'],
];
}
}