From 90c1717b6b87c4ddbc7dde9a0e63f789bedd7cc4 Mon Sep 17 00:00:00 2001 From: Redume Date: Wed, 8 Jan 2025 22:52:12 +0300 Subject: [PATCH] refactor(convert): Rewrote the requests to aiohttp. Reverted the old query algorithm, first kekkai, then ddg --- functions/convert.py | 74 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 functions/convert.py diff --git a/functions/convert.py b/functions/convert.py new file mode 100644 index 0000000..7c18700 --- /dev/null +++ b/functions/convert.py @@ -0,0 +1,74 @@ +from utils.format_number import format_number + +import yaml + +import aiohttp +import json +import re + +from datetime import datetime +from http import HTTPStatus +from decimal import Decimal, ROUND_DOWN +from utils.format_number import format_number + +config = yaml.safe_load(open('config.yaml')) + +class Converter: + def __init__(self): + self.amount: float = 1.0 + self.conv_amount: float = 0.0 + self.from_currency: str = '' + self.conv_currency: str = '' + + async def convert(self) -> None: + if not await self.kekkai(): + await self.ddg() + + number = Decimal(str(self.conv_amount)) + self.conv_amount = format_number(number.quantize(Decimal('1.0000'), rounding=ROUND_DOWN)) + + + async def kekkai(self) -> bool: + date = datetime.today().strftime('%Y-%m-%d') + + async with aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=3)) as session: + async with session.get(f'{config['kekkai_instance']}/api/getRate/', params={ + 'from_currency': self.from_currency, + 'conv_currency': self.conv_currency, + 'date': date, + 'conv_amount': self.amount + }, + timeout=3) as res: + if not HTTPStatus(res.status).is_success: + return False + + data = await res.json() + self.conv_amount = data.get('conv_amount', 0.0) + + return True + + + async def ddg(self) -> None: + async with aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=3)) as session: + async with session.get( + 'https://duckduckgo.com/js/spice/currency/' + f'{self.amount}/{self.from_currency}/{self.conv_currency}' + ) as res: + + data_text = await res.text() + + data = json.loads(re.findall(r'\(\s*(.*)\s*\);$', data_text)[0]) + + for key in ['terms', 'privacy', 'timestamp']: + data.pop(key, None) + + if len(data.get('to')) == 0: + raise RuntimeError('Failed to get the exchange rate from DuckDuckGo') + + conv = data.get('to')[0] + conv_amount = conv.get('mid') + + if conv_amount is None: + raise RuntimeError('Error when converting currency via DuckDuckGo') + + self.conv_amount = float(conv_amount)