diff --git a/bot/commands/__init__.py b/bot/commands/__init__.py index 0777435..681fe5d 100644 --- a/bot/commands/__init__.py +++ b/bot/commands/__init__.py @@ -1,10 +1,11 @@ from bot.commands.base import config_handlers as base_handlers from bot.commands.subscription import config_handlers as subscription_handlers from bot.commands.callback import config_handlers as callback_handlers - +from bot.commands.exchange import config_handlers as exchange_handlers handlers = [ base_handlers, subscription_handlers, - callback_handlers + callback_handlers, + exchange_handlers ] diff --git a/bot/commands/exchange.py b/bot/commands/exchange.py new file mode 100644 index 0000000..1f7d11e --- /dev/null +++ b/bot/commands/exchange.py @@ -0,0 +1,64 @@ +import logging + +from telegram import Update +from telegram.ext import CommandHandler, CallbackContext + +from bot.core import BotTelegramCore +from bot.utils import convert_dcr +from bot.exceptions import DcrDataAPIError, ExchangeAPIError + + +logging.basicConfig( + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', + level=logging.INFO) + +logger = logging.getLogger(__name__) + + +def dcr(update: Update, context: CallbackContext): + target_currency = None + dcr_amount = None + + try: + arg_0 = context.args[0] + if arg_0.isdigit(): + dcr_amount = float(arg_0) + else: + target_currency = arg_0.upper() + except IndexError: + dcr_amount = 1 + target_currency = "USD" + + try: + arg_1 = context.args[1] + if arg_1.isdigit(): + dcr_amount = float(arg_1) + else: + target_currency = arg_1.upper() + except IndexError: + if target_currency is None: + target_currency = "USD" + if dcr_amount is None: + dcr_amount = 1 + + try: + target_value = convert_dcr(dcr_amount, target_currency) + except ExchangeAPIError as e: + update.effective_message.reply_text(f"{e}") + return + except DcrDataAPIError as e: + update.effective_message.reply_text("Error requests data from " + "DCRData API.\n " + "Please contact my managers!") + update.effective_message.reply_text(f"{e}") + return + + message = f"{dcr_amount} DCR => {target_value:.2f} {target_currency}" + + update.effective_message.reply_text(message) + + +def config_handlers(instance: BotTelegramCore): + logger.info('Setting exchange commands...') + + instance.add_handler(CommandHandler("dcr", dcr)) diff --git a/bot/exceptions.py b/bot/exceptions.py new file mode 100644 index 0000000..fdee208 --- /dev/null +++ b/bot/exceptions.py @@ -0,0 +1,7 @@ + +class ExchangeAPIError(Exception): + pass + + +class DcrDataAPIError(Exception): + pass diff --git a/bot/utils.py b/bot/utils.py index d9574a4..d248b88 100644 --- a/bot/utils.py +++ b/bot/utils.py @@ -1,3 +1,8 @@ +import json + +import requests + +from bot.exceptions import DcrDataAPIError, ExchangeAPIError def build_menu(buttons, @@ -10,3 +15,28 @@ def build_menu(buttons, if footer_buttons: menu.append([footer_buttons]) return menu + + +def convert_dcr(dcr_amount: float, target_currency: str): + dcrdata_response = requests.get("https://dcrdata.decred.org/api/exchanges") + if dcrdata_response.status_code != 200: + raise DcrDataAPIError(dcrdata_response.content) + + dcr_to_usd_value = json.loads(dcrdata_response.content) + dcr_to_usd_value = dcr_to_usd_value.get("price") + + if target_currency == 'USD': + return dcr_amount*dcr_to_usd_value + + exchangerate_response = requests.get(f"https://api.exchangeratesapi.io/" + f"latest?base=USD" + f"&symbols={target_currency}") + if exchangerate_response.status_code != 200: + raise ExchangeAPIError(f"Currency {target_currency} is not valid!\n" + f"Choose one from " + f"https://api.exchangeratesapi.io/latest") + + usd_to_target_value = json.loads(exchangerate_response.content) + usd_to_target_value = usd_to_target_value.get("rates").get(target_currency) + + return dcr_amount*dcr_to_usd_value*usd_to_target_value diff --git a/requirements.txt b/requirements.txt index 36a73a2..4667e31 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,5 @@ python-decouple==3.3 mongoengine==0.18.2 python-telegram-bot==12.2.0 websocket-client==0.56.0 -pendulum==2.0.5 \ No newline at end of file +pendulum==2.0.5 +requests==2.22.0 \ No newline at end of file