Exemple #1
0
async def tagremote_update(bot, context):
    """Renames the webhook with an updated tag list file."""

    # Check for an existing session
    session_data = data.get(bot, __name__, 'data', guild_id=context.guild.id)
    if not session_data:
        raise CBException("No session available.")
    channel = data.get_channel(bot, session_data['channel'])
    if not channel:
        await _delete_session(bot, context.guild)
        raise CBException("Failed to get the channel.")
    voice_channel = data.get_channel(bot, session_data['voice_channel'])
    if not voice_channel:
        await _delete_session(bot, context.guild)
        raise CBException("Failed to get the voice channel.")
    webhooks = await channel.webhooks()
    if not webhooks:
        await _delete_session(bot, context.guild)
        raise CBException("No webhooks available.")
    for webhook in webhooks:
        if webhook.id == session_data['webhook']:
            break
    else:
        await _delete_session(bot, context.guild)
        raise CBException("Webhook not found.")

    tag_dictionary = _get_tag_dictionary(bot, context.guild)
    session_code = await _upload_session_data(bot, channel, voice_channel, webhook, tag_dictionary)

    updated_code = session_code.split(':')[1]
    await webhook.edit(name='Tag Remote [{}]'.format(updated_code))

    return Response(
        content="Tag data refreshed. Update the remote on your phone via the options menu.")
Exemple #2
0
async def setup_globals(bot):
    """Sets up the DATA_CHANNEL global"""
    global DATA_CHANNEL
    DATA_CHANNEL = data.get_channel(bot, configurations.get(bot, __name__, key='data_channel'))
    if not DATA_CHANNEL:
        logger.warn("Failed to find the data channel. Defaulting to the upload channel.")
        DATA_CHANNEL = data.get_channel(bot, configurations.get(bot, 'core', key='upload_channel'))

    # Clear any webhooks (debug)
    webhooks = await DATA_CHANNEL.webhooks()
    for webhook in webhooks:
        logger.debug("Deleting webhook %s", webhook)
        await webhook.delete()
Exemple #3
0
async def commission_configure(bot, context):
    """Configures the channel and cooldown for the commission channel rules."""
    rules = data.get(bot,
                     __name__,
                     'rules',
                     guild_id=context.guild.id,
                     default={})
    default_cooldown = configurations.get(bot, __name__, 'default_cooldown')
    replace_channel = context.options.get('channel', rules.get('channel'))
    replace_cooldown = context.options.get(
        'cooldown', rules.get('cooldown', default_cooldown))
    if not replace_channel:
        raise CBException("No commission channel configured.")

    # Reset advertisement data
    rules = {'channel': replace_channel, 'cooldown': replace_cooldown}
    data.add(bot, __name__, 'rules', rules, guild_id=context.guild.id)
    data.remove(bot,
                __name__,
                'advertisements',
                guild_id=context.guild.id,
                volatile=True,
                safe=True)
    await _get_advertisement_data(bot, context.guild)

    description = 'Channel: {0.mention}\nCooldown: {1}'.format(
        data.get_channel(bot, replace_channel),
        utilities.get_time_string(replace_cooldown, text=True, full=True))
    embed = discord.Embed(title='Commission channel configuration:',
                          description=description)
    return Response(embed=embed)
