Skip to content

Commit

Permalink
Pre
Browse files Browse the repository at this point in the history
  • Loading branch information
h4kuna committed Feb 13, 2024
1 parent 9a515cc commit c51500a
Show file tree
Hide file tree
Showing 40 changed files with 1,267 additions and 945 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ $exchangeFactory = new Exchange\ExchangeFactory(
'USD',
'eur', // lower case will be changed to upper case
],
cacheFactory: $cacheFactory
cache: $cacheFactory
);

$exchange = $exchangeFactory->create();
Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@
"php": ">=8.0",
"h4kuna/critical-cache": "^v0.1.3",
"h4kuna/data-type": "^v3.0.7",
"h4kuna/serialize-polyfill": "^0.2.2",
"malkusch/lock": "^2.2",
"psr/http-client": "^1.0",
"psr/http-factory": "^1.0",
"psr/http-message": "^1.0 || ^2.0"
},
"require-dev": {
"guzzlehttp/psr7": "^2.4",
"guzzlehttp/guzzle": "^7.5",
"guzzlehttp/psr7": "^2.4",
"h4kuna/dir": "^0.1.2",
"mockery/mockery": "^1.6",
"nette/caching": "^3.2",
"nette/tester": "^2.5",
"phpstan/phpstan": "^1.10",
Expand Down
2 changes: 1 addition & 1 deletion examples/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
'USD',
'eur', // lower case will be changed to upper case
],
cacheFactory: $cacheFactory
cache: $cacheFactory
);

$exchange = $exchangeFactory->create();
Expand Down
5 changes: 1 addition & 4 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ parameters:
- tests/bootstrap.php
checkGenericClassInNonGenericObjectType: false
ignoreErrors:
-
message: "#^Expression \"\\$ratingList\\['QWE'\\]\" on a separate line does not do anything\\.$#"
count: 1
path: tests/src/RatingList/RatingListTest.php
- "#^Call to an undefined method Mockery\\.*#"

includes:
- vendor/phpstan/phpstan-strict-rules/rules.neon
20 changes: 20 additions & 0 deletions src/Download/SourceData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php declare(strict_types=1);

namespace h4kuna\Exchange\Download;

use DateTimeImmutable;

final class SourceData
{
/**
* @param iterable<mixed> $properties
*/
public function __construct(
public DateTimeImmutable $date,
public string $refresh,
public iterable $properties,
)
{
}

}
88 changes: 88 additions & 0 deletions src/Download/SourceDownload.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php declare(strict_types=1);

namespace h4kuna\Exchange\Download;

use DateTime;
use DateTimeImmutable;
use DateTimeInterface;
use h4kuna\Exchange\Driver\Source;
use h4kuna\Exchange\RatingList\RatingList;
use h4kuna\Exchange\Utils;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestFactoryInterface;
use Psr\Http\Message\RequestInterface;
use ReflectionClass;

final class SourceDownload implements SourceDownloadInterface
{
/**
* @var array<string, SourceData>
*/
private array $cache = [];


/**
* @param array<string, int> $allowedCurrencies
*/
public function __construct(
private ClientInterface $client,
private RequestFactoryInterface $requestFactory,
private array $allowedCurrencies = [],
)
{
}


private static function makeKey(Source $sourceExchange, ?DateTimeImmutable $date): string
{
$rf = new ReflectionClass($sourceExchange);
do {
$class = $rf->getName();
$rf = $rf->getParentClass();
} while ($rf !== false);

if ($date === null) {
$date = new DateTimeImmutable('now', $sourceExchange->getTimeZone());
}

return $class . '.' . $date->format('Y-m-d');
}


public function execute(Source $sourceExchange, ?DateTimeInterface $date): RatingList
{
$date = Utils::toImmutable($date, $sourceExchange->getTimeZone());
$key = self::makeKey($sourceExchange, $date);

$sourceData = $this->cache[$key]
?? $this->cache[$key] = $sourceExchange->createSourceData(
$this->client->sendRequest(
$this->createRequest($sourceExchange, $date)
)
);

$expire = $date === null ? new DateTime($sourceData->refresh . sprintf(', +%s seconds', Utils::CacheMinutes), $sourceExchange->getTimeZone()) : null;

$properties = [];
foreach ($sourceData->properties as $item) {
$property = $sourceExchange->createProperty($item);
if ($property->rate === 0.0 || ($this->allowedCurrencies !== [] && isset($this->allowedCurrencies[$property->code]) === false)) {
continue;
}

$properties[$property->code] = $property;
}

return new RatingList($sourceData->date, $date, $expire, $properties);
}


private function createRequest(Source $sourceExchange, ?DateTimeInterface $date): RequestInterface
{
$request = $this->requestFactory->createRequest('GET', $sourceExchange->makeUrl($date));
$request->withHeader('X-Powered-By', 'h4kuna/exchange');

return $request;
}

}
17 changes: 17 additions & 0 deletions src/Download/SourceDownloadInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php declare(strict_types=1);

