Exemple #1
0
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)
Exemple #2
0
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)
Exemple #3
0
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')
Exemple #4
0
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
Exemple #5
0
def pr_news(text):
    time_tpprint('Ev', ' ', text)
    other.later_coro(
        0, C.client.send_message(C.vtm_news_ch, content='<Ev> ' + text))
Exemple #6
0
 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)