Split groups.swiss task into separate console commands to spread load

This commit is contained in:
Björn Fromme
2021-06-09 16:17:38 +02:00
parent 95b3ebae5e
commit ad82781031
4 changed files with 128 additions and 107 deletions
@@ -0,0 +1,85 @@
<?php
namespace EP\EpProducts\Command;
/***************************************************************
*
* Copyright notice
*
* (c) 2021 Björn Fromme <[email protected]>, dreipunktnull
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use EP\EpProducts\Service\GroupsSwissService;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Object\ObjectManager;
class GroupsSwissCommand extends Command
{
/**
* @var GroupsSwissService
*/
private $groupsSwissService;
protected static $defaultName = 'ep:groups-swiss';
public function __construct()
{
/** @var ObjectManager $objectManager */
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$this->groupsSwissService = $objectManager->get(GroupsSwissService::class);
parent::__construct();
}
protected function configure()
{
$this->addArgument(
'hotel',
InputArgument::REQUIRED,
'E&P hotel code'
);
$this->addArgument(
'house',
InputArgument::REQUIRED,
'House number'
);
$this->addArgument(
'key',
InputArgument::REQUIRED,
'Groups.swiss API key'
);
}
public function execute(InputInterface $input, OutputInterface $output)
{
$hotelCode = $input->getArgument('hotel');
$houseNumber = $input->getArgument('house');
$apiKey = $input->getArgument('key');
$success = $this->groupsSwissService->publishContingents($hotelCode, $houseNumber, $apiKey);
return $success ? 1 : 0;
}
}
@@ -26,7 +26,7 @@ namespace EP\EpProducts\Service;
* This copyright notice MUST APPEAR in all copies of the script! * This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/ ***************************************************************/
use Doctrine\DBAL\DBALException; use Doctrine\DBAL\Exception as DBALException;
use EP\EpProducts\Domain\Model\Contingent; use EP\EpProducts\Domain\Model\Contingent;
use EP\EpProducts\Domain\Model\Hotel; use EP\EpProducts\Domain\Model\Hotel;
use EP\EpProducts\Domain\Repository\ContingentRepository; use EP\EpProducts\Domain\Repository\ContingentRepository;
@@ -37,7 +37,6 @@ use Psr\Log\LoggerAwareTrait;
use Symfony\Component\HttpClient\HttpClient; use Symfony\Component\HttpClient\HttpClient;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use TYPO3\CMS\Core\SingletonInterface; use TYPO3\CMS\Core\SingletonInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface; use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
use TYPO3\CMS\Extbase\Configuration\Exception; use TYPO3\CMS\Extbase\Configuration\Exception;
@@ -55,11 +54,6 @@ class GroupsSwissService implements SingletonInterface, LoggerAwareInterface
*/ */
protected $contingentRepository; protected $contingentRepository;
/**
* @var array
*/
protected $apiKeys;
/** /**
* @var HttpClient * @var HttpClient
*/ */
@@ -77,61 +71,45 @@ class GroupsSwissService implements SingletonInterface, LoggerAwareInterface
) { ) {
$this->hotelRepository = $hotelRepository; $this->hotelRepository = $hotelRepository;
$this->contingentRepository = $contingentRepository; $this->contingentRepository = $contingentRepository;
$settings = GeneralUtility::removeDotsFromTS(
$configurationManager->getConfiguration(
ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT
)
);
$this->apiKeys = $settings['plugin']['tx_epproducts']['settings']['groupsSwissApiKeys'];
$this->httpClient = HttpClient::create(); $this->httpClient = HttpClient::create();
} }
/** public function publishContingents(string $hotelCode, int $houseNumber, string $apiKey): bool
* @return void
* @throws Exception
*/
public function publishContingents(): void
{ {
$range = Period::after(new \DateTime('now'), '1 year'); $range = Period::after(new \DateTime('now'), '1 year');
foreach ($this->apiKeys as $config) { $result = $this->hotelRepository->findByCode($hotelCode);
$hotelCode = $config['hotelCode']; if (null === $result) {
$this->logger->error(sprintf('Hotel with code %s not found', $hotelCode));
return false;
}
$result = $this->hotelRepository->findByCode($hotelCode); /** @var Hotel $hotel */
$hotel = $result->getFirst();
if (null === $result) { try {
$this->logger->error(sprintf('Hotel with code %s not found', $hotelCode)); $events = $this->contingentRepository->getEvents(
continue; \DateTime::createFromImmutable($range->getStartDate()),
} \DateTime::createFromImmutable($range->getEndDate()),
['hotel' => $hotel, 'hotelCode' => $hotelCode]
/** @var Hotel $hotel */
$hotel = $result->getFirst();
$this->logger->info(sprintf(
'Publishing availabilities for hotel %s',
preg_replace( '/[\r\n]/', '', $hotel->getName())
));
try {
$events = $this->contingentRepository->getEvents(
\DateTime::createFromImmutable($range->getStartDate()),
\DateTime::createFromImmutable($range->getEndDate()),
['hotel' => $hotel, 'hotelCode' => $hotelCode]
);
}
catch (DBALException $e) {
$events = [];
}
$this->resetChart($range, $config['key'], $config['number']);
$this->generateChart(
$events,
$config['key'],
$config['number']
); );
} }
catch (DBALException $e) {
$events = [];
}
$this->resetChart($range, $apiKey, $houseNumber);
if (count($events) > 0) {
$this->generateChart(
$events,
$apiKey,
$houseNumber
);
}
return true;
} }
/** /**
@@ -176,8 +154,6 @@ class GroupsSwissService implements SingletonInterface, LoggerAwareInterface
$itemCount++; $itemCount++;
} }
} }
$this->logger->info(sprintf('Published %d dates.', $itemCount));
} }
/** /**
@@ -211,9 +187,16 @@ class GroupsSwissService implements SingletonInterface, LoggerAwareInterface
*/ */
protected function addItem(array $item, $status, $apiKey, $houseNumber): void protected function addItem(array $item, $status, $apiKey, $houseNumber): void
{ {
$this->logger->info(sprintf('Adding status %d in %s-%s for %s', $status, $item['from']->format('Y-m-d'), $item['to']->format('Y-m-d'), $houseNumber)); $this->logger->info(sprintf(
'Adding status %d in %s-%s for %s',
$status,
$item['from']->format('Y-m-d'),
$item['to']->format('Y-m-d'),
$houseNumber
));
$url = sprintf( $url = sprintf(
'http://www.groups.swiss/api/1.0/json.php?apiKey=%s&method=setAvailabilityChart&house=%d&from=%s&till=%s&state=%d', 'https://www.groups.swiss/api/1.0/json.php?apiKey=%s&method=setAvailabilityChart&house=%d&from=%s&till=%s&state=%d',
$apiKey, $apiKey,
$houseNumber, $houseNumber,
$item['from']->format('Y-m-d'), $item['from']->format('Y-m-d'),
@@ -222,7 +205,8 @@ class GroupsSwissService implements SingletonInterface, LoggerAwareInterface
); );
try { try {
$this->httpClient->request('GET', $url); $response = $this->httpClient->request('GET', $url);
$this->logger->info($response->getContent());
} catch (TransportExceptionInterface $e) { } catch (TransportExceptionInterface $e) {
$this->logger->error(sprintf('A problem occured: %s', $e->getMessage())); $this->logger->error(sprintf('A problem occured: %s', $e->getMessage()));
} }
@@ -1,51 +0,0 @@
<?php
namespace EP\EpProducts\Task;
/***************************************************************
*
* Copyright notice
*
* (c) 2020 Björn Fromme <[email protected]>, dreipunktnull
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use EP\EpProducts\Service\GroupsSwissService;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Configuration\Exception;
use TYPO3\CMS\Extbase\Object\ObjectManager;
use TYPO3\CMS\Scheduler\Task\AbstractTask;
class GroupsSwissTask extends AbstractTask
{
public function execute()
{
/** @var \TYPO3\CMS\Extbase\Object\ObjectManager $objectManager */
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
/** @var GroupsSwissService $groupsSwissService */
$groupsSwissService = $objectManager->get(GroupsSwissService::class);
try {
$groupsSwissService->publishContingents();
} catch (Exception $e) {
}
return true;
}
}
@@ -5,4 +5,7 @@ return [
'class' => \EP\EpProducts\Command\ExportCommandController::class, 'class' => \EP\EpProducts\Command\ExportCommandController::class,
'scheduleable' => false, 'scheduleable' => false,
], ],
'ep:groups-swiss' => [
'class' => \EP\EpProducts\Command\GroupsSwissCommand::class,
],
]; ];