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)
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()
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_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')
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')
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')
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.")
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
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()
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 ''))
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 []