def insert_competitor_in_table(data: Competitor, check_for_existence=False, at_row=None, all_data=None): cfg = get_config() if check_for_existence: pass data.reload() if not data.legacy_number: data.legacy_number = str(Competitor.objects.count() + 100) data.save() if at_row is None: if not all_data: already_inserted_data = UsersSheet.get_all_users() else: already_inserted_data = all_data at_row = len(already_inserted_data) + 2 update_data( cfg.spreadsheet_id, f'{cfg.spreadsheet_users_sheet}!A{at_row}:G', values=[ [ data.legacy_number, data.name, Competitor.status_code_to_str_dict[data.status], data.level or '', data.matches or 0, data.wins or 0, data.losses or 0 ], ] )
def run(self, day=date.today()): """Retirieve and save competitors prices""" for room_id in self._rooms: listing = self._airbnb.listing(room_id)['listing'] params = { 'date': day, 'room_id': room_id, 'price': listing['price_native'], 'currency': listing['listing_native_currency'], 'data': json.dumps(listing) } Competitor.update_or_create(self._db, params)
def form_valid(self,form): self.object = form.save() competitor = Competitor(name="Default Name", bracket=self.object) seeds = xrange(self.object.maxnum) for person in range(self.object.maxnum): competitor.pk = None competitor.seed = person competitor.save() for i in range(self.object.maxnum / 2 ): comp = Competition(bracket=self.object,competitor_a=Competitor.objects.get(bracket=self.object,seed=seeds[2 * i]),competitor_b=Competitor.objects.get(bracket=self.object,seed=seeds[2 * i + 1])) comp.save() return super(BracketCreateView, self).form_valid(form)
def end_sick_leave(self, message: Message, user: User, bot: TeleBot, competitor: Competitor): if competitor.status != COMPETITOR_STATUS.INJUIRY: return RET.OK, None, None, None competitor.change_status(competitor.previous_status) competitor.save() bot.send_message( message.chat.id, get_translation_for('menu_on_sick_leave_end_msg'), reply_markup=self.__base_keyboard(status=competitor.status) ) LogsSheet.glog(get_translation_for('gsheet_log_on_injuiry_ended').format(competitor.name)) return RET.OK, None, None, None
def dismiss_results(self, message: Message, user: User, bot: TeleBot, competitor: Competitor): res = user.check_result() if not res: pass # TODO opponent, opponent_user = get_opponent_and_opponent_user(competitor) if not opponent or not opponent_user: res.delete() return teardown_challenge( competitor, message, user, bot, 'challenge_confirm_cannot_find_opponent_msg' if not opponent else 'challenge_confirm_cannot_fin_opponents_user_msg') if opponent.previous_challenge_status: opponent.change_status(opponent.previous_challenge_status) opponent.previous_challenge_status = None opponent.save() competitor.change_status(competitor.previous_challenge_status) competitor.previous_challenge_status = None competitor.save() if not smwae_check( opponent_user.user_id, get_translation_for( 'result_confirmation_dismissed_opponent_msg'), opponent_user, reply_markup=get_menu_keyboard(status=opponent.status)): teardown_challenge( competitor, message, user, bot, 'error_bot_blocked_by_opponent_challenge_canceled_msg') res.delete() opponent_user.reload() opponent_user.current_result = None opponent_user.save() user.current_result = None user.save() return RET.GO_TO_STATE, 'MenuState', message, user bot.send_message( message.chat.id, get_translation_for('result_confirmation_dismissed_msg')) res.delete() opponent_user.reload() opponent_user.current_result = None opponent_user.save() user.current_result = None user.save() return RET.GO_TO_STATE, 'MenuState', message, user
def readNovena(): wb = xlrd.open_workbook(filename = './data/novena.xls') sheet = wb.sheet_by_index(0) max_rows = sheet.nrows col_b = 1 #column 'B' col_g = 6 #column 'G' bar = progressbar.ProgressBar(maxval=max_rows, widgets=[ progressbar.Bar(left='novena Progress: [', marker='*', right=']')]).start() for index in range(max_rows): row = sheet.row_values(index) name = row[col_b] price = row[col_g] if (name != None) and (price not in (None, 'Цена', 'Цена3', 'Грин', 'Дилер', ' ', '')): record = Competitor(comp_name='Novena', name=name, low_price=float(price)) db.session.add(record) db.session.commit() bar.update(index) bar.finish()
def update_and_paginate(self, message: Message, user: User, bot: TeleBot, competitor: Competitor, page=1, update=False, updateText=False): if guard.get_allowed()[0] and guard.update_allowed()[0]: UsersSheet.update_model() possible_levels = ChallengeSendState.get_possible_levels( competitor.level) available_competitors = Competitor.objects( status__in=(COMPETITOR_STATUS.ACTIVE, COMPETITOR_STATUS.PASSIVE), level__in=possible_levels, 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, message, bot, get_translation_for('challenge_send_msg'), self.__base_keyboard, update=update, updateText=updateText): bot.send_message( message.chat.id, get_translation_for('challenge_no_applicable_competitors_msg')) return False return True
def readGreens(): wb = xlrd.open_workbook(filename = './data/greenspark.xlsx') sheet = wb.sheet_by_index(0) max_rows = sheet.nrows col_a = 0 #column 'A' col_p = 15 #column 'P' bar = progressbar.ProgressBar(maxval=max_rows, widgets=[ progressbar.Bar(left='Green Progress: [', marker='*', right=']')]).start() for index in range(max_rows): row = sheet.row_values(index) name = row[col_a] price = row[col_p] if (name != None) and (price not in (None, 'Цена', 'Грин', 'Дилер', ' ', '')): record = Competitor(comp_name='GreenSpark', name=name, low_price=float(price)) db.session.add(record) db.session.commit() bar.update(index) bar.finish()
def loadAndUpdate(path,file_name): fullpath = os.path.join(path, file_name) base=os.path.basename(fullpath) wb = xlrd.open_workbook(fullpath) file_name = os.path.splitext(base)[0] sheet = wb.sheet_by_index(0) max_rows = sheet.nrows col_a = 0 #column 'C' col_b = 1 #column 'F' if file_name == 'AppleHelp.ru': for index in range(max_rows): row = sheet.row_values(index) name = row[col_a] price = row[col_b] try: record = MainPrice.query.filter_by(name=name).first() if record is not None: rows = MainPrice.query.filter_by(name=name).update({'low_price': float(price)}) else: if (name != None) and (price not in (None, 'ОПТ 3', 'Цена', 'Грин', 'Дилер', ' ', '')): rows = MainPrice(name=name, low_price=float(price)) db.session.add(rows) db.session.commit() except: db.session.rollback() else: for index in range(max_rows): row = sheet.row_values(index) name = row[col_a] price = row[col_b] try: record = Competitor.query.filter_by(comp_name=file_name,name=name).first() if record is not None: rows = Competitor.query.filter_by(name = name).update({'low_price': float(price)}) else: if (name != None) and (price not in (None, 'ОПТ 3', 'Цена', 'Грин', 'Дилер', ' ', '')): rows = Competitor(comp_name=file_name, name=name, low_price=float(price)) db.session.add(rows) db.session.commit() except: db.session.rollback() # if (name != None) and (price not in (None, 'Цена', 'Грин', 'Дилер', ' ', '')): # record = MainPrice(name=name, # low_price=float(price)) # db.session.add(record) # db.session.commit() return ''
def update_competitor_db_record(table_row, competitor: Competitor): competitor.level = to_int(table_row[3], None) competitor.matches = to_int(table_row[4]) competitor.wins = to_int(table_row[5]) competitor.losses = to_int(table_row[6]) competitor.performance = to_int(table_row[7]) competitor.save()
def confirm_cancellation_opponent(self, message: Message, user: User, bot: TeleBot, competitor: Competitor): if competitor.status != COMPETITOR_STATUS.CHALLENGE_NEED_CANCELLATION_CONFIRMATION: return RET.OK, None, None, None if not user.dismiss_confirmed: bot.send_message( message.chat.id, get_translation_for('challenge_cancel_msg'), reply_markup=self.__base_keyboard(status=competitor.status) ) user.dismiss_confirmed = True user.save() return RET.OK, None, None, None else: user.dismiss_confirmed = False user.save() opponent, opponent_user = get_opponent_and_opponent_user(competitor) if not opponent or not opponent_user: return teardown_challenge( competitor, message, user, bot, 'challenge_confirm_cannot_find_opponent_msg' if not opponent else 'challenge_confirm_cannot_fin_opponents_user_msg' ) opponent.change_status(opponent.previous_status) opponent.previous_status = None opponent.previous_challenge_status = None opponent.in_challenge_with = None opponent.challenge_started_at = None opponent.save() competitor.change_status(competitor.previous_status) competitor.previous_status = None competitor.previous_challenge_status = None competitor.in_challenge_with = None competitor.challenge_started_at = None competitor.save() smwae_check( opponent_user.user_id, get_translation_for('challenge_canceled_msg').format(competitor.name), opponent_user, reply_markup=self.__base_keyboard(status=opponent.status) ) bot.send_message( message.chat.id, get_translation_for('challenge_canceled_msg').format(opponent.name), reply_markup=self.__base_keyboard(status=competitor.status) ) LogsSheet.glog(get_translation_for('gsheet_log_game_canceled').format(opponent.name, competitor.name)) return RET.OK, None, None, None
def dismiss_cancellation_opponent(self, message: Message, user: User, bot: TeleBot, competitor: Competitor): if competitor.status != COMPETITOR_STATUS.CHALLENGE_NEED_CANCELLATION_CONFIRMATION: return RET.OK, None, None, None opponent, opponent_user = get_opponent_and_opponent_user(competitor) if not opponent or not opponent_user: return teardown_challenge( competitor, message, user, bot, 'challenge_confirm_cannot_find_opponent_msg' if not opponent else 'challenge_confirm_cannot_fin_opponents_user_msg' ) competitor.change_status(competitor.previous_challenge_status) competitor.previous_challenge_status = None competitor.save() user.dismiss_confirmed = False user.save() if not smwae_check( opponent_user.user_id, get_translation_for('challenge_cancellation_denied_opponent_msg').format(competitor.name), opponent_user, reply_markup=self.__base_keyboard(status=opponent.status) ): return teardown_challenge( competitor, message, user, bot, 'error_bot_blocked_by_opponent_challenge_canceled_msg' ) bot.send_message( user.user_id, get_translation_for('challenge_cancellation_denied_msg').format(opponent.name), reply_markup=self.__base_keyboard(status=competitor.status) ) return RET.OK, None, None, None
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 end_vacation(self, message: Message, user: User, bot: TeleBot, competitor: Competitor): if competitor.status != COMPETITOR_STATUS.VACATION: return RET.OK, None, None, None if not competitor.vacation_started_at: logger.error(f"Cannot calculate user's ({user.user_id}) time on vacation - cannot find vacation_started_at") delta = 0 else: tz = timezone('Europe/Kiev') now = datetime.now(tz=tz) delta = now - mongo_time_to_local(competitor.vacation_started_at, tz) delta = delta.total_seconds() if competitor.used_vacation_time is None: competitor.used_vacation_time = delta else: competitor.used_vacation_time += delta competitor.change_status(competitor.previous_status) competitor.save() bot.send_message( message.chat.id, get_translation_for('menu_on_vacation_end_manual_msg'), reply_markup=self.__base_keyboard(status=competitor.status) ) LogsSheet.glog(get_translation_for('gsheet_log_player_finished_vacation').format(competitor.name)) return RET.OK, None, None, None
def entry(self, message: Message, user: User, bot: TeleBot): if user.check_association(): return RET.GO_TO_STATE, 'MenuState', message, user 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, message, bot, get_translation_for('authentication_msg'), self.__base_keyboard): bot.send_message( message.chat.id, get_translation_for( 'authentication_cannot_find_competitors_msg')) return RET.OK, None, None, None
def update_model(cleanse=True): data = UsersSheet.get_all_users() if not data: pass else: stored_in_sheet_records = set() row_num = 1 for row in data: existing_data = Competitor.objects( name=row[1], legacy_number=row[0] ).first() if existing_data is None: cfg = get_config() new_data = Competitor( legacy_number=row[0], name=row[1], status=COMPETITOR_STATUS.UNAUTHORIZED, level=to_int(row[3], None), matches=to_int(row[4]), wins=to_int(row[5]), losses=to_int(row[6]), performance=to_int(row[7]), used_vacation_time=0 ) new_data.save() new_data.reload() stored_in_sheet_records.add(new_data.id) else: stored_in_sheet_records.add(existing_data.id) UsersSheet.update_competitor_db_record(row, existing_data) row_num += 1 for new_record in Competitor.objects(id__not__in=stored_in_sheet_records): if not cleanse: row_num += 1 UsersSheet.insert_competitor_in_table(new_record, at_row=row_num) else: new_record.delete() hr_logger.info('Оновлено список гравців з гугл-таблиці')
def readDici(): #Парсинг прайса Диси wb = xlrd.open_workbook(filename = './data/dici.xlsx') for sheet_num in range(0, 5): sheet = wb.sheet_by_index(sheet_num) max_rows = sheet.nrows col_a = 0 #column 'A' col_b = 1 #column 'B' col_d = 3 #column 'D' col_e = 4 #column 'E' bar = progressbar.ProgressBar(maxval=max_rows, widgets=[ progressbar.Bar(left='Dici Progress: [', marker='*', right=']')]).start() for index in range(max_rows): row = sheet.row_values(index) if sheet_num == 0: name = row[col_a] + row[col_b] price = row[col_e] else: name = row[col_a] price = row[col_d] if (name != None) and (price not in (None, 'ОПТ 3', 'Цена', 'Грин', 'Дилер', ' ', '')): record = Competitor(comp_name='Dici', name=name, low_price=float(price)) db.session.add(record) db.session.commit() bar.update(index) bar.finish()
def daily_task(): now = datetime.now(tz=tz) tbot = None bconfig = get_config() for competitor in Competitor.objects( status=COMPETITOR_STATUS.VACATION): if competitor.vacation_started_at: delta = now - mongo_time_to_local( competitor.vacation_started_at, tz) delta = delta.total_seconds() if competitor.used_vacation_time is not None: delta += competitor.used_vacation_time if timedelta(seconds=delta).days > bconfig.vacation_time: competitor.change_status(competitor.previous_status or COMPETITOR_STATUS.ACTIVE) competitor.save() relevant_user: User = User.objects( associated_with=competitor).first() if relevant_user is not None: if not tbot: tbot = TeleBot(BOT_TOKEN, threaded=False) smwae_check( relevant_user.user_id, get_translation_for('menu_on_vacation_end_msg'), relevant_user, reply_markup=get_menu_keyboard( status=competitor.status)) else: competitor.vacation_started_at = now competitor.used_vacation_time = delta competitor.save() else: logger.error( f"Cannot find vacation_started_at for competitor {competitor.name} (on vacation). Saved current time" ) competitor.vacation_started_at = now competitor.save()
def go_on_vacation(self, message: Message, user: User, bot: TeleBot, competitor: Competitor): if competitor.status not in (COMPETITOR_STATUS.ACTIVE, COMPETITOR_STATUS.PASSIVE): return RET.OK, None, None, None config = get_config() if timedelta(seconds=competitor.used_vacation_time).days >= config.vacation_time: bot.send_message( message.chat.id, get_translation_for('menu_vacation_no_days_left_msg'), reply_markup=self.__base_keyboard(status=competitor.status) ) return RET.OK, None, None, None competitor.previous_status = competitor.status competitor.change_status(COMPETITOR_STATUS.VACATION) competitor.vacation_started_at = datetime.now(tz=timezone('Europe/Kiev')) competitor.save() bot.send_message( message.chat.id, get_translation_for('menu_on_vacation_start_msg'), reply_markup=self.__base_keyboard(status=competitor.status) ) LogsSheet.glog(get_translation_for('gsheet_log_player_started_vacation').format(competitor.name)) return RET.OK, None, None, None
def accept_button(self, message: Message, user: User, bot: TeleBot, competitor: Competitor): opponent_user: User opponent, opponent_user = get_opponent_and_opponent_user(competitor) if not opponent or not opponent_user: return teardown_challenge( competitor, message, user, bot, 'challenge_confirm_cannot_find_opponent_msg' if not opponent else 'challenge_confirm_cannot_fin_opponents_user_msg' ) opponent.change_status(COMPETITOR_STATUS.CHALLENGE_STARTER) competitor.change_status(COMPETITOR_STATUS.CHALLENGE_RECEIVER) competitor.latest_challenge_received_at = None n = datetime.now(tz=timezone('Europe/Kiev')) opponent.challenge_started_at = n competitor.challenge_started_at = n opponent.challenge_remainder_sent = False competitor.challenge_remainder_sent = False competitor.challenges_dismissed_in_a_row = 0 opponent.save() competitor.save() config = get_config() if not smwae_check( opponent_user.user_id, get_translation_for('challenge_confirm_challenge_accepted_opponent_msg').format( f'<a href="tg://user?id={user.user_id}">{competitor.name}</a>', config.time_to_play_challenge ), opponent_user, reply_markup=get_menu_keyboard(status=opponent.status), parse_mode='html' ): return teardown_challenge( competitor, message, user, bot, 'error_bot_blocked_by_opponent_challenge_canceled_msg' ) opponent_user.reload() opponent_user.dismiss_confirmed = False opponent_user.states.append('MenuState') if len(opponent_user.states) > STATES_HISTORY_LEN: del opponent_user.states[0] opponent_user.save() user.dismiss_confirmed = False user.save() bot.send_message( user.user_id, get_translation_for('challenge_confirm_challenge_accepted_competitor_msg').format( f'<a href="tg://user?id={opponent_user.user_id}">{opponent.name}</a>', # TODO config.time_to_play_challenge ), parse_mode='html' ) LogsSheet.glog( get_translation_for('gsheet_log_player_accepted_challenge_from_player').format(competitor.name, opponent.name) ) return RET.GO_TO_STATE, 'MenuState', message, user
def confirm_results(self, message: Message, user: User, bot: TeleBot, competitor: Competitor): res = user.check_result() if not res: pass # TODO opponent, opponent_user = get_opponent_and_opponent_user(competitor) if not opponent or not opponent_user: res.delete() return teardown_challenge( competitor, message, user, bot, 'challenge_confirm_cannot_find_opponent_msg' if not opponent else 'challenge_confirm_cannot_fin_opponents_user_msg') if not user.dismiss_confirmed: bot.send_message( message.chat.id, get_translation_for('result_confirmation_confirm_msg')) user.dismiss_confirmed = True user.save() return RET.OK, None, None, None else: user.dismiss_confirmed = False user.save() pa = res.player_a.fetch() pb = res.player_b.fetch() winner: Competitor loser: Competitor if res.result == RESULT.A_WINS: winner = pa loser = pb elif res.result == RESULT.B_WINS: winner = pb loser = pa else: logger.error('INCONSISTENT RESULT OF A RESULT') return RET.GO_TO_STATE, 'MenuState', None, None res.confirmed = True res.date = datetime.now(timezone('Europe/Kiev')) res.player_a_s = pa.name res.player_b_s = pb.name winner.wins = winner.wins + 1 if winner.wins is not None else 1 winner.matches = winner.matches + 1 if winner.matches is not None else 1 winner.change_status(COMPETITOR_STATUS.ACTIVE) winner.previous_status = None winner.previous_challenge_status = None winner.challenge_started_at = None winner.in_challenge_with = None winner.save() UsersSheet.update_competitor_table_record(winner) loser.losses = loser.losses + 1 if loser.losses is not None else 1 loser.matches = loser.matches + 1 if loser.matches is not None else 1 loser.change_status(loser.previous_status) loser.previous_status = None loser.previous_challenge_status = None loser.challenge_started_at = None loser.in_challenge_with = None loser.save() UsersSheet.update_competitor_table_record(loser) prev_level, new_level = None, None if winner.level > loser.level: prev_level = winner.level new_level = loser.level res.level_change = f'{prev_level}->{new_level}' res.save() opponent.reload() competitor.reload() if prev_level: if opponent == winner: sw = smwae_check( opponent_user.user_id, get_translation_for( 'result_confirmation_confirmed_opponent_msg') + '\n' + get_translation_for('your_level_changed_str').format( prev_level, new_level), opponent_user, reply_markup=get_menu_keyboard(status=opponent.status)) bot.send_message( message.chat.id, get_translation_for('result_confirmation_confirmed_msg') + '\n' + get_translation_for('your_level_changed_str').format( new_level, prev_level), ) opponent.reload() opponent.level = new_level opponent.save() UsersSheet.update_competitor_table_record(opponent) competitor.reload() competitor.level = prev_level competitor.save() UsersSheet.update_competitor_table_record(competitor) else: sw = smwae_check( opponent_user.user_id, get_translation_for( 'result_confirmation_confirmed_opponent_msg') + '\n' + get_translation_for('your_level_changed_str').format( new_level, new_level), opponent_user, reply_markup=get_menu_keyboard(status=opponent.status)) bot.send_message( message.chat.id, get_translation_for('result_confirmation_confirmed_msg') + '\n' + get_translation_for('your_level_changed_str').format( prev_level, new_level), ) competitor.reload() competitor.level = new_level competitor.save() UsersSheet.update_competitor_table_record(competitor) opponent.reload() opponent.level = prev_level opponent.save() UsersSheet.update_competitor_table_record(opponent) else: sw = smwae_check( opponent_user.user_id, get_translation_for( 'result_confirmation_confirmed_opponent_msg'), opponent_user, reply_markup=get_menu_keyboard(status=opponent.status)) opponent_user.reload() opponent_user.current_result = None opponent_user.states.append('MenuState') if len(opponent_user.states) > STATES_HISTORY_LEN: del opponent_user.states[0] opponent_user.save() user.reload() user.current_result = None user.save() res.reload() ResultsSheet.upload_result(res) if not res.level_change: LogsSheet.glog( get_translation_for('gsheet_log_game_finished').format( competitor.name, opponent.name, winner.name, res.repr_score())) else: LogsSheet.glog( get_translation_for('gsheet_log_game_finished').format( competitor.name, opponent.name, winner.name, res.repr_score()) + '. ' + get_translation_for('group_chat_players_level_changed').format( res.level_change)) config = get_config() if config.group_chat_id: score = res.repr_score() gmsg = get_translation_for('group_chat_match_result_msg').format( winner.name, loser.name, score) if res.level_change: gmsg += '.\n' gmsg += get_translation_for( 'group_chat_players_level_changed').format( res.level_change) try: bot.send_message(config.group_chat_id, gmsg, parse_mode='html') except: logger.exception( 'Exception occurred while sending message to group chat') return RET.GO_TO_STATE, 'MenuState', message, user
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
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 teardown_challenge(competitor: Competitor, message, user: User, bot: TeleBot, cause_key, canceled_by_bot=True, opponent: Competitor = None, opponent_msg_key=None, no_glog=False): competitor.in_challenge_with = None competitor.change_status(competitor.previous_status) competitor.previous_status = None competitor.latest_challenge_received_at = None competitor.save() if opponent: opponent_user = User.objects(associated_with=opponent).first() opponent.in_challenge_with = None opponent.change_status(opponent.previous_status) opponent.previous_status = None opponent.latest_challenge_received_at = None opponent.save() if canceled_by_bot and not no_glog: LogsSheet.glog( get_translation_for('gsheet_log_challenge_canceled').format( competitor.name, opponent.name)) if opponent_user: opponent_user.dismiss_confirmed = False opponent_user.states.append('MenuState') if len(opponent_user.states) > STATES_HISTORY_LEN: del opponent_user.states[0] opponent_user.save() if opponent_msg_key: if canceled_by_bot: bot.send_message( opponent_user.user_id, f'{get_translation_for(opponent_msg_key).format(competitor.name)}.\n{get_translation_for("challenge_confirm_challenge_canceled_by_bot_msg")}', reply_markup=get_menu_keyboard(status=opponent.status), parse_mode='html') else: bot.send_message( opponent_user.user_id, f'{get_translation_for(opponent_msg_key).format(competitor.name)}', reply_markup=get_menu_keyboard(status=opponent.status), parse_mode='html') else: if canceled_by_bot and not no_glog: LogsSheet.glog( get_translation_for( 'gsheet_log_challenge_canceled_no_opponent').format( competitor.name)) user.dismiss_confirmed = False user.save() if cause_key is not None: if canceled_by_bot: bot.send_message( user.user_id, f'{get_translation_for(cause_key)}.\n{get_translation_for("challenge_confirm_challenge_canceled_by_bot_msg")}' ) else: bot.send_message(user.user_id, f'{get_translation_for(cause_key)}') return RET.GO_TO_STATE, 'MenuState', message, user
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 monthly_task(): for competitor in Competitor.objects(): competitor.used_vacation_time = 0 if competitor.status == COMPETITOR_STATUS.VACATION: competitor.vacation_started_at = datetime.now(tz=tz) competitor.save()
try: competitor = Competitor.objects.get(student_no=request.POST['stunumber']) return render(request, 'register.html', { 'academies': Academy.objects.all(), "sexs": Sex.objects.all(), 'error': "学号已存在"}) except Exception, e: pass except Exception, e: pass newUser = User.objects.create_user(request.POST['email'], request.POST['email'], request.POST['password']) newUser.save() competitor = Competitor( student_no=request.POST['stunumber'] , user=newUser , name=request.POST['name'] , phone=request.POST['phone'] , academy=Academy.objects.get(academy=request.POST['academy']) , sex=Sex.objects.get(sex=request.POST['sex']) , motto=request.POST['motto'] ) competitor.save() newUser = authenticate(username=request.POST['email'], password=request.POST['password']) auth_login(request, newUser) return redirect('/contest/entry') return render(request, 'register.html', { 'academies': Academy.objects.all(), "sexs": Sex.objects.all() }) def logout(request): auth_logout(request) return redirect('/contest/index') @login_required(login_url='/competitor/login')
def dismiss_button(self, message: Message, user: User, bot: TeleBot, competitor: Competitor): defeat = False if not user.dismiss_confirmed: if competitor.previous_status == COMPETITOR_STATUS.PASSIVE: bot.send_message( message.chat.id, get_translation_for('challenge_confirm_technical_defeat') ) else: bot.send_message( message.chat.id, get_translation_for('challenge_received_dismiss_confirm_msg') ) user.dismiss_confirmed = True user.save() return RET.OK, None, None, None else: user.dismiss_confirmed = False user.save() if competitor.previous_status == COMPETITOR_STATUS.PASSIVE and competitor.challenges_dismissed_in_a_row >= 1: defeat = True opponent, opponent_user = get_opponent_and_opponent_user(competitor) if not opponent or not opponent_user: return teardown_challenge( competitor, message, user, bot, 'challenge_confirm_cannot_find_opponent_msg' if not opponent else 'challenge_confirm_cannot_fin_opponents_user_msg' ) opponent.in_challenge_with = None opponent.change_status(opponent.previous_status) opponent.previous_status = None opponent.save() if defeat: 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 level_change = None if opponent.level > competitor.level: level_change = f'{opponent.level}->{competitor.level}' c = opponent.level opponent.level = competitor.level competitor.level = c ResultsSheet.upload_canceled_result(opponent, competitor, level_change, was_dismissed=True) UsersSheet.update_competitor_table_record(opponent) res = Result( player_a=opponent, player_a_s=opponent.name, player_b=competitor, player_b_s=competitor.name, result=RESULT.DISMISSED, canceled=True, date=datetime.now(tz=timezone('Europe/Kiev')), level_change=level_change ) res.save() 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) try: bot.send_message( config.group_chat_id, gmsg, parse_mode='html' ) except: logger.exception('Exception occurred while sending message to group chat') result = Result( player_a=opponent, player_b=competitor, result=RESULT.A_WINS ) result.save() opponent.save() competitor.in_challenge_with = None if defeat: competitor.change_status(COMPETITOR_STATUS.ACTIVE) competitor.challenges_dismissed_in_a_row = 0 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 UsersSheet.update_competitor_table_record(competitor) else: competitor.change_status(COMPETITOR_STATUS.PASSIVE) competitor.challenges_dismissed_in_a_row = 1 competitor.challenges_dismissed_total = competitor.challenges_dismissed_total + 1 if competitor.challenges_dismissed_total is not None else 1 competitor.latest_challenge_received_at = None competitor.save() opponent_user.states.append('MenuState') if len(opponent_user.states) > STATES_HISTORY_LEN: del opponent_user.states[0] opponent_user.save() if defeat: smwae_check( opponent_user.user_id, get_translation_for('challenge_confirm_opponent_wins') + ' ' + str(opponent.level), opponent_user, reply_markup=get_menu_keyboard(status=opponent.status) ) bot.send_message( user.user_id, get_translation_for('challenge_confirm_competitor_losses') + ' ' + str(competitor.level), ) else: smwae_check( opponent_user.user_id, get_translation_for('challenge_confirmation_dismissed_opponent_msg'), opponent_user, reply_markup=get_menu_keyboard(status=opponent.status) ) bot.send_message( user.user_id, get_translation_for('challenge_confirmation_dismissed_competitor_msg'), ) LogsSheet.glog( get_translation_for('gsheet_log_player_dismissed_challenge_from_player').format(competitor.name, opponent.name) ) return RET.GO_TO_STATE, 'MenuState', message, user
def get_opponent_and_opponent_user( competitor: Competitor) -> (Competitor, User): opponent: Competitor = competitor.check_opponent() opponent_user = User.objects( associated_with=opponent).first() if opponent else None return opponent, opponent_user