namespace h4kuna\Exchange\Download;

use DateTimeInterface;
use h4kuna\Exchange\Driver\Source;
use h4kuna\Exchange\RatingList\RatingList;
use Psr\Http\Client\ClientExceptionInterface;

interface SourceDownloadInterface
{

/**
* @throws ClientExceptionInterface
*/
function execute(Source $sourceExchange, ?DateTimeInterface $date): RatingList;
}
62 changes: 36 additions & 26 deletions src/Driver/Cnb/Day.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,65 @@

namespace h4kuna\Exchange\Driver\Cnb;

use DateTimeInterface;
use DateTimeZone;
use h4kuna\Exchange;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestFactoryInterface;
use h4kuna\Exchange\Download\SourceData;
use h4kuna\Exchange\Utils;
use Psr\Http\Message\ResponseInterface;

/**
* @extends Exchange\Driver\Driver<string, Property>
*/
class Day extends Exchange\Driver\Driver
class Day implements Exchange\Driver\Source
{
// private const URL_DAY_OTHER = 'http://www.cnb.cz/cs/financni_trhy/devizovy_trh/kurzy_ostatnich_men/kurzy.txt';

public static string $url = 'https://www.cnb.cz/cs/financni_trhy/devizovy_trh/kurzy_devizoveho_trhu/denni_kurz.txt';

private DateTimeZone $timeZone;


public function __construct(
ClientInterface $client,
RequestFactoryInterface $requestFactory,
string $timeZone = 'Europe/Prague',
string $refresh = 'today 14:45:00',
string|DateTimeZone $timeZone = 'Europe/Prague',
private string $refresh = 'today 14:30:00',
)
{
parent::__construct($client, $requestFactory, $timeZone, $refresh);
$this->timeZone = Utils::createTimeZone($timeZone);
}


public function getTimeZone(): DateTimeZone
{
return $this->timeZone;
}


protected function createList(ResponseInterface $response): iterable
public function makeUrl(?DateTimeInterface $date): string
{
$url = self::$url;

if ($date === null) {
return $url;
}

return "$url?" . http_build_query([
'date' => $date->format('d.m.Y'),
]);
}


public function createSourceData(ResponseInterface $response): SourceData
{
$data = $response->getBody()->getContents();
$list = explode("\n", Exchange\Utils::stroke2point($data));
$list = explode("\n", Utils::stroke2point($data));
$list[1] = 'Česká Republika|koruna|1|CZK|1';

$this->setDate('!d.m.Y', explode(' ', $list[0])[0]);
$date = Utils::createFromFormat('!d.m.Y', explode(' ', $list[0])[0], $this->timeZone);
unset($list[0]);

return $list;
return new SourceData($date, $this->refresh, $list);
}


protected function createProperty($row): Property
public function createProperty(mixed $row): Property
{
assert(is_string($row));
$currency = explode('|', $row);

return new Property(
Expand All @@ -54,12 +72,4 @@ protected function createProperty($row): Property
);
}


protected function prepareUrl(?\DateTimeInterface $date): string
{
$url = self::$url;

return $date === null ? $url : "$url?date=" . urlencode($date->format('d.m.Y'));
}

}
113 changes: 0 additions & 113 deletions src/Driver/Driver.php

This file was deleted.

10 changes: 0 additions & 10 deletions src/Driver/DriverAccessor.php

This file was deleted.

0 comments on commit c51500a

Please sign in to comment.