Added progress bar to command downloading new GeoLite2 database file

This commit is contained in:
Alejandro Celaya 2018-11-12 21:30:30 +01:00
parent 58e8c8e182
commit 9964d3e24b
4 changed files with 22 additions and 7 deletions

View File

@ -6,6 +6,7 @@ namespace Shlinkio\Shlink\CLI\Command\Visit;
use Shlinkio\Shlink\Common\Exception\RuntimeException; use Shlinkio\Shlink\Common\Exception\RuntimeException;
use Shlinkio\Shlink\Common\IpGeolocation\GeoLite2\DbUpdaterInterface; use Shlinkio\Shlink\Common\IpGeolocation\GeoLite2\DbUpdaterInterface;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Console\Style\SymfonyStyle;
@ -47,11 +48,23 @@ class UpdateDbCommand extends Command
protected function execute(InputInterface $input, OutputInterface $output): void protected function execute(InputInterface $input, OutputInterface $output): void
{ {
$io = new SymfonyStyle($input, $output); $io = new SymfonyStyle($input, $output);
$progressBar = new ProgressBar($output);
$progressBar->start();
try { try {
$this->geoLiteDbUpdater->downloadFreshCopy(); $this->geoLiteDbUpdater->downloadFreshCopy(function (int $total, int $downloaded) use ($progressBar) {
$progressBar->setMaxSteps($total);
$progressBar->setProgress($downloaded);
});
$progressBar->finish();
$io->writeln('');
$io->success($this->translator->translate('GeoLite2 database properly updated')); $io->success($this->translator->translate('GeoLite2 database properly updated'));
} catch (RuntimeException $e) { } catch (RuntimeException $e) {
$progressBar->finish();
$io->writeln('');
$io->error($this->translator->translate('An error occurred while updating GeoLite2 database')); $io->error($this->translator->translate('An error occurred while updating GeoLite2 database'));
if ($io->isVerbose()) { if ($io->isVerbose()) {
$this->getApplication()->renderException($e, $output); $this->getApplication()->renderException($e, $output);

View File

@ -4,6 +4,7 @@ declare(strict_types=1);
namespace ShlinkioTest\Shlink\CLI\Command\Visit; namespace ShlinkioTest\Shlink\CLI\Command\Visit;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\Prophecy\ObjectProphecy; use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\CLI\Command\Visit\UpdateDbCommand; use Shlinkio\Shlink\CLI\Command\Visit\UpdateDbCommand;
use Shlinkio\Shlink\Common\Exception\RuntimeException; use Shlinkio\Shlink\Common\Exception\RuntimeException;
@ -39,7 +40,7 @@ class UpdateDbCommandTest extends TestCase
*/ */
public function successMessageIsPrintedIfEverythingWorks() public function successMessageIsPrintedIfEverythingWorks()
{ {
$download = $this->dbUpdater->downloadFreshCopy()->will(function () { $download = $this->dbUpdater->downloadFreshCopy(Argument::type('callable'))->will(function () {
}); });
$this->commandTester->execute([]); $this->commandTester->execute([]);
@ -54,7 +55,7 @@ class UpdateDbCommandTest extends TestCase
*/ */
public function errorMessageIsPrintedIfAnExceptionIsThrown() public function errorMessageIsPrintedIfAnExceptionIsThrown()
{ {
$download = $this->dbUpdater->downloadFreshCopy()->willThrow(RuntimeException::class); $download = $this->dbUpdater->downloadFreshCopy(Argument::type('callable'))->willThrow(RuntimeException::class);
$this->commandTester->execute([]); $this->commandTester->execute([]);
$output = $this->commandTester->getDisplay(); $output = $this->commandTester->getDisplay();

View File

@ -42,22 +42,23 @@ class DbUpdater implements DbUpdaterInterface
/** /**
* @throws RuntimeException * @throws RuntimeException
*/ */
public function downloadFreshCopy(): void public function downloadFreshCopy(callable $handleProgress = null): void
{ {
$tempDir = $this->options->getTempDir(); $tempDir = $this->options->getTempDir();
$compressedFile = sprintf('%s/%s', $tempDir, self::DB_COMPRESSED_FILE); $compressedFile = sprintf('%s/%s', $tempDir, self::DB_COMPRESSED_FILE);
$this->downloadDbFile($compressedFile); $this->downloadDbFile($compressedFile, $handleProgress);
$tempFullPath = $this->extractDbFile($compressedFile, $tempDir); $tempFullPath = $this->extractDbFile($compressedFile, $tempDir);
$this->copyNewDbFile($tempFullPath); $this->copyNewDbFile($tempFullPath);
$this->deleteTempFiles([$compressedFile, $tempFullPath]); $this->deleteTempFiles([$compressedFile, $tempFullPath]);
} }
private function downloadDbFile(string $dest): void private function downloadDbFile(string $dest, callable $handleProgress = null): void
{ {
try { try {
$this->httpClient->request(RequestMethod::METHOD_GET, $this->options->getDownloadFrom(), [ $this->httpClient->request(RequestMethod::METHOD_GET, $this->options->getDownloadFrom(), [
RequestOptions::SINK => $dest, RequestOptions::SINK => $dest,
RequestOptions::PROGRESS => $handleProgress,
]); ]);
} catch (Throwable | GuzzleException $e) { } catch (Throwable | GuzzleException $e) {
throw new RuntimeException( throw new RuntimeException(

View File

@ -10,5 +10,5 @@ interface DbUpdaterInterface
/** /**
* @throws RuntimeException * @throws RuntimeException
*/ */
public function downloadFreshCopy(): void; public function downloadFreshCopy(callable $handleProgress = null): void;
} }