#meta developer: @matubuntu
import requests, bs4
from datetime import datetime
from .. import loader, utils
import lxml
# requires: lxml requests bs4
_FLAGS = {
"AUD": "🇦🇺",
"AZN": "🇦🇿",
"GBP": "🇬🇧",
"AMD": "🇦🇲",
"BYN": "🇧🇾",
"BGN": "🇧🇬",
"BRL": "🇧🇷",
"HUF": "🇭🇺",
"VND": "🇻🇳",
"HKD": "🇭🇰",
"GEL": "🇬🇪",
"DKK": "🇩🇰",
"AED": "🇦🇪",
"USD": "🇺🇸",
"EUR": "🇪🇺",
"EGP": "🇪🇬",
"INR": "🇮🇳",
"IDR": "🇮🇩",
"KZT": "🇰🇿",
"CAD": "🇨🇦",
"QAR": "🇶🇦",
"KGS": "🇰🇬",
"CNY": "🇨🇳",
"MDL": "🇲🇩",
"NZD": "🇳🇿",
"NOK": "🇳🇴",
"PLN": "🇵🇱",
"RON": "🇷🇴",
"SGD": "🇸🇬",
"TJS": "🇹🇯",
"THB": "🇹🇭",
"TRY": "🇹🇷",
"TMT": "🇹🇲",
"UZS": "🇺🇿",
"UAH": "🇺🇦",
"CZK": "🇨🇿",
"SEK": "🇸🇪",
"CHF": "🇨🇭",
"RSD": "🇷🇸",
"ZAR": "🇿🇦",
"KRW": "🇰🇷",
"JPY": "🇯🇵",
}
_CRYPTO_EMOJIS = {
"BTC": "
{}" ), "valute_specific": ( "💵 Курс валюты с сайта ЦБ(РФ)\n" "Актуально на {}\n\n{}" ), "valute_not_found": "🚫 Валюта {} не найдена", "crypto_description": "<кол-во> <код> - курс крипты\n<кол-во> - список", "crypto_no_args": "💎 Курсы криптовалют\n\n
{}", "crypto_specific": "💎 Курс криптовалюты\n\n{}", "crypto_not_found": "🚫 Криптовалюта {} не найдена", "error": "🚫 Ошибка получения данных", } def __init__(self): self.config = loader.ModuleConfig( loader.ConfigValue( "crypto_currency", "USD", lambda: "Валюта для отображения крипты (USD, RUB, EUR)", validator=loader.validators.Choice(["USD", "RUB", "EUR"]) ) ) async def _get_curr_data(self): try: r = requests.get("https://www.cbr.ru/scripts/XML_daily.asp") s = bs4.BeautifulSoup(r.content, 'xml') d = datetime.strptime(s.ValCurs['Date'], "%d.%m.%Y").strftime("%d.%m.%Y") return d, s.find_all('Valute') except: return None, None async def _get_rates(self): try: r = requests.get("https://www.cbr.ru/scripts/XML_daily.asp") s = bs4.BeautifulSoup(r.content, 'xml') rt = {'USD': None, 'EUR': None} for v in s.find_all('Valute'): if v.CharCode.text in ['USD', 'EUR']: n = float(v.Nominal.text.replace(',', '.')) vl = float(v.Value.text.replace(',', '.')) rt[v.CharCode.text] = vl / n if rt['USD'] and rt['EUR']: rt['EUR_USD'] = rt['USD'] / rt['EUR'] else: rt['EUR_USD'] = None return rt except: return None async def _fmt_curr(self, v, a=1): if v.CharCode.text == "XDR": return None c = v.CharCode.text n = v.Name.text v = float(v.Value.text.replace(',', '.')) / float(v.Nominal.text.replace(',', '.')) t = v * a ts = _fmt_num(t, 3) return f"{_FLAGS.get(c, '🏳')} [{a}] {n} ({c}) - {ts} руб." async def _get_crypto(self): try: return requests.get("https://api.coinlore.net/api/tickers/").json().get('data', []) except: return None async def _fmt_crypto(self, c, a=1): r = await self._get_rates() if not r: return "🚫 Ошибка получения курсов валют" cr = self.config["crypto_currency"] try: p = float(c['price_usd']) except: return "🚫 Ошибка данных криптовалюты" if cr == "RUB": if not r['USD']: return "🚫 Курс USD не найден" p *= r['USD'] elif cr == "EUR": if not r['EUR_USD']: return "🚫 Курс EUR/USD не рассчитан" p *= r['EUR_USD'] t = p * a ts = _fmt_num(t) s = c['symbol'].upper() e = _CRYPTO_EMOJIS.get(s, "💠") n = _CRYPTO_LIST.get(s, c['name']) cs = {"USD": "$", "RUB": "₽", "EUR": "€"}.get(cr, "$") return f"{e} [{a}] {n} ({s}) - {ts}{cs}" @loader.command() async def valutecmd(self, m): """[count] [usd, eur, ...]""" a = utils.get_args(m) d, v = await self._get_curr_data() if not d or not v: return await utils.answer(m, self.strings["error"]) if len(a) == 0: l = [] for x in v: if (n := await self._fmt_curr(x)): l.append(n) await utils.answer(m, self.strings["valute_no_args"].format(d, "\n".join(l))) elif len(a) == 1: try: am = float(a[0]) l = [] for x in v: if (n := await self._fmt_curr(x, am)): l.append(n) await utils.answer(m, self.strings["valute_no_args"].format(d, "\n".join(l))) except: await utils.answer(m, "🚫 Некорректное число") elif len(a) == 2: try: am = float(a[0]) c = a[1].upper() for x in v: if x.CharCode.text == c: if (n := await self._fmt_curr(x, am)): return await utils.answer(m, self.strings["valute_specific"].format(d, n)) await utils.answer(m, self.strings["valute_not_found"].format(c)) except: await utils.answer(m, "🚫 Некорректное число") @loader.command() async def cryptocmd(self, m): """[count] [ton, btc, ...]""" a = utils.get_args(m) c = await self._get_crypto() if not c: return await utils.answer(m, self.strings["error"]) try: if len(a) == 0: f = [x for x in c if x['symbol'].upper() in _CRYPTO_LIST] l = [] for x in f: if (n := await self._fmt_crypto(x)): l.append(n) await utils.answer(m, self.strings["crypto_no_args"].format("\n".join(l))) elif len(a) == 1: am = float(a[0]) f = [x for x in c if x['symbol'].upper() in _CRYPTO_LIST] l = [] for x in f: if (n := await self._fmt_crypto(x, am)): l.append(n) await utils.answer(m, self.strings["crypto_no_args"].format("\n".join(l))) elif len(a) == 2: am = float(a[0]) t = a[1].upper() f = False for x in c: if x['symbol'].upper() == t: if (n := await self._fmt_crypto(x, am)): f = True await utils.answer(m, self.strings["crypto_specific"].format(n)) break if not f: await utils.answer(m, self.strings["crypto_not_found"].format(t)) except ValueError: await utils.answer(m, "🚫 Некорректное число") except Exception as e: await utils.answer(m, f"🚫 Ошибка: {str(e)}")