def write(self, s): self.std.write(s) if len(s) > 2: self.logfile.write(other.t2s(frm='![%T]!\t') + s) else: self.logfile.write(s) self.flush()
async def silence_on(name, t=1.0, force=False): """ :param name: string :param t: float :param force: bool :rtype: C.Types.Member """ s = C.prm_server user = other.find_member(s, name) if not user: return None if user.top_role >= s.me.top_role and not force: return 'top_role' if other.has_roles(user, C.roles['protege']): return 'protege' t = max(t, 0.02) if user.id in ram.silence_users: check = ram.silence_users[user.id]['check'] else: check = await turn_silence(user, turn=True, force=force) ram.silence_users[user.id] = {'time': other.get_sec_total() + t * 3600 - 1, 'check': tuple(check)} if not C.is_test: add_roles = [other.find(s.roles, id=C.roles['Silence'])] other.add_roles(user, add_roles, 'silence_on') log.I('Silence on for ', user, ' at ', other.t2s(), ' on ', t, 'h.') return user
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.")
async def silence_off(name): """ :param name: string :rtype: C.Types.Member """ s = C.prm_server user = other.find_member(s, name) if not user: ram.silence_users.pop(name, 0) return None s_user = ram.silence_users.pop(user.id, False) if s_user: await turn_silence(user, turn=False, check=s_user['check']) if not C.is_test: rem_roles = [other.find(s.roles, id=C.roles['Silence'])] other.rem_roles(user, rem_roles, 'silence_off') log.I('Silence off for ', user, ' at ', other.t2s()) return user else: return False
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 []
def E(*args, sep=''): print('!!!\t<E>[{0}]'.format(other.t2s(frm='%T')), *args, sep=sep)
def time_tpprint(kind, *args, sep=''): #time_type_print print('<{0}>[{1}] '.format(kind, other.t2s(frm='%T')), *args, sep=sep)
def tp(*args, sep=''): #time_print print(other.t2s(frm='[%T]'), *args, sep=sep)
def make_d2u(): log.I('<make_d2u>') log.jI('\t -make dictionary good_type') good_time = {} def _make_gt_phrases(phrases, obj2save=None, resp=False): obj2save = obj2save or { 'simple': set(), 'check_phrases': [], 'response': [] } if not phrases: return obj2save if 'simple' in phrases: obj2save['simple'].update(phrases['simple']) for noun in phrases['noun']: for adj in phrases['adj']: n_a = ' '.join((noun, adj)) a_n = ' '.join((adj, noun)) obj2save['check_phrases'].append(n_a) obj2save['check_phrases'].append(a_n) if resp: obj2save['response'].append(a_n) return obj2save for g_key in d2p.good_time: g_period = [] for d_type in d2p.good_time[g_key]: gt_type = {} if 'key' in d_type: gt_type = _make_gt_phrases(d_type['key']) gt_type = _make_gt_phrases(d_type, gt_type, resp=True) gt_type = { 'simple': gt_type['simple'], 'check_phrases': tuple(gt_type['check_phrases']), 'response': tuple(gt_type['response']) } g_period.append(gt_type) good_time[g_key] = tuple(g_period) log.jI('\t -make resp_keys') resp_keys = {} # searching resp_keys can be done with regex, but test show, # that intersection with set(words) and "in"-check(collocations) in for-cycle are faster (≈ in 10 times) def _make_words(words, endings): s = set() for w in words: s.update({f'{w}{end}' for end in endings}) return s for ind, keys in d2p.response_keys.items(): dct = {'words': set(), 'colls': set()} dct['words'].update(keys.clear) dct['words'].update(_make_words(keys.noun, d2p.noun_endings)) dct['words'].update(_make_words(keys.adj, d2p.adj_endings)) dct['words'].update(_make_words(keys.eng, d2p.eng_endings)) dct['colls'].update(keys.clear_collocation) for coll in keys.n_c: dct['colls'].update( {f'{coll[0]}{end} {coll[1]}' for end in d2p.noun_endings}) for coll in keys.a_c: dct['colls'].update( {f'{coll[0]}{end} {coll[1]}' for end in d2p.adj_endings}) resp_keys[ind] = dct log.jI('\t -make resp_values & resp_data') resp_values = {} # keys: {hashes} resp_data = {} # hash : text object {'text':"", etc} def _make_resp(obj: (dict, list, tuple, set, str), add_keys: set = None): importlib__reload(d2p) add_keys = add_keys or set() add_phr = {} if isinstance(obj, str): add_phr = {'text': obj} elif isinstance(obj, dict): if 'text' in obj: add_phr = obj add_phr['text'] = str(add_phr['text']) else: for key in obj: _make_resp(obj[key], add_keys.union({key})) elif other.is_iterable( obj ): # isinstance(obj, list) or isinstance(obj, set) or isinstance(obj, tuple): for phr in obj: _make_resp(phr, add_keys) else: log.jW('<make_d2u.make_resp> Fail phrase in response data: ', obj) if add_phr: h = hashlib__md5(add_phr['text'].encode('utf-8')).hexdigest() add_phr['keys'] = set(add_phr.get('keys', set())).union(add_keys) if h in resp_data: add_phr['keys'].update(resp_data[h]['keys']) resp_data[h] = add_phr for key in add_phr['keys']: resp_values.setdefault(key, set()).add(h) _make_resp(d2p.data_text) log.jI('\t -save to d2u.py') data_used = [] saved_args = ('data_used', 'good_time', 'resp_keys', 'resp_values', 'resp_data') l_args = locals() time_upd = other.t2s(frm="%d/%m/%y %H:%M:%S") with open('d/data_to_use.py', "w", -1, 'utf-8') as file: print( '"""\nThis document was created from data_to_process.py by command !data_process' f'\nDon\'t edit it by yourself.\nCreated: {time_upd}.\n"""\n\n', file=file) print(*(f'{name} = {repr(l_args[name])}' for name in saved_args), file=file, sep='\n\n') print( f'\n\nprint("<!>\\t\\tGenerated module data_to_use from {time_upd} was successfully loaded.")', file=file) log.I('Reload module d2u...') importlib__reload(d2u) log.I('Prepare make_d2u done.')