99 lines
2.9 KiB
PHP
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);
|
|
}
|
|
}
|