예제 #1
0
 def from_table(self, table):
     """
     Parses a ship's construction info from a table.
     :type table: lxml.html.HtmlElement
     """
     const_nest = {
         0: 'light',
         1: 'heavy',
         2: 'special',
         3: 'limited',
         4: 'exchange'
     }
     const_time = table[1][0].text_content().strip()
     try:
         self.time = convert_to_seconds(const_time)
         self.possible = True
     except LookupError:
         self.time = None
         self.possible = False
     for cell_index, cell in enumerate(table[3][:5]):
         cell_key = const_nest.get(cell_index)
         cell_text = cell.text_content().strip()
         if cell_text == '-':
             const_type_possible = False
         else:
             const_type_possible = True
         setattr(self, cell_key, const_type_possible)
예제 #2
0
async def decay(cmd: SigmaCommand, message: discord.Message, args: list):
    if message.author.permissions_in(message.channel).manage_guild:
        if message.channel_mentions and len(args):
            try:
                decay_time = convert_to_seconds(args[0])
                if decay_time >= 10:
                    decaying_channels = await cmd.db.get_guild_settings(message.guild.id, 'DecayingChannels') or []
                    decaying_timers = await cmd.db.get_guild_settings(message.guild.id, 'DecayingTimers') or {}
                    target = message.channel_mentions[0]
                    if target.id not in decaying_channels:
                        decaying_channels.append(target.id)
                        action = 'created'
                    else:
                        action = 'updated'
                    decaying_timers.update({str(target.id): decay_time})
                    await cmd.db.set_guild_settings(message.guild.id, 'DecayingChannels', decaying_channels)
                    await cmd.db.set_guild_settings(message.guild.id, 'DecayingTimers', decaying_timers)
                    response = discord.Embed(color=0x66CC66, title=f'✅ Decay timer for #{target.name} {action}.')
                else:
                    response = discord.Embed(color=0xBE1931, title='❗ Decay has a minimum of 10 seconds.')
            except (LookupError, ValueError):
                response = discord.Embed(color=0xBE1931, title='❗ Please use the format HH:MM:SS.')
        else:
            response = discord.Embed(color=0xBE1931, title='❗ Missing channel or time.')
    else:
        response = permission_denied('Manage Server')
    await message.channel.send(embed=response)
