Compare commits

...

3 commits

6 changed files with 98 additions and 43 deletions

View file

@ -4,12 +4,13 @@ from datetime import datetime
from decimal import Decimal
from http import HTTPStatus
import pytz
import aiohttp
import yaml
from utils.format_number import format_number
config = yaml.safe_load(open('config.yaml'))
config = yaml.safe_load(open('config.yaml', 'r', encoding='utf-8'))
class Converter:
def __init__(self):
@ -24,9 +25,23 @@ class Converter:
self.conv_amount = format_number(Decimal(self.conv_amount))
async def get_timezone(self) -> str:
async with aiohttp.ClientSession(
timeout=aiohttp.ClientTimeout(total=3)
) as session:
async with session.get(
f'{config['kekkai_instance']}/api/metadata'
) as res:
if not HTTPStatus(res.status).is_success:
return 'UTC'
data = await res.json()
return data.get('timezone', 'UTC')
async def kekkai(self) -> bool:
date = datetime.today().strftime('%Y-%m-%d')
timezone = pytz.timezone(await self.get_timezone())
date = datetime.now(timezone).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={
@ -45,7 +60,9 @@ class Converter:
async def ddg(self) -> None:
async with aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=3)) as session:
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}'
@ -59,12 +76,16 @@ class Converter:
data.pop(key, None)
if not data.get('to'):
raise RuntimeError('Failed to get the exchange rate from DuckDuckGo')
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')
raise RuntimeError(
'Error when converting currency via DuckDuckGo'
)
self.conv_amount = float(conv_amount)

View file

@ -1,13 +1,14 @@
from http import HTTPStatus
import yaml
import aiohttp
from http import HTTPStatus
config = yaml.safe_load(open('config.yaml'))
config = yaml.safe_load(open('config.yaml', 'r', encoding='utf-8'))
async def create_chart(from_currency: str, conv_currency: str) -> (dict, None):
async with aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=3)) as session:
async with session.get(f'{config["kekkai_instance"]}/api/getChart/month/', params={
async with session.get(
f'{config["kekkai_instance"]}/api/getChart/month/', params={
'from_currency': from_currency,
'conv_currency': conv_currency
}) as res:

65
main.py
View file

@ -1,8 +1,4 @@
from functions.convert import Converter
from utils.format_number import format_number
from utils.inline_query import reply
from functions.create_chart import create_chart
import hashlib
import yaml
from aiohttp import web
@ -13,10 +9,16 @@ from aiogram.enums import ParseMode
from aiogram.webhook.aiohttp_server import SimpleRequestHandler, setup_application
from aiogram.filters import CommandStart
import hashlib
from functions.convert import Converter
from functions.create_chart import create_chart
from utils.format_number import format_number
from utils.inline_query import reply
config = yaml.safe_load(open('config.yaml'))
bot = Bot(token=config['telegram_token'], default=DefaultBotProperties(parse_mode=ParseMode.HTML))
config = yaml.safe_load(open('config.yaml', 'r', encoding='utf-8'))
bot = Bot(
token=config['telegram_token'],
default=DefaultBotProperties(parse_mode=ParseMode.HTML)
)
router = Router()
@ -57,13 +59,26 @@ async def currency(query: types.InlineQuery) -> None:
try:
conv.amount = float(args[0].replace(',', '.'))
if conv.amount < 0:
return await reply(result_id, [("Negative amounts are not supported.", None, None)], query)
return await reply(
result_id,
[
("Negative amounts are not supported.", None, None)
],
query
)
except ValueError:
return await reply(result_id, [("Please enter a valid number for the amount.",
return await reply(
result_id,
[
(
"Please enter a valid number for the amount.",
f'@{get_bot.username} USD RUB \n'
f'@{get_bot.username} 12 USD RUB',
None, None)], query)
None, None
)
],
query)
from_currency = args[1]
conv_currency = args[2]
@ -71,23 +86,37 @@ async def currency(query: types.InlineQuery) -> None:
from_currency = args[0]
conv_currency = args[1]
else:
return await reply(result_id,
[(
return await reply(
result_id,
[
(
'The source and target currency could not be determined.',
None, None
)],
query)
)
],
query
)
conv.from_currency = from_currency.upper()
conv.conv_currency = conv_currency.upper()
try:
await conv.convert()
except RuntimeError as e:
return await reply(result_id, [('The currency exchange rate could not be determined', None, None)], query)
except RuntimeError:
return await reply(
result_id,
[
(
'The currency exchange rate could not be determined',
None, None
)
],
query
)
chart = await create_chart(from_currency, conv_currency)
message = f'{format_number(conv.amount)} {conv.from_currency} = {conv.conv_amount} {conv.conv_currency}'
message = f'{format_number(conv.amount)} {conv.from_currency} ' \
f'= {conv.conv_amount} {conv.conv_currency}'
results = [(message, None, None)]

View file

@ -1,3 +1,4 @@
aiohttp~=3.9.5
PyYAML~=6.0.1
aiogram~=3.15.0
pytz~=2025.2

View file

@ -11,7 +11,10 @@ def format_number(number):
return formatted_integer
fractional_str = f"{fractional_part:.30f}".split('.')[1]
first_non_zero = next((i for i, char in enumerate(fractional_str) if char != '0'), len(fractional_str))
first_non_zero = next(
(i for i, char in enumerate(fractional_str) if char != '0'),
len(fractional_str)
)
result_fractional = fractional_str[:first_non_zero + 3]
result_fractional = result_fractional.rstrip('0')

View file

@ -1,7 +1,7 @@
from aiogram import types
import re
from aiogram import types
async def reply(result_id: str, args: list, query: types.InlineQuery) -> None:
if not args:
return