setName('backup:status')->setDescription('Show the backup key, locations and recent runs'); } protected function execute(InputInterface $input, OutputInterface $output): int { if (!$this->keys->isInitialized()) { $output->writeln('Key: not created (occ backup:key:init)'); } else { $c = $this->keys->recoveryKitConfirmation(); $output->writeln('Key: ' . $this->keys->fingerprint() . ', recovery kit ' . ($c ? 'confirmed by ' . $c['uid'] . ' on ' . date('Y-m-d H:i', $c['time']) : 'not confirmed (occ backup:key:confirm)')); } $names = []; foreach ($this->targets->list() as $t) { $names[$t->getId()] = $t->getName(); } $output->writeln('Locations: ' . ($names === [] ? 'none' : implode(', ', $names))); $rows = []; foreach ($this->runs->findRecent(10) as $r) { $s = json_decode($r->getStats() ?? '{}', true)['files'] ?? []; $rows[] = [$r->getId(), $names[$r->getTargetId()] ?? '#' . $r->getTargetId(), $r->getKind(), $r->getStatus() . ($r->getStatus() === 'running' ? ' (' . $r->getPhase() . self::percent($r) . ')' : ''), date('Y-m-d H:i', $r->getStartedAt()), $r->getFinishedAt() ? gmdate('H:i:s', $r->getFinishedAt() - $r->getStartedAt()) : '', $s['files'] ?? '', isset($s['uploaded']) ? sprintf('%.1f MiB', $s['uploaded'] / 1048576) : '', mb_strimwidth((string)$r->getError(), 0, 50, '…')]; } if ($rows !== []) { (new Table($output))->setHeaders(['run', 'location', 'kind', 'status', 'started', 'took', 'files', 'uploaded', 'error'])->setRows($rows)->render(); } return 0; } /** " 68%", or " ~68%" when estimated from the file cache; empty without an estimate */ private static function percent(\OCA\NgBackup\Db\Run $r): string { $p = \OCA\NgBackup\Job\BackupRun::progressOf($r); return $p === null ? '' : sprintf(' %s%d%%', $p['approximate'] ? '~' : '', (int)floor($p['fraction'] * 100.0)); } }