async def yes(): await ctx.send( Lang.get_string('custom_commands/updating_command')) await ctx.invoke(self.update, trigger, reply=reply)
async def setflag(self, ctx: commands.Context, trigger: str = None, flag: int = None, value: bool = None): """ar_update_help""" db_trigger = None while db_trigger is None: if trigger is None: try: trigger = await self.choose_trigger(ctx) except ValueError: return # get db trigger based on raw trigger db_trigger = await get_db_trigger(ctx.guild.id, trigger) trigger = None try: options = [] flag_names = [] for i, v in self.flags.items(): options.append(f"{v}) {i}") flag_names.append(i) if flag is None: options = '\n'.join(options) flag = int(await Questions.ask_text( self.bot, ctx.channel, ctx.author, Lang.get_string('autoresponder/which_flag', options=options))) if not len(flag_names) > int(flag) >= 0: raise ValueError if value is None: def choose(val): nonlocal value value = bool(val) await Questions.ask( self.bot, ctx.channel, ctx.author, Lang.get_string('autoresponder/on_or_off', subject=flag_names[flag]), [ Questions.Option( f"YES", 'On', handler=choose, args=[True]), Questions.Option( f"NO", 'Off', handler=choose, args=[False]) ], delete_after=True, show_embed=True) if flag not in AutoResponders.flags.values(): msg = "Invalid Flag. Try one of these:\n" for key, value in AutoResponders.flags.items(): msg += f"{value}: {key}\n" await ctx.send(msg) return if value: db_trigger.flags = db_trigger.flags | (1 << flag) await ctx.send(f"`{self.get_flag_name(flag)}` flag activated") if flag is self.flags['mod_action']: await ctx.send( Lang.get_string('autoresponder/mod_action_warning')) else: db_trigger.flags = db_trigger.flags & ~(1 << flag) await ctx.send(f"`{self.get_flag_name(flag)}` flag deactivated" ) db_trigger.save() await self.reload_triggers(ctx) except asyncio.TimeoutError: pass except ValueError: await nope(ctx)
async def bug_maintenance(self, ctx, active: bool): """ Bot maintenance mode. Closes bug reporting channels and opens bug maintenance channel. Watches active bug reports for 10 minutes or so to give people a chance to finish reports in progress. """ for guild in self.bot.guilds: try: default_role = guild.default_role # show/hide maintenance channel maint_message_channel = self.bot.get_guild_maintenance_channel(guild.id) if maint_message_channel is None: message = f'maintenance channel is not configured for `{guild.name}`' await self.bot.guild_log(guild.id, message) await ctx.send(message) continue channel_overwrite = maint_message_channel.overwrites_for(default_role) channel_overwrite.view_channel = active await maint_message_channel.set_permissions(default_role, overwrite=channel_overwrite) guild_config = self.bot.get_guild_db_config(guild.id) beta_role = None if guild_config and guild_config.betarole: beta_role = guild.get_role(guild_config.betarole) beta_overwrite = maint_message_channel.overwrites[beta_role] beta_overwrite.read_messages = active await maint_message_channel.set_permissions(beta_role, overwrite=beta_overwrite) else: message = f'beta role is not configured for `{guild.name}`' await self.bot.guild_log(guild.id, message) await ctx.send(message) for row in guild_config.bug_channels: cid = row.channelid branch = row.platform.branch # show/hide reporting channels channel = guild.get_channel(cid) channel_overwrite = channel.overwrites_for(default_role) channel_overwrite.read_messages = False if active else True await channel.set_permissions(default_role, overwrite=channel_overwrite) if re.search(r'beta', branch, re.I) and beta_role: beta_overwrite = channel.overwrites[beta_role] beta_overwrite.read_messages = False if active else True await channel.set_permissions(beta_role, overwrite=beta_overwrite) except Exception as e: await ctx.send( Lang.get_locale_string( 'bugs/report_channel_permissions_fail', ctx, channel=maint_message_channel.mention, server=guild.name)) await Utils.handle_exception("failed to set bug report channel permissions", self.bot, e) else: if active: self.maint_check_count = 0 if not self.verify_empty_bug_queue.is_running(): self.maintenance_message = None self.verify_empty_bug_queue.start(ctx) await ctx.send(Lang.get_locale_string('bugs/maint_on', ctx)) else: await ctx.send(Lang.get_locale_string('bugs/maint_off', ctx))
async def yes(): await ctx.send(Lang.get_string('autoresponder/updating')) await ctx.invoke(self.update, db_trigger, reply=reply)
async def help(self, ctx: commands.Context): await ctx.send(Lang.get_string('autoresponder/help'))
# Set models, criteria, optimizers generator = Generator(args.vocab_size, g_embed_dim, g_hidden_dim, args.cuda) nll_loss = nn.NLLLoss() gen_optimizer = optim.Adam(params=generator.parameters(), lr=args.gen_lr) if args.cuda: generator = generator.cuda() nll_loss = nll_loss.cuda() cudnn.benchmark = True # Container of experiment data train_loss = [] eval_loss = [] # Read real data and build vocab dictionary lang = Lang(args.vocab_size, POSITIVE_FILE) with open(VOCAB_FILE, 'wb') as f: pkl.dump(lang, f, protocol=pkl.HIGHEST_PROTOCOL) # Pre-train generator using MLE print('#####################################################') print('Start pre-training generator with MLE...') print('#####################################################\n') gen_data_iter = getGenDataIter(VOCAB_FILE, POSITIVE_FILE, args.batch_size, g_seq_len) for epoch in range(args.epochs): train_generator_MLE(generator, gen_data_iter, nll_loss, gen_optimizer, epoch, train_loss, args) eval_iter = getGenDataIter(VOCAB_FILE, EVAL_FILE, args.batch_size, g_seq_len) gen_loss = eval_generator(generator, eval_iter, nll_loss, args)
# import the necessary packages import json import os import random import jieba import pandas as pd import torch from config import device, save_folder, valid_folder, valid_filename from data_gen import parse_user_reviews, batch2TrainData from utils import Lang, encode_text if __name__ == '__main__': voc = Lang('data/WORDMAP.json') print("voc.n_words: " + str(voc.n_words)) checkpoint = '{}/BEST_checkpoint.tar'.format( save_folder) # model checkpoint print('checkpoint: ' + str(checkpoint)) # Load model checkpoint = torch.load(checkpoint) encoder = checkpoint['encoder'] # Use appropriate device encoder = encoder.to(device) # Set dropout layers to eval mode encoder.eval()
async def entries(self, ctx: commands.Context): """reporting group""" if ctx.invoked_subcommand is None: await ctx.send(Lang.get_string('sweeps/entries_sub_command'))
async def end_sweeps(self, ctx: commands.Context): """reporting group""" # TODO: add sub-commands for ending, with reaction clear, restarting with reaction reset to only author if ctx.invoked_subcommand is None: await ctx.send(Lang.get_string('sweeps/end_sweeps_sub_command'))
async def ask_text( bot, channel, user, text, validator=None, timeout=Configuration.get_var("question_timeout_seconds"), confirm=False, escape=True, delete_after=False, locale="en_US"): def check(msg): return user == msg.author and msg.channel == channel ask_again = True def confirmed(): nonlocal ask_again ask_again = False def clean_text(txt): """Remove multiple spaces and multiple newlines from input txt.""" txt = re.sub(r' +', ' ', txt) txt = re.sub(r'\n\s*\n', '\n\n', txt) return txt my_messages = [] async def clean_dialog(): nonlocal delete_after nonlocal my_messages if delete_after: for msg in my_messages: try: await msg.delete() except Exception as e: pass while ask_again: message_cleaned = "" my_messages.append(await channel.send(text)) try: while True: message = await bot.wait_for('message', timeout=timeout, check=check) my_messages.append(message) if message.content is None or message.content == "": result = Lang.get_locale_string("questions/text_only", locale) else: message_cleaned = clean_text(message.content) result = validator(message_cleaned) if validator is not None else True if result is True: break else: my_messages.append(await channel.send(result)) except asyncio.TimeoutError as ex: await clean_dialog() await channel.send( # TODO: remove "bug" from lang string. send report cancel language from Bugs.py exception handler Lang.get_locale_string("questions/error_reaction_timeout", locale, error_emoji=Emoji.get_emoji("WARNING"), timeout=timeout_format(timeout)) ) raise ex else: content = Utils.escape_markdown(message_cleaned) if escape else message_cleaned if confirm: backticks = "``" if len(message_cleaned.splitlines()) == 1 else "```" message = Lang.get_locale_string('questions/confirm_prompt', locale, backticks=backticks, message=message_cleaned) await ask(bot, channel, user, message, [ Option("YES", handler=confirmed), Option("NO") ], delete_after=delete_after) else: confirmed() await clean_dialog() return content
async def sweepstakes(self, ctx: commands.Context): """sweeps help""" if ctx.invoked_subcommand is None: await ctx.send(Lang.get_string('sweeps/help'))
async def ask_attachements( bot, channel, user, timeout=Configuration.get_var("question_timeout_seconds"), max_files=Configuration.get_var('max_attachments'), locale="en_US"): def check(message): return user == message.author and message.channel == channel done = False def ready(): nonlocal done done = True async def restart_attachments(): nonlocal final_attachments final_attachments = [] await ask(bot, channel, user, Lang.get_locale_string("questions/attachments_restart", locale), [ Option("YES", Lang.get_locale_string('questions/restart_attachments_yes', locale)), Option("NO", Lang.get_locale_string('questions/restart_attachments_no', locale), handler=ready) ], show_embed=True) while not done: ask_again = True final_attachments = [] count = 0 def confirmed(): nonlocal ask_again ask_again = False while ask_again: if not final_attachments: await channel.send(Lang.get_locale_string("questions/attachment_prompt", locale, max=max_files)) elif len(final_attachments) < max_files - 1: await channel.send( Lang.get_locale_string("questions/attachment_prompt_continued", locale, max=max_files - len(final_attachments))) elif len(final_attachments): await channel.send(Lang.get_locale_string("questions/attachment_prompt_final", locale)) done = False try: while True: message = await bot.wait_for('message', timeout=timeout, check=check) links = Utils.URL_MATCHER.findall(message.content) attachment_links = [str(a.url) for a in message.attachments] if len(links) != 0 or len(message.attachments) != 0: if (len(links) + len(message.attachments)) > max_files: await channel.send(Lang.get_locale_string("questions/attachments_overflow", locale, max=max_files)) else: final_attachments += links + attachment_links count += len(links) + len(attachment_links) break else: await channel.send(Lang.get_locale_string("questions/attachment_not_found", locale)) except asyncio.TimeoutError as ex: await channel.send( Lang.get_locale_string("questions/error_reaction_timeout", locale, error_emoji=Emoji.get_emoji("WARNING"), timeout=timeout_format(timeout)) ) raise ex else: if count < max_files: await ask(bot, channel, user, Lang.get_locale_string('questions/another_attachment', locale), [Option("YES"), Option("NO", handler=confirmed)]) else: ask_again = False prompt_yes = Lang.get_locale_string("questions/approve_attachments", locale) if len(final_attachments) == 1: prompt_no = Lang.get_locale_string('questions/restart_attachment_singular', locale) else: prompt_no = Lang.get_locale_string('questions/restart_attachment_plural', locale) await ask(bot, channel, user, Lang.get_locale_string('questions/confirm_attachments', locale), [ Option("YES", prompt_yes, handler=ready), Option("NO", prompt_no, handler=restart_attachments) ], show_embed=True) return final_attachments
async def reload(self, ctx): """Reload language locale files""" Lang.load_locales() await ctx.send(Lang.get_locale_string('lang/reloaded', ctx, server_name=ctx.guild.name))
def __init__(self, bot): super().__init__(bot) Lang.load_locales()
async def reload_lang(self, ctx): """ Reload localization files """ Lang.load() await ctx.send("Language file reloaded")
async def end_reset(self, ctx: commands.Context, jump_url: str): message: Message = await self.get_reaction_message(ctx, jump_url) if not message.reactions: # no reactions to reset await ctx.send(Lang.get_string('sweeps/no_reactions')) return # gather all emojis from message reactions my_emoji = set() not_my_emoji = set() for reaction in message.reactions: if (isinstance(reaction.emoji, str) or (hasattr(reaction.emoji, 'id') and self.bot.get_emoji(reaction.emoji.id))): my_emoji.add(reaction.emoji) else: # Can't use a custom emoji from a server I'm not in not_my_emoji.add(reaction.emoji) clear = True def no(): nonlocal clear clear = False async def yes(): await ctx.send( Lang.get_string('sweeps/invalid_emoji_confirm', count=len(not_my_emoji))) if not_my_emoji: # some emoji on the original message that I can't access if not my_emoji: # no emoji left that I can add back. prompt = Lang.get_string('sweeps/all_invalid_emoji') else: prompt = Lang.get_string('sweeps/some_invalid_emoji') try: await Questions.ask(self.bot, ctx.channel, ctx.author, prompt, [ Questions.Option('YES', handler=yes), Questions.Option('NO', handler=no) ], delete_after=True) except asyncio.TimeoutError: return if clear: # show entries await self.fetch_unique(ctx, message) await self.fetch_all(ctx, message) pending = await ctx.send( Lang.get_string('sweeps/removing_reactions')) await message.clear_reactions() await pending.delete() if my_emoji: pending = await ctx.send( Lang.get_string('sweeps/adding_reactions')) emoji_success = True add_react_msg = await ctx.send( Lang.get_string('sweeps/adding_reactions_progress')) for emoji in my_emoji: try: # emoji = f"{emoji.id}" if hasattr(emoji, "id") else emoji await message.add_reaction(emoji) await add_react_msg.edit( content=f"{add_react_msg.content} {emoji}") except discord.errors.HTTPException as e: emoji_success = False await ctx.send( Lang.get_string('sweeps/emoji_fail', emoji=emoji)) continue await pending.delete() if not emoji_success: await ctx.send(Lang.get_string('sweeps/partial_emoji_fail') ) await ctx.send(Lang.get_string('sweeps/drawing_restarted')) else: await ctx.send(Lang.get_string('sweeps/drawing_closed'))
#if args.arch=='ernn': #net=ernn.NTRNN #elif args.arch=='darnn': #net=darnn.DARNN #else: net = rnn.RNN logfileAcc = open("log_gru_acc%d.txt" % args.hidden_size, 'w') logfileLoss = open("log_gru_loss%d.txt" % args.hidden_size, 'w') # Set batch size to 1 for embedding dataloaders['train'].set_batch_size(1) dataloaders['test'].set_batch_size(1) # Word embedding lang = Lang('eng') for _, (text, _) in enumerate(dataloaders['train']): for i in range(len(text)): lang.addSentence(text[i]) for _, (text, _) in enumerate(dataloaders['test']): for i in range(len(text)): lang.addSentence(text[i]) dataloaders['train'].set_batch_size(batch_size) dataloaders['test'].set_batch_size(batch_size) embedding = nn.Embedding(lang.n_words, input_size, padding_idx=0) encoder = EncoderRNN(input_size, hidden_size, embedding,
async def yes(): await ctx.send( Lang.get_string('sweeps/invalid_emoji_confirm', count=len(not_my_emoji)))
import torch import random import transformer.Modules as Modules from torch import optim import utils.Lang as Lang from dataset.groupSet import groupSet import torch.nn as nn from Config import * import transformer.Modules as Modules import transformer.Models as Models import torch from torch.autograd import Variable from torch.utils.data import DataLoader mylang = Lang.npLang('all','data/clean_group.npy') mylang.prepareData() mydata = groupSet(mylang) mydata.loadfnp('data/clean_group.npy') input_size = mylang.n_words output_size = mylang.n_words hidden_size = 128 for item in mydata[0]: print(item) # for session in mydata: # criterion = nn.NLLLoss() # in_session = session[0:-1] # tar_session = session[1:] # hidden = torch.zeros(1, in_session.shape[0], hidden_size, device=device)
async def help(self, ctx): await ctx.send(Lang.get_string('sweeps/help'))
async def nope(ctx, msg: str = None): msg = msg or Lang.get_string('nope') await ctx.send(f"{Emoji.get_chat_emoji('WARNING')} {msg}")
async def yes(): await ctx.send( Lang.get_locale_string( 'custom_commands/updating_command', ctx)) await ctx.invoke(self.update, trigger, response=response)
async def no(): await ctx.send( Lang.get_string('autoresponder/not_updating'))
async def no(): await ctx.send( Lang.get_locale_string( 'custom_commands/not_updating_command', ctx))
async def setchannel(self, ctx: commands.Context, mode: str = None, trigger: str = None, channel_id: int = None): if mode is None or mode not in ['respond', 'listen']: def choose(val): nonlocal mode mode = val try: await Questions.ask( self.bot, ctx.channel, ctx.author, Lang.get_string('autoresponder/which_mode'), [ Questions.Option(f"NUMBER_1", 'Response Channel', handler=choose, args=['respond']), Questions.Option(f"NUMBER_2", 'Listen Channel', handler=choose, args=['listen']) ], delete_after=True, show_embed=True) except (ValueError, asyncio.TimeoutError) as e: return if trigger is None: try: trigger = await self.choose_trigger(ctx) except ValueError: return db_trigger = await get_db_trigger(ctx.guild.id, trigger) if not channel_id: channel_id = await Questions.ask_text( self.bot, ctx.channel, ctx.author, Lang.get_string("autoresponder/prompt_channel_id", mode=mode)) channel_id = re.sub(r'[^\d]', '', channel_id) if db_trigger is None or not re.match(r'^\d+$', channel_id): await nope(ctx) return channel = self.bot.get_channel(int(channel_id)) if channel_id is "0": await ctx.send( Lang.get_string("autoresponder/channel_unset", mode=mode, trigger=get_trigger_description(trigger))) elif channel is not None: await ctx.send( Lang.get_string("autoresponder/channel_set", channel=channel.mention, mode=mode, trigger=get_trigger_description(trigger))) else: await ctx.send( Lang.get_string("autoresponder/no_channel", mode=mode)) return if mode == "respond": db_trigger.responsechannelid = channel_id elif mode == "listen": db_trigger.listenchannelid = channel_id db_trigger.save() await self.reload_triggers(ctx)
async def add(self, ctx, sourceid: int, targetid: int): # validate channel ids source_channel = self.bot.get_channel(sourceid) target_channel = self.bot.get_channel(targetid) if not source_channel: await ctx.send( Lang.get_locale_string('dropbox/channel_not_found', ctx, channel_id=sourceid)) if not target_channel: await ctx.send( Lang.get_locale_string('dropbox/channel_not_found', ctx, channel_id=targetid)) if not source_channel or not target_channel: # valid source and target channels are required return # initialize to None for the case of adding a new entry update_entry = None # channel descriptions source_description = Utils.get_channel_description(self.bot, sourceid) new_target_description = Utils.get_channel_description( self.bot, targetid) old_target_description = "" def update(choice): nonlocal update_entry update_entry = choice if sourceid in self.dropboxes[ctx.guild.id]: # existing source channel. ask user to confirm old_target_description = Utils.get_channel_description( self.bot, self.dropboxes[ctx.guild.id][sourceid].targetchannelid) try: await Questions.ask( self.bot, ctx.channel, ctx.author, Lang.get_locale_string('dropbox/override_confirmation', ctx, source=source_description, old_target=old_target_description, new_target=new_target_description), [ Questions.Option('YES', handler=lambda: update(True)), Questions.Option('NO', handler=lambda: update(False)) ], delete_after=True, locale=ctx) except asyncio.TimeoutError as e: update(False) if update_entry is False: # user chose not to update await ctx.send(Lang.get_locale_string('dropbox/not_updating', ctx)) return if update_entry: # user chose to update msg = Lang.get_locale_string('dropbox/updated', ctx, source=source_description, old_target=old_target_description, new_target=new_target_description) else: # no existing source. adding a new dropbox msg = Lang.get_locale_string('dropbox/added', ctx, source=source_description, target=new_target_description) # update local mapping and save to db db_row = DropboxChannel.get_or_create(serverid=ctx.guild.id, sourcechannelid=sourceid)[0] db_row.targetchannelid = targetid db_row.save() self.dropboxes[ctx.guild.id][sourceid] = db_row # message success to user await ctx.send(msg)
async def on_message(self, message: discord.Message): if message.author.bot or not hasattr(message.author, "guild"): return welcome_channel = self.bot.get_config_channel(message.guild.id, Utils.welcome_channel) rules_channel = self.bot.get_config_channel(message.guild.id, Utils.rules_channel) log_channel = self.bot.get_config_channel(message.guild.id, Utils.log_channel) member_role = message.guild.get_role( Configuration.get_var("member_role")) nonmember_role = message.guild.get_role( Configuration.get_var("nonmember_role")) if message.author.id == 349977940198555660: # is gearbot pattern = re.compile( r'\(``(\d+)``\) has re-joined the server before their mute expired' ) match = re.search(pattern, message.content) if match: user_id = int(match[1]) # gearbot is handling it. never unmute this user self.remove_member_from_cooldown(message.guild.id, user_id) muted_member = message.guild.get_member(user_id) muted_member_name = Utils.get_member_log_name(muted_member) await log_channel.send(f''' Gearbot re-applied mute when member re-joined: {muted_member_name} I won't try to unmute them later. ''') return if message.author.guild_permissions.mute_members or \ await self.member_verify_action(message) or \ member_role in message.author.roles: # is a mod or # verification flow triggered. no further processing or # message from regular member. no action for welcomer to take. return # ignore when channels not configured if not welcome_channel or not rules_channel or message.channel.id != welcome_channel.id: if member_role not in message.author.roles: # nonmember speaking somewhere other than welcome channel? Maybe we're not using the # welcome channel anymore? or something else went wrong... give them member role. try: await message.author.add_roles(member_role) if nonmember_role in message.author.roles: Logging.info( f"{Utils.get_member_log_name(message.author)} - had shadow role when speaking. removing it!" ) await message.author.remove_roles(nonmember_role) except Exception as e: try: Logging.info(f"message: {message.content}") Logging.info(f"author id: {message.author.id}") except Exception as ee: pass await Utils.handle_exception("member join exception", self.bot, e) return # Only act on messages in welcome channel from here on # Nonmember will only be warned once every 10 minutes that they are speaking in welcome channel now = datetime.now().timestamp() then = 0 grace_period = 10 * 60 # 10 minutes try: was_welcomed = self.welcome_talkers[message.guild.id][ message.author.id] then = was_welcomed + grace_period except Exception as ex: # TODO: refine exception. KeyError only? pass if then > now: # grace period has not expired. Do not warn member again yet. # print("it hasn't been 10 minutes...") return # record the time so member won't be pinged again too soon if they keep talking self.welcome_talkers[message.guild.id][message.author.id] = now await welcome_channel.send( Lang.get_string("welcome/welcome_help", author=message.author.mention, rules_channel=rules_channel.mention)) # ping log channel with detail if log_channel: await log_channel.send( f"{Utils.get_member_log_name(message.author)} " f"spoke in {welcome_channel.mention} ```{message.content}```")
async def drop_message_impl(self, source_message, drop_channel): ''' handles copying to dropbox, sending confirm message in channel, sending dm receipt, and deleting original for each message in any dropbox ''' guild_id = source_message.channel.guild.id source_channel_id = source_message.channel.id source_message_id = source_message.id # get the ORM row for this dropbox. drop = None if source_channel_id in self.dropboxes[guild_id]: drop = self.dropboxes[guild_id][source_channel_id] else: # should only return one entry because of how rows are added drop = DropboxChannel.select().where( DropboxChannel.serverid == guild_id and DropboxChannel.sourcechannelid == source_channel_id) # the embed to display who was the author in dropbox channel embed = Embed(timestamp=source_message.created_at, color=0x663399) embed.set_author( name=f"{source_message.author} ({source_message.author.id})", icon_url=source_message.author.avatar_url_as(size=32)) embed.add_field(name="Author link", value=source_message.author.mention) ctx = await self.bot.get_context(source_message) pages = Utils.paginate(source_message.content) page_count = len(pages) if source_message.author.dm_channel is None: await source_message.author.create_dm() dm_channel = source_message.author.dm_channel attachment_names = [] delivery_success = None try: # send embed and message to dropbox channel for attachment in source_message.attachments: try: buffer = io.BytesIO() await attachment.save(buffer) await drop_channel.send( file=discord.File(buffer, attachment.filename)) attachment_names.append(attachment.filename) except Exception as attach_e: await drop_channel.send( Lang.get_locale_string( 'dropbox/attachment_fail', ctx, author=source_message.author.mention)) if len(pages) == 0: # means no text content included if len(attachment_names) < 1: # if there isn't any attachments, the dropbox might end up having a floating embed so include a helpful message too last_drop_message = await drop_channel.send( embed=embed, content=Lang.get_locale_string('dropbox/msg_blank', ctx)) else: last_drop_message = await drop_channel.send(embed=embed) else: # deliver all the pages of text content for i, page in enumerate(pages[:-1]): if len(pages) > 1: page = f"**{i+1} of {page_count}**\n{page}" await drop_channel.send(page) last_page = pages[ -1] if page_count == 1 else f"**{page_count} of {page_count}**\n{pages[-1]}" last_drop_message = await drop_channel.send(embed=embed, content=last_page) # TODO: try/ignore: add reaction for "claim" "flag" "followup" "delete" msg = Lang.get_locale_string('dropbox/msg_delivered', ctx, author=source_message.author.mention) await ctx.send(msg) delivery_success = True except Exception as e: msg = Lang.get_locale_string('dropbox/msg_not_delivered', ctx, author=source_message.author.mention) await ctx.send(msg) await self.bot.guild_log(guild_id, "broken dropbox...? Call alex, I guess") await Utils.handle_exception("dropbox delivery failure", self.bot, e) delivery_success = False try: # delete original message, the confirmation of sending is deleted in clean_channels loop await source_message.delete() del self.drop_messages[guild_id][source_channel_id][ source_message_id] set(self.delivery_in_progress[guild_id][source_channel_id]).remove( source_message_id) except discord.errors.NotFound as e: # ignore missing message pass #give senders a moment before spam pinging them the copy await asyncio.sleep(1) try: # try sending dm receipts and report in dropbox channel if it was sent or not if drop and drop.sendreceipt: # get the locale versions of the messages for status, receipt header, and attachments ready to be sent status_msg = Lang.get_locale_string( 'dropbox/msg_delivered' if delivery_success else 'dropbox/msg_not_delivered', ctx, author="") receipt_msg_header = Lang.get_locale_string( 'dropbox/msg_receipt', ctx, channel=ctx.channel.mention) if len(attachment_names) == 0: attachment_msg = "" else: attachment_msg_key = 'dropbox/receipt_attachment_plural' if len( attachment_names ) > 1 else 'dropbox/receipt_attachment_singular' attachment_msg = Lang.get_locale_string( attachment_msg_key, ctx, number=len(attachment_names), attachments=", ".join(attachment_names)) # might as well try to stuff in as few pages as possible dm_header_pages = Utils.paginate( f"{status_msg}\n{receipt_msg_header}\n{attachment_msg}") for page in dm_header_pages: await dm_channel.send(page) if len(pages) == 0: # no text content if len(attachment_names) < 1: #if no text and no attachments, then send a response that there wasn't any text content await dm_channel.send(content=Lang.get_locale_string( 'dropbox/msg_blank', ctx)) else: # send the page(s) in code blocks to dm. for i, page in enumerate(pages[:-1]): if len(pages) > 1: page = f"**{i+1} of {page_count}**\n```{page}```" await dm_channel.send(page) last_page = f'```{pages[-1]}```' if page_count == 1 else f"**{page_count} of {page_count}**\n```{pages[-1]}```" await dm_channel.send(last_page) if delivery_success: embed.add_field(name="receipt status", value="sent") # this is used if drop first before dms to add status to embed await last_drop_message.edit(embed=embed) except Exception as e: Logging.info( "Dropbox DM receipt failed, not an issue so ignoring exception and giving up" ) if drop.sendreceipt and delivery_success: embed.add_field(name="receipt status", value="failed") # this is used if drop first before dms to add status to embed await last_drop_message.edit(embed=embed)
async def report_bug(self, user, trigger_channel): # fully ignore muted users m = self.bot.metrics last_message = await trigger_channel.history(limit=1).flatten() last_message = last_message[0] ctx = await self.bot.get_context(last_message) await asyncio.sleep(1) # Get member from home guild. failing that, check other bot.guilds for member guild = Utils.get_home_guild() member = guild.get_member(user.id) if not member: for my_guild in self.bot.guilds: member = my_guild.get_member(user.id) if member: guild = my_guild break for bot_guild in self.bot.guilds: guild_member = bot_guild.get_member(user.id) guild_config = self.bot.get_guild_db_config(bot_guild.id) guild_mute_role = bot_guild.get_role(guild_config.mutedrole) if guild_member and guild_mute_role and (guild_mute_role in guild_member.roles): # member is muted in at least one server. hard pass on letting them report return if member is None: # user isn't even on the server, how did we get here? return if user.id in self.in_progress: # already tracking progress for this user if user.id in self.blocking: # user blocked from starting a new report. waiting for DM response await ctx.send(Lang.get_locale_string("bugs/stop_spamming", ctx, user=user.mention), delete_after=10) return should_reset = False async def start_over(): nonlocal should_reset should_reset = True # block more clicks to the initial trigger self.blocking.add(user.id) # ask if user wants to start over await Questions.ask(self.bot, trigger_channel, user, Lang.get_locale_string("bugs/start_over", ctx, user=user.mention), [ Questions.Option("YES", Lang.get_locale_string("bugs/start_over_yes", ctx), handler=start_over), Questions.Option("NO", Lang.get_locale_string("bugs/start_over_no", ctx)) ], delete_after=True, show_embed=True, locale=ctx) # not starting over. remove blocking if user.id in self.blocking: self.blocking.remove(user.id) # cancel running task, delete progress, and fall through to start a new report await self.delete_progress(user.id) if not should_reset: # in-progress report should not be reset. bail out return # Start a bug report task = self.bot.loop.create_task(self.actual_bug_reporter(user, trigger_channel)) sweep = self.bot.loop.create_task(self.sweep_trash(user, ctx)) self.in_progress[user.id] = task self.sweeps[user.id] = sweep try: await task except CancelledError as ex: pass
def real_check(text): if len(text) > length: return Lang.get_locale_string("music/text_too_long", self.locale, max=length) # TODO: check that this string exists return True