예제 #3
0
async def textmute(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    if not pld.msg.author.permissions_in(pld.msg.channel).manage_messages:
        response = denied('Access Denied. Manage Messages needed.')
    else:
        if not pld.msg.mentions:
            response = error('No user targeted.')
        else:
            author = pld.msg.author
            target = pld.msg.mentions[0]
            if author.id == target.id:
                response = error('Can\'t mute yourself.')
            elif cmd.bot.user.id == target.id:
                response = error('I can\'t mute myself.')
            else:
                above_hier = hierarchy_permit(author, target)
                if not above_hier:
                    response = denied('Can\'t mute someone equal or above you.')
                else:
                    timed = pld.args[-1].startswith('--time=')
                    try:
                        now = arrow.utcnow().timestamp
                        endstamp = now + convert_to_seconds(pld.args[-1].split('=')[-1]) if timed else None
                    except (LookupError, ValueError):
                        err_response = error('Please use the format HH:MM:SS.')
                        await pld.msg.channel.send(embed=err_response)
                        return
                    mute_list = pld.settings.get('muted_users')
                    if mute_list is None:
                        mute_list = []
                    if target.id in mute_list:
                        response = error(f'{target.display_name} is already text muted.')
                    else:
                        mute_list.append(target.id)
                        await cmd.db.set_guild_settings(pld.msg.guild.id, 'muted_users', mute_list)
                        response = ok(f'{target.display_name} has been text muted.')
                        rarg = pld.args[1:-1] if timed else pld.args[1:] if pld.args[1:] else None
                        reason = ' '.join(rarg) if rarg else None
                        await make_incident(cmd.db, pld.msg.guild, pld.msg.author, target, reason)
                        log_embed = generate_log_embed(pld.msg, target, reason)
                        await log_event(cmd.bot, pld.settings, log_embed, 'log_mutes')
                        guild_icon = str(pld.msg.guild.icon_url) if pld.msg.guild.icon_url else discord.Embed.Empty
                        to_target_title = '🔇 You have been text muted.'
                        to_target = discord.Embed(color=0x696969)
                        to_target.add_field(name=to_target_title, value=f'Reason: {reason}')
                        to_target.set_footer(text=f'On: {pld.msg.guild.name}', icon_url=guild_icon)
                        try:
                            await target.send(embed=to_target)
                        except discord.Forbidden:
                            pass
                        if endstamp:
                            doc_data = {'server_id': pld.msg.guild.id, 'user_id': target.id, 'time': endstamp}
                            await cmd.db[cmd.db.db_nam].TextmuteClockworkDocs.insert_one(doc_data)
    await pld.msg.channel.send(embed=response)
예제 #4
0
async def remindme(cmd: SigmaCommand, message: discord.Message, args: list):
    if args:
        time_req = args[0]
        try:
            in_seconds = convert_to_seconds(time_req)
            upper_limit = 7776000
            if in_seconds <= upper_limit:
                rem_count = await cmd.db[cmd.db.db_nam].Reminders.find({
                    'UserID':
                    message.author.id
                }).count()
                rem_limit = 15
                if rem_count < rem_limit:
                    if len(args) > 1:
                        text_message = ' '.join(args[1:])
                    else:
                        text_message = 'No reminder message set.'
                    execution_stamp = arrow.utcnow().timestamp + in_seconds
                    timestamp = arrow.get(execution_stamp).datetime
                    if in_seconds < 60:
                        time_diff = f'In {in_seconds} seconds'
                    else:
                        time_diff = arrow.get(execution_stamp + 5).humanize(
                            arrow.utcnow())
                    reminder_id = secrets.token_hex(2)
                    reminder_data = {
                        'ReminderID': reminder_id,
                        'UserID': message.author.id,
                        'CreationStamp': arrow.utcnow().timestamp,
                        'ExecutionStamp': execution_stamp,
                        'ChannelID': message.channel.id,
                        'ServerID': message.guild.id,
                        'TextMessage': text_message
                    }
                    await cmd.db[cmd.db.db_nam
                                 ]['Reminders'].insert_one(reminder_data)
                    response = discord.Embed(color=0x66CC66,
                                             timestamp=timestamp)
                    response.description = text_message
                    response.set_author(name=f'Reminder {reminder_id} Created',
                                        icon_url=user_avatar(message.author))
                    response.set_footer(text=f'Executes: {time_diff.title()}')
                else:
                    response = discord.Embed(
                        color=0xBE1931,
                        title='❗ You already have 15 reminders pending.')
            else:
                response = discord.Embed(
                    color=0xBE1931,
                    title='❗ Reminders have a limit of 90 days.')
        except (LookupError, ValueError):
            response = discord.Embed(color=0xBE1931,
                                     title='❗ Please use the format HH:MM:SS.')
    else:
        response = discord.Embed(color=0xBE1931, title='❗ Nothing inputted.')
    await message.channel.send(embed=response)
예제 #5
0
async def createinvite(_cmd, pld):
    """
    :param _cmd: The command object referenced in the command.
    :type _cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    if pld.msg.author.guild_permissions.create_instant_invite:
        target = pld.msg.channel_mentions[
            0] if pld.msg.channel_mentions else pld.msg.channel
        age, uses = 0, 0
        for arg in pld.args:
            if arg.lower().startswith('d:'):
                try:
                    age = convert_to_seconds(arg.partition(':')[-1])
                except (LookupError, ValueError):
                    age = None
            if arg.lower().startswith('u:'):
                try:
                    uses = int(arg.split(':')[-1])
                except ValueError:
                    uses = None
        if age is not None:
            if not age > 86400:
                if uses is not None:
                    if not uses > 100:
                        try:
                            invite = await target.create_invite(max_age=age,
                                                                max_uses=uses)
                            guild_icon = str(
                                pld.msg.guild.icon_url
                            ) if pld.msg.guild.icon_url else discord.Embed.Empty
                            response = discord.Embed(
                                color=await get_image_colors(guild_icon))
                            response.set_author(
                                name=f'Invite for {target.name}.',
                                icon_url=guild_icon)
                            age = arrow.get(arrow.utcnow().timestamp +
                                            age).humanize() if age else None
                            details = f"**Link:** {invite}\n**Expires:** {age or 'Never'}"
                            details += f"\n**Uses:** {uses or 'Unlimited'}"
                            response.description = details
                        except discord.Forbidden:
                            response = error('I was unable to make an invite.')
                    else:
                        response = error('Maximum invite uses is 100.')
                else:
                    response = error('Max uses must be a number.')
            else:
                response = error('Maximum invite duration is 24 hours.')
        else:
            response = error('Please use the format HH:MM:SS.')
    else:
        response = denied('Access Denied. Create Instant Invites needed.')
    await pld.msg.channel.send(embed=response)
 def test_convert_to_seconds():
     targets = [['00:0:00000001', 1], ['11:10:99', 40299],
                ['51:99:10', 189550], ['711:74', 42734], ['15:88', 988],
                ['9:59', 599], ['51', 51], ['13', 13], ['98', 98],
                ['banana', None], ['1:1:1:1', None],
                ['-19:x:chinchilla', None]]
     for to_conv, conv_tar in targets:
         try:
             end = convert_to_seconds(to_conv)
         except LookupError:
             end = None
         assert end == conv_tar
예제 #7
0
async def delayreminder(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    if pld.args:
        if len(pld.args) == 2:
            rem_id = pld.args[0].lower()
            lookup_data = {'user_id': pld.msg.author.id, 'reminder_id': rem_id}
            reminder = await cmd.db[cmd.db.db_nam
                                    ].Reminders.find_one(lookup_data)
            if reminder:
                try:
                    time_req = pld.args[1]
                    upper_limit = 7776000
                    in_seconds = convert_to_seconds(time_req)
                    execution_stamp = reminder.get(
                        'execution_stamp') + in_seconds
                    expires_in = execution_stamp - arrow.utcnow().int_timestamp
                    if expires_in <= upper_limit:
                        timestamp = arrow.get(execution_stamp).datetime
                        if execution_stamp < 60:
                            time_diff = f'In {in_seconds} seconds'
                        else:
                            time_diff = arrow.get(execution_stamp +
                                                  5).humanize(arrow.utcnow())
                        reminder.update({'execution_stamp': execution_stamp})
                        await cmd.db[cmd.db.db_nam].Reminders.update_one(
                            lookup_data, {'$set': reminder})
                        response = discord.Embed(color=0x66CC66,
                                                 timestamp=timestamp)
                        response.title = f'✅ Reminder {rem_id} has been delayed.'
                        response.set_footer(
                            text=f'Executes: {time_diff.title()}')
                    else:
                        response = GenericResponse(
                            'Reminders have a limit of 90 days.').error()
                except (LookupError, ValueError):
                    response = GenericResponse(
                        'Please use the format HH:MM:SS.').error()
            else:
                response = GenericResponse(
                    f'Reminder `{rem_id}` not found.').not_found()
        else:
            response = GenericResponse('Invalid number of arguments.').error()
    else:
        response = GenericResponse('Missing reminder ID and duration.').error()
    await pld.msg.channel.send(embed=response)
예제 #8
0
async def delayreminder(cmd: SigmaCommand, message: discord.Message,
                        args: list):
    if args:
        if len(args) == 2:
            rem_id = args[0].lower()
            lookup_data = {'user_id': message.author.id, 'reminder_id': rem_id}
            reminder = await cmd.db[cmd.db.db_nam
                                    ].Reminders.find_one(lookup_data)
            if reminder:
                try:
                    time_req = args[1]
                    upper_limit = 7776000
                    in_seconds = convert_to_seconds(time_req)
                    execution_stamp = reminder.get(
                        'execution_stamp') + in_seconds
                    expires_in = execution_stamp - arrow.utcnow().timestamp
                    if expires_in <= upper_limit:
                        timestamp = arrow.get(execution_stamp).datetime
                        if execution_stamp < 60:
                            time_diff = f'In {in_seconds} seconds'
                        else:
                            time_diff = arrow.get(execution_stamp +
                                                  5).humanize(arrow.utcnow())
                        reminder.update({'execution_stamp': execution_stamp})
                        await cmd.db[cmd.db.db_nam].Reminders.update_one(
                            lookup_data, {'$set': reminder})
                        response = discord.Embed(color=0x66CC66,
                                                 timestamp=timestamp)
                        response.title = f'✅ Reminder {rem_id} has been delayed.'
                        response.set_footer(
                            text=f'Executes: {time_diff.title()}')
                    else:
                        response = discord.Embed(
                            color=0xBE1931,
                            title='❗ Reminders have a limit of 90 days.')
                except (LookupError, ValueError):
                    response = discord.Embed(
                        color=0xBE1931,
                        title='❗ Please use the format HH:MM:SS.')
            else:
                response = discord.Embed(
                    color=0x696969, title=f'🔍 Reminder `{rem_id}` not found.')
        else:
            response = discord.Embed(color=0xBE1931,
                                     title='❗ Invalid number of arguments.')
    else:
        response = discord.Embed(color=0xBE1931,
                                 title='❗ Missing reminder ID and duration.')
    await message.channel.send(embed=response)
예제 #9
0
async def raffle(cmd: SigmaCommand, message: discord.Message, args: list):
    if len(args) >= 2:
        time_input = args[0]
        raffle_title = ' '.join(args[1:])
        try:
            time_sec = convert_to_seconds(time_input)
            start_stamp = arrow.utcnow().float_timestamp
            end_stamp = start_stamp + time_sec
            end_dt = arrow.get(end_stamp).datetime
            if time_sec < 90:
                end_hum = f'in {time_sec} seconds'
            else:
                end_hum = arrow.get(end_stamp).humanize()
            rafid = secrets.token_hex(3)
            reaction_icon = secrets.choice(raffle_icons)
            icon_color = icon_colors.get(reaction_icon)
            resp_title = f'{message.author.display_name} started a raffle!'
            starter = discord.Embed(color=icon_color, timestamp=end_dt)
            starter.set_author(name=resp_title,
                               icon_url=user_avatar(message.author))
            starter.description = f'Reward: **{raffle_title}**'
            starter.description += f'\nReact with a {reaction_icon} to enter the raffle.'
            starter.set_footer(text=f'[{rafid}] Raffle ends {end_hum}.')
            starter_message = await message.channel.send(embed=starter)
            await starter_message.add_reaction(reaction_icon)
            raffle_data = {
                'Author': message.author.id,
                'Channel': message.channel.id,
                'Title': raffle_title,
                'Start': start_stamp,
                'End': end_stamp,
                'Icon': reaction_icon,
                'Color': icon_color,
                'Message': starter_message.id,
                'Active': True,
                'ID': rafid
            }
            await cmd.db[cmd.db.db_cfg.database
                         ].Raffles.insert_one(raffle_data)
            response = None
        except (LookupError, ValueError):
            response = discord.Embed(color=0xBE1931,
                                     title='❗ Please use the format HH:MM:SS.')
    else:
        response = discord.Embed(color=0xBE1931,
                                 title='❗ No arguments inputted.')
    if response:
        await message.channel.send(embed=response)
예제 #10
0
async def textmute(cmd: SigmaCommand, message: discord.Message, args: list):
    if not message.author.permissions_in(message.channel).manage_messages:
        response = permission_denied('Manage Messages')
    else:
        if not message.mentions:
            response = discord.Embed(color=0xBE1931, title='❗ No user targeted.')
        else:
            author = message.author
            target = message.mentions[0]
            if author.id == target.id:
                response = discord.Embed(color=0xBE1931, title='❗ Can\'t mute yourself.')
            else:
                above_hier = hierarchy_permit(author, target)
                if not above_hier:
                    response = discord.Embed(color=0xBE1931, title='⛔ Can\'t mute someone equal or above you.')
                else:
                    timed = args[-1].startswith('--time=')
                    endstamp = arrow.utcnow().timestamp + convert_to_seconds(args[-1].split('=')[-1]) if timed else None
                    mute_list = await cmd.db.get_guild_settings(message.guild.id, 'MutedUsers')
                    if mute_list is None:
                        mute_list = []
                    if target.id in mute_list:
                        resp_title = f'❗ {target.display_name} is already text muted.'
                        response = discord.Embed(color=0xBE1931, title=resp_title)
                    else:
                        mute_list.append(target.id)
                        await cmd.db.set_guild_settings(message.guild.id, 'MutedUsers', mute_list)
                        response = discord.Embed(color=0x77B255, title=f'✅ {target.display_name} has been text muted.')
                        rarg = args[1:-1] if timed else args[1:] if args[1:] else None
                        reason = ' '.join(rarg) if rarg else None
                        log_embed = generate_log_embed(message, target, reason)
                        await log_event(cmd.bot, message.guild, cmd.db, log_embed, 'LogMutes')
                        to_target_title = f'🔇 You have been text muted.'
                        to_target = discord.Embed(color=0x696969)
                        to_target.add_field(name=to_target_title, value=f'Reason: {reason}')
                        to_target.set_footer(text=f'On: {message.guild.name}', icon_url=message.guild.icon_url)
                        try:
                            await target.send(embed=to_target)
                        except discord.Forbidden:
                            pass
                        if endstamp:
                            doc_data = {'ServerID': message.guild.id, 'UserID': target.id, 'Time': endstamp}
                            await cmd.db[cmd.db.db_nam].TextmuteClockworkDocs.insert_one(doc_data)
    await message.channel.send(embed=response)
예제 #11
0
async def createinvite(cmd: SigmaCommand, message: discord.Message,
                       args: list):
    if message.author.guild_permissions.create_instant_invite:
        target = message.channel_mentions[
            0] if message.channel_mentions else message.channel
        age, uses = 0, 0
        for arg in args:
            if arg.lower().startswith('d:'):
                try:
                    age = convert_to_seconds(arg.partition(':')[-1])
                except (LookupError, ValueError):
                    age = None
            if arg.lower().startswith('u:'):
                try:
                    uses = int(arg.split(':')[-1])
                except ValueError:
                    uses = None
        if age is not None:
            if uses is not None:
                try:
                    invite = await target.create_invite(max_age=age,
                                                        max_uses=uses)
                    response = discord.Embed(
                        color=await get_image_colors(message.guild.icon_url))
                    response.set_author(name=f'Invite for {target.name}.',
                                        icon_url=message.guild.icon_url)
                    age = arrow.get(arrow.utcnow().timestamp +
                                    age).humanize() if age else None
                    details = f"**Link:** {invite}\n**Expires:** {age or 'Never'}\n**Uses:** {uses or 'Unlimited'}"
                    response.description = details
                except discord.Forbidden:
                    response = discord.Embed(
                        color=0xBE1931,
                        title='❗ I was unable to make an invite.')
            else:
                response = discord.Embed(color=0xBE1931,
                                         title='❗ Max uses must be a number.')
        else:
            response = discord.Embed(color=0xBE1931,
                                     title='❗ Please use the format HH:MM:SS.')
    else:
        response = permission_denied('Create Instant Invites')
    await message.channel.send(embed=response)
예제 #12
0
async def raffle(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    if len(pld.args) >= 2:
        time_input = pld.args[0]
        try:
            time_sec = convert_to_seconds(time_input)
            start_stamp = arrow.utcnow().float_timestamp
            end_stamp = start_stamp + time_sec
            end_dt = arrow.get(end_stamp).datetime
            if time_sec < 90:
                end_hum = f'in {time_sec} seconds'
            else:
                end_hum = arrow.get(end_stamp).humanize()
            rafid = secrets.token_hex(3)
            reaction_name = reaction_icon = pld.settings.get('raffle_icon')
            icon_color = None
            if reaction_icon:
                gld = pld.msg.guild
                guild_icon = str(
                    gld.icon_url) if gld.icon_url else discord.Embed.Empty
                custom_emote = reaction_icon.startswith(
                    '<:') and reaction_icon.endswith('>')
                if custom_emote:
                    emote_name = reaction_icon.split(':')[1]
                    matching_emote = None
                    for emote in pld.msg.guild.emojis:
                        if emote.name == emote_name:
                            matching_emote = emote
                    if not matching_emote:
                        reaction_icon = None
                        await cmd.db.set_guild_settings(
                            pld.msg.guild.id, 'raffle_icon', None)
                    else:
                        reaction_icon = matching_emote
                        icon_color = await get_image_colors(matching_emote.url)
                else:
                    icon_color = await get_image_colors(guild_icon)
            if not reaction_icon:
                reaction_name = reaction_icon = secrets.choice(raffle_icons)
                icon_color = icon_colors.get(reaction_icon)
            resp_title = f'{pld.msg.author.display_name} started a raffle!'
            target_ch = pld.msg.channel_mentions[
                0] if pld.msg.channel_mentions else pld.msg.channel
            external = pld.msg.channel.id != target_ch.id
            draw_count = 1
            args = [a.lower() for a in pld.args]
            for arg in args:
                if arg.startswith('winners:'):
                    pld.args.pop(args.index(arg))
                    draw_num = arg.split(':')[-1]
                    if draw_num.isdigit():
                        draw_count = int(draw_num)
                        break
            if external:
                allowed = pld.msg.author.permissions_in(
                    target_ch).send_messages
                if allowed:
                    for ai, arg in enumerate(pld.args):
                        if arg == target_ch.mention:
                            pld.args.pop(ai)
            else:
                allowed = True
            if allowed:
                raffle_title = ' '.join(pld.args[1:])
                starter = discord.Embed(color=icon_color, timestamp=end_dt)
                starter.set_author(name=resp_title,
                                   icon_url=user_avatar(pld.msg.author))
                starter.description = f'Prize: **{raffle_title}**'
                starter.description += f'\nReact with a {reaction_icon} to enter the raffle.'
                starter.set_footer(text=f'[{rafid}] Raffle ends {end_hum}.')
                starter_message = await target_ch.send(embed=starter)
                await starter_message.add_reaction(reaction_icon)
                raffle_data = {
                    'author': pld.msg.author.id,
                    'channel': target_ch.id,
                    'title': raffle_title,
                    'start': start_stamp,
                    'end': end_stamp,
                    'icon': reaction_name,
                    'color': icon_color,
                    'draw_count': draw_count,
                    'message': starter_message.id,
                    'active': True,
                    'id': rafid
                }
                await cmd.db[cmd.db.db_nam].Raffles.insert_one(raffle_data)
                response = None
            else:
                response = denied(
                    f'You can\'t send messages to #{target_ch.name}.')
        except (LookupError, ValueError):
            response = error('Please use the format HH:MM:SS.')
    else:
        response = error('Nothing inputted.')
    if response:
        await pld.msg.channel.send(embed=response)
예제 #13
0
async def autopunishlevels(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    if pld.msg.author.guild_permissions.manage_guild:
        if not pld.args:
            settings = pld.settings.get('auto_punish_levels') or {}
            if settings:
                level_info = []
                for level, details in settings.items():
                    action = details.get('action')
                    duration = details.get('duration')
                    lvl_word = 'Warning' if int(level) == 1 else 'Warnings'
                    info = f'**{level} {lvl_word}:** {action.title()}'
                    if duration:
                        info += f' ({parse_time(duration)})'
                    level_info.append(info)
                response = discord.Embed(color=0x3B88C3,
                                         title='🔄 Auto-Punishment Levels')
                response.description = '\n'.join(level_info)
            else:
                response = GenericResponse('No Auto-Punishments set.').error()
        else:
            if ':' in pld.args[0]:
                duration = None
                if len(pld.args) > 1:
                    try:
                        duration = convert_to_seconds(pld.args[-1])
                    except (LookupError, ValueError):
                        err_response = GenericResponse(
                            'Please use the format HH:MM:SS.').error()
                        await pld.msg.channel.send(embed=err_response)
                        return
                level, _, action = pld.args[0].partition(':')
                if level.isdigit() and action.lower() in actions:
                    settings = pld.settings.get('auto_punish_levels') or {}
                    if action.lower() == 'remove':
                        if str(level) in settings:
                            settings.pop(str(level))
                        response = GenericResponse(
                            f'Level {level} punishment removed.').ok()
                    else:
                        if duration and action.lower() in ['softban', 'kick']:
                            err_response = GenericResponse(
                                f'{action.title()} cannot be timed.').error()
                            await pld.msg.channel.send(embed=err_response)
                            return
                        settings.update({
                            str(level): {
                                'action': action.lower(),
                                'duration': duration
                            }
                        })
                        ok_text = f'Level {level} set to {action.lower()}'
                        if duration:
                            ok_text += f' ({parse_time(duration)})'
                        response = GenericResponse(ok_text).ok()
                    await cmd.db.set_guild_settings(pld.msg.guild.id,
                                                    'auto_punish_levels',
                                                    settings)
                else:
                    ender = 'level' if not level.isdigit() else 'punishment'
                    response = GenericResponse(f'Invalid {ender}.').error()
            else:
                response = GenericResponse(
                    'Separate level and punishment with a colon.').error()
    else:
        response = GenericResponse(
            'Access Denied. Manage Server needed.').denied()
    await pld.msg.channel.send(embed=response)
예제 #14
0
async def ban(cmd: SigmaCommand, message: discord.Message, args: list):
    if message.author.permissions_in(message.channel).ban_members:
        if message.mentions:
            target = message.mentions[0]
            timed = args[-1].startswith('--time=')
            try:
                now = arrow.utcnow().timestamp
                endstamp = now + convert_to_seconds(
                    args[-1].split('=')[-1]) if timed else None
            except (LookupError, ValueError):
                err_response = discord.Embed(
                    color=0xBE1931, title='❗ Please use the format HH:MM:SS.')
                await message.channel.send(embed=err_response)
                return
            if len(args) >= 2:
                try:
                    if endstamp:
                        clean_days = int(args[-2])
                    else:
                        clean_days = int(args[-1])
                except ValueError:
                    clean_days = 0
            else:
                clean_days = 0
            clean_days = clean_days if clean_days in [0, 1, 7] else 0
            if cmd.bot.user.id != target.id:
                if message.author.id != target.id:
                    above_hier = hierarchy_permit(message.author, target)
                    is_admin = message.author.permissions_in(
                        message.channel).administrator
                    if above_hier or is_admin:
                        above_me = hierarchy_permit(message.guild.me, target)
                        if above_me:
                            rarg = args[1:-1] if timed else args[1:] if args[
                                1:] else None
                            reason = ' '.join(rarg) if rarg else None
                            response = discord.Embed(
                                color=0x696969,
                                title=f'🔨 The user has been banned.')
                            response_title = f'{target.name}#{target.discriminator}'
                            response.set_author(name=response_title,
                                                icon_url=user_avatar(target))
                            to_target = discord.Embed(color=0x696969)
                            to_target.add_field(name='🔨 You have been banned.',
                                                value=f'Reason: {reason}')
                            to_target.set_footer(
                                text=f'From: {message.guild.name}.',
                                icon_url=message.guild.icon_url)
                            try:
                                await target.send(embed=to_target)
                            except discord.Forbidden:
                                pass
                            audit_reason = f'By {message.author.name}: {reason}'
                            await target.ban(reason=audit_reason,
                                             delete_message_days=clean_days)
                            log_embed = generate_log_embed(
                                message, target, reason)
                            await log_event(cmd.bot, message.guild, cmd.db,
                                            log_embed, 'log_bans')
                            if endstamp:
                                doc_data = {
                                    'server_id': message.guild.id,
                                    'user_id': target.id,
                                    'time': endstamp
                                }
                                await cmd.db[
                                    cmd.db.db_nam
                                ].BanClockworkDocs.insert_one(doc_data)
                        else:
                            response = discord.Embed(
                                color=0xBE1931,
                                title='⛔ Target is above my highest role.')
                    else:
                        response = discord.Embed(
                            color=0xBE1931,
                            title='⛔ Can\'t ban someone equal or above you.')
                else:
                    response = discord.Embed(
                        color=0xBE1931, title='❗ You can\'t ban yourself.')
            else:
                response = discord.Embed(color=0xBE1931,
                                         title='❗ I can\'t ban myself.')
        else:
            response = discord.Embed(color=0xBE1931,
                                     title='❗ No user targeted.')
    else:
        response = permission_denied('Ban permissions')
    await message.channel.send(embed=response)
예제 #15
0
async def remindme(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    if pld.args:
        time_req = pld.args[0]
        try:
            in_seconds = convert_to_seconds(time_req)
            upper_limit = 7776000
            if in_seconds <= upper_limit:
                rem_count = await cmd.db[cmd.db.db_nam
                                         ].Reminders.count_documents(
                                             {'user_id': pld.msg.author.id})
                rem_limit = 15
                if rem_count < rem_limit:
                    is_dm = False
                    if len(pld.args) > 1:
                        if pld.args[-1].lower() == '--direct':
                            is_dm = True
                            text_message = ' '.join(pld.args[1:-1])
                            text_message = 'No reminder message set.' if not text_message else text_message
                        else:
                            text_message = ' '.join(pld.args[1:])
                    else:
                        text_message = 'No reminder message set.'
                    execution_stamp = arrow.utcnow().int_timestamp + in_seconds
                    timestamp = arrow.get(execution_stamp).datetime
                    if in_seconds < 60:
                        time_diff = f'In {in_seconds} seconds'
                    else:
                        time_diff = arrow.get(execution_stamp + 5).humanize(
                            arrow.utcnow())
                    reminder_id = secrets.token_hex(2)
                    reminder_data = {
                        'reminder_id': reminder_id,
                        'user_id': pld.msg.author.id,
                        'creation_stamp': arrow.utcnow().int_timestamp,
                        'execution_stamp': execution_stamp,
                        'channel_id': pld.msg.channel.id,
                        'server_id': pld.msg.guild.id,
                        'text_message': text_message,
                        'direct_message': is_dm
                    }
                    await cmd.db[cmd.db.db_nam
                                 ].Reminders.insert_one(reminder_data)
                    response = discord.Embed(color=0x66CC66,
                                             timestamp=timestamp)
                    response.description = text_message
                    response.set_author(name=f'Reminder {reminder_id} Created',
                                        icon_url=user_avatar(pld.msg.author))
                    response.set_footer(text=f'Executes: {time_diff.title()}')
                else:
                    response = GenericResponse(
                        'You already have 15 reminders pending.').error()
            else:
                response = GenericResponse(
                    'Reminders have a limit of 90 days.').error()
        except (LookupError, ValueError):
            response = GenericResponse(
                'Please use the format HH:MM:SS.').error()
    else:
        response = GenericResponse('Nothing inputted.').error()
    await pld.msg.channel.send(embed=response)
예제 #16
0
async def hardmute(cmd: SigmaCommand, message: discord.Message, args: list):
    if message.author.permissions_in(message.channel).manage_channels:
        if message.mentions:
            target = message.mentions[0]
            hierarchy_me = hierarchy_permit(message.guild.me, target)
            if hierarchy_me:
                hierarchy_auth = hierarchy_permit(message.author, target)
                if hierarchy_auth:
                    ongoing = discord.Embed(color=0x696969,
                                            title='⛓ Editing permissions...')
                    ongoing_msg = await message.channel.send(embed=ongoing)
                    timed = args[-1].startswith('--time=')
                    try:
                        now = arrow.utcnow().timestamp
                        endstamp = now + convert_to_seconds(
                            args[-1].split('=')[-1]) if timed else None
                    except (LookupError, ValueError):
                        err_response = discord.Embed(
                            color=0xBE1931,
                            title='❗ Please use the format HH:MM:SS.')
                        await message.channel.send(embed=err_response)
                        return
                    for channel in message.guild.channels:
                        if isinstance(channel,
                                      discord.TextChannel) or isinstance(
                                          channel, discord.CategoryChannel):
                            try:
                                await channel.set_permissions(
                                    target,
                                    send_messages=False,
                                    add_reactions=False)
                            except discord.Forbidden:
                                pass
                    await ongoing_msg.delete()
                    rarg = args[
                        1:-1] if timed else args[1:] if args[1:] else None
                    reason = ' '.join(rarg) if rarg else None
                    log_embed = generate_log_embed(message, target, reason)
                    await log_event(cmd.bot, message.guild, cmd.db, log_embed,
                                    'log_mutes')
                    title = f'✅ {target.display_name} has been hard-muted.'
                    response = discord.Embed(color=0x77B255, title=title)
                    to_target_title = f'🔇 You have been hard-muted.'
                    to_target = discord.Embed(color=0x696969)
                    to_target.add_field(name=to_target_title,
                                        value=f'Reason: {reason}')
                    to_target.set_footer(text=f'On: {message.guild.name}',
                                         icon_url=message.guild.icon_url)
                    try:
                        await target.send(embed=to_target)
                    except discord.Forbidden:
                        pass
                    if endstamp:
                        doc_data = {
                            'server_id': message.guild.id,
                            'user_id': target.id,
                            'time': endstamp
                        }
                        await cmd.db[
                            cmd.db.db_nam
                        ].HardmuteClockworkDocs.insert_one(doc_data)
                else:
                    response = discord.Embed(
                        color=0xBE1931,
                        title='❗ That user is equal or above you.')
            else:
                response = discord.Embed(
                    color=0xBE1931,
                    title='❗ I can\'t mute a user equal or above me.')
        else:
            response = discord.Embed(color=0xBE1931,
                                     title='❗ No user targeted.')
    else:
        response = permission_denied('Manage Channels')
    await message.channel.send(embed=response)
예제 #17
0
async def ban(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    if pld.msg.author.permissions_in(pld.msg.channel).ban_members:
        target = get_broad_target(pld)
        if target:
            timed = pld.args[-1].startswith('--time=')
            try:
                now = arrow.utcnow().timestamp
                endstamp = now + convert_to_seconds(
                    pld.args[-1].split('=')[-1]) if timed else None
            except (LookupError, ValueError):
                err_response = error('Please use the format HH:MM:SS.')
                await pld.msg.channel.send(embed=err_response)
                return
            if len(pld.args) >= 2:
                try:
                    if endstamp:
                        clean_days = int(pld.args[-2])
                    else:
                        clean_days = int(pld.args[-1])
                except ValueError:
                    clean_days = 0
            else:
                clean_days = 0
            clean_days = clean_days if clean_days in [0, 1, 7] else 0
            if cmd.bot.user.id != target.id:
                if pld.msg.author.id != target.id:
                    above_hier = hierarchy_permit(pld.msg.author, target)
                    is_admin = pld.msg.author.permissions_in(
                        pld.msg.channel).administrator
                    if above_hier or is_admin:
                        above_me = hierarchy_permit(pld.msg.guild.me, target)
                        if above_me:
                            rarg = pld.args[1:-1] if timed else pld.args[
                                1:] if pld.args[1:] else None
                            reason = ' '.join(rarg) if rarg else None
                            response = discord.Embed(
                                color=0x696969,
                                title='🔨 The user has been banned.')
                            response_title = f'{target.name}#{target.discriminator}'
                            response.set_author(name=response_title,
                                                icon_url=user_avatar(target))
                            guild_icon = str(
                                pld.msg.guild.icon_url
                            ) if pld.msg.guild.icon_url else discord.Embed.Empty
                            to_target = discord.Embed(color=0x696969)
                            to_target.add_field(
                                name='🔨 You have been banned.',
                                value=f'Reason: {reason}')
                            to_target.set_footer(
                                text=f'From: {pld.msg.guild.name}.',
                                icon_url=guild_icon)
                            try:
                                await target.send(embed=to_target)
                            except discord.Forbidden:
                                pass
                            audit_reason = f'By {pld.msg.author.name}#{pld.msg.author.discriminator}: {reason}'
                            await target.ban(reason=audit_reason,
                                             delete_message_days=clean_days)
                            log_embed = generate_log_embed(
                                pld.msg, target, reason)
                            await log_event(cmd.bot, pld.settings, log_embed,
                                            'log_bans')
                            if endstamp:
                                doc_data = {
                                    'server_id': pld.msg.guild.id,
                                    'user_id': target.id,
                                    'time': endstamp
                                }
                                await cmd.db[
                                    cmd.db.db_nam
                                ].BanClockworkDocs.insert_one(doc_data)
                        else:
                            response = denied(
                                'Target is above my highest role.')
                    else:
                        response = denied(
                            'Can\'t ban someone equal or above you.')
                else:
                    response = error('You can\'t ban yourself.')
            else:
                response = error('I can\'t ban myself.')
        else:
            response = error('No user targeted.')
    else:
        response = denied('Access Denied. Ban permissions needed.')
    await pld.msg.channel.send(embed=response)
예제 #18
0
async def hardmute(cmd, pld):
    """
    :param cmd: The command object referenced in the command.
    :type cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    if pld.msg.author.permissions_in(pld.msg.channel).manage_channels:
        target = get_broad_target(pld)
        if target:
            hierarchy_me = hierarchy_permit(pld.msg.guild.me, target)
            if hierarchy_me:
                hierarchy_auth = hierarchy_permit(pld.msg.author, target)
                if hierarchy_auth:
                    ongoing = discord.Embed(color=0x696969, title='⛓ Editing permissions...')
                    ongoing_msg = await pld.msg.channel.send(embed=ongoing)
                    timed = pld.args[-1].startswith('--time=')
                    try:
                        now = arrow.utcnow().int_timestamp
                        endstamp = now + convert_to_seconds(pld.args[-1].split('=')[-1]) if timed else None
                    except (LookupError, ValueError):
                        err_response = GenericResponse('Please use the format HH:MM:SS.').error()
                        await pld.msg.channel.send(embed=err_response)
                        return
                    for channel in pld.msg.guild.channels:
                        if isinstance(channel, discord.TextChannel) or isinstance(channel, discord.CategoryChannel):
                            try:
                                await channel.set_permissions(target, send_messages=False, add_reactions=False)
                            except (discord.Forbidden, discord.NotFound):
                                pass
                    try:
                        await ongoing_msg.delete()
                    except discord.NotFound:
                        pass
                    rarg = pld.args[1:-1] if timed else pld.args[1:] if pld.args[1:] else None
                    reason = ' '.join(rarg) if rarg else None
                    await make_incident(cmd.db, pld.msg.guild, pld.msg.author, target, reason)
                    log_embed = generate_log_embed(pld.msg, target, reason)
                    await log_event(cmd.bot, pld.settings, log_embed, 'log_mutes')
                    response = GenericResponse(f'{target.display_name} has been hard-muted.').ok()
                    guild_icon = str(pld.msg.guild.icon_url) if pld.msg.guild.icon_url else discord.Embed.Empty
                    to_target_title = '🔇 You have been hard-muted.'
                    to_target = discord.Embed(color=0x696969)
                    to_target.add_field(name=to_target_title, value=f'Reason: {reason}')
                    to_target.set_footer(text=f'On: {pld.msg.guild.name}', icon_url=guild_icon)
                    try:
                        await target.send(embed=to_target)
                    except (discord.Forbidden, discord.HTTPException):
                        pass
                    if endstamp:
                        doc_data = {'server_id': pld.msg.guild.id, 'user_id': target.id, 'time': endstamp}
                        await cmd.db[cmd.db.db_nam].HardmuteClockworkDocs.insert_one(doc_data)
                else:
                    response = GenericResponse('That user is equal or above you.').error()
            else:
                response = GenericResponse('I can\'t mute a user equal or above me.').error()
        else:
            response = GenericResponse('No user targeted.').error()
    else:
        response = GenericResponse('Access Denied. Manage Channels needed.').denied()
    await pld.msg.channel.send(embed=response)
예제 #19
0
async def wftrials(_cmd, pld):
    """
    :param _cmd: The command object referenced in the command.
    :type _cmd: sigma.core.mechanics.command.SigmaCommand
    :param pld: The payload with execution data and details.
    :type pld: sigma.core.mechanics.payload.CommandPayload
    """
    if pld.args:
        username = '******'.join(pld.args)
        trials_url = f'https://api.trials.wf/api/player/pc/{username}/completed'
        async with aiohttp.ClientSession() as session:
            async with session.get(trials_url) as data:
                trial_data = await data.read()
                trial_data = json.loads(trial_data)
        if len(trial_data) == 0:
            response = GenericResponse(
                f'User {username} Not Found.').not_found()
        else:
            # noinspection PyBroadException
            try:
                username_proper = get_usercaps(username, trial_data)
                raidlist_url = f'https://trials.wf/player/?user={username_proper}'

                # LoR
                lor_deaths = 0
                lor_kills = 0
                lor_time_total = 0
                lor_time_short = 0
                lor_count = 0
                lor_won = 0
                lor_failed = 0

                # LoR NM
                lornm_deaths = 0
                lornm_kills = 0
                lornm_time_total = 0
                lornm_time_short = 0
                lornm_count = 0
                lornm_won = 0
                lornm_failed = 0

                # JV
                jv_deaths = 0
                jv_kills = 0
                jv_time_total = 0
                jv_time_short = 0
                jv_count = 0
                jv_won = 0
                jv_failed = 0

                # Calculate Data
                for trial in trial_data:
                    if trial['type'] == 'lor':
                        lor_deaths += trial['deaths']
                        lor_kills += trial['kills']
                        lor_time_total += convert_to_seconds(trial['time'])
                        if lor_time_short == 0:
                            lor_time_short = convert_to_seconds(trial['time'])
                        else:
                            if lor_time_short > convert_to_seconds(
                                    trial['time']):
                                if trial['objective'] == 'VICTORY':
                                    lor_time_short = convert_to_seconds(
                                        trial['time'])
                        lor_count += 1
                        if trial['objective'] == 'VICTORY':
                            lor_won += 1
                        elif trial['objective'] == 'FAILED':
                            lor_failed += 1
                    elif trial['type'] == 'lornm':
                        lornm_deaths += trial['deaths']
                        lornm_kills += trial['kills']
                        lornm_time_total += convert_to_seconds(trial['time'])
                        lornm_count += 1
                        if trial['objective'] == 'VICTORY':
                            lornm_won += 1
                        elif trial['objective'] == 'FAILED':
                            lornm_failed += 1
                        if lornm_time_short == 0:
                            lornm_time_short = convert_to_seconds(
                                trial['time'])
                        else:
                            if lornm_time_short > convert_to_seconds(
                                    trial['time']):
                                if trial['objective'] == 'VICTORY':
                                    lornm_time_short = convert_to_seconds(
                                        trial['time'])
                    elif trial['type'] == 'jv':
                        jv_deaths += trial['deaths']
                        jv_kills += trial['kills']
                        jv_time_total += convert_to_seconds(trial['time'])
                        jv_count += 1
                        if trial['objective'] == 'VICTORY':
                            jv_won += 1
                        elif trial['objective'] == 'FAILED':
                            jv_failed += 1
                        if jv_time_short == 0:
                            jv_time_short = convert_to_seconds(trial['time'])
                        else:
                            if jv_time_short > convert_to_seconds(
                                    trial['time']):
                                if trial['objective'] == 'VICTORY':
                                    jv_time_short = convert_to_seconds(
                                        trial['time'])

                # Total
                total_deaths = lor_deaths + lornm_deaths + jv_deaths
                total_kills = lor_kills + lornm_kills + jv_kills
                total_time_total = lor_time_total + lornm_time_total + jv_time_total
                total_time_short = 0
                short_times = [lor_time_short, lornm_time_short, jv_time_short]
                for short_time in short_times:
                    if total_time_short == 0:
                        total_time_short = short_time
                    else:
                        if total_time_short > short_time:
                            total_time_short = short_time
                total_count = lor_count + lornm_count + jv_count
                total_won = lor_won + lornm_won + jv_won
                total_failed = lor_failed + lornm_failed + jv_failed

                # Make Descriptions
                try:
                    lor_desc = f'Total: {lor_count}'
                    lor_desc += f'\nWin/Lose: {lor_won}/{lor_failed}'
                    lor_desc += f'\nTotal Time: {str(datetime.timedelta(seconds=lor_time_total))}'
                    lor_desc += f'\nAverage Time: {str(datetime.timedelta(seconds=(lor_time_total // lor_count)))}'
                    lor_desc += f'\nShortest Time: {str(datetime.timedelta(seconds=lor_time_short))}'
                    lor_desc += f'\nKills: {lor_kills}'
                    lor_desc += f'\nAverage Kills: {lor_kills // lor_count}'
                    lor_desc += f'\nDeaths: {lor_deaths}'
                    lor_desc += f'\nAverage Deaths: {lor_deaths // lor_count}'
                except ZeroDivisionError:
                    lor_desc = 'Invalid Data'
                try:
                    lornm_desc = f'Total: {lornm_count}'
                    lornm_desc += f'\nWin/Lose: {lornm_won}/{lornm_failed}'
                    lornm_desc += f'\nTotal Time: {str(datetime.timedelta(seconds=lornm_time_total))}'
                    lornm_avg_sec = lornm_time_total // lornm_count
                    lornm_desc += f'\nAverage Time: {str(datetime.timedelta(seconds=lornm_avg_sec))}'
                    lornm_desc += f'\nShortest Time: {str(datetime.timedelta(seconds=lornm_time_short))}'
                    lornm_desc += f'\nKills: {lornm_kills}'
                    lornm_desc += f'\nAverage Kills: {lornm_kills // lornm_count}'
                    lornm_desc += f'\nDeaths: {lornm_deaths}'
                    lornm_desc += f'\nAverage Deaths: {lornm_deaths // lornm_count}'
                except ZeroDivisionError:
                    lornm_desc = 'Invalid Data'
                try:
                    jv_desc = f'Total: {jv_count}'
                    jv_desc += f'\nWin/Lose: {jv_won}/{jv_failed}'
                    jv_desc += f'\nTotal Time: {str(datetime.timedelta(seconds=jv_time_total))}'
                    jv_desc += f'\nAverage Time: {str(datetime.timedelta(seconds=(jv_time_total // jv_count)))}'
                    jv_desc += f'\nShortest Time: {str(datetime.timedelta(seconds=jv_time_short))}'
                    jv_desc += f'\nKills: {jv_kills}'
                    jv_desc += f'\nAverage Kills: {jv_kills // jv_count}'
                    jv_desc += f'\nDeaths: {jv_deaths}'
                    jv_desc += f'\nAverage Deaths: {jv_deaths // jv_count}'
                except ZeroDivisionError:
                    jv_desc = 'Invalid Data'
                try:
                    total_desc = f'Total: {total_count}'
                    total_desc += f'\nWin/Lose: {total_won}/{total_failed}'
                    total_desc += f'\nTotal Time: {str(datetime.timedelta(seconds=total_time_total))}'
                    total_desc += '\nAverage Time: '
                    total_desc += f'{str(datetime.timedelta(seconds=(total_time_total // total_count)))}'
                    total_desc += f'\nShortest Time: {str(datetime.timedelta(seconds=total_time_short))}'
                    total_desc += f'\nKills: {total_kills}'
                    total_desc += f'\nAverage Kills: {total_kills // total_count}'
                    total_desc += f'\nDeaths: {total_deaths}'
                    total_desc += f'\nAverage Deaths: {total_deaths // total_count}'
                except ZeroDivisionError:
                    total_desc = 'Invalid Data'
                response = discord.Embed(color=0xa12626)
                response.set_thumbnail(url='https://i.imgur.com/pf89nIk.png')
                response.set_author(name=username_proper,
                                    icon_url='https://i.imgur.com/n0EESkn.png',
                                    url=raidlist_url)
                response.add_field(name='Law of Retribution', value=lor_desc)
                response.add_field(name='Nightmare LoR', value=lornm_desc)
                response.add_field(name='Jordas Verdict', value=jv_desc)
                response.add_field(name='Total Trials', value=total_desc)
            except Exception:
                response = GenericResponse(
                    f'Stats for {username} were found but contained errors.'
                ).warn()
        await pld.msg.channel.send(embed=response)