balikobot-api/src/Command/FetchForecastData.php
2025-01-27 01:24:59 +01:00

99 lines
2.9 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Command;
use App\DTO\GEOPoint;
use App\Services\GeoPointResolverService;
use App\Services\Granularity\Factory\WeatherGranularityFactory;
use App\Services\WeatherProviderInterface;
use App\Services\WeatherStorageStoreInterface;
use App\Utils\Weather\WeatherInterval;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class FetchForecastData extends Command
{
public function __construct(
protected readonly string $forecastForDays,
protected readonly WeatherProviderInterface $weatherProvider,
protected readonly WeatherStorageStoreInterface $weatherStorageStore,
protected readonly WeatherGranularityFactory $weatherGranularityFactory,
protected readonly GeoPointResolverService $geoPointResolverService,
protected readonly LoggerInterface $logger,
?string $name = null,
) {
parent::__construct($name);
}
public static function getDefaultName(): ?string
{
return 'nano:fetch-forecast-data';
}
protected function configure(): void
{
$this->addOption(
'cityName',
'c',
InputOption::VALUE_REQUIRED,
'City name'
);
}
public function doExecute(InputInterface $input, OutputInterface $output): int
{
if ($input->getOption('cityName') !== null) {
$latLon = $this->geoPointResolverService->getGeoPointFromCityName($input->getOption('cityName'));
if ($latLon === null) {
$this->logger->error(
"Invalid city name {cityName}",
[
'cityName' => $input->getOption('cityName'),
]
);
return self::INVALID;
}
$cities = [$latLon];
} else {
$cities = $this->geoPointResolverService->getCitiesWithPoints();
}
foreach ($cities as $city) {
$this->fetchDataForCity($city);
}
return self::SUCCESS;
}
protected function fetchDataForCity(GEOPoint $geoPoint): void
{
$fromDate = new \DateTime();
$toDate = new \DateTime();
$toDate->add(new \DateInterval($this->forecastForDays));
$weather = $this->weatherProvider->fetchWeather(
$geoPoint,
WeatherInterval::DAILY,
$fromDate,
$toDate
);
// handle granularity
$granularityService = $this->weatherGranularityFactory->createWeatherGranularityByInterval(WeatherInterval::DAILY);
$granularForCastByDay = $granularityService->calculateFromMultipleRecords($weather);
// store data
$this->weatherStorageStore->storeWeatherForPointByDay($geoPoint, $granularForCastByDay);
}
}