def _check_queue(ch_id): queue = msg_queue.get(ch_id, []) if not queue: return count = msg_type_count.get(ch_id, 0) if count < 1: if queue[0] in msg_args: msg_type_count[ch_id] = msg_type_count.get(ch_id, 0) + 1 other.later_coro(0, _send_msg(*msg_args.pop(queue[0]))) else: log.W('com._check_queue, lost msg with id ', queue.pop(0)) _check_queue(ch_id)
async def _send_msg(ident, ti, tn, ch, text=None, emb=None, save_obj=None, fun: callable = None, a_fun: callable = None): if ident not in msg_queue.get(ch.id, []): msg_type_count[ch.id] = msg_type_count.get(ch.id, 1) - 1 # log.D(f'<write_msg>[STOP] tn = {tn}, ti = {ti}, ident = {ident}, count = {msg_type_count[ch.id]}.') _check_queue(ch.id) return if ti < tn: dt = min(tn - ti, 10) # log.D(f'<write_msg>[go] tn = {tn}, ti = {ti}, dt = {dt}, ident = {ident}, count = {msg_type_count[ch.id]}.') await C.client.send_typing(ch) other.later_coro( dt, _send_msg(ident, ti + dt, tn, ch, text, emb, save_obj, fun, a_fun)) else: try: msgs = [] msg_queue[ch.id].remove(ident) msg_type_count[ch.id] = msg_type_count.get(ch.id, 1) - 1 # log.D(f'<write_msg>[end] ident = {ident}, count = {msg_type_count[ch.id]}.') for txt in other.split_text(text): msgs.append(await C.client.send_message(ch, content=txt, embed=emb)) if save_obj is not None: if isinstance(save_obj, list): save_obj += msgs elif isinstance(save_obj, set): save_obj.update(msgs) elif isinstance(save_obj, dict): save_obj[ident] = tuple(msgs) elif isinstance(save_obj, tuple): # type (dict, key) save_obj[0][save_obj[1]] = tuple(msgs) if fun: fun(msgs) if a_fun: await a_fun(msgs) except Exception as e: other.pr_error(e, 'com._send_msg', 'Unexpected error') finally: _check_queue(ch.id)
def timer_half_min(): global day_ev_check start_half_min_timer() try: now = other.get_now() sec_total = int(now.timestamp()) if now.hour == 0 and now.minute == 0 and day_ev_check != now.day: timer_midnight_update(now) for uid, user in ram.silence_users.items(): if sec_total > user['time']: other.later_coro(1, manager.silence_end(uid)) other.later(15, timer_quarter_h) except Exception as e: other.pr_error(e, 'timer_half_min')
async def voting(channel, text='', timeout=60, votes=None, count=3): votes = votes or set() text = text + '\n*(для согласия введите за/y/yes/ok//д/да/+/1/:ok_hand:/:thumbsup:)*' yes = {'за', '1', 'y', 'yes', 'д', 'да', 'ок', 'у', '+', 't_d_', 'ok_hand', 'ok', 'thumbsup', '+1', 'thumbup'} await C.client.send_message(channel, text) time_end = other.get_sec_total() + timeout def check(msg): return (msg.author.id not in votes.union({C.users['bot']}) and yes.intersection(emj.em2text(msg.content).lower().replace('.', '').replace(':', ' ').split())) while len(votes) < count: time_left = time_end - other.get_sec_total() log.I('<voting> We have {0}/{1} votes, wait more for {2} sec.'.format(len(votes), count, time_left)) ans = await C.client.wait_for_message(timeout=time_left, channel=channel, check=check) if ans: votes.add(ans.author.id) other.later_coro(0, C.client.add_reaction(ans, emj.e('ok_hand'))) else: break else: return votes return False
def pr_news(text): time_tpprint('Ev', ' ', text) other.later_coro( 0, C.client.send_message(C.vtm_news_ch, content='<Ev> ' + text))
def answer_reaction(self, emoji_name, delay=0): other.later_coro(delay, C.client.add_reaction(self.message, emj.e(emoji_name)))
async def reaction(message, edit=False): msg = Msg(message) # in vtm open channels, save date of last message if msg.is_vtm: save = msg.chid == C.channels['flood'] if not save: every_prm = msg.channel.overwrites_for(C.vtm_server.default_role) save = every_prm.read_messages is not False if save: ram.last_vtm_msg = other.get_sec_total() if msg.auid == C.users['bot']: if msg.original == data.tremer_joke: other.later_coro(20, msg.delete('tremer_joke')) if msg.auid in data.day_events: _emj_on_message(msg, False, edit) return if msg.torpor: await msg.delete('torpor') return if C.roles['Silence'] in msg.roles: await msg.delete('Silence') ram.silence_ans[msg.auid] = ram.silence_ans.setdefault(msg.auid, 0) + 1 if ram.silence_ans[msg.auid] < 4: msg.answer(f'Неугодный <@{msg.auid}> пытается нам нечто сказать, но заноза в сердце мешает...') return # delete messages containing forbidden links if not msg.admin: if any(link in msg.text for link in data.forbiddenLinks): log.I(f'<reaction> forbidden links') await msg.delete('forbidden links') msg.answer(com.get_t('threats', name=msg.auid)) return # delete double messages for last 60 sec if ( not msg.super and not msg.personal and not (msg.text.startswith('!r') or msg.text.startswith('!shuffle')) and not edit and not (msg.message.attachments or msg.message.embeds) ): txt_now = (msg.original + ''.join([str(att.get('url', other.rand())) for att in msg.message.attachments]) + ''.join([str(emb.get('url', other.rand())) for emb in msg.message.embeds])) get_sec_now = other.get_sec_total() new_last_msgs = [] user_last_msgs = last_msgs.get(msg.auid, []) for txt, date in user_last_msgs: if (get_sec_now - date) < 60: new_last_msgs.append((txt, date)) if txt == txt_now: await msg.delete('double messages') return new_last_msgs.append((txt_now, get_sec_now)) last_msgs[msg.auid] = new_last_msgs # log.D(f'last_msgs["{msg.author.name}"]: {len(last_msgs[msg.auid])}.') # log.D(f'txt_now: {txt_now}.') if not msg.is_bot: # if edit msg with "good_time" or command - do nothing resp = _data_msgs_check(msg) if edit and resp and (resp['type'].startswith('cmd_') or resp['type'] == 'gt'): return # if we have !cmd -> doing something if msg.text.startswith('!'): fun = re.match(r'!\w*', msg.text).group(0)[1:] if fun in msg.get_commands(): msg.prepare(fun) log.I(f'<reaction> [cmd] {fun}') _data_msgs_add(msg, 'cmd_' + fun) await getattr(cmd, fun)(msg) return m_type, text = _do_reaction(msg, edit) if edit: old_type = resp['type'] if resp else '' if old_type == m_type: return if old_type and not m_type: return if m_type and old_type and text: log.I(f'<reaction> edit [{old_type}] to [{m_type}]') typing = _data_tp_check(msg) if typing in com.msg_queue.get(msg.channel.id, ()) or old_type == 'no-response': com.rem_from_queue(msg.channel.id, typing) # and type new mess else: for mess in resp['ans']: await C.client.edit_message(mess, new_content=text) # if mess>1, all will be with the same text resp['type'] = m_type return # elif m_type and not old_type: else: m_type, text = _do_reaction(msg, edit) _send_reaction(msg, m_type, text, edit)