예제 #1
0
async def delete_msg(message=None, ch_i=None, msg_id=None, reason='-'):
    if not message:
        try:
            message = await C.client.get_message(other.get_channel(ch_i),
                                                 msg_id)
        except Exception as e:
            other.pr_error(e, 'com.delete_msg.get_message', 'Unexpected error')
            return
    await other.delete_msg(message, reason)
예제 #2
0
def main_loop():
    for sig_name in ('SIGINT', 'SIGTERM'):
        C.loop.add_signal_handler(getattr(signal, sig_name),
                                  functools__partial(ev.on_exit, sig_name))
    try:
        log.I("Start ClientRun.")
        C.client.run(C.DISCORD_TOKEN)
    except Exception as e:
        other.pr_error(e, 'ClientRun', 'Unexpected error')
    else:
        log.I("ClientRun is completed without errors.")
    finally:
        ev.on_final_exit()
예제 #3
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)
예제 #4
0
def timer_midnight_update(now=None):
    if not now:
        now = other.get_now()

    log.I('[=== New day! ===]')

    try:
        _check_day_ev(now, on_midnight=True)
    except Exception as e:
        other.pr_error(e, '_check_day_ev', 'Unexpected error')

    try:
        _check_once_in_day()
    except Exception as e:
        other.pr_error(e, '_check_once_in_day', 'Unexpected error')
예제 #5
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')
예제 #6
0
def timer_quarter_h():
    global timer_quarter_works
    start_quarter_h_timer()
    try:
        log.D('+ Quarter hour timer event!')
        _timer_check_games()
        _timer_check_silence_in_chat()
        timer_quarter_works += 1
        save()
        if timer_quarter_works % TMR_IN_H == 0:  # hour_timer
            # other.later_coro(1, _timer_check_stuff())
            mn = 4
        else:
            mn = 1
        log.D('+ Timer event finished!')
        log.p('------------------------------------- ' * mn)
    except Exception as e:
        other.pr_error(e, 'timer_quarter_h')
예제 #7
0
 async def purge(self, channel, check_count=1, check=None, aft=None, bef=None):
     try:
         count = int(check_count)
     except Exception as e:
         other.pr_error(e, 'purge')
         await self.qanswer('N должно быть числом!')
         return
     mess_count = 0
     auth = set()
     first, last = None, None
     async for mess in C.client.logs_from(channel, limit=count, before=bef, after=aft):
         if not check or check(mess):
             mess_count += 1
             auth.add(mess.author.id)
             if mess_count == 1:
                 first = mess.timestamp
                 last = mess.timestamp
             else:
                 if first > mess.timestamp:
                     first = mess.timestamp
                 elif last < mess.timestamp:
                     last = mess.timestamp
     if not mess_count:
         await self.qanswer('Не найдено сообщений для purge.')
         return
     else:
         text_mess = 'сообщение' if mess_count == 1 else 'сообшения' if mess_count < 5 else 'сообщений'
         list_auth = other.get_mentions(auth)
         yes = await self.question(
             'Вы уверены что хотите удалить {count} {text_mess} от {list_auth} с {first} по {last} в {channel}? '
             .format(
                 count=mess_count, text_mess=text_mess, list_auth=', '.join(list_auth),
                 first=other.t2s(first, '{%x %X}'), last=other.t2s(last, '{%x %X}'), channel=channel))
         if yes:
             try:
                 await C.client.purge_from(channel, limit=count, check=check, after=aft, before=bef)
             except C.Exceptions.Forbidden:
                 log.jW("Bot haven't permissions here.")
             except Exception as e:
                 other.pr_error(e, 'Msg.purge', 'Unexpected error')
             else:
                 await self.qanswer(":ok_hand:")
         else:
             await self.qanswer("Отмена purge.")
