Пример #1
0
 async def yes():
     await ctx.send(
         Lang.get_string('custom_commands/updating_command'))
     await ctx.invoke(self.update, trigger, reply=reply)
Пример #2
0
    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)
Пример #3
0
    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))
Пример #4
0
 async def yes():
     await ctx.send(Lang.get_string('autoresponder/updating'))
     await ctx.invoke(self.update, db_trigger, reply=reply)
Пример #5
0
 async def help(self, ctx: commands.Context):
     await ctx.send(Lang.get_string('autoresponder/help'))
Пример #6
0
    # 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)
Пример #7
0
# 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()
Пример #8
0
 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'))
Пример #9
0
 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'))
Пример #10
0
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
Пример #11
0
 async def sweepstakes(self, ctx: commands.Context):
     """sweeps help"""
     if ctx.invoked_subcommand is None:
         await ctx.send(Lang.get_string('sweeps/help'))
Пример #12
0
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
Пример #13
0
 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))
Пример #14
0
 def __init__(self, bot):
     super().__init__(bot)
     Lang.load_locales()
Пример #15
0
 async def reload_lang(self, ctx):
     """
     Reload localization files
     """
     Lang.load()
     await ctx.send("Language file reloaded")
Пример #16
0
    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'))
Пример #17
0
#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,
Пример #18
0
 async def yes():
     await ctx.send(
         Lang.get_string('sweeps/invalid_emoji_confirm',
                         count=len(not_my_emoji)))
Пример #19
0
Файл: test.py Проект: jinzy15/jd
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)
Пример #20
0
 async def help(self, ctx):
     await ctx.send(Lang.get_string('sweeps/help'))
Пример #21
0
async def nope(ctx, msg: str = None):
    msg = msg or Lang.get_string('nope')
    await ctx.send(f"{Emoji.get_chat_emoji('WARNING')} {msg}")
Пример #22
0
 async def yes():
     await ctx.send(
         Lang.get_locale_string(
             'custom_commands/updating_command', ctx))
     await ctx.invoke(self.update, trigger, response=response)
Пример #23
0
 async def no():
     await ctx.send(
         Lang.get_string('autoresponder/not_updating'))
Пример #24
0
 async def no():
     await ctx.send(
         Lang.get_locale_string(
             'custom_commands/not_updating_command', ctx))
Пример #25
0
    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)
Пример #26
0
    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)
Пример #27
0
    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}```")
Пример #28
0
    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)
Пример #29
0
    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
Пример #30
0
 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