Exemple #4
0
async def autolog_dump(bot, context):
    """Dumps logs into the set channel."""
    log_channel = _check_log_channel(bot, context.guild)
    logged_channel_ids = data.get(bot, __name__, 'channels', guild_id=context.guild.id, default=[])
    logged_channels = []
    if context.arguments[0]:
        for channel in context.arguments:
            if channel.id not in logged_channel_ids:
                raise CBException("{} is not being logged.".format(channel.mention))
            else:
                logged_channels.append(channel)
    else:
        for channel_id in logged_channel_ids:
            channel = data.get_channel(bot, channel_id, safe=True)
            if channel:
                logged_channels.append(channel)
            else:
                channel = discord.Object(id=channel_id)
                channel.mention = 'Deleted channel ({})'.format(channel_id)
                logged_channels.append(channel)

    # Build dump data
    logs = data.get(bot, __name__, 'logs', guild_id=context.guild.id, volatile=True)
    details = 'Manual dump by {0} (<@{0.id}>): {1}'.format(
        context.author, context.options['details'])
    dump_data = _build_dump_data(bot, logs, log_channel, details=details)

    # Upload dump data
    logged_messages = await _dump(
        bot, dump_data, log_channel, details=details, query=context.options['query'],
        moderator_id=context.author.id, logged_channels=logged_channels)
    if not logged_messages:
        raise CBException("No messages to log.")
    return Response("Messages dumped in {}".format(log_channel.mention))
Exemple #5
0
async def tagremote(bot, context):
    """Gets the current session data as a link."""
    session_data = data.get(bot, __name__, 'data', guild_id=context.guild.id)
    if not session_data:
        raise CBException(
            "No session available.\nStart one with `{}tagremote start`".format(
                utilities.get_invoker(bot, guild=context.guild)))

    channel_id, session_code = session_data['channel'], session_data['session']
    voice_channel_id = session_data['voice_channel']
    channel_mention = data.get_channel(bot, channel_id, guild=context.guild).mention
    voice_channel_mention = data.get_channel(bot, voice_channel_id, guild=context.guild).mention
    description = 'The session code is:\n`{}`\nThe session is attached to {} and {}'.format(
        session_code, channel_mention, voice_channel_mention)
    return Response(embed=discord.Embed(
        title='Tap here on your phone to use the tag remote',
        url='https://jkchen2.github.io/tag-remote/#{}'.format(session_code),
        description=description))
Exemple #6
0
 def __call__(self, bot, message, value, *a):
     if self.live_check:
         guild = self.live_check(bot, message, value, *a)
     else:
         guild = message.guild if self.server_only else None
     try:
         return data.get_channel(
             bot, value, guild=guild, strict=self.server_only,
             constraint=self.constraint, attribute=self.attribute)
     except BotException as e:
         self.set_error_reason(e, 'channel')
Exemple #7
0
async def _get_advertisement_data(bot, guild, ignore_user_id=None):
    """Gets a dictionary of advertisements in the guild, or builds one if necessary.

    If ignore_user_id is provided, this will ignore the first message by that user.
    """
    rules = data.get(bot, __name__, 'rules', guild_id=guild.id)
    if not rules:
        raise CBException(
            "Commission channel rules are not configured on this server.")
    advertisement_data = data.get(bot,
                                  __name__,
                                  'advertisements',
                                  guild_id=guild.id,
                                  volatile=True)

    if advertisement_data:
        return advertisement_data

    # No data found. Fetch it manually
    channel = data.get_channel(bot, rules['channel'], safe=True)
    if not channel:
        raise CBException("The commission channel was not found.")

    # TODO: Add permission checks for channel access and deleting messages
    advertisement_data = {}
    whitelist = data.get(bot,
                         __name__,
                         'whitelist',
                         guild_id=guild.id,
                         default=[])
    async for message in channel.history(limit=100):
        author_id = message.author.id
        if (not message.author.bot
                and message.type is discord.MessageType.default
                and not message.pinned and author_id not in whitelist):
            if author_id in advertisement_data:
                logger.warn('Deleting previously undetected message %s',
                            message.id)
                await message.delete()
            else:
                if ignore_user_id == author_id:
                    ignore_user_id = None
                else:
                    advertisement_data[author_id] = message

    data.add(bot,
             __name__,
             'advertisements',
             advertisement_data,
             guild_id=guild.id,
             volatile=True)
    return advertisement_data