예제 #8
0
def phrase_gt(gt=None, uid=None, add_id=None):
    if not gt:
        return False

    uid = uid or 'here'
    phr = other.choice(d2u.good_time[gt['g_key']][gt['g_type']]['response'])
    str_weather = ''
    if gt['g_key'] == 'g_morn':  # and uid in emj.morn_add:
        smile_ids = other.it2list(uid) + other.it2list(add_id)
        smiles = []
        for sm_id in smile_ids:
            smiles += emj.morn_add.get(sm_id, [])
        if smiles:
            phr += ' ' + other.choice(smiles)
    if uid == C.users['Natali'] and gt['g_key'] in ('g_morn', 'g_day'):
        try:
            log.I('try get_weather for Natali')
            str_weather = '\n:newspaper: ' + get_weather()
        except Exception as e:
            other.pr_error(e, 'get_weather')
    return other.name_phr(uid, phr) + str_weather
예제 #9
0
def load_mem():
    log.I('+ load data from memory')
    not_load = {'t_start', 't_finish', 't_work'}
    module = sys.modules[ram.__name__]
    module_attrs = dir(module)
    variables = set(key for key in module_attrs
                    if key[0] != '_' and not callable(getattr(module, key))
                    and not hasattr(getattr(module, key), '__dict__'))
    conn = None
    try:
        conn = psycopg2.connect(C.DATABASE_URL, sslmode='require')
        cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
        cur.execute("SELECT * FROM memory")
        rows = cur.fetchall()
        for row in rows:
            #print("%s %s %s" % (row["id"], row["var"], row["val"]))
            if row['var'] in variables and not row['var'] in not_load:
                try:
                    if row['val'] == 'set()':
                        v = set()
                    else:
                        v = ast__literal_eval(row['val'])
                except Exception as e:
                    other.pr_error(e, 'load_mem')
                    log.jW("ast.literal_eval can't eval [%s] = '%s'" %
                           (row['var'], row['val']))
                else:
                    setattr(module, row['var'], v)
    except psycopg2.DatabaseError as e:
        log.E('<ev.load_mem> DatabaseError %s' % e)
        sys.exit(1)
    else:
        log.I('+ memory loaded successfully')
    finally:
        if conn:
            conn.close()
예제 #10
0
async def format_mess(msg, time=False, date=False, dbase=None):
    """
    :type msg: C.Types.Message
    :type time: Bool
    :type date: Bool
    :type dbase: dict
    :rtype: str
    """
    try:
        t_m = other.t2s(msg.timestamp)
        t_n = other.t2s()
        s_time = ('(from {0})'.format(t_m) if
                  (time or (t_n[:-1] != t_m[:-1]) or
                   (int(t_n[-1]) - int(t_m[-1]) > 1)) else '')

        if msg.channel.is_private:
            ch_name = '@#' + str(msg.channel.user)
        else:
            every_prm = msg.channel.overwrites_for(msg.server.default_role)
            if msg.server.id == C.vtm_server.id and every_prm.read_messages is False:
                ch_name = '##' + str(msg.channel.name)
            else:
                ch_name = '#' + str(msg.channel.name)

        t = ('(from {0})'.format(other.t2s(msg.timestamp, '%d|%m|%y %T'))
             if date else s_time)
        cont = msg.content or (
            ('≤System≥ ' + msg.system_content) if msg.system_content else '')
        cont = cont.replace('\n', '\n\t')  # type: str
        db = dbase if dbase is not None else {}  # we need a=={} if it is
        if msg.author.id not in db:
            db[msg.author.id] = msg.author
        if msg.raw_mentions:
            for uid in msg.raw_mentions:
                if uid in db:
                    usr = db[uid]
                else:
                    usr = other.find_member(msg.server,
                                            uid) or other.find_user(uid)
                    if not usr:
                        usr = await C.client.get_user_info(uid)
                    if usr:
                        db[uid] = usr
                    else:
                        continue
                usr_name = other.uname(usr)
                cont = cont.replace('<@' + usr.id + '>',
                                    usr_name).replace('<@!' + usr.id + '>',
                                                      usr_name)
        if msg.raw_channel_mentions:
            for chid in msg.raw_channel_mentions:
                ch = C.client.get_channel(chid)
                if ch:
                    cont = cont.replace('<#' + ch.id + '>', '#' + str(ch))
        if msg.raw_role_mentions and msg.server:
            for role_id in msg.raw_role_mentions:
                role = other.find(msg.server.roles, id=role_id)
                if not role:
                    for s in C.client.servers:
                        if s.id == msg.server.id:
                            continue
                        role = other.find(s.roles, id=role_id)
                        if role:
                            break
                if role:
                    cont = cont.replace('<@&' + role.id + '>', '&' + str(role))
        a_n = other.uname(msg.author)
        return '{t}<{ch}> {author}: {cont}'.format(t=t,
                                                   ch=ch_name,
                                                   author=a_n,
                                                   cont=cont)
    except Exception as e:
        other.pr_error(e, 'log.format_mess', 'format_mess[253] error')
        return '<format error> ' + (msg.content or (
            ('≤System≥ ' + msg.system_content) if msg.system_content else ''))
