def update_competitor_performance_from_table(competitor: Competitor, row=None): try: if row is None: data = UsersSheet.get_all_users() for row_number, row_data in enumerate(data, 2): if row_data[0] == competitor.legacy_number and row_data[1] == competitor.name: row = row_number competitor.performance = to_int(row_data[7]) competitor.save() break if row is None: logger.error(f'Cannot get new performance for competitor: {competitor} - cannot found record in gsheet') return cfg = get_config() new_perf = retrieve_data( cfg.spreadsheet_id, f'{cfg.spreadsheet_users_sheet}!H{row}' ) new_perf = to_int(new_perf, None) if new_perf is None: logger.error(f'Cannot get new performance for competitor: {competitor}') return competitor.performance = new_perf competitor.save() except: logger.exception(f'Error occurred while updating performance for competitor: {competitor}')
def daily_task_check(): try: config = get_config_document() n = datetime.now(tz=tz) if config.latest_daily_check: lc = mongo_time_to_local(config.latest_daily_check, tz) if (n - lc) > timedelta(hours=1): if 8 <= n.hour <= 21: logger.debug(f'Performing vacation check task at {n}') config.latest_daily_check = n config.save() daily_task() else: config.latest_daily_check = n config.save() config.reload() if config.latest_monthly_check: lc = mongo_time_to_local(config.latest_monthly_check, tz) if (n - lc) > timedelta(days=1): if n.day == 1: hr_logger.info(f'Performing monthly task at {n}') config.latest_monthly_check = n config.save() monthly_task() else: config.latest_monthly_check = n config.save() except KeyboardInterrupt: return except: logger.exception('Exception occurred while performing daily check')
def debug_delete_mes(message: Message): try: user = self.__get_or_register_user(message.chat.id, message.from_user) if len(user.states): associated_with: Competitor = user.check_association() if associated_with: if associated_with.status in ( COMPETITOR_STATUS.ACTIVE, COMPETITOR_STATUS.PASSIVE): associated_with.change_status( COMPETITOR_STATUS.UNAUTHORIZED) associated_with.save() user.delete() user = self.__get_or_register_user(message.chat.id, message.from_user) user.states = [self.__start_state] user.save() if blocked_check(message.chat, user): return self.__process_message(message, user) except: logger.exception("Error!")
def update_competitor_status(competitor: Competitor, upsert=False, all_data=None): try: cfg = get_config() if not all_data: data = UsersSheet.get_all_users() else: data = all_data updated = False row_number = 1 for row_number, row in enumerate(data, 2): if row[0] == competitor.legacy_number and row[1] == competitor.name: update_data( cfg.spreadsheet_id, f'{cfg.spreadsheet_users_sheet}!C{row_number}', values=[ [ Competitor.status_code_to_str_dict[competitor.status], ] ] ) updated = True break if not updated: if not upsert: logger.error(f"Cannot update record for competitor {competitor.name} ({competitor.legacy_number}) - table record not found") else: logger.warning(f"Cannot update record for competitor {competitor.name} ({competitor.legacy_number}) - table record not found. Performing upsert") UsersSheet.insert_competitor_in_table(competitor, at_row=row_number+1) except: logger.exception('Exception occurred while updating competitor status in gsheet')
def glog(text: str, severity=logging.INFO, at_row=None): try: cfg = get_config() if not cfg.spreadsheet_logs_sheet: hr_logger.error( 'Не вдалося надіслати лог в гуглтаблицю - у налаштуваннях відсутня назва листа' ) logger.error( 'Cannot insert log into a google sheet - sheet name is missing' ) return if at_row is None: stored_logs = LogsSheet.get_all_logs() if stored_logs is None: stored_logs = [] at_row = len(stored_logs) + 2 update_data( cfg.spreadsheet_id, f'{cfg.spreadsheet_logs_sheet}!A{at_row}:C', values=[[ datetime.now(tz=_k_tz).strftime('%d/%m/%Y %H:%M:%S (%Z)'), _logging_severity_to_str_dict[severity], text ]]) except: logger.exception( 'Exception occurred while uploading log to gsheet')
def get_id(message): try: t = 'This chat ID: ' + str(message.chat.id) self.bot.send_message(message.chat.id, t) except: logger.exception( 'Unexpected error while processing /get_id command')
def check_results(): try: ResultsSheet.synchronize_results(timedelta(days=1)) except KeyboardInterrupt: return except: logger.exception('Exception occurred while checking results')
def update_competitor_table_record(competitor: Competitor, all_data=None): try: cfg = get_config() if not all_data: data = UsersSheet.get_all_users() else: data = all_data updated = False row_number = 1 for row_number, row in enumerate(data, 2): if row[0] == competitor.legacy_number and row[1] == competitor.name: update_data( cfg.spreadsheet_id, f'{cfg.spreadsheet_users_sheet}!C{row_number}:G', values=[ [ Competitor.status_code_to_str_dict[competitor.status], competitor.level or '', competitor.matches or 0, competitor.wins or 0, competitor.losses or 0 ] ] ) # UsersSheet.update_competitor_performance_from_table( # competitor, # row_number # ) updated = True break if not updated: logger.error(f"Cannot update record for competitor {competitor.name} ({competitor.legacy_number}) - table record not found") except: logger.exception('Exception occurred while updating competitor in gsheet')
def text_handler(message): try: if self.botType == "fi": self.bot.send_chat_action(message.chat.id, 'typing') self.__bot_state_handler.handle_state_with_message(message) except Exception as e: print(e) logger.exception('[ERROR]')
def text_handler(message): try: user = self.__get_or_register_user(message.chat.id, message.from_user) if blocked_check(message.chat, user): return self.__process_message(message, user) except: logger.exception("Error!")
def callback_inline(reply: CallbackQuery): try: user = self.__get_or_register_user(reply.from_user.id, reply.from_user) if blocked_check(reply.message.chat, user): return self.__process_callback(reply, user) except: logger.exception("Error!")
def callback_inline(call): try: if call.data: if self.botType == "sec": self.bot.answer_callback_query(call.id) self.bot.send_chat_action(call.from_user.id, 'typing') self.__bot_state_handler.handle_state_with_message( call) print(call.data) except: logger.exception('[ERROR]')
def send_msg_to_admin(msg): try: cfg = get_config() if not cfg.admin_username: return bot = TeleBot(BOT_TOKEN, threaded=False) admin_user = User.objects(username=cfg.admin_username).first() if not admin_user: return bot.send_message(admin_user.user_id, msg, parse_mode='html') except: logger.exception('Error!')
def update_model_mes(message: Message): try: user = self.__get_or_register_user(message.chat.id, message.from_user) cfg = get_config() if user.username != cfg.admin_username: return UsersSheet.update_model() ResultsSheet.synchronize_results() self.bot.send_message(message.chat.id, 'Дані оновлено') except: logger.exception("Error!")
def __process_callback(self, callback, user): state_correct, current_state, c_name = self.__get_state( user_last_state(user, self.__start_state)) if not state_correct: user.states = [c_name] user.save() try: self.__process_ret_code( current_state.process_callback(callback, user, self.bot)) except: logger.exception( self.__get_state(user_last_state(user, 'Unknown state')))
def __process_message(self, message, user): state_correct, current_state, c_name = self.__get_state( user_last_state(user, self.__start_state)) if not state_correct: user.states = [c_name] user.save() try: self.__process_ret_code( current_state.process_message_with_buttons( message, user, self.bot)) except: logger.exception( self.__get_state(user_last_state(user, 'Unknown state')))
def send_welcome(message): try: user = self.__get_or_register_user(message.chat.id, message.from_user) user.states = [self.__start_state] user.save() if blocked_check(message.chat, user): return self.__process_message(message, user) except: logger.exception("Error!")
def main(): # Thread(target=bitrumb_post).start() # Thread(target=okex_post).start() # Thread(target=binance_post).start() while True: try: check_save_send_bitrumb(get_first_news_bitrumb()) check_save_send_okex(get_first_news_okex()) check_save_send_binance(get_first_news_binance()) check_save_send_binance2(get_first_news_binance2()) except Exception: logger.exception('[E]')
def upload_canceled_result(winner: Competitor, looser: Competitor, level_change=None, was_dismissed=False, was_ignored=False, at_row=None): try: if not was_dismissed and not was_ignored: logger.error( 'upload_canceled_result called without both was_dismissed and was_ignored - one must be set') return if was_dismissed and was_ignored: logger.error( 'upload_canceled_result called with both was_dismissed and was_ignored - only one must be set') return cfg = get_config() if not cfg.spreadsheet_results_sheet: hr_logger.error( 'Не вдалося надіслати результат матчу в гуглтаблицю - у налаштуваннях відсутня назва листа') logger.error('Cannot insert result into a google sheet - sheet name is missing') return if not at_row: results = ResultsSheet.get_all_canceled_results() if results is None: results = [] at_row = len(results) + 2 t = '' if was_ignored: t = get_translation_for('gsheet_technical_win_ignored_str') if was_dismissed: t = get_translation_for('gsheet_technical_win_dismissed_str') update_data( cfg.spreadsheet_id, f'{cfg.spreadsheet_results_sheet}!H{at_row}:L', values=[ [ datetime.now(tz=_k_tz).strftime('%d/%m/%Y'), looser.name, t, winner.name, level_change or '-' ] ] ) except: logger.exception('Exception occurred while uploading canceled match results')
def change_status(self, new_status, bot=None, do_not_notify_admin=False): from google_integration.sheets.users import UsersSheet from localization.translations import get_translation_for from bot.settings_interface import get_config from telebot import TeleBot from config import BOT_TOKEN from logger_settings import hr_logger, logger update_sheet = False if self.status_code_to_str_dict[self.status] != self.status_code_to_str_dict[new_status]: update_sheet = True cfg = get_config() if update_sheet and cfg.admin_username and not do_not_notify_admin: try: if self.status in (COMPETITOR_STATUS.INJUIRY, COMPETITOR_STATUS.INACTIVE) or \ new_status in (COMPETITOR_STATUS.INJUIRY, COMPETITOR_STATUS.INACTIVE): admin_user = User.objects(username=cfg.admin_username).first() if admin_user: name = self.name associated_user = self.get_relevant_user() if associated_user: name = f'<a href="tg://user?id={associated_user.user_id}">{name}</a>' t = get_translation_for('admin_notification_competitor_changed_status').format( name, self.status_code_to_str_dict[self.status], self.status_code_to_str_dict[new_status] ) if bot is None: bot = TeleBot(BOT_TOKEN, threaded=False) bot.send_message( admin_user.user_id, t, parse_mode='html' ) except: logger.exception('Exception occurred while sending message to admin') hr_logger.error(f'Не вдалося надіслати адміністратору повідомлення про зміну стану користувача {self.name}') self.status = new_status if update_sheet: UsersSheet.update_competitor_status(self)
def __send_user_to_state(self, message, user, state): state_correct, current_state, c_name = self.__get_state(state) user.states.append(c_name) if len(user.states) > config.STATES_HISTORY_LEN: del user.states[0] user.save() try: if current_state.has_entry: self.__process_ret_code( current_state.entry(message=message, user=user, bot=self.bot)) else: self.__process_ret_code( current_state.process_message_with_buttons(message=message, user=user, bot=self.bot)) except: logger.exception( self.__get_state(user_last_state(user, 'Unknown state')))
def get_all_successful_results(): cfg = get_config() if not cfg.spreadsheet_results_sheet: return None values = retrieve_data( cfg.spreadsheet_id, f'{cfg.spreadsheet_results_sheet}!A2:E' ) if values is None: return [] values = values.get('values', []) if values: try: for v in values: while len(v) < 5: v.append('') except: logger.exception('Error!') return [] return values
def retrieve_data(spreadsheetId, range, valueRenderOption='FORMATTED_VALUE', majorDimension='ROWS', dateTimeRenderOption='SERIAL_NUMBER'): try: logger.debug(f'Started retrieving data at {datetime.now()}') guard.account_forced_get() data = gsheets.values().get( spreadsheetId=spreadsheetId, range=range, valueRenderOption=valueRenderOption, majorDimension=majorDimension, dateTimeRenderOption=dateTimeRenderOption).execute() logger.debug(f'Finished retrieving data at {datetime.now()}') return data except HttpError as e: logger.exception( 'Exception occurred while retrieving data from spreadsheet') return None
def everything_handler(message): try: user = self.__get_or_register_user(message.chat.id, message.from_user) if blocked_check(message.chat, user): return state_correct, current_state, c_name = self.__get_state( user_last_state(user, self.__start_state)) if not state_correct: user.states = [c_name] user.save() self.__process_message(message, user) else: if current_state.accepts_everything: self.__process_message(message, user) else: self.bot.send_message( message.chat.id, get_translation_for( 'message_type_not_supported_msg')) except: logger.exception("Error!")
def update_data(spreadsheetId, range, values, data_as_cols=False, valueInputOption='USER_ENTERED'): try: logger.debug(f'Started data update at {datetime.now()}') guard.account_forced_update() majorDimension = 'COLUMNS' if data_as_cols else 'ROWS' result = gsheets.values().update( spreadsheetId=spreadsheetId, range=range, body={ 'values': values, 'majorDimension': majorDimension }, valueInputOption=valueInputOption).execute() logger.debug(f'Finished data update at {datetime.now()}') return result except HttpError as e: logger.exception('Exception occurred while updating spreadsheet') return None
def upload_result(result: Result, at_row=None): try: cfg = get_config() if not cfg.spreadsheet_results_sheet: hr_logger.error( 'Не вдалося надіслати результат матчу в гуглтаблицю - у налаштуваннях відсутня назва листа') logger.error('Cannot insert result into a google sheet - sheet name is missing') return if at_row is None: results = ResultsSheet.get_all_successful_results() if results is None: results = [] at_row = len(results) + 2 if result.result in (RESULT.A_WINS, RESULT.B_WINS): winner = result.player_a.fetch() if result.result == RESULT.A_WINS else result.player_b.fetch() looser = result.player_b.fetch() if result.result == RESULT.A_WINS else result.player_a.fetch() score = result.repr_score() update_data( cfg.spreadsheet_id, f'{cfg.spreadsheet_results_sheet}!A{at_row}:E', values=[ [ mongo_time_to_local(result.date, tz=_k_tz).strftime('%d/%m/%Y'), winner.name, score, looser.name, result.level_change or '-' ] ] ) else: logger.error(f"Wrong method called for result {result.id}. Call upload_canceled_result instead") except: logger.exception('Exception occurred while uploading match result')
def check_challenges(): bconfig = get_config() n = datetime.now(tz=tz) tbot = None for competitor in Competitor.objects( status=COMPETITOR_STATUS.CHALLENGE_NEED_RESPONSE): try: if not competitor.latest_challenge_received_at: logger.error( f'Competitor {competitor.name} {competitor.legacy_number} has no latest_challenge_received_at' ) competitor.latest_challenge_received_at = datetime.now( tz=tz) competitor.save() continue cs = mongo_time_to_local( competitor.latest_challenge_received_at, tz) if (n - cs) > timedelta(days=max( 0, bconfig.time_to_accept_challenge - bconfig.accept_challenge_reminder )) and not competitor.challenge_remainder_sent: if tbot is None: tbot = TeleBot(PROJECT_NAME, threaded=False) cuser = User.objects(associated_with=competitor).first() if cuser is None: continue if not smwae_check( cuser.user_id, get_translation_for( 'remainder_challenge_accept_msg').format( bconfig.accept_challenge_reminder), cuser): opponent, opponent_user = get_opponent_and_opponent_user( competitor) if opponent and opponent_user: teardown_challenge( opponent, None, opponent_user, tbot, 'error_bot_blocked_by_opponent_challenge_canceled_msg' ) continue competitor.reload() competitor.challenge_remainder_sent = True competitor.save() elif (n - cs) > timedelta(days=bconfig.time_to_accept_challenge): if tbot is None: tbot = TeleBot(PROJECT_NAME, threaded=False) cuser = User.objects(associated_with=competitor).first() skip_comp = False if cuser is None: skip_comp = True opponent_user: User opponent, opponent_user = get_opponent_and_opponent_user( competitor) prev_level, new_level = None, None level_change = None if opponent and opponent.level > competitor.level: new_level = competitor.level prev_level = opponent.level level_change = f'{prev_level}->{new_level}' ResultsSheet.upload_canceled_result(opponent, competitor, level_change, was_ignored=True) if opponent: config = get_config() if config.group_chat_id: gmsg = get_translation_for( 'group_chat_technical_win_report_msg').format( opponent.name, competitor.name) if level_change: gmsg += '.\n' gmsg += get_translation_for( 'group_chat_players_level_changed').format( level_change) LogsSheet.glog( get_translation_for( 'gsheet_log_player_ignored_challenge_from_player' ).format(competitor.name, opponent.name) + '. ' + get_translation_for( 'group_chat_players_level_changed'). format(level_change)) else: LogsSheet.glog( get_translation_for( 'gsheet_log_player_ignored_challenge_from_player' ).format(competitor.name, opponent.name)) try: tbot.send_message(config.group_chat_id, gmsg, parse_mode='html') except: logger.exception( 'Exception occurred while sending message to group chat' ) res = Result(player_a=opponent, player_a_s=opponent.name, player_b=competitor, player_b_s=competitor.name, result=RESULT.IGNORED, canceled=True, date=datetime.now(tz=tz), level_change=level_change) res.save() competitor.in_challenge_with = None competitor.change_status(competitor.previous_status) competitor.previous_status = None competitor.latest_challenge_received_at = None if prev_level: competitor.level = prev_level competitor.challenges_ignored = ( competitor.challenges_ignored + 1) if competitor.challenges_ignored is not None else 1 competitor.challenges_ignored_total = ( competitor.challenges_ignored_total + 1 ) if competitor.challenges_ignored_total is not None else 1 competitor.losses = competitor.losses + 1 if competitor.losses is not None else 1 competitor.matches = competitor.matches + 1 if competitor.matches is not None else 1 if competitor.challenges_ignored >= bconfig.maximum_challenges_ignored: competitor.change_status(COMPETITOR_STATUS.INACTIVE) LogsSheet.glog( get_translation_for( 'gsheet_log_player_moved_to_inactive').format( competitor.name)) competitor.save() UsersSheet.update_competitor_table_record(competitor) t = get_translation_for( 'challenge_was_ignored_msg').format( competitor.challenges_ignored, bconfig.maximum_challenges_ignored) if not skip_comp: if competitor.status == COMPETITOR_STATUS.INACTIVE: t += '.\n<b>' t += get_translation_for( 'user_was_moved_to_inactive') t += '</b>' elif prev_level: t += '.\n' t += get_translation_for( 'your_level_changed_str').format( new_level, prev_level) smwae_check(cuser.user_id, t, cuser, reply_markup=get_menu_keyboard( status=competitor.status), parse_mode='html') if opponent: opponent.reload() opponent.in_challenge_with = None if opponent.status != COMPETITOR_STATUS.INACTIVE: opponent.change_status(opponent.previous_status) opponent.previous_status = None opponent.latest_challenge_received_at = None opponent.wins = opponent.wins + 1 if opponent.wins is not None else 1 opponent.matches = opponent.matches + 1 if opponent.matches is not None else 1 opponent.level = new_level opponent.save() UsersSheet.update_competitor_table_record(opponent) t = get_translation_for( 'challenge_was_ignored_opponent_msg') if prev_level: t += '\n' t += get_translation_for( 'your_level_changed_str').format( prev_level, new_level) if opponent_user: smwae_check(opponent_user.user_id, t, opponent_user, reply_markup=get_menu_keyboard( status=opponent.status), parse_mode='html') except: logger.exception( f'Exception occurred while checking challenge requests for competitor {competitor.name} {competitor.legacy_number}' ) for competitor in Competitor.objects(status__in=( COMPETITOR_STATUS.CHALLENGE_STARTER, COMPETITOR_STATUS.CHALLENGE_RECEIVER, COMPETITOR_STATUS.CHALLENGE_NEED_RESULTS_CONFIRMATION, COMPETITOR_STATUS.CHALLENGE_NEED_CANCELLATION_CONFIRMATION)): try: if not competitor.challenge_started_at: logger.error( f'Competitor {competitor.name} {competitor.legacy_number} has no challenge_started_at' ) competitor.challenge_started_at = datetime.now(tz=tz) competitor.save() continue cs = mongo_time_to_local(competitor.challenge_started_at, tz) if (n - cs) > timedelta(days=max( 0, bconfig.time_to_play_challenge - bconfig.challenge_play_reminder )) and not competitor.challenge_remainder_sent: if tbot is None: tbot = TeleBot(PROJECT_NAME, threaded=False) cuser = User.objects(associated_with=competitor).first() if cuser is None: continue if not smwae_check( cuser.user_id, get_translation_for('remainder_challenge_play_msg') .format(bconfig.challenge_play_reminder), cuser): opponent, opponent_user = get_opponent_and_opponent_user( competitor) if opponent and opponent_user: teardown_challenge( opponent, None, opponent_user, tbot, 'error_bot_blocked_by_opponent_challenge_canceled_msg' ) continue competitor.reload() competitor.challenge_remainder_sent = True competitor.save() elif (n - cs) > timedelta(days=bconfig.time_to_play_challenge): # TODO pass except: logger.exception( f'Exception occurred while checking challenges in progress (for competitor {competitor.name} {competitor.legacy_number})' )
def process_callback(self, callback: CallbackQuery, user, bot: TeleBot): data = callback.data if data.find('auth_') != 0: return RET.ANSWER_CALLBACK, None, callback, user data = data.replace('auth_', '') if data.find('user='******'=') if len(ds) == 2: competitor_id = ds[1] try: competitor = Competitor.objects(id=competitor_id).first() if competitor is not None: competitor.change_status(COMPETITOR_STATUS.ACTIVE) competitor.associated_user_vanished = False competitor.save() user.associated_with = competitor user.save() competitor.reload() hr_logger.info( f'Користувач {user.str_repr()} аутентифікувався як {competitor.name}' ) return RET.ANSWER_AND_GO_TO_STATE, 'MenuState', callback, user else: hr_logger.error( f'Сталася помилка при аутентифікації користувача {user.str_repr()} - не вдається знайти в базі обраного ним гравця' ) return RET.ANSWER_CALLBACK, get_translation_for( 'authentication_specified_competitor_not_found_clb' ), callback, user except ValidationError: logger.exception( f'Incorrect competitor_id: {competitor_id} from user with user_id: {user.user_id}' ) elif data.find('paginate=') == 0: ds = data.split('=') if len(ds) == 2: page = ds[1] page = to_int(page, 1) try: available_competitors = Competitor.objects( status=COMPETITOR_STATUS.UNAUTHORIZED).paginate( page=page, per_page=10) except NotFound: logger.exception( f'User {user.user_id} tried to switch to nonexistent page {page}' ) available_competitors = Competitor.objects( status=COMPETITOR_STATUS.UNAUTHORIZED).paginate( page=1, per_page=10) if not render_pagination( available_competitors, callback.message, bot, get_translation_for('authentication_msg'), self.__base_keyboard, update=True): bot.send_message( callback.message.chat.id, get_translation_for( 'authentication_cannot_find_competitors_msg')) hr_logger.error( f'При авторизації користувача {user.str_repr()} не вдалося знайти жодного гравця' ) elif data.find('none') == 0: return RET.ANSWER_CALLBACK, None, callback, user elif data.find('refresh') == 0: if guard.get_allowed()[0] and guard.update_allowed()[0]: UsersSheet.update_model() available_competitors = Competitor.objects( status=COMPETITOR_STATUS.UNAUTHORIZED).paginate(page=1, per_page=10) if not render_pagination( available_competitors, callback.message, bot, get_translation_for('authentication_msg'), self.__base_keyboard, ): bot.send_message( callback.message.chat.id, get_translation_for( 'authentication_cannot_find_competitors_msg')) hr_logger.error( f'При авторизації користувача {user.str_repr()} не вдалося знайти жодного гравця' ) return RET.ANSWER_CALLBACK, None, callback, user
def render_pagination(pagination: Pagination, message: Message, bot: TeleBot, text: str, keyboard_func, update=False, updateText=False): if pagination.total: available_competitors_encoded_names = [] for c in pagination.items: available_competitors_encoded_names.append([ f'{c.name}. {get_translation_for("info_level_str")}: {f"({c.level})"if c.level else "(_)"}.', str(c.id) ]) update_failed = False if update: try: if updateText: bot.edit_message_text( text, message.chat.id, message.message_id, reply_markup=keyboard_func( names=available_competitors_encoded_names, has_pages=pagination.pages > 1, cur_page=pagination.page, pages=pagination.pages, has_next=pagination.has_next, has_prev=pagination.has_prev)) else: bot.edit_message_reply_markup( message.chat.id, message.message_id, reply_markup=keyboard_func( names=available_competitors_encoded_names, has_pages=pagination.pages > 1, cur_page=pagination.page, pages=pagination.pages, has_next=pagination.has_next, has_prev=pagination.has_prev)) except ApiException as e: j = loads(e.result.text) if j['description'].find('is not modified') != -1: logger.warning( f'Pagination update resulted in the same message. New message is not sent: {message.chat.id}' ) else: logger.exception( f'Exception occurred while updating keyboard pagination. Chat: {message.chat.id}' ) update_failed = True except Exception: logger.exception( f'Exception occurred while updating keyboard pagination. Chat: {message.chat.id}' ) update_failed = True if not update or update_failed: bot.send_message(message.chat.id, text, reply_markup=keyboard_func( names=available_competitors_encoded_names, has_pages=pagination.pages > 1, cur_page=pagination.page, pages=pagination.pages, has_next=pagination.has_next, has_prev=pagination.has_prev)) return True return False
def process_callback(self, callback: CallbackQuery, user: User, bot: TeleBot): data = callback.data if data.find('challenge_to_') != 0: return RET.ANSWER_CALLBACK, None, callback, user data = data.replace('challenge_to_', '') competitor: Competitor = user.check_association() if not competitor: bot.send_message( callback.message.chat.id, get_translation_for('competitor_record_vanished_msg')) return RET.ANSWER_AND_GO_TO_STATE, 'AuthenticationState', callback, user if data.find('user='******'=') if len(ds) == 2: opponent_id = ds[1] try: opponent = Competitor.objects(id=opponent_id).first() if opponent is not None: text = get_translation_for( 'challenge_send_confirm_msg').format(opponent.name) text = f'<b>{text}</b>\n' \ f'{get_translation_for("info_status_str")}: {Competitor.status_code_to_str_dict[opponent.status]}\n' \ f'{get_translation_for("info_level_str")}: {opponent.level or get_translation_for("not_found_str")}\n' \ f'{get_translation_for("info_matches_str")}: {opponent.matches}\n' \ f'{get_translation_for("info_wins_str")}: {opponent.wins}\n' \ f'{get_translation_for("info_losses_str")}: {opponent.losses}\n' \ f'{get_translation_for("info_performance_str")}: {opponent.performance}' update_failed = False try: bot.edit_message_text( text, callback.message.chat.id, callback.message.message_id, reply_markup=self.__confirmation_keyboard( id=opponent_id), parse_mode='html') except: update_failed = True logger.exception( f'Exception occurred while updating keyboard for challenge sending. Chat: {callback.message.chat.id}' ) if update_failed: bot.send_message( callback.message.chat.id, text, reply_markup=self.__confirmation_keyboard( id=opponent_id), parse_mode='html') return RET.ANSWER_CALLBACK, None, callback, user else: return RET.ANSWER_CALLBACK, get_translation_for( 'authentication_specified_competitor_not_found_clb' ), callback, user except ValidationError: logger.exception( f'Incorrect opponent_id: {opponent_id} from user with user_id: {user.user_id}' ) elif data.find('paginate=') == 0: ds = data.split('=') if len(ds) == 2: page = ds[1] page = to_int(page, 1) try: available_competitors = Competitor.objects( status__in=(COMPETITOR_STATUS.ACTIVE, COMPETITOR_STATUS.PASSIVE), level__in=self.get_possible_levels(competitor.level), id__ne=competitor.latest_challenge_sent_to.id if competitor.latest_challenge_sent_to is not None else ObjectId(), associated_user_vanished__ne=True).paginate( page=page, per_page=10) except NotFound: logger.exception( f'User {user.user_id} tried to switch to nonexistent page {page}' ) available_competitors = Competitor.objects( status__in=(COMPETITOR_STATUS.ACTIVE, COMPETITOR_STATUS.PASSIVE), level__in=self.get_possible_levels(competitor.level), id__ne=competitor.latest_challenge_sent_to.id if competitor.latest_challenge_sent_to is not None else ObjectId(), associated_user_vanished__ne=True).paginate( page=1, per_page=10) if not render_pagination( available_competitors, callback.message, bot, get_translation_for('challenge_send_msg'), self.__base_keyboard, update=True): bot.send_message( callback.message.chat.id, get_translation_for( 'challenge_no_applicable_competitors_msg')) elif data.find('none') == 0: return RET.ANSWER_CALLBACK, None, callback, user elif data.find('refresh') == 0: if guard.get_allowed()[0] and guard.update_allowed()[0]: UsersSheet.update_model() available_competitors = Competitor.objects( status__in=(COMPETITOR_STATUS.ACTIVE, COMPETITOR_STATUS.PASSIVE), level__in=self.get_possible_levels(competitor.level), id__ne=competitor.latest_challenge_sent_to.id if competitor.latest_challenge_sent_to is not None else ObjectId(), associated_user_vanished__ne=True).paginate(page=1, per_page=10) if not render_pagination( available_competitors, callback.message, bot, get_translation_for('challenge_send_msg'), self.__base_keyboard, update=True, ): bot.send_message( callback.message.chat.id, get_translation_for( 'challenge_no_applicable_competitors_msg')) elif data.find('confirm_send=') == 0: ds = data.split('=') if len(ds) == 2: opponent_id = ds[1] if competitor.latest_challenge_sent_to and opponent_id == str( competitor.latest_challenge_sent_to): bot.send_message( callback.message.chat.id, get_translation_for( 'challenge_opponent_no_longer_available_msg')) return RET.ANSWER_AND_GO_TO_STATE, 'MenuState', callback, user try: opponent: Competitor = Competitor.objects( status__in=(COMPETITOR_STATUS.ACTIVE, COMPETITOR_STATUS.PASSIVE), level__in=self.get_possible_levels(competitor.level), id=opponent_id, associated_user_vanished__ne=True).first() if opponent is None: bot.send_message( callback.message.chat.id, get_translation_for( 'challenge_opponent_no_longer_available_msg')) return RET.ANSWER_AND_GO_TO_STATE, 'MenuState', callback, user opponent_user: User = User.objects( associated_with=opponent).first() if opponent_user is None: bot.send_message( callback.message.chat.id, get_translation_for( 'challenge_cannot_send_message_to_opponent_msg' )) send_msg_to_admin( get_translation_for( 'admin_notification_tg_user_vanished').format( opponent.name)) opponent.associated_user_vanished = True opponent.save() return RET.ANSWER_AND_GO_TO_STATE, 'MenuState', callback, user config = get_config() if opponent.status == COMPETITOR_STATUS.ACTIVE: if not smwae_check( opponent_user.user_id, get_translation_for( 'challenge_you_are_challenged_msg').format( user.user_id, competitor.name, competitor.level, config.time_to_accept_challenge), opponent_user, reply_markup= get_challenge_confirmation_keyboard(), parse_mode='html'): bot.send_message( callback.message.chat.id, get_translation_for( 'error_bot_blocked_by_opponent_challenge_canceled_msg' ) + '\n' + get_translation_for( 'error_bot_blocked_by_opponent_challenge_canceled_contact_admin_str' ), parse_mode='html') return RET.ANSWER_AND_GO_TO_STATE, 'MenuState', callback, user opponent_user.reload() opponent_user.states.append('ChallengeReceivedState') if len(opponent_user.states) > STATES_HISTORY_LEN: del opponent_user.states[0] opponent_user.save() elif opponent.status == COMPETITOR_STATUS.PASSIVE: if not smwae_check( opponent_user.user_id, get_translation_for( 'challenge_you_are_challenged_passive_msg' ).format(user.user_id, competitor.name, competitor.level, config.time_to_accept_challenge), opponent_user, reply_markup= get_challenge_confirmation_keyboard(), parse_mode='html'): bot.send_message( callback.message.chat.id, get_translation_for( 'error_bot_blocked_by_opponent_challenge_canceled_msg' ) + '\n' + get_translation_for( 'error_bot_blocked_by_opponent_challenge_canceled_contact_admin_str' ), parse_mode='html') return RET.ANSWER_AND_GO_TO_STATE, 'MenuState', callback, user opponent_user.reload() opponent_user.states.append('ChallengeReceivedState') if len(opponent_user.states) > STATES_HISTORY_LEN: del opponent_user.states[0] opponent_user.save() else: logger.error( f'Trying to send message to opponent with incorrect state: {opponent.name} {opponent.legacy_number}' ) bot.send_message( callback.message.chat.id, get_translation_for( 'error_occurred_contact_administrator_msg'), parse_mode='html') return RET.ANSWER_AND_GO_TO_STATE, 'MenuState', callback, user opponent.previous_status = opponent.status opponent.change_status( COMPETITOR_STATUS.CHALLENGE_NEED_RESPONSE) opponent.in_challenge_with = competitor opponent.latest_challenge_received_at = datetime.now( tz=timezone('Europe/Kiev')) opponent.challenge_remainder_sent = False opponent.save() competitor.previous_status = competitor.status competitor.change_status( COMPETITOR_STATUS.CHALLENGE_INITIATED) competitor.in_challenge_with = opponent competitor.latest_challenge_sent_to = opponent competitor.challenge_remainder_sent = False competitor.save() user.dismiss_confirmed = False user.save() bot.send_message( callback.message.chat.id, get_translation_for('challenge_sent_msg').format( opponent_user.user_id, opponent.name), parse_mode='html') LogsSheet.glog( get_translation_for( 'gsheet_log_player_created_challenge_for_player'). format(competitor.name, opponent.name)) return RET.ANSWER_AND_GO_TO_STATE, 'MenuState', callback, user except ValidationError: logger.exception( f'Incorrect opponent_id: {opponent_id} from user with user_id: {user.user_id}' ) elif data.find('cancel_send') == 0: if not self.update_and_paginate(callback.message, user, bot, competitor, update=True, updateText=True): bot.send_message( callback.message.chat.id, get_translation_for( 'challenge_no_applicable_competitors_msg')) elif data.find('back') == 0: return RET.ANSWER_AND_GO_TO_STATE, 'MenuState', callback, user return RET.ANSWER_CALLBACK, None, callback, user