Exemple #8
0
async def autolog_channels(bot, context):
    """Sets the channels that will be logged."""
    log_channel = _check_log_channel(bot, context.guild)

    # Toggle channels for logging
    if context.arguments[0]:
        changes = []
        for channel in context.arguments:
            appended = data.list_data_toggle(
                bot, __name__, 'channels', channel.id, guild_id=context.guild.id)
            if appended:
                changes.append('Now logging {}'.format(channel.mention))
                _set_logger(bot, channel)
            else:
                changes.append('No longer logging {}'.format(channel.mention))
                _delete_logger(bot, channel)
        embed = discord.Embed(title='Logging changes', description='\n'.join(changes))

    # Show channels that are currently logged
    else:
        default_message_limit = configurations.get(bot, __name__, key='message_limit')
        message_limit = data.get(
            bot, __name__, 'message_limit', guild_id=context.guild.id,
            default=default_message_limit)
        logged_channel_ids = data.get(bot, __name__, 'channels', guild_id=context.guild.id)
        if not logged_channel_ids:
            raise CBException("No channels are currently logged.")

        # Check logged channels
        # Removes channels that were deleted and have no logged messages
        logged_channels = []
        logs = data.get(bot, __name__, 'logs', guild_id=context.guild.id, volatile=True)
        for channel_id in logged_channel_ids:
            channel = data.get_channel(bot, channel_id, safe=True)
            if channel:
                logged_channels.append(channel)
            else:
                if len(logs[channel_id]):
                    channel = discord.Object(id=channel_id)
                    channel.mention = 'Deleted channel ({})'.format(channel_id)
                    logged_channels.append(channel)
                else:  # No logged messages for removed channel. Delete log.
                    del logs[channel_id]

        embed = discord.Embed(title='Logging info')
        embed.add_field(
            inline=False, name='Logged channels',
            value=', '.join(it.mention for it in logged_channels))
        embed.add_field(name='Dump channel', value=log_channel.mention)
        embed.add_field(name='Logged messages', value=message_limit)

    return Response(embed=embed)
Exemple #9
0
 def __call__(self, bot, message, value, *a):
     if self.live_check:
         guild = live_check(bot, message, value, *a)
     else:
         guild = message.guild if self.server_only else None
     try:
         return data.get_channel(bot,
                                 value,
                                 guild=guild,
                                 strict=self.server_only,
                                 constraint=self.constraint)
     except BotException as e:
         self.set_error_reason(e, 'channel')
Exemple #10
0
async def autolog_dump(bot, context):
    """Dumps logs into the set channel."""
    log_channel = _check_log_channel(bot, context.guild)
    logged_channel_ids = data.get(bot,
                                  __name__,
                                  'channels',
                                  guild_id=context.guild.id,
                                  default=[])
    logged_channels = []
    if context.arguments[0]:
        for channel in context.arguments:
            if channel.id not in logged_channel_ids:
                raise CBException("{} is not being logged.".format(
                    channel.mention))
            else:
                logged_channels.append(channel)
    else:
        for channel_id in logged_channel_ids:
            channel = data.get_channel(bot, channel_id, safe=True)
            if channel:
                logged_channels.append(channel)
            else:
                channel = discord.Object(id=channel_id)
                channel.mention = 'Deleted channel ({})'.format(channel_id)
                logged_channels.append(channel)

    # Build dump data
    logs = data.get(bot,
                    __name__,
                    'logs',
                    guild_id=context.guild.id,
                    volatile=True)
    details = 'Manual dump by {0} (<@{0.id}>): {1}'.format(
        context.author, context.options['details'])
    dump_data = _build_dump_data(bot, logs, log_channel, details=details)

    # Upload dump data
    logged_messages = await _dump(bot,
                                  dump_data,
                                  log_channel,
                                  details=details,
                                  query=context.options['query'],
                                  moderator_id=context.author.id,
                                  logged_channels=logged_channels)
    if not logged_messages:
        raise CBException("No messages to log.")
    return Response("Messages dumped in {}".format(log_channel.mention))
