async def handle(self, message: types.Message, user: UserRepository, _: dict): user_accounts = await user.get_accounts(message.from_user.id) keyboard_markup = types.InlineKeyboardMarkup(row_width=1) message_text = _['cabinet_msg'] if (len(user_accounts) == 0): message_text += "\n\n" + _['add_account'] else: for i, account in enumerate(user_accounts): keyboard_markup.add( types.InlineKeyboardButton( f'#{i + 1} - {account.username}', callback_data=menu_cb.new(id=account.account_id, type="account", action='open'), )) keyboard_markup.add( types.InlineKeyboardButton( _['add_account_btn'], callback_data=menu_cb.new(id='_', type="account", action='new'), )) await message.answer(message_text.format( account_count=len(user_accounts), ), reply_markup=keyboard_markup)
async def cabinet_callback_handler( query: types.CallbackQuery, callback_data: typing.Dict[str, str], user: UserRepository, _: dict, ): user_accounts = await user.get_accounts(query.from_user.id) keyboard_markup = types.InlineKeyboardMarkup(row_width=1) message_text = _["cabinet_msg"] if len(user_accounts) == 0: message_text += "\n\n" + _["add_account"] else: for i, account in enumerate(user_accounts): keyboard_markup.add( types.InlineKeyboardButton( f"#{i + 1} - {account.username}", callback_data=menu_cb.new(id=account.account_id, type="account", action="open"), )) keyboard_markup.add( types.InlineKeyboardButton( _["add_account_btn"], callback_data=menu_cb.new(id="_", type="account", action="new"), )) await query.message.edit_text( message_text.format(account_count=len(user_accounts), ), reply_markup=keyboard_markup, ) await query.answer()
async def delete_account_confirmation_callback_handler( query: types.CallbackQuery, callback_data: typing.Dict[str, str], user: UserRepository, _: dict, ): account_id = callback_data["id"] keyboard_markup = types.InlineKeyboardMarkup(row_width=2) keyboard_markup.add( types.InlineKeyboardButton( _["back_to_account_list_button"], callback_data=menu_cb.new( id="_", type="menu", action="main_menu" ), ), ) await user.delete_account_notification_settings_account(account_id, query.from_user.id) await user.delete_user_account_coin(account_id, query.from_user.id) await user.delete_user_account(account_id, query.from_user.id) await query.message.edit_text( _['account_deleted_descr'], reply_markup=keyboard_markup, ) await query.answer()
def keyboard_when_account_deleted(_: LangHolder) -> types.InlineKeyboardMarkup: keyboard_markup = types.InlineKeyboardMarkup(row_width=2) keyboard_markup.add( types.InlineKeyboardButton( _["back_to_account_list_button"], callback_data=menu_cb.new(id="_", type="menu", action="main_menu"), ), ) return keyboard_markup
async def finance_callback_handler( query: types.CallbackQuery, callback_data: typing.Dict[str, str], user: UserRepository, _: LangHolder, ): account_id = callback_data["id"] page = int(callback_data["page"]) keyboard_markup = types.InlineKeyboardMarkup(row_width=2) account = next( (acc for acc in await user.get_accounts(query.from_user.id) if str(acc.account_id) == account_id), None, ) if (account is None): return await reply_to_account_not_found(query.message, _) btn_list = [] for coin in await user.get_account_coins(query.from_user.id, account_id): if coin.is_active: btn_list.append( types.InlineKeyboardButton( f"{Coin(coin.coin_id).name}", callback_data=finance_cb.new( id=account_id, type=coin.coin_id, action="payouts", page=page, ), ), ) for i in grouper(2, btn_list): keyboard_markup.add(*i) keyboard_markup.add( types.InlineKeyboardButton( _['back_to_account_button'], callback_data=menu_cb.new(id=account.account_id, type="account", action='open'), ), ) await query.message.edit_text( _["finance_choose_coin"], reply_markup=keyboard_markup, ) await query.answer()
async def handle(self, message: types.Message, user: UserRepository, _: dict, state: FSMContext, logger: LoggerAdapter): account_id = message.text await state.finish() if (validate_uuid4(account_id)): user_account = await user.get_accounts(message.from_user.id) exist_account = next( (acc for acc in user_account if str(acc.account_id) == account_id), None) if (not exist_account): async with EmcdClient(account_id, logger) as client: account = await client.get_info() if (account): await user.add_account(message.from_user.id, account_id, account.username) coins_api = account.get_coins() for coin in await user.get_coins(message.from_user.id): c = coins_api[coin.coin_id] await user.add_account_coin( message.from_user.id, account_id, coin.coin_id, c, coin.is_enabled) await message.answer(_['account_added'].format( account_name=account.username)) return else: await message.answer(_['account_id_already_registered'].format( account_name=exist_account.username)) return keyboard_markup = types.InlineKeyboardMarkup(row_width=1) keyboard_markup.add( types.InlineKeyboardButton( _['again_button'], callback_data=menu_cb.new(id='_', type="account", action='new'), )) await message.answer(_['account_id_invalid'], reply_markup=keyboard_markup)
async def handle(self, message: types.Message, user: UserRepository, _: dict): inline_keyboard_markup = types.InlineKeyboardMarkup(row_width=2) inline_keyboard_markup.row( types.InlineKeyboardButton( _["delete_account"], callback_data=delete_account_cb.new(id="_", action="choose"), ), types.InlineKeyboardButton( _['language'], callback_data=lang_cb.new(id="_", ), ), ) inline_keyboard_markup.row( types.InlineKeyboardButton( _["notifcation_button"], callback_data=notification_cb.new(action="_", ), ), types.InlineKeyboardButton( _['change_coins_button'], callback_data=menu_cb.new(id="_", type="account", action="c_coins"), ), ) inline_keyboard_markup.row( types.InlineKeyboardButton( _["notifcation_payout_button"], callback_data=notification_payout_cb.new(action="_", ), ), types.InlineKeyboardButton( _["curr_list_button"], callback_data=currency_cb.new( action="open", id="_", ), ), ) await message.answer(_['setting_descr'], reply_markup=inline_keyboard_markup)
async def account_cabinet_callback_handler( query: types.CallbackQuery, callback_data: typing.Dict[str, str], user: UserRepository, _: LangHolder, ): # id=account.account_id, type="account", action='open' account_id = callback_data["id"] keyboard_markup = types.InlineKeyboardMarkup(row_width=2) action_type = SELECT_COIN_CB account = next( (acc for acc in await user.get_accounts(query.from_user.id) if str(acc.account_id) == str(account_id)), None, ) if (account is None): return await reply_to_account_not_found(query.message, _) coins = [ coin for coin in await user.get_account_coins( query.from_user.id, account_id) if coin.is_active ] if (len(coins) == 1 ): #in case if enabled only one coin we treat them as default action_type = coins[0].coin_id keyboard_markup.add( types.InlineKeyboardButton( _["workers_stat_button"], callback_data=worker_cb.new( id=account_id, page=1, type=action_type, status_id=3, ), ), types.InlineKeyboardButton( _["workers_black_list_button"], callback_data=worker_black_cb.new( id=account_id, page=1, type=action_type, action="_", ), ), ) keyboard_markup.add( types.InlineKeyboardButton( _["statistic_button"], callback_data=statistic_cb.new( id=account_id, type=action_type, ), ), types.InlineKeyboardButton( _["finance_button"], callback_data=finance_cb.new( id=account_id, type=action_type, action="_" if action_type == SELECT_COIN_CB else "payouts", page=1, #id=account_id, type=coin.coin_id, action=, page=page, ), ), ) keyboard_markup.add( types.InlineKeyboardButton( _["back_to_account_list_button"], callback_data=menu_cb.new(id="_", type="menu", action="main_menu"), ), ) await query.message.edit_text( _["account_cabinet"].format(account_name=account.username), reply_markup=keyboard_markup, ) await query.answer()
async def payouts_info_callback_handler( query: types.CallbackQuery, callback_data: typing.Dict[str, str], user: UserRepository, _: LangHolder, logger: logging.Logger, ): account_id = callback_data["id"] coind_id = callback_data['type'] page = int(callback_data['page']) coin_name = Coin(coind_id).name.lower() keyboard_markup = types.InlineKeyboardMarkup(row_width=2) account = next( (acc for acc in await user.get_accounts(query.from_user.id) if str(acc.account_id) == account_id), None, ) if (account is None): await query.answer() return await reply_to_account_not_found(query.message, _) payouts = None async with EmcdClient(account_id, logger) as client: payouts = await client.get_payouts(coind_id) if (payouts is None): await query.answer() logger.warning('payouts is none') return message_text = _['payouts'] buttons = [] if (page > 1): buttons.append( types.InlineKeyboardButton( _["prev_button"], callback_data=payouts_cb.new( id=account_id, page=page - 1, type=coind_id, ), ), ) if (payouts.payouts): buttons.append( types.InlineKeyboardButton( f"{page}/{ceil(len(payouts.payouts) / PER_PAGE_PAYOUTS)}", callback_data="do_nothing"), ) if (payouts): for payout in payouts.payouts[(page - 1) * PER_PAGE_PAYOUTS:page * PER_PAGE_PAYOUTS]: message_text += '\n' + _['payouts_template'].format( datetime=payout.gmt_time, amount=payout.amount, transaction_link= (f'<a href="https://blockchair.com/{coin_name}/transaction/{payout.txid}">{payout.txid[8:]}</a>' ) if payout.txid else _['no_link']) if (len(payouts.payouts) > page * PER_PAGE_PAYOUTS): buttons.append( types.InlineKeyboardButton( _["next_button"], callback_data=payouts_cb.new( id=account_id, page=page + 1, type=coind_id, ), ), ) keyboard_markup.row(*buttons) action_type = SELECT_COIN_CB coins = [ coin for coin in await user.get_account_coins( query.from_user.id, account_id) if coin.is_active ] if (len(coins) == 1 ): #in case if enabled only one coin we treat them as default action_type = coins[0].coin_id keyboard_markup.row( types.InlineKeyboardButton( _["income_stat_button"], callback_data=income_cb.new( id=account_id, page=1, type=coind_id, ), ), types.InlineKeyboardButton( _['back_to_account_button'], callback_data=menu_cb.new( id=account.account_id, type="account", action='open'), ) if len(coins) == 1 else types.InlineKeyboardButton( _["back_to_payouts"], callback_data=finance_cb.new( id=account_id, type=action_type, action=SELECT_COIN_CB, page= page, #id=account_id, type=coin.coin_id, action=, page=page, ), ), ) await query.message.edit_text( message_text, reply_markup=keyboard_markup, disable_web_page_preview=True, ) await query.answer()
async def worker_info_callback_handler( query: types.CallbackQuery, callback_data: typing.Dict[str, str], user: UserRepository, _: dict, logger: logging.Logger, ): account_id = callback_data["id"] coind_id = callback_data['type'] page = int(callback_data['page']) status_id = int(callback_data['status_id']) keyboard_markup = types.InlineKeyboardMarkup(row_width=2) workers = None async with EmcdClient(account_id, logger) as client: workers = await client.get_workers(coind_id) if (workers is None): await query.answer() logger.warning('workers is none') return message_text = "" buttons = [] if (page > 1): buttons.append( types.InlineKeyboardButton( _["prev_button"], callback_data=worker_cb.new( id=account_id, page=page - 1, type=coind_id, status_id=status_id, ), ), ) workers_normalized = workers.get_all_workers_by_status(0, status_id) if (workers_normalized): buttons.append( types.InlineKeyboardButton( f"{page}/{ceil(len(workers_normalized) / PER_PAGE_WORKERS)}", callback_data="do_nothing" ), ) locales = { 'hashrate': _['hashrate'], 'current': _['current'], '1_hour': _['1_hour'], '24_hour': _['24_hour'], } if (workers): for worker in workers_normalized[(page - 1) * PER_PAGE_WORKERS: page * PER_PAGE_WORKERS]: message_text += '\n' + format_worker_info(worker, locales) if (len(workers_normalized) > page * PER_PAGE_WORKERS): buttons.append( types.InlineKeyboardButton( _["next_button"], callback_data=worker_cb.new( id=account_id, page=page + 1, type=coind_id, status_id=status_id, ), ), ) keyboard_markup.row(*buttons) coins = [coin for coin in await user.get_account_coins(query.from_user.id, account_id) if coin.is_active] filter_text = _['show_dead_workers'] new_status_id = WORKER_STATUS_CAROUSEL[status_id] if (new_status_id == -1): filter_text = _['show_dead_workers'] elif (new_status_id == 0): filter_text = _['show_inactive_workers'] elif (new_status_id == 1): filter_text = _['show_active_workers'] elif (new_status_id == 3): filter_text = _['show_all_workers'] if (len(coins) == 1): #in case if enabled only one coin we treat them as default keyboard_markup.row( types.InlineKeyboardButton( filter_text, callback_data=worker_cb.new( id=account_id, page=page, type=coind_id, status_id=new_status_id, ), ), types.InlineKeyboardButton( _["cabinet"], callback_data=menu_cb.new( id=account_id, type="account", action="open", ), ), ) else: keyboard_markup.row( types.InlineKeyboardButton( filter_text, callback_data=worker_cb.new( id=account_id, page=page, type=coind_id, status_id=new_status_id, ), ), types.InlineKeyboardButton( _["back_to_workers"], callback_data=worker_cb.new( id=account_id, page=page, type=SELECT_COIN_CB, status_id=status_id, ), ), ) workers_all = workers.get_all_workers(0) await query.message.edit_text( _['worker_info_descr'].format( hashrate=format_rate(workers.total_hashrate.hashrate), hashrate1h=format_rate(workers.total_hashrate.hashrate1_h), hashrate24h=format_rate(workers.total_hashrate.hashrate24_h), total=str(len(workers_all)) + (_['show_workers_filter_pointer'] if status_id == 3 else ''), dead=str(len([i for i in workers_all if i.status_id == -1])) + (_['show_workers_filter_pointer'] if status_id == -1 else ''), active=str(len([i for i in workers_all if i.status_id == 1])) + (_['show_workers_filter_pointer'] if status_id == 1 else ''), inactive=str(len([i for i in workers_all if i.status_id == 0])) + (_['show_workers_filter_pointer'] if status_id == 0 else ''), description=message_text, ), reply_markup=keyboard_markup, ) await query.answer()
async def statistic_info_callback_handler( query: types.CallbackQuery, callback_data: typing.Dict[str, str], user: UserRepository, _: LangHolder, logger: logging.Logger, ): account_id = callback_data["id"] coin_id = callback_data['type'] keyboard_markup = types.InlineKeyboardMarkup(row_width=2) account = next( (acc for acc in await user.get_accounts(query.from_user.id) if str(acc.account_id) == account_id), None, ) if (account is None): await query.answer() return await reply_to_account_not_found(query.message, _) account_coin = next( (i for i in await user.get_account_coins(query.from_user.id, account_id) if i.coin_id == coin_id), None, ) buttons = [] coins = [ coin for coin in await user.get_account_coins( query.from_user.id, account_id) if coin.is_active ] if (len(coins) == 1 ): #in case if enabled only one coin we treat them as default buttons.append( types.InlineKeyboardButton( _["cabinet"], callback_data=menu_cb.new(id=account_id, type="account", action="open"), ), ) else: buttons.append( types.InlineKeyboardButton( _["back_to_statistic"], callback_data=statistic_cb.new( id=account_id, type=SELECT_COIN_CB, ), ), ) keyboard_markup.row(*buttons) account_api = None currency_list = None user_currency = await user.get_user_currency(query.from_user.id) async with EmcdClient(account_id, logger) as client: account_api = await client.get_info() if (account_api is None): await query.answer() logger.warning('account_api is none') return is_fallback = False async with CoinCapClient() as client: c_id = coin_id if (c_id == 'bchn'): c_id = 'bch' currency_list = await client.get_info_for_exchange( c_id, user_currency.currency_code) if (currency_list is None or len(currency_list.data) == 0): currency_list = await client.get_info_for_exchange( c_id, FALLBACK_CURRENCY) is_fallback = True if (currency_list is None): await query.answer('Please try later, 3rd party service is busy') logger.warning('currency_list is none') return curr = sorted(currency_list.data, key=take_update_timestamp)[0] coin_info = account_api.get_coins()[coin_id] message_text = "" if (is_fallback): message_text = _['currency_not_found'].format( currency_code=user_currency.currency_code, fallback_currency_code=FALLBACK_CURRENCY, ) + '\n' message_text += _['statistic_descr'].format( account_name=account.username, address=account_coin.address, current_balance=format(coin_info.balance, '.8f'), current_balance_dol=format_currency(round( coin_info.balance * curr.price_usd, 4), '', locale="en_US"), current_balance_sec=format_currency(round( coin_info.balance * curr.price_quote, 4), '', locale="en_US"), current_balance_sec_symbol=curr.quote_symbol, total_paid=format(coin_info.total_paid, '.8f'), total_paid_dol=format_currency(round( coin_info.total_paid * curr.price_usd, 4), '', locale="en_US"), total_paid_sec=format_currency(round( coin_info.total_paid * curr.price_quote, 4), '', locale="en_US"), total_paid_sec_symbol=curr.quote_symbol, currency_dol=format_currency(round(curr.price_usd, 2), '', locale="en_US"), currency_sec=format_currency(round(curr.price_quote, 2), '', locale="en_US"), currency_sec_symbol=curr.quote_symbol, ) await query.message.edit_text( message_text, reply_markup=keyboard_markup, ) await query.answer()
async def income_info_callback_handler( query: types.CallbackQuery, callback_data: typing.Dict[str, str], user: UserRepository, _: LangHolder, logger: logging.Logger, ): account_id = callback_data["id"] coind_id = callback_data['type'] page = int(callback_data['page']) keyboard_markup = types.InlineKeyboardMarkup(row_width=2) account = next( (acc for acc in await user.get_accounts(query.from_user.id) if str(acc.account_id) == account_id), None, ) if (account is None): await query.answer() return await reply_to_account_not_found(query.message, _) incomes = None async with EmcdClient(account_id, logger) as client: incomes = await client.get_rewards(coind_id) if (incomes is None): await query.answer() logger.warning('incomes is none') return message_text = _['income'] buttons = [] if (page > 1): buttons.append( types.InlineKeyboardButton( _["prev_button"], callback_data=income_cb.new( id=account_id, page=page - 1, type=coind_id, ), ), ) if (incomes.income): buttons.append( types.InlineKeyboardButton( f"{page}/{ceil(len(incomes.income) / PER_PAGE_INCOME)}", callback_data="do_nothing"), ) if (incomes): for income in incomes.income[(page - 1) * PER_PAGE_INCOME:page * PER_PAGE_INCOME]: message_text += '\n' + _['income_template'].format( datetime=income.gmt_time, amount=format(income.income, '.8f'), ) if (len(incomes.income) > page * PER_PAGE_INCOME): buttons.append( types.InlineKeyboardButton( _["next_button"], callback_data=income_cb.new( id=account_id, page=page + 1, type=coind_id, ), ), ) keyboard_markup.row(*buttons) action_type = SELECT_COIN_CB coins = [ coin for coin in await user.get_account_coins( query.from_user.id, account_id) if coin.is_active ] if (len(coins) == 1 ): #in case if enabled only one coin we treat them as default action_type = coins[0].coin_id keyboard_markup.row( types.InlineKeyboardButton( _["payouts_stat_button"], callback_data=payouts_cb.new( id=account_id, page=1, type=coind_id, ), ), types.InlineKeyboardButton( _['back_to_account_button'], callback_data=menu_cb.new( id=account.account_id, type="account", action='open'), ) if len(coins) == 1 else types.InlineKeyboardButton( _["back_to_income"], callback_data=finance_cb.new( id=account_id, type=action_type, action=SELECT_COIN_CB, page= page, #id=account_id, type=coin.coin_id, action=, page=page, ), ), ) await query.message.edit_text( message_text, reply_markup=keyboard_markup, ) await query.answer()
async def black_list_info_callback_handler( query: types.CallbackQuery, callback_data: typing.Dict[str, str], user: UserRepository, _: dict, logger: logging.Logger, state: FSMContext, ): account_id = callback_data["id"] coin_id = callback_data['type'] action = callback_data['action'] page = int(callback_data['page']) if (action != '_'): async with state.proxy() as data: worker_id = data.get('workers_unique', {}).get(action, None) if (worker_id): is_blacklisted = await user.toggle_worker_blacklist( query.from_user.id, worker_id) await query.answer(_['worker_blacklisted' if is_blacklisted else 'worker_not_blacklisted'].format( worker=worker_id, )) else: logger.warning( f'worker_id was null {data.get("workers_unique")}') await query.answer( 'If you see this message please contact with support', show_alert=True) keyboard_markup = types.InlineKeyboardMarkup(row_width=2) blacklisted_workers = [ w.worker_id for w in await user.get_blacklisted_workers(query.from_user.id) ] workers = None async with EmcdClient(account_id, logger) as client: workers = await client.get_workers(coin_id) if (workers is None): await query.answer() logger.warning('workers is none') return buttons = [] buttons_workers = [] if (page > 1): buttons.append( types.InlineKeyboardButton( _["prev_button"], callback_data=worker_black_cb.new(id=account_id, page=page - 1, type=coin_id, action="_"), ), ) workers_normalized = workers.get_all_workers(0, ) if (workers_normalized): buttons.append( types.InlineKeyboardButton( f"{page}/{ceil(len(workers_normalized) / PER_PAGE_BLACK_LIST)}", callback_data="do_nothing"), ) async with state.proxy() as data: data['workers_unique'] = generate_unique_workers_dict( workers_normalized) for worker in workers_normalized[(page - 1) * PER_PAGE_BLACK_LIST:page * PER_PAGE_BLACK_LIST]: buttons_workers.append( types.InlineKeyboardButton( worker.worker + (_["blacklist_pointer"] if worker.worker in blacklisted_workers else ""), callback_data=worker_black_cb.new( id=account_id, page=page, type=coin_id, action=worker.hash_name()), ), ) if (len(workers_normalized) > page * PER_PAGE_BLACK_LIST): buttons.append( types.InlineKeyboardButton( _["next_button"], callback_data=worker_black_cb.new(id=account_id, page=page + 1, type=coin_id, action="_"), ), ) for w_row in grouper(2, buttons_workers): keyboard_markup.row(*w_row) keyboard_markup.row(*buttons) coins = [ coin for coin in await user.get_account_coins( query.from_user.id, account_id) if coin.is_active ] if (len(coins) == 1 ): #in case if enabled only one coin we treat them as default keyboard_markup.row( types.InlineKeyboardButton( _["cabinet"], callback_data=menu_cb.new( id=account_id, type="account", action="open", ), ), ) else: keyboard_markup.row( types.InlineKeyboardButton( _["back_to_workers_blacklist"], callback_data=worker_black_cb.new( id=account_id, page=page, type=SELECT_COIN_CB, action="_", ), ), ) await query.message.edit_text( _['worker_blacklist_descr'].format( b_count=len(blacklisted_workers), pointer=_["blacklist_pointer"], ), reply_markup=keyboard_markup, ) await query.answer()