Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 16 additions & 25 deletions src/Application/Cli/AddressSearch/AddressAutocompleteCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,17 @@
use App\Domain\AddressSearch\Model\AddressSearch;
use App\Domain\AddressSearch\Model\BuildingAddressScored;
use App\Infrastructure\Symfony\Console\Autocomplete;
use App\Infrastructure\Symfony\Console\OptionHelper;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Attribute\Option;
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: 'app:address-search:autocomplete',
description: 'Autocomplete the addresses by using the indexed data',
)]
final class AddressAutocompleteCommand extends Command
final class AddressAutocompleteCommand
{
private const int MAX_AUTOCOMPLETE_ITEMS = 20;
private const int DEFAULT_AUTOCOMPLETE_ITEMS = 10;
Expand All @@ -28,28 +27,20 @@ final class AddressAutocompleteCommand extends Command

public function __construct(
private readonly BuildingAddressSearcherInterface $buildingAddressSearcher,
) {
parent::__construct();
}

protected function configure(): void
{
$this
->addOption('limit', null, InputOption::VALUE_REQUIRED, 'Number of items to show', self::DEFAULT_AUTOCOMPLETE_ITEMS)
->addOption('min-score', null, InputOption::VALUE_REQUIRED, 'Filter results by their min score (min: 1, max: 100)')
;
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$limit = self::MAX_AUTOCOMPLETE_ITEMS;
if (null !== ($inputLimit = OptionHelper::getPositiveIntOptionValue($input, 'limit', 1, self::MAX_AUTOCOMPLETE_ITEMS))) {
$limit = min($inputLimit, self::MAX_AUTOCOMPLETE_ITEMS);
}

$minScore = null;
if (null !== ($inputMinScore = OptionHelper::getPositiveIntOptionValue($input, 'min-score', 1, self::MAX_MIN_SCORE))) {
$minScore = min($inputMinScore, self::MAX_MIN_SCORE);
) {}

public function __invoke(
InputInterface $input,
OutputInterface $output,
#[Option(description: 'Number of items to show')]
int $limit = self::DEFAULT_AUTOCOMPLETE_ITEMS,
#[Option(description: 'Filter results by their min score (min: 1, max: 100)', name: 'min-score')]
?int $minScore = null,
): int {
$limit = min($limit, self::MAX_AUTOCOMPLETE_ITEMS);

if (null !== $minScore) {
$minScore = min($minScore, self::MAX_MIN_SCORE);
}

$stream = \STDIN;
Expand Down
31 changes: 12 additions & 19 deletions src/Application/Cli/AddressSearch/AddressSearchCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,35 @@

use App\Application\Contract\BuildingAddressSearcherInterface;
use App\Domain\AddressSearch\Model\AddressSearch;
use App\Infrastructure\Symfony\Console\OptionHelper;
use Symfony\Component\Console\Attribute\Argument;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Attribute\Option;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\TableSeparator;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

#[AsCommand(
name: 'app:address-search:search',
description: 'Searches an address in the indexed data',
)]
final class AddressSearchCommand extends Command
final class AddressSearchCommand
{
private const int DEFAULT_LIMIT = 3;

public function __construct(
private readonly BuildingAddressSearcherInterface $buildingAddressSearcher,
) {
parent::__construct();
}

protected function configure(): void
{
$this->addArgument('search', InputArgument::REQUIRED, 'Address to search for')
->addOption('limit', null, InputOption::VALUE_REQUIRED, 'Number of results to show', self::DEFAULT_LIMIT)
;
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$search = $input->getArgument('search');
$limit = OptionHelper::getPositiveIntOptionValue($input, 'limit', 1) ?? self::DEFAULT_LIMIT;
) {}

public function __invoke(
InputInterface $input,
OutputInterface $output,
#[Argument(description: 'Address to search for')]
string $search,
#[Option(description: 'Number of results to show')]
int $limit = self::DEFAULT_LIMIT,
): int {
$filter = new AddressSearch(
limit: $limit,
filterByQuery: $search,
Expand Down
29 changes: 12 additions & 17 deletions src/Application/Cli/AddressSearch/AddressSearchIndexAllCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,30 @@
use App\Infrastructure\Model\CountryCodeEnum;
use App\Infrastructure\Symfony\Console\OptionHelper;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Attribute\Option;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

#[AsCommand(
name: 'app:address-search:index-all',
description: 'Index ALL building addresses in the search index',
)]
final class AddressSearchIndexAllCommand extends Command
final readonly class AddressSearchIndexAllCommand
{
public function __construct(
private readonly BuildingAddressIndexerInterface $addressIndexer,
) {
parent::__construct();
}

protected function configure(): void
{
$this
->addOption('country-code', null, InputOption::VALUE_REQUIRED, 'Index only entries with the given country code')
;
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
private BuildingAddressIndexerInterface $addressIndexer,
) {}

public function __invoke(
InputInterface $input,
OutputInterface $output,
#[Option(description: 'Index only entries with the given country code', name: 'country-code')]
?string $countryCodeText = null,
): int {
$io = new SymfonyStyle($input, $output);
$countryCode = OptionHelper::getStringBackedEnumOptionValue($input, 'country-code', CountryCodeEnum::class);
$countryCode = CountryCodeEnum::from($countryCodeText);

$progress = $io->createProgressBar();
$progress->maxSecondsBetweenRedraws(2);
Expand Down
28 changes: 11 additions & 17 deletions src/Application/Cli/AddressSearch/AddressSearchIndexCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
use App\Application\Contract\BuildingAddressIndexerInterface;
use App\Domain\AddressSearch\Exception\BuildingAddressNotFoundException;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Attribute\Option;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Uid\Uuid;
Expand All @@ -18,27 +18,21 @@
name: 'app:address-search:index',
description: 'Index (or update) a single BuildingAddress into the search index',
)]
final class AddressSearchIndexCommand extends Command
final class AddressSearchIndexCommand
{
public function __construct(
private readonly BuildingAddressIndexerInterface $addressIndexer,
) {
parent::__construct();
}
) {}

protected function configure(): void
{
$this
->addOption('id', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'The BuildingAddress ID to index')
->addOption('from-file', null, InputOption::VALUE_REQUIRED, 'The file containing one BuildingAddress ID per line to be imported ')
;
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
public function __invoke(
InputInterface $input,
OutputInterface $output,
#[Option(description: 'The BuildingAddress ID to index')]
?string $id = null,
#[Option(description: 'The file containing one BuildingAddress ID per line to be imported', name: 'from-file')]
?string $file = null,
): int {
$io = new SymfonyStyle($input, $output);
$file = $input->getOption('from-file');
$id = $input->getOption('id');
if (!$file && !$id) {
$io->error([
'No source of BuildingAddress ID was provided',
Expand Down
40 changes: 19 additions & 21 deletions src/Application/Cli/AddressSearch/AddressSearchListCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,47 +9,45 @@
use App\Infrastructure\Model\CountryCodeEnum;
use App\Infrastructure\Symfony\Console\OptionHelper;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Attribute\Option;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

#[AsCommand(
name: 'app:address-search:list',
description: 'List the addresses in the indexed data',
)]
final class AddressSearchListCommand extends Command
final class AddressSearchListCommand
{
private const int DEFAULT_LIMIT = 10;
private const string DATE_FORMAT = 'Y-m-d';

public function __construct(
private readonly BuildingAddressSearcherInterface $buildingAddressSearcher,
) {
parent::__construct();
}

protected function configure(): void
{
$this
->addOption('limit', null, InputOption::VALUE_REQUIRED, 'Number of items to show', self::DEFAULT_LIMIT)
// Filters
->addOption('id', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Show only entries with the ID)')
->addOption('building-id', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Show only entries with the given building ID (EGID, GEID)')
->addOption('country-code', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Show only entries with the given country code')
;
}
) {}

protected function execute(InputInterface $input, OutputInterface $output): int
{
public function __invoke(
InputInterface $input,
OutputInterface $output,
#[Option(description: 'Number of items to show')]
int $limit = self::DEFAULT_LIMIT,
// Filters
#[Option(description: 'Show only entries with the ID')]
?array $id = null,
#[Option(description: 'Show only entries with the given building ID (EGID, GEID)', name: 'building-id')]
?array $buildingIds = null,
#[Option(description: 'Show only entries with the given country code', name: 'country-code')]
?array $countryCodes = null,
): int {
$io = new SymfonyStyle($input, $output);

try {
$limit = OptionHelper::getPositiveIntOptionValue($input, 'limit') ?? self::DEFAULT_LIMIT;
$ids = OptionHelper::getStringListOptionValues($input, 'id');
$buildingIds = OptionHelper::getStringListOptionValues($input, 'building-id');
$countryCodes = OptionHelper::getStringBackedEnumListOptionValues($input, 'country-code', CountryCodeEnum::class);
$ids = OptionHelper::getStringListOptionValues($id);
$buildingIds = OptionHelper::getStringListOptionValues($buildingIds);
$countryCodes = OptionHelper::getStringBackedEnumListOptionValues($countryCodes, CountryCodeEnum::class);
} catch (\UnexpectedValueException $e) {
$io->error($e->getMessage());

Expand Down
10 changes: 4 additions & 6 deletions src/Application/Cli/AddressSearch/AddressSearchStatsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,13 @@
name: 'app:address-search:stats',
description: 'Provides stats for the indexed data',
)]
final class AddressSearchStatsCommand extends Command
final readonly class AddressSearchStatsCommand
{
public function __construct(
private readonly BuildingAddressStatsProviderInterface $statsProvider,
) {
parent::__construct();
}
private BuildingAddressStatsProviderInterface $statsProvider,
) {}

protected function execute(InputInterface $input, OutputInterface $output): int
public function __invoke(InputInterface $input, OutputInterface $output): int
{
$list[] = ['Indexed addresses' => $this->statsProvider->countIndexedAddresses()];

Expand Down
29 changes: 12 additions & 17 deletions src/Application/Cli/BuildingData/BuildingDataImportCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,29 @@
use Doctrine\DBAL\Exception\TableNotFoundException;
use League\Csv\UnavailableStream;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Attribute\Option;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

#[AsCommand(
name: 'app:building-data:import',
description: 'Imports the building data from the available building registries',
)]
final class BuildingDataImportCommand extends Command
final readonly class BuildingDataImportCommand
{
public function __construct(
private readonly BuildingEntranceImporterInterface $importer,
) {
parent::__construct();
}

protected function configure(): void
{
$this
->addOption('country-code', null, InputOption::VALUE_REQUIRED, 'Only handle the given country')
;
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$countryCode = OptionHelper::getStringBackedEnumOptionValue($input, 'country-code', CountryCodeEnum::class);
private BuildingEntranceImporterInterface $importer,
) {}

public function __invoke(
InputInterface $input,
OutputInterface $output,
#[Option(description: 'Only handle the given country', name: 'country-code')]
?string $countryCode = null,
): int {
$countryCode = CountryCodeEnum::from($countryCode);

$io = new SymfonyStyle($input, $output);
$progress = $io->createProgressBar();
Expand Down
Loading
Loading