Exemple #11
0
async def upload_to_discord(bot, fp, filename=None, rewind=True, close=False):
    """Uploads the given file-like object to the upload channel.

    If the upload channel is specified in the configuration files, files
    will be uploaded there. Otherwise, a new guild will be created, and
    used as the upload channel."""
    channel_id = configurations.get(bot, 'core', 'upload_channel')
    if not channel_id:  # Check to see if a guild was already created
        channel_id = data.get(bot, 'core', 'upload_channel')
    channel = data.get_channel(bot, channel_id, safe=True)

    if channel is None:  # Create guild
        logger.debug("Creating guild for upload channel...")
        try:
            guild = await bot.create_guild('uploads')
        except Exception as e:
            raise CBException(
                "Failed to create upload guild. This bot is not whitelisted "
                "to create guilds.",
                e=e)
        data.add(bot, 'core', 'upload_channel', guild.id)
        channel = bot.get_channel(guild.id)

    if channel is None:  # Shouldn't happen
        raise CBException("Failed to get upload channel.")

    try:
        discord_file = discord.File(fp, filename=filename)
        message = await channel.send(file=discord_file)
        upload_url = message.attachments[0].url
    except Exception as e:
        raise CBException("Failed to upload file.", e=e)

    try:
        if close:
            fp.close()
        elif rewind:
            fp.seek(0)
    except:
        pass

    return upload_url
Exemple #12
0
async def upload_to_discord(bot, fp, filename=None, rewind=True, close=False):
    """Uploads the given file-like object to the upload channel.

    If the upload channel is specified in the configuration files, files
    will be uploaded there. Otherwise, a new guild will be created, and
    used as the upload channel."""
    channel_id = configurations.get(bot, 'core', 'upload_channel')
    if not channel_id:  # Check to see if a guild was already created
        channel_id = data.get(bot, 'core', 'upload_channel')
    channel = data.get_channel(bot, channel_id, safe=True)

    # TODO: Remove. Guild creation via bots is a whitelisted process
    if channel is None:  # Create guild
        logger.debug("Creating guild for upload channel...")
        try:
            guild = await bot.create_guild('uploads')
        except Exception as e:
            raise CBException(
                "Failed to create upload guild. This bot is not whitelisted "
                "to create guilds.", e=e)
        data.add(bot, 'core', 'upload_channel', guild.id)
        channel = bot.get_channel(guild.id)

    if channel is None:  # Shouldn't happen
        raise CBException("Failed to get upload channel.")

    try:
        discord_file = discord.File(fp, filename=filename)
        message = await channel.send(file=discord_file)
        upload_url = message.attachments[0].url
    except Exception as e:
        raise CBException("Failed to upload file.", e=e)

    try:
        if close:
            fp.close()
        elif rewind:
            fp.seek(0)
    except:
        pass

    return upload_url
Exemple #13
0
async def check_webhook_messages(bot, message):
    """Reads webhook messages and calls tags if necessary."""
    if message.author.id in WEBHOOK_SET:
        session_data = data.get(bot, __name__, 'data', guild_id=message.guild.id)
        voice_channel = data.get_channel(bot, session_data['voice_channel'], guild=message.guild)

        # Ignore if nobody is in the channel
        if not [it for it in voice_channel.members if not it.bot]:
            pass

        # Retrieve tag
        elif message.content.startswith('[Retrieve]'):
            tag_name = message.content[10:].strip()
            try:
                tag = TAG_CONVERTER(bot, message, tag_name, channel_bypass=voice_channel)
            except BotException as e:
                logger.warn("Failed to retrieve tag: %s", e)
            else:
                tags_plugin = bot.plugins['tags.py']
                url = random.choice(tag.value)
                try:
                    await tags_plugin._play_sound_tag(bot, tag, url, voice_channel, delay=-1)
                except BotException as e:
                    logger.warn("Failed to play tag: %s", e)
                else:
                    tags_plugin._update_hits(bot, tag.key, message.author.id, message.guild.id)

        # Stop audio
        elif message.content == '[Stop audio]':
            voice_client = message.guild.voice_client
            if (voice_client and
                    voice_client.channel == voice_channel and
                    voice_client.is_playing()):
                voice_client.stop()

        # Always remove messages
        await asyncio.sleep(3)
        try:
            await message.delete()
        except:
            pass
