85 lines
3.0 KiB
Python
85 lines
3.0 KiB
Python
import datetime
|
|
import os
|
|
from typing import List, Dict, Tuple, Union, Type
|
|
|
|
import boto3
|
|
from boto3.dynamodb.conditions import Key
|
|
|
|
from wow_token.db.trinity import Trinity
|
|
from wow_token.db.year_month import YearMonth
|
|
from wow_token.db.cache import Cache
|
|
from wow_token.region import Region
|
|
|
|
# TODO: Reduce Compacted Table Sprawl
|
|
|
|
REGION_MAP = {
|
|
'us-west-1': 'us-west-1',
|
|
'us-west-2': 'us-west-2',
|
|
'us-east-1': 'us-east-1',
|
|
'us-east-2': 'us-east-2',
|
|
'ap-south-1': 'eu-north-1',
|
|
'ap-northeast-3': 'ap-northeast-1',
|
|
'ap-northeast-2': 'ap-northeast-1',
|
|
'ap-southeast-1': 'ap-southeast-1',
|
|
'ap-southeast-2': 'ap-southeast-2',
|
|
'ap-northeast-1': 'ap-northeast-1',
|
|
'ca-central-1': 'us-east-1',
|
|
'eu-central-1': 'eu-north-1',
|
|
'eu-west-1': 'eu-west-1',
|
|
'eu-west-2': 'eu-west-1',
|
|
'eu-west-3': 'eu-west-3',
|
|
'eu-north-1': 'eu-north-1',
|
|
'sa-east-1': 'sa-east-1',
|
|
'eu-south-1': 'eu-north-1'
|
|
}
|
|
|
|
|
|
def _region_selector():
|
|
if os.environ['AWS_REGION'] in REGION_MAP:
|
|
local_region = REGION_MAP[os.environ['AWS_REGION']]
|
|
else:
|
|
local_region = 'eu-central-1'
|
|
return local_region
|
|
|
|
|
|
def _data_as_str(data: List[Tuple[datetime.datetime, int]]) -> List[Tuple[str, int]]:
|
|
data_as_str = []
|
|
for timestamp, price in data:
|
|
data_as_str.append((timestamp.isoformat(), price))
|
|
return data_as_str
|
|
|
|
|
|
class Compacted:
|
|
_cache : Cache
|
|
def __init__(self):
|
|
self._ddb = boto3.resource('dynamodb', region_name=_region_selector())
|
|
self._table = self._ddb.Table('wow-token-compacted')
|
|
self._cache = Cache(self)
|
|
|
|
def ddb_get_data(self, trinity: Trinity, _type: Union[Type[str], Type[datetime.datetime]] = datetime.datetime) -> Union[List[Tuple[datetime.datetime, int]], List[Tuple[str, int]]]:
|
|
data = []
|
|
response = self._table.query(
|
|
KeyConditionExpression=Key('region-flavor-timestamp').eq(str(trinity))
|
|
)
|
|
if response['Items']:
|
|
for timestamp, price in response['Items'][0]['data'].items():
|
|
date_time = datetime.datetime.fromtimestamp(int(timestamp), datetime.UTC)
|
|
if _type == str:
|
|
date_time = date_time.isoformat()
|
|
data.append((
|
|
date_time,
|
|
int(price)
|
|
))
|
|
return sorted(data, key=lambda x: x[0])
|
|
|
|
def get_month(self, trinity: Trinity, _type: Union[Type[str], Type[datetime.datetime]] = datetime.datetime) -> Union[List[Tuple[datetime.datetime, int]], List[Tuple[str, int]]]:
|
|
if _type == str:
|
|
return _data_as_str(self._cache.get_month(trinity))
|
|
return self._cache.get_month(trinity)
|
|
|
|
def get_precomputed_range(self, trinity: Trinity, _type: Union[Type[str], Type[datetime.datetime]] = datetime.datetime) -> Union[List[Tuple[datetime.datetime, int]], List[Tuple[str, int]]]:
|
|
if isinstance(trinity.range, YearMonth):
|
|
return self.get_month(trinity, _type=_type)
|
|
else:
|
|
return self.ddb_get_data(trinity, _type=_type)
|