- Nouveau domaine System/Domain/Model/SystemStatus (value object) - QueryHandler agrégeant métriques mangas, chapitres, jobs (global/24h/7j), stockage et sources - Endpoint GET /api/system/status via API Platform (singleton) - Calcul de l'espace disque par RecursiveDirectoryIterator sur public/images - Page Vue /system/status avec 6 cards (Mangas, Chapitres, Jobs, Stockage, Sources, Système) - Nettoyage du router : suppression des PlaceholderComponent et routes placeholder - Sidebar : suppression des entrées sans page réelle
94 lines
4.1 KiB
PHP
94 lines
4.1 KiB
PHP
<?php
|
|
|
|
namespace App\Domain\System\Application\QueryHandler;
|
|
|
|
use App\Domain\Shared\Domain\Contract\JobRepositoryInterface;
|
|
use App\Domain\Shared\Domain\Model\JobStatus;
|
|
use App\Domain\System\Application\Query\GetSystemStatusQuery;
|
|
use App\Domain\System\Domain\Contract\Repository\SystemStatusRepositoryInterface;
|
|
use App\Domain\System\Domain\Model\SystemStatus;
|
|
|
|
readonly class GetSystemStatusQueryHandler
|
|
{
|
|
public function __construct(
|
|
private SystemStatusRepositoryInterface $systemStatusRepository,
|
|
private JobRepositoryInterface $jobRepository,
|
|
private string $mangaDataPath,
|
|
private string $imagesStoragePath,
|
|
) {
|
|
}
|
|
|
|
public function handle(GetSystemStatusQuery $query): SystemStatus
|
|
{
|
|
$now = new \DateTimeImmutable();
|
|
$last24h = $now->modify('-24 hours');
|
|
$last7d = $now->modify('-7 days');
|
|
|
|
$totalJobs = $this->jobRepository->countByCriteria([]);
|
|
$completedJobs = $this->jobRepository->countByCriteria(['status' => JobStatus::COMPLETED]);
|
|
$failedJobs = $this->jobRepository->countByCriteria(['status' => JobStatus::FAILED]);
|
|
$pendingJobs = $this->jobRepository->countByCriteria(['status' => JobStatus::PENDING]);
|
|
$inProgressJobs = $this->jobRepository->countByCriteria(['status' => JobStatus::IN_PROGRESS]);
|
|
|
|
$totalJobsLast24h = $this->jobRepository->countByCriteria(['createdAfter' => $last24h]);
|
|
$completedJobsLast24h = $this->jobRepository->countByCriteria(['status' => JobStatus::COMPLETED, 'createdAfter' => $last24h]);
|
|
$failedJobsLast24h = $this->jobRepository->countByCriteria(['status' => JobStatus::FAILED, 'createdAfter' => $last24h]);
|
|
|
|
$totalJobsLast7d = $this->jobRepository->countByCriteria(['createdAfter' => $last7d]);
|
|
$completedJobsLast7d = $this->jobRepository->countByCriteria(['status' => JobStatus::COMPLETED, 'createdAfter' => $last7d]);
|
|
$failedJobsLast7d = $this->jobRepository->countByCriteria(['status' => JobStatus::FAILED, 'createdAfter' => $last7d]);
|
|
|
|
$storagePath = $this->imagesStoragePath;
|
|
$storageTotalBytes = (int) (@disk_total_space($storagePath) ?: 0);
|
|
$storageFreeBytes = (int) (@disk_free_space($storagePath) ?: 0);
|
|
$storageUsedBytes = $this->computeDirectorySize($storagePath);
|
|
|
|
return new SystemStatus(
|
|
totalMangas: $this->systemStatusRepository->countMangas(),
|
|
monitoredMangas: $this->systemStatusRepository->countMonitoredMangas(),
|
|
mangasByStatus: $this->systemStatusRepository->countMangasByStatus(),
|
|
totalChapters: $this->systemStatusRepository->countChapters(),
|
|
downloadedChapters: $this->systemStatusRepository->countDownloadedChapters(),
|
|
totalJobs: $totalJobs,
|
|
completedJobs: $completedJobs,
|
|
failedJobs: $failedJobs,
|
|
pendingJobs: $pendingJobs,
|
|
inProgressJobs: $inProgressJobs,
|
|
totalJobsLast24h: $totalJobsLast24h,
|
|
completedJobsLast24h: $completedJobsLast24h,
|
|
failedJobsLast24h: $failedJobsLast24h,
|
|
totalJobsLast7d: $totalJobsLast7d,
|
|
completedJobsLast7d: $completedJobsLast7d,
|
|
failedJobsLast7d: $failedJobsLast7d,
|
|
storagePath: $this->mangaDataPath,
|
|
storageTotalBytes: $storageTotalBytes,
|
|
storageFreeBytes: $storageFreeBytes,
|
|
storageUsedBytes: $storageUsedBytes,
|
|
totalSources: $this->systemStatusRepository->countContentSources(),
|
|
sourcesByHealth: $this->systemStatusRepository->countContentSourcesByHealth(),
|
|
phpVersion: PHP_VERSION,
|
|
generatedAt: $now,
|
|
);
|
|
}
|
|
|
|
private function computeDirectorySize(string $path): int
|
|
{
|
|
if (!is_dir($path)) {
|
|
return 0;
|
|
}
|
|
|
|
$size = 0;
|
|
$iterator = new \RecursiveIteratorIterator(
|
|
new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS)
|
|
);
|
|
|
|
foreach ($iterator as $file) {
|
|
if ($file->isFile()) {
|
|
$size += $file->getSize();
|
|
}
|
|
}
|
|
|
|
return $size;
|
|
}
|
|
}
|