Exemple #14
0
async def _delete_session(bot, guild):
    """Deletes the session for the given guild."""
    session_data = data.remove(bot, __name__, 'data', guild_id=guild.id, safe=True)
    if not session_data:
        raise CBException("Session does not exist.")
    channel_id, webhook_id = session_data['channel'], session_data['webhook']
    channel = data.get_channel(bot, channel_id, safe=True)
    webhooks = await channel.webhooks()
    for webhook in webhooks:
        if webhook.id == webhook_id:
            await webhook.delete()
            break
    else:
        logger.warn('Webhook to delete (%s) not found!', webhook_id)
    try:
        WEBHOOK_SET.remove(webhook_id)
    except KeyError:
        logger.warn("Webhook not found in WEBHOOK_SET")
    data.list_data_remove(bot, __name__, 'webhooks', value=webhook_id, safe=True)

    if guild.voice_client and guild.voice_client.channel.id == session_data['voice_channel']:
        await utilities.stop_audio(bot, guild)
Exemple #15
0
    async def _menu(bot, context, response, result, timed_out):
        if not result and not timed_out:
            return

        # Timed out or skipped waiting period
        if timed_out or (result[0].emoji == '⏭'):
            response.embed.remove_field(2)
            response.embed.set_field_at(1,
                                        name='\u200b',
                                        value='Logging started.')
            await response.message.edit(embed=response.embed)
            asyncio.ensure_future(
                _dump(bot,
                      dump_data,
                      log_channel,
                      details=details,
                      query=query,
                      moderator_id=moderator_id))

        # Cancelled
        elif result[0].emoji == '❌':
            response.embed.remove_field(2)
            response.embed.add_field(name='\u200b', value='Logging cancelled.')
            await response.message.edit(embed=response.embed)

        # Specify channels
        else:
            response.embed.set_field_at(
                2,
                name='\u200b',
                inline=False,
                value=
                '**Type the channels you want to log, separated by spaces.**')
            await response.message.edit(embed=response.embed)
            try:
                await response.message.clear_reactions()
            except:
                pass

            # Read response
            kwargs = {
                'timeout':
                300,
                'check':
                lambda m: m.author == result[1] and m.channel == context.
                channel
            }
            channels = []
            response.embed.remove_field(2)
            try:
                result = await bot.wait_for('message', **kwargs)
                for it in result.content.split():
                    channel = data.get_channel(bot,
                                               it,
                                               constraint=discord.TextChannel)
                    if channel.id not in channel_ids:
                        raise CBException("Channel {} not logged.".format(
                            channel.mention))
                    channels.append(channel)
                try:
                    await result.delete()
                except:
                    pass
            except BotException as e:
                logger.debug("Error!")
                response.embed.set_field_at(
                    1,
                    name='\u200b',
                    value='{}\nDefault channels will be logged.'.format(
                        e.error_details))
            except Exception as e:
                logger.debug("Timeout!")
                response.embed.set_field_at(
                    1,
                    name='\u200b',
                    value=
                    'Channel selection timed out. Default channels will be logged.'
                )

            # Upload dump data
            await response.message.edit(embed=response.embed)
            await _dump(bot,
                        dump_data,
                        log_channel,
                        details=details,
                        query=query,
                        moderator_id=moderator_id,
                        logged_channels=channels)

        return False