예제 #11
0
async def mess_plus(message,
                    save_disc_links=False,
                    save_all_links=False,
                    update_links=False,
                    other_channel=None):
    try:
        emb_keys = {
            'author': ['name', 'icon_url'],
            'image': ['url'],
            'fields': ['name', 'value'],
            'footer': ['icon_url', 'text'],
        }
        links = []
        res = []
        if message.attachments:
            attachments = []
            for att in message.attachments:
                url = att['proxy_url'] or att['url']
                attachments.append('\t\t' + url)
                if save_all_links or (save_disc_links and 'discordapp'
                                      in url) and url not in disc_links:
                    links.append(url)
            if attachments:
                res.append('Attachments({0}):'.format(len(attachments)))
                res.append('\n'.join(attachments))

        if message.embeds:
            embeds = []
            i = 1
            for emb in message.embeds:
                embed = ['\tEmb_' + str(i) + ':']
                embed += other.str_keys(emb, ['title', 'url', 'description'],
                                        '\t\t')

                for key in emb_keys:
                    if key in emb:
                        if isinstance(emb[key], list):
                            j = 1
                            for l in emb[key]:
                                embed += ['\t\t[{0}_{1}]:'.format(key, str(j))]
                                embed += other.str_keys(
                                    l, emb_keys[key], '\t\t\t')
                                j += 1
                        else:
                            embed += ['\t\t[{0}]:'.format(key)]
                            embed += other.str_keys(emb[key], emb_keys[key],
                                                    '\t\t\t')

                i += 1
                if embed:
                    embeds.append('\n'.join(embed))

            if embeds:
                text_embeds = '\n'.join(embeds)
                res.append(text_embeds)
                if save_all_links:
                    links += re.findall(r'https?://.*\S', text_embeds)
                elif save_disc_links:
                    links += re.findall(r'https?://.*discordapp.*\S',
                                        text_embeds)

        if links:
            links = list(set(links).difference(disc_links))
            if links:
                disc_links.update(links)
                if not update_links:
                    text = '[{t}]<{ch}> {author} ({desc})'.format(
                        t=other.t2s(message.timestamp, '%d|%m|%y %T'),
                        ch=str(message.channel.name or message.author),
                        author=str(message.author),
                        desc='save_all_links'
                        if save_all_links else 'save_disc_links')
                    ch = (other_channel
                          or (C.vtm_links_ch if
                              (message.server and message.server.id
                               == C.vtm_server.id) else C.other_links_ch))
                    await C.client.send_message(ch, content=text)
                    async for file, name, url in other.get_url_files(links):
                        try:
                            await C.client.send_file(ch,
                                                     file,
                                                     filename=name,
                                                     content='<' + url + '>')
                        except Exception as e:
                            other.pr_error(e, 'log.mess_plus',
                                           'send_file error')
                            try:
                                await C.client.send_message(ch, content=url)
                            except Exception as e:
                                other.pr_error(e, 'log.mess_plus',
                                               'send_just_url error')

        return ['\n'.join(res)] if res else []
    except Exception as e:
        other.pr_error(e, 'log.mess_plus', 'mess_plus[198] error')
        return []