def rangers_notify_start(bot, update): cursor = conn.cursor() time_to_battle = get_time_remaining_to_battle() print("time_to_battle", time_to_battle) try: callback_chat_id = update.message.chat_id except AttributeError: try: callback_chat_id = int(update) except TypeError: return count = 0 request = "select id from players where class_skill_lvl is not NULL" cursor.execute(request) row = cursor.fetchone() while row is not None: player = Player.get_player(row[0]) if player is None: row = cursor.fetchone() continue if player.settings is not None and player.settings.get( "rangers_notify") is False: row = cursor.fetchone() continue guild = Guild.get_guild(guild_id=player.guild) if guild is None: row = cursor.fetchone() continue telegram_username = player.username username = player.nickname class_skill_lvl = player.class_skill_lvl context = [telegram_username, username, guild.chat_id] print(class_skill_lvl) time_to_aim_mins = ranger_aiming_minutes[class_skill_lvl] if \ class_skill_lvl < len(ranger_aiming_minutes) else 40 time_to_aim = datetime.timedelta(minutes=time_to_aim_mins) print("time_to_aim", time_to_aim) time_to_notify = time_to_battle - time_to_aim - datetime.timedelta( minutes=1) print(time_to_notify) # time_to_notify = datetime.timedelta(minutes=1) # TEST if time_to_notify >= datetime.timedelta(minutes=0): job.run_once(ranger_notify, time_to_notify, context=context) row = cursor.fetchone() count += 1 cursor.close() bot.send_message( chat_id=callback_chat_id, text="Запланировано оповещение <b>{0}</b> бедных лучников".format( count), parse_mode='HTML')
def reward_g_def(player, reward, cost, *args, **kwargs): guild = Guild.get_guild(player.guild) if guild is None: dispatcher.bot.send_message( player.id, text="Гильдия не найдена. Вы должны состоять в гильдии. " "Жетоны возвращены.") player.reputation += cost player.update() return do_mailing( dispatcher.bot, "📣📣📣Вы слышите звуки рога! Это {} зазывает сынов и дочерей Скалы на защиту!\n" "/g_def {}".format(guild.tag, guild.tag)) dispatcher.bot.send_message( chat_id=STATUSES_MODERATION_CHAT_ID, text="Не забудьте снять жетоны тем, " "кого не будет в дефе <b>{}</b> в ближайшую битву!".format(guild.tag), parse_mode='HTML') job.run_once(when=get_time_remaining_to_battle() + datetime.timedelta(minutes=5), callback=g_def_remind_after_battle, context={"tag": guild.tag})
def plan_clear_alliance_results(*args): job.run_once(clear_results, get_time_remaining_to_battle())
def notify_guild_attack(bot, update): mes = update.message remaining_time = get_time_remaining_to_battle() forward_message_date = utc.localize( mes.forward_date).astimezone(tz=moscow_tz).replace(tzinfo=None) if forward_message_date - datetime.datetime.now() > datetime.timedelta( minutes=2): return 0 if remaining_time > datetime.timedelta(minutes=30): pass return 0 ready_to_battle = mes.text.count("[⚔]") + mes.text.count("[🛡]") sleeping = mes.text.count("[🛌]") + mes.text.count("[⚒]") response = "<b>{0}</b>\nГотово к битве: <b>{1}</b>\nНе готово к битве, но занято <b>{2}</b>\n" \ "Спит: <b>{3}</b>\n\nВремя до битвы: {4}\n".format(mes.text.splitlines()[0], ready_to_battle, mes.text.count("\n") - ready_to_battle - sleeping, sleeping, ":".join(str(remaining_time).partition(".")[0].split(":")[0:3])) request = "select guild_id from guilds where chat_id = %s" cursor.execute(request, (mes.chat_id, )) row = cursor.fetchone() if row is None: return guild = Guild.get_guild(guild_id=row[0]) set = guild.settings.get( "battle_notify") if guild.settings is not None else True if guild is None or set is False: return if mes.chat_id != guild.chat_id: return if mes.from_user.id not in get_admin_ids( bot, chat_id=mes.chat_id) and not check_access(mes.from_user.id): bot.send_message(chat_id=mes.chat_id, text="Доступ только у админов", parse_mode='HTML', reply_to_message_id=mes.message_id) return do_not_ready = [] sleeping = [] for string in mes.text.splitlines()[1:]: if not ("[⚔]" in string or "[🛡]" in string): nickname = string.partition("]")[2][1:] do_not_ready.append(nickname) if "[🛌]" in string or "[⚒]" in string: sleeping.append(nickname) in_dict_do_not_ready = [] in_dict_sleeping = [] ping_dict = { "do not ready": in_dict_do_not_ready, "sleeping": in_dict_sleeping } for player_id in guild.members: player = Player.get_player(player_id, notify_on_error=False) if player is None: continue db_nickname = player.nickname.partition("]")[2] if db_nickname in do_not_ready: in_dict_do_not_ready.append(player.username) if db_nickname in sleeping: in_dict_sleeping.append(player.username) ping_by_chat_id.update({mes.chat_id: ping_dict}) response += "Пингануть тех, кто спит: /notify_guild_sleeping\n" \ "Пингануть всех, кто не готов: /notify_guild_not_ready" bot.send_message(chat_id=mes.chat_id, text=response, parse_mode='HTML')
def players_update_monitor(): """ Выполняется на всём протяжении функционирования бота. Раз в секунду запрашивает обновление MAX_PLAYERS_AUTO_UPDATE_PER_SECOND профилей игроков, ранее всего обновлявших свои профили. Раз в GUILD_UPDATE_INTERVAL_SECONDS секунд вызывает обновление гильдии, которая не обновлялась дольше всего. :return: None """ cursor = conn.cursor() time.sleep(7) check_guilds_api_access() logging.info("Started updating profiles") i = 0 while True: try: i += 1 if not cwapi.active: return 0 time_to_battle = get_time_remaining_to_battle() if time_to_battle < datetime.timedelta(minutes=30) or \ time_to_battle > datetime.timedelta(minutes=30, hours=7): time.sleep(1) continue if i % GUILD_UPDATE_INTERVAL_SECONDS == 0: # Обновление гильдии request = "select guild_id from guilds order by last_updated nulls first" cursor.execute(request) rows = cursor.fetchall() guild, player_id = None, None for row in rows: guild_id = row[0] guild = Guild.get_guild(guild_id=guild_id) player_id = get_player_with_api_access_from_guild(guild) if player_id is not None: break if guild is None or player_id is None: logging.error("No guild to update") continue cwapi.update_guild_info(player_id) guild.api_info.update() logging.debug("Updating {} through CW3 API".format(guild.tag)) request = "select id from players where api_info -> 'token' is not null order by last_updated limit %s" cursor.execute(request, (MAX_PLAYERS_AUTO_UPDATE_PER_SECOND, )) row = cursor.fetchone() while row is not None: if row is None: logging.error("Request is None in players_update_monitor") return 0 player = Player.get_player(row[0]) cwapi.update_player(player.id, player=player) logging.debug("Updating {} through CW3 API".format( player.nickname)) if not cwapi.active: return 0 access = player.api_info.get("access") if access is not None and "gear" in access: cwapi.update_gear(player.id, player=player) row = cursor.fetchone() time.sleep(1) except Exception: logging.error(traceback.format_exc())
def actually_send_message(self, *args, **kwargs): chat_id = kwargs.get('chat_id') lock = self.counter_lock wait_start = time.time() try: with lock: while True: if self.messages_per_second < MESSAGE_PER_SECOND_LIMIT: self.messages_per_second += 1 # lock.release() break # logging.info("sleeping") lock.wait() # logging.info("woke up") finally: pass wait_end = time.time() advanced_callback.put({ "chat_id": kwargs.get("chat_id"), "wait_start": wait_start, "wait_end": wait_end }) message = None body = {"chat_id": chat_id, "time": time.time()} self.second_reset_queue.put(body) remaining_time = get_time_remaining_to_battle() timeout = 5 if kwargs.get("timeout_retry"): try: kwargs.pop("timeout_retry") kwargs.pop("timeout") except Exception: pass elif remaining_time <= datetime.timedelta(seconds=15): kwargs.update({"timeout": 0.8, "timeout_retry": True}) timeout = 0.8 try: reply_markup = kwargs.get("reply_markup") if isinstance(reply_markup, ReplyMarkup): reply_markup = reply_markup.to_json() parse_mode = kwargs.get("parse_mode") data = {'chat_id': chat_id, 'text': kwargs["text"]} if reply_markup is not None: data.update({'reply_markup': reply_markup}) if parse_mode is not None: data.update({'parse_mode': parse_mode}) # try: # resp = requests.post(self.base_url + '/sendMessage', data=json.dumps(data).encode('utf-8'), # headers={'Content-Type': 'application/json'}, timeout=timeout) # except Exception: # raise TimedOut # resp = resp.json() # print(resp) # ok = resp["ok"] # if not ok: # code, descr = resp["error_code"], resp["description"] # errors = {400: BadRequest(descr), 403: Unauthorized(descr)} # error = errors.get(code) # if error is None: # logging.error("Unknown error for code {}".format(code)) # raise BadRequest # raise error # message = Message.de_json(resp["result"], super(AsyncBot, self)) message = super(AsyncBot, self).send_message(*args, **kwargs) except TimedOut: logging.error("Order timeout") # time.sleep(0.1) # message = self.actually_send_message(*args, **kwargs) return TIMEOUT_ERROR_CODE except Unauthorized: return UNAUTHORIZED_ERROR_CODE except BadRequest: logging.error(traceback.format_exc()) return BADREQUEST_ERROR_CODE except NetworkError: time.sleep(0.1) message = super(AsyncBot, self).send_message(*args, **kwargs) except Exception: logging.error(traceback.format_exc()) return OTHER_ERROR_CODE return message