opsdash-app/opsdash/lib/Command/ReportCommand.php
2026-05-14 13:24:17 +07:00

98 lines
3.8 KiB
PHP

<?php
declare(strict_types=1);
namespace OCA\Opsdash\Command;
use OCA\Opsdash\Service\ReportSummaryService;
use OCP\IUserManager;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
#[AsCommand(
name: 'opsdash:report',
description: 'Generate a lightweight Opsdash report snapshot for a user.',
hidden: false,
)]
class ReportCommand extends Command {
protected static $defaultName = 'opsdash:report';
public function __construct(
private ReportSummaryService $reportSummaryService,
private IUserManager $userManager,
) {
parent::__construct();
}
protected function configure(): void {
$this
->setDescription('Generate a lightweight Opsdash report snapshot for a user.')
->addOption('user', null, InputOption::VALUE_REQUIRED, 'User ID to report on')
->addOption('range', null, InputOption::VALUE_REQUIRED, 'Range: week or month', 'week')
->addOption('offset', null, InputOption::VALUE_REQUIRED, 'Range offset (-24..24)', '0')
->addOption('cals', null, InputOption::VALUE_OPTIONAL, 'Comma-separated calendar ids (optional)')
->addOption('format', null, InputOption::VALUE_REQUIRED, 'Output format: text or json', 'text');
}
protected function execute(InputInterface $input, OutputInterface $output): int {
$uid = trim((string)$input->getOption('user'));
if ($uid === '') {
$output->writeln('<error>[opsdash] --user is required.</error>');
return Command::FAILURE;
}
if ($this->userManager->get($uid) === null) {
$output->writeln('<error>[opsdash] User not found.</error>');
return Command::FAILURE;
}
$range = strtolower((string)$input->getOption('range'));
if ($range !== 'month') {
$range = 'week';
}
$offset = (int)$input->getOption('offset');
$calsCsv = (string)$input->getOption('cals');
$requested = trim($calsCsv) !== ''
? array_values(array_filter(explode(',', $calsCsv), static fn ($x) => $x !== ''))
: null;
$summary = $this->reportSummaryService->build(
'opsdash',
$uid,
$range,
$offset,
$requested,
);
$format = strtolower((string)$input->getOption('format'));
if ($format === 'json') {
$output->writeln(json_encode($summary, JSON_PRETTY_PRINT));
return Command::SUCCESS;
}
$output->writeln(sprintf(
'<info>[opsdash]</info> Report for %s (%s, offset %d)',
$uid,
ucfirst($range),
$offset,
));
$output->writeln(sprintf('Range: %s → %s', $summary['from'], $summary['to']));
$output->writeln(sprintf('Total hours: %.2f', $summary['total_hours']));
$output->writeln(sprintf('Events: %d', $summary['events']));
$output->writeln(sprintf('Active days: %d', $summary['active_days']));
$output->writeln(sprintf('Avg/day: %.2f', $summary['avg_per_day']));
$output->writeln(sprintf('Avg/event: %.2f', $summary['avg_per_event']));
$topCategory = is_array($summary['top_category'] ?? null) ? $summary['top_category'] : null;
$topCalendar = is_array($summary['top_calendar'] ?? null) ? $summary['top_calendar'] : null;
if ($topCategory) {
$output->writeln(sprintf('Top category: %s (%.2f h)', $topCategory['label'], $topCategory['hours']));
}
if ($topCalendar) {
$output->writeln(sprintf('Top calendar: %s (%.2f h)', $topCalendar['label'], $topCalendar['hours']));
}
return Command::SUCCESS;
}
}