Exemple #16
0
    async def _menu(bot, context, response, result, timed_out):
        if not result and not timed_out:
            return

        # Timed out or skipped waiting period
        if timed_out or (result[0].emoji == '⏭'):
            response.embed.remove_field(2)
            response.embed.set_field_at(1, name='\u200b', value='Logging started.')
            await response.message.edit(embed=response.embed)
            asyncio.ensure_future(_dump(
                bot, dump_data, log_channel, details=details,
                query=query, moderator_id=moderator_id))

        # Cancelled
        elif result[0].emoji == '❌':
            response.embed.remove_field(2)
            response.embed.add_field(
                name='\u200b',
                value='Logging cancelled.')
            await response.message.edit(embed=response.embed)

        # Specify channels
        else:
            response.embed.set_field_at(
                2, name='\u200b', inline=False,
                value='**Type the channels you want to log, separated by spaces.**')
            await response.message.edit(embed=response.embed)
            try:
                await response.message.clear_reactions()
            except:
                pass

            # Read response
            kwargs = {
                'timeout': 300,
                'check': lambda m: m.author == result[1] and m.channel == context.channel
            }
            channels = []
            response.embed.remove_field(2)
            try:
                result = await bot.wait_for('message', **kwargs)
                for it in result.content.split():
                    channel = data.get_channel(bot, it, constraint=discord.TextChannel)
                    if channel.id not in channel_ids:
                        raise CBException("Channel {} not logged.".format(channel.mention))
                    channels.append(channel)
                try:
                    await result.delete()
                except:
                    pass
            except BotException as e:
                logger.debug("Error!")
                response.embed.set_field_at(
                    1, name='\u200b',
                    value='{}\nDefault channels will be logged.'.format(e.error_details))
            except Exception as e:
                logger.debug("Timeout!")
                response.embed.set_field_at(
                    1, name='\u200b',
                    value='Channel selection timed out. Default channels will be logged.')

            # Upload dump data
            await response.message.edit(embed=response.embed)
            await _dump(
                bot, dump_data, log_channel, details=details, query=query,
                moderator_id=moderator_id, logged_channels=channels)

        return False
Exemple #17
0
async def mod_wrapper(bot, message, base, blueprint_index, options, arguments,
                      keywords, cleaned_content):
    response, tts, message_type, extra = ('', False, 0, None)
    mod_action = ''

    if blueprint_index == 0:  # info
        server_data = data.get(bot,
                               'base',
                               None,
                               server_id=message.server.id,
                               default={})
        disabled_commands = server_data.get('disabled', [])
        display_list = []
        for disabled_command in disabled_commands:
            display_list.append('{0} ({1})'.format(
                disabled_command[0],
                'all' if disabled_command[1] == -1 else disabled_command[1] +
                1))
        response = ('```\n'
                    'Information for server {0}\n'
                    'ID: {0.id}\n'
                    'Owner: {0.owner.id}\n'
                    'Moderators: {1}\n'
                    'Blocked users: {2}\n'
                    'Muted: {3}\n'
                    'Muted channels: {4}\n'
                    'Command invoker: {5}\n'
                    'Mention mode: {6}\n'
                    'Disabled commands: {7}```').format(
                        message.server, server_data.get('moderators', []),
                        server_data.get('blocked', []),
                        server_data.get('muted', []),
                        server_data.get('muted_channels', []),
                        server_data.get('command_invoker', None),
                        server_data.get('mention_mode', False), display_list)

    elif blueprint_index == 1:  # Toggle command
        try:  # Explicit index
            split_arguments = arguments[0].split()
            command = bot.commands[split_arguments[0]]
            guess = [command.base, int(split_arguments[1]) - 1]
            assert -1 < guess[1] < len(command.blueprints)
        except IndexError:  # No index
            guess = [command.base, -1]
        except:  # Guess the help index
            guess = list(parser.guess_index(bot, arguments[0]))
        if guess[0] is None:
            raise BotException(EXCEPTION, "Invalid base.")

        command = bot.commands[guess[0]]
        if command.plugin is bot.commands['base'].plugin:
            raise BotException(EXCEPTION,
                               "The base commands cannot be disabled.")
        pass_in = (bot, 'base', 'disabled', guess)
        pass_in_keywords = {'server_id': message.server.id}
        disabled_commands = data.get(*pass_in[:-1],
                                     **pass_in_keywords,
                                     default=[])
        if guess in disabled_commands:
            data.list_data_remove(*pass_in, **pass_in_keywords)
            response = "Enabled"
        else:
            data.list_data_append(*pass_in, **pass_in_keywords)
            response = "Disabled"
        response += " the `{0}` command {1}.".format(
            guess[0], "and all associated subcommands"
            if guess[1] == -1 else "(subcommand {})".format(guess[1] + 1))
        mod_action = response

    elif blueprint_index in (2, 3):  # Block or unblock
        user = data.get_member(bot, arguments[0], message.server)
        block = blueprint_index == 2
        mod_action = 'Blocked {}' if block else 'Unblocked {}'
        mod_action = mod_action.format('{0} ({0.id})'.format(user))
        blocked = data.is_blocked(bot, message.server, user.id, strict=True)
        mod = data.is_mod(bot, message.server, user.id)
        if mod:
            raise BotException(EXCEPTION,
                               "Cannot block or unblock a moderator.")
        elif block:
            if blocked:
                raise BotException(EXCEPTION, "User is already blocked.")
            else:
                data.list_data_append(bot,
                                      'base',
                                      'blocked',
                                      user.id,
                                      server_id=message.server.id)
                response = "User is now blocked."
        else:
            if not blocked:
                raise BotException(EXCEPTION, "User is already unblocked.")
            else:
                data.list_data_remove(bot,
                                      'base',
                                      'blocked',
                                      user.id,
                                      server_id=message.server.id)
                response = "User is now unblocked."

    elif blueprint_index == 4:  # Clear
        response = ('​' + '\n' * 80 +
                    "The chat was pushed up by a bot moderator.")

    elif blueprint_index in (5, 6):  # Mute or unmute
        server_id = message.server.id
        mute = blueprint_index == 5
        mod_action = 'Muted {}' if mute else 'Unmuted {}'

        if arguments[0]:
            channel = data.get_channel(bot, arguments[0], message.server)
            muted = channel.id in data.get(bot,
                                           'base',
                                           'muted_channels',
                                           server_id=server_id,
                                           default=[])
            mod_action = mod_action.format(channel.name)
            if mute:
                if muted:
                    raise BotException(EXCEPTION, "Channel is already muted.")
                else:
                    data.list_data_append(bot,
                                          'base',
                                          'muted_channels',
                                          channel.id,
                                          server_id=server_id)
                    if str(channel.type) == 'voice':  # disconnect
                        await utilities.leave_and_stop(bot, message.server)
                    response = "Channel muted."
            else:  # unmute
                if not muted:
                    raise BotException(EXCEPTION,
                                       "Channel is already unmuted.")
                else:
                    data.list_data_remove(bot,
                                          'base',
                                          'muted_channels',
                                          channel.id,
                                          server_id=server_id)
                    response = "Channel unmuted."

        else:  # server
            mod_action = mod_action.format('the server')
            muted = data.get(bot,
                             'base',
                             'muted',
                             server_id=server_id,
                             default=False)
            if not (muted ^ mute):
                response = "Server is already {}muted.".format(
                    '' if muted else 'un')
                raise BotException(EXCEPTION, response)
            else:
                data.add(bot, 'base', 'muted', mute, server_id=server_id)
                response = "Server {}muted.".format('' if mute else 'un')

    elif blueprint_index == 7:  # Invoker
        if len(arguments[0]) > 10:
            raise BotException(
                EXCEPTION,
                "The invoker can be a maximum of 10 characters long.")
        data.add(bot,
                 'base',
                 'command_invoker',
                 arguments[0] if arguments[0] else None,
                 server_id=message.server.id)
        response = "Custom command invoker {}.".format(
            'set' if arguments[0] else 'cleared')
        if arguments[0]:
            response = "Custom command invoker set."
            mod_action = "Set the server command invoker to '{}'.".format(
                arguments[0])
        else:
            response = "Custom command invoker cleared."
            mod_action = "Removed the custom command invoker."

    elif blueprint_index == 8:  # Mention
        current_mode = data.get(bot,
                                'base',
                                'mention_mode',
                                server_id=message.server.id,
                                default=False)
        data.add(bot,
                 'base',
                 'mention_mode',
                 not current_mode,
                 server_id=message.server.id)
        response = "Mention mode {}activated.".format(
            'de' if current_mode else '')
        mod_action = "{}activated mention mode.".format(
            'de' if current_mode else '').capitalize()

    # Send notification if configured
    send_notifications = data.get(bot,
                                  'base',
                                  'notifications',
                                  server_id=message.server.id,
                                  default=True)
    if mod_action and send_notifications:
        if message.edited_timestamp:
            timestamp = message.edited_timestamp
        else:
            timestamp = message.timestamp
        notification = ('Moderator {0} ({0.id}) from {0.server} on {1}:\n\t'
                        '{2}').format(message.author, timestamp, mod_action)
        logs = await utilities.get_log_text(bot,
                                            message.channel,
                                            limit=20,
                                            before=message)
        logs += '\n{}'.format(utilities.get_formatted_message(message))
        await bot.send_message(message.server.owner, notification)
        await utilities.send_text_as_file(bot, message.server.owner, logs,
                                          'context')

    return (response, tts, message_type, extra)
Exemple #18
0
async def autolog_channels(bot, context):
    """Sets the channels that will be logged."""
    log_channel = _check_log_channel(bot, context.guild)

    # Toggle channels for logging
    if context.arguments[0]:
        changes = []
        for channel in context.arguments:
            appended = data.list_data_toggle(bot,
                                             __name__,
                                             'channels',
                                             channel.id,
                                             guild_id=context.guild.id)
            if appended:
                changes.append('Now logging {}'.format(channel.mention))
                _set_logger(bot, channel)
            else:
                changes.append('No longer logging {}'.format(channel.mention))
                _delete_logger(bot, channel)
        embed = discord.Embed(title='Logging changes',
                              description='\n'.join(changes))

    # Show channels that are currently logged
    else:
        default_message_limit = configurations.get(bot,
                                                   __name__,
                                                   key='message_limit')
        message_limit = data.get(bot,
                                 __name__,
                                 'message_limit',
                                 guild_id=context.guild.id,
                                 default=default_message_limit)
        logged_channel_ids = data.get(bot,
                                      __name__,
                                      'channels',
                                      guild_id=context.guild.id)
        if not logged_channel_ids:
            raise CBException("No channels are currently logged.")

        # Check logged channels
        # Removes channels that were deleted and have no logged messages
        logged_channels = []
        logs = data.get(bot,
                        __name__,
                        'logs',
                        guild_id=context.guild.id,
                        volatile=True)
        for channel_id in logged_channel_ids:
            channel = data.get_channel(bot, channel_id, safe=True)
            if channel:
                logged_channels.append(channel)
            else:
                if len(logs[channel_id]):
                    channel = discord.Object(id=channel_id)
                    channel.mention = 'Deleted channel ({})'.format(channel_id)
                    logged_channels.append(channel)
                else:  # No logged messages for removed channel. Delete log.
                    del logs[channel_id]

        embed = discord.Embed(title='Logging info')
        embed.add_field(inline=False,
                        name='Logged channels',
                        value=', '.join(it.mention for it in logged_channels))
        embed.add_field(name='Dump channel', value=log_channel.mention)
        embed.add_field(name='Logged messages', value=message_limit)

    return Response(embed=embed)