Exemple #1
0
 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')
Exemple #3
0
        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!")
Exemple #4
0
 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')
Exemple #5
0
    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')
Exemple #6
0
 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')
Exemple #8
0
 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')
Exemple #9
0
 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]')
Exemple #10
0
 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!")
Exemple #11
0
 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!")
Exemple #12
0
 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]')
Exemple #13
0
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!')
Exemple #14
0
 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!")
Exemple #15
0
 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')))
Exemple #16
0
 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')))
Exemple #17
0
        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!")
Exemple #18
0
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]')
Exemple #19
0
    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')
Exemple #20
0
    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)
Exemple #21
0
 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')))
Exemple #22
0
 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
Exemple #23
0
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
Exemple #24
0
 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!")
Exemple #25
0
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
Exemple #26
0
    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})'
                )
Exemple #28
0
    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
Exemple #29
0
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
Exemple #30
0
    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