async def unmonitor(self, ctx, mention):
    """Admin command: unmonitor a user.

    Args:
      ctx (Context)

      mention (Member)

    Returns:
      None
    """
    target_user = ctx.message.mentions[0]

    if not is_admin(ctx.author):
      if ctx.author == target_user:
        notifications_channel = find_channel(ctx.guild, CONFIG['NotificationsChannel'])
        cap(ctx, ctx.author)
        await ctx.send("`!unmonitor`: This is an admin-only command. {} has been capped for trying to use it.".format(ctx.author.display_name))
        await notifications_channel.send('{} was capped by the `!unmonitor` command!')

      return

    if len(ctx.message.mentions) == 0:
      await ctx.send("`!unmonitor`: The user to be monitored must be @-mentioned as the first argument.")
      return

    if target_user in CONFIG['DATA']['monitor']:
      unwatch(ctx, target_user)
      await ctx.send('`!unmonitor`: {} has been removed from watch.'.format(target_user.display_name))
      CONFIG['DATA']['monitor'].remove(target_user)
      save_data(CONFIG['DATAFILE'])
    
    else:
      await ctx.send('`!unmonitor`: {} is not on watch.'.format(target_user.display_name))
Exemple #2
0
    async def setname(self, ctx, user, *, name):
        """Mod command: change a user's nickname on this server.

    Args:
      user (Member):
        The user whose nickname will be updated.

      name (String):
        String to which to set the user's nickname.
    """
        if is_admin(ctx.author) or is_mod(ctx.author):

            if len(ctx.message.mentions) == 0:
                await ctx.send(
                    "`!setname`: The user whose name you wish to change must be mentioned as the first argument."
                )
                return

            target_user = ctx.message.mentions[0]
            old_name = target_user.display_name
            await target_user.edit(nick=name)
            await send_notification(
                ctx.guild, "{} updated {}'s nickname to {}!".format(
                    ctx.author.display_name, old_name, name))

        else:
            await ctx.send(
                "`!setname`: You do not have the privileges to use this command."
            )
 async def crap(self, ctx, mention, *, reason='no reason'):
   """Admin command: Crap a mentioned user.
   
   Args:
     mention (User)
       The user to crap.
   
   Returns:
     None
   """
   if not is_admin(ctx.author):
     await ctx.send('No.')
     return
   
   if len(ctx.message.mentions) == 0:
     await ctx.send("`!crap`: The user to be crapped must be @-mentioned as the first argument.")
     return
   
   target_user = ctx.message.mentions[0]
   crap_role = find_role(ctx.guild, CONFIG['CrapRole'])
   notifications_channel = find_channel(ctx.guild, CONFIG['NotificationsChannel'])
   
   if not crap_role:
     await ctx.send('`!crap`: There was an error attempting to crap {}.'.format(target_user.display_name))
     return
   
   if user_has_role(target_user, CONFIG['CrapRole']):
     await ctx.send('`!crap`: {} has been double-crapped!'.format(target_user.display_name))
   
   else:
     await target_user.add_roles(crap_role)
     await ctx.send('💩💩💩')
     await notifications_channel.send('{} has been crapped for {}'.format(
                                                                   target_user.display_name, 
                                                                   reason))
 async def uncrap(self, ctx, mention):
   """Admin command: Uncrap a mentioned user.
   
   Args:
     mention (User)
       The user to uncrap.
   
   Returns:
     None
   """
   if not is_admin(ctx.author):
     await ctx.send('Nope.')
     return
   
   if len(ctx.message.mentions) == 0:
     await ctx.send("`!uncrap`: The user to be uncrapped must be @-mentioned as the first argument.")
     return
   
   target_user = ctx.message.mentions[0]
   crap_role = find_role(ctx.guild, CONFIG['CrapRole'])
   notifications_channel = find_channel(ctx.guild, CONFIG['NotificationsChannel'])
   
   if not crap_role:
     await ctx.send('`!uncrap`: There was an error attempting to uncrap {}.'.format(target_user.display_name))
     return
   
   if user_has_role(target_user, CONFIG['CrapRole']):
     await target_user.remove_roles(crap_role)
     await ctx.send('🚫💩')
     await notifications_channel.send('{} has been uncrapped.'.format(target_user.display_name))
   
   else:
     await ctx.send('`!uncrap`: {} doesn\'t appear to be crapped.'.format(target_user.display_name))
Exemple #5
0
    async def uncap(self, ctx, mention):
        """Mod command: Remove the dunce cap from a mentioned user.

      Args:
        mention (User)
          The user to uncap.

      Returns:
        None
    """
        if len(ctx.message.mentions) == 0:
            await ctx.send(
                "`!uncap`: The user to be uncapped must be @-mentioned as the first argument."
            )
            return

        target_user = ctx.message.mentions[0]
        cap_role = find_role(ctx.guild, CONFIG['CapRole'])
        staff_channel = find_channel(ctx.guild, CONFIG['StaffChannel'])
        notifications_channel = find_channel(ctx.guild,
                                             CONFIG['NotificationsChannel'])

        if not cap_role:
            await ctx.send(
                '`!uncap`: There was an error attempting to uncap {}.'.format(
                    target_user.mention))
            return

        # Moderator uses !cap
        if is_admin(ctx.author) or is_mod(ctx.author):

            if not user_has_role(target_user, CONFIG['CapRole']):
                await ctx.send(
                    'Are you blind, {}? You can\'t uncap {} '.format(
                        ctx.author.mention, target_user.display_name) +
                    'if they\'re not wearing the Dunce Cap!')

            else:
                await target_user.remove_roles(cap_role)
                await target_user.send('Your dunce cap is lifted.')
                await staff_channel.send('{} has been uncapped by {}!'.format(
                    target_user.mention, ctx.author.mention))
                await notifications_channel.send(
                    '{} has been uncapped by {}!'.format(
                        target_user.display_name, ctx.author.display_name))
                return

        else:

            # Non-moderator attempts to use !uncap
            if not user_has_role(target_user, CONFIG['CapRole']):
                await ctx.send(
                    '`!uncap`: How can you uncap someone who isn\'t ' +
                    'wearing a cap to begin with? Reconsider your life choices.'
                )
            else:
                await ctx.send(
                    '`!uncap`: You are not strong enough to discard the mighty cap.'
                )
 async def write(self, ctx):
   """Admin command: write out current state of persistent data."""
   
   if not is_admin(ctx.author):
     await ctx.send('`!write`: This is an admin-only command.')
   
   else:
     save_data(CONFIG['DATAFILE'])
     await ctx.send('`!write`: Persistent store updated.')
 async def addchannel(self, ctx, name, category):
   """Admin command: Create a new channel with the correct permissions.
   
   Args:
     name (String)
       The name of the new channel.
     
     category(String)
       The name of one of the existing categories to place the new channel in.
   
   Returns:
     None
   """
   if not is_admin(ctx.author):
     await ctx.send('`!addchannel`: Only admins may use this command.')
     return
   
   if not name:
     await ctx.send('`!addchannel`: You must specify a name for the new channel.')
     return
   
   if not category:
     await ctx.send('`!addchannel`: You must specify a category for the new channel.')
     return
     
   channel_list = ctx.guild.text_channels
   
   for channel in channel_list:
     if channel.name == name:
       await ctx.send('`!addchannel`: A channel with this name already exists.')
       return
   
   category_list = ctx.guild.categories
   target_category = None
   
   for cat in category_list:
     if cat.name == category:
       target_category = cat
   
   if not target_category:
     await ctx.send('`!addchannel`: This category could not be found.')
     return
       
   new_channel = await ctx.guild.create_text_channel(name, 
                                                     category=target_category)
   
   if not isinstance(new_channel, discord.TextChannel):
     await ctx.send('`!addchannel`: Unable to add new channel.')
   
   cap_role = find_role(ctx.guild, CONFIG['CapRole'])
   
   await new_channel.set_permissions(cap_role, send_messages=False)
   
   if not new_channel.overwrites_for(cap_role):
     await ctx.send('`!addchannel`: Cap role overwrite not effective.')
   
   await ctx.send('`!addchannel`: {} created in {}!'.format(name, category))
  async def echo(self, ctx, *, message):
    """Admin command: make the bot say something.

    Args:
      message (String)
        The string to be said by the bot.

    Returns:
      None
    """
    if is_admin(ctx.author):
      await ctx.message.delete()
      await ctx.send(message)
Exemple #9
0
    async def prune(self, ctx, limit=90, exec=False):
        """Admin command: prune users
    
    Arg:
      limit (Int): number of days of inactivity for pruning
      exec (Bool): whether or not to execute pruning
    
    Return:
      None
    """
        if not is_admin(ctx.author):
            await ctx.send('`!prune`: Only admins may use this command.')
            return

        await ctx.send(
            'Generating list of users who have not posted in {} days...'.
            format(limit))

        month_ago = datetime.now() - timedelta(days=limit)
        count = Counter()

        for channel in ctx.guild.channels:
            if isinstance(channel, discord.TextChannel):
                async for post in channel.history(limit=None, after=month_ago):
                    count[post.author] += 1

        prune_list = []
        to_prune = ''

        for member in ctx.guild.members:
            if not count[member] and not member.id in CONFIG['PruneProtect']:
                prune_list.append(member)
                to_prune += '{} [{}]\n'.format(member.display_name,
                                               member.name)

        await ctx.send('{} users to be pruned:\n{}'.format(
            len(prune_list), to_prune))

        if exec:
            pass

        return
  async def watchlist(self, ctx):
    """Admin command: list users on the watchlist."""
  
    if not is_admin(ctx.author):
      await ctx.send('`!watchlist`: This is an admin-only command.')
  
    else:
    
      if CONFIG['DATA']['monitor'] == []:
        await ctx.send('`!watchlist`: No users currently on watch.')
        return

      else:
        watched = ''

      for member in CONFIG['DATA']['monitor']:
        if member == CONFIG['DATA']['monitor'][0]:
          watched += '{}'.format(member.display_name)
        else:
          watched += ', {}'.format(member.display_name)

      await ctx.send('`!watchlist`: {}'.format(watched))
Exemple #11
0
  async def release(self, ctx):
    """Claim an event channel, if it is not previously claimed."""

    channel = ctx.message.channel

    if not CONFIG['EventChannelPrefix'] in channel.name:
      await ctx.send('`!release`: This command can only be used in an event channel.')
      return

    pins = await channel.pins()

    if not pins:
      await ctx.send('`!release`: This channel does not appear to have an active claim to release.')
      return

    if pins[0].author == ctx.author or is_admin(ctx.author) or is_mod(ctx.author):
      await pins[0].unpin()
      await ctx.send('{0} has released this event channel!  It is now open to be claimed for other events'.
                format(ctx.author.display_name))
    
    else:
      await ctx.send('`!release`: You do not appear to be the user who claimed this channel.')
      return
Exemple #12
0
    async def cap(self, ctx, mention, *, reason='N/A'):
        """Mod command: Dunce cap a mentioned user.

    Args:
      mention (User)
        The user to cap.

    Returns:
      None
    """
        if len(ctx.message.mentions) == 0:
            await ctx.send(
                "`!cap`: The user to be capped must be @-mentioned as the first argument."
            )
            return

        target_user = ctx.message.mentions[0]
        cap_role = find_role(ctx.guild, CONFIG['CapRole'])
        staff_channel = find_channel(ctx.guild, CONFIG['StaffChannel'])
        notifications_channel = find_channel(ctx.guild,
                                             CONFIG['NotificationsChannel'])

        if not cap_role:
            await ctx.send(
                '`!cap`: There was an error attempting to cap {}.'.format(
                    target_user.mention))
            return

        # Attempt to cap the Admin
        if is_admin(target_user):
            await ctx.author.add_roles(cap_role)
            await ctx.author.send(
                'You have been dunce capped for attempting to dunce cap the admin. '
                +
                'While you are dunce capped, you will not be able to send messages, '
                +
                'but you will be able to add reactions to other users\' messages. '
                +
                'Your dunce cap will be removed after a certain amount of time.'
            )
            await ctx.send(
                '{} has been capped for trying to cap {} - hoisted by your own petard!'
                .format(ctx.author.mention, target_user.mention))
            await staff_channel.send(
                '{} has been capped for attempting to cap {}!'.format(
                    ctx.author.mention, target_user.mention))
            return

        # Moderator uses !cap
        if is_admin(ctx.author) or is_mod(ctx.author):

            if user_has_role(target_user, CONFIG['CapRole']):
                await ctx.send('`!cap`: {} is already capped!'.format(
                    target_user.display_name))

            else:
                await target_user.add_roles(cap_role)
                await ctx.send('WEE WOO WEE WOO')
                await target_user.send(
                    'You have been dunce capped for violating a rule. While you are '
                    +
                    'dunce capped, you will not be able to send messages, but you will '
                    +
                    'be able to add reactions to other users\' messages. The offending '
                    +
                    'violation must be remediated, and your dunce cap will be removed '
                    + 'after a certain amount of time.')
                await staff_channel.send(
                    '{} has been dunce capped by {} for {}!'.format(
                        target_user.mention, ctx.author.mention, reason))
                await notifications_channel.send(
                    '{} has been dunce capped by {}!'.format(
                        target_user.display_name, ctx.author.display_name))

                user = get_db_user(conn, cursor, target_user)

                if not user:
                    cmd = '''INSERT INTO users 
                    VALUES (?, ?, 0, 0, 1)'''
                    params = (target_user.id, target_user.name)

                else:
                    cmd = '''UPDATE users 
                    SET times_capped = ?
                    WHERE id == ?'''
                    params = (user[4] + 1, target_user.id)

                cursor.execute(cmd, params)
                conn.commit()

                cmd = '''INSERT INTO notes
                  VALUES (NULL, ?, ?, ?, ?, ?)'''
                params = (datetime.now(), target_user.id, target_user.name,
                          'cap', reason)
                cursor.execute(cmd, params)
                conn.commit()

        # Non-moderator uses !cap
        else:
            await ctx.send(
                '`!cap`: You are not worthy to wield the mighty cap.')
  async def stats(self, ctx, num: int=5, range: str='month'):
    """Admin command: generate post stats.
    
    Args:
      num (Int, optional)
        The number of top posters to find. Defaults to 5.
        
      range (String, optional)
        One of {all, month}. Defaults to month.
    
    Returns:
      None
    """
    if not is_admin(ctx.author):
      await ctx.send('`!stats`: This is an admin-only command.')
      return
      
    if range != 'month' and range != 'all':
      await ctx.send('`!stats`: Range must be `month` or `all`.')
      return
      
    await ctx.send('`!stats`: Calculating post statistics. This will take some time.')
    
    start_time = time()
    
    channels = ctx.guild.channels
    count = Counter()    
    target_date = datetime.now() - timedelta(days=30)
    
    for channel in channels:
      if isinstance(channel, discord.TextChannel):      
        if channel.category.name not in CONFIG['StatsCategories']:
          continue
      
        if range == 'all':
          async for post in channel.history(limit=None):
            count[post.author] += 1

        elif range == 'month':
          async for post in channel.history(limit=None, after=target_date):
            count[post.author] += 1
    
    max_name_width = 0
    max_num_width = 0
    
    top_list = count.most_common(num)
    
    for member, posts_num in top_list:
      first_name = member.display_name.split()[0]
      
      if first_name[-1] == ':':
        first_name = first_name[:-1]
        
      name_len = len(first_name)
      if name_len > max_name_width:
        max_name_width = name_len
      
      num_len = len('{}'.format(posts_num))
      if num_len > max_num_width:
        max_num_width = num_len
      
    output_text = ''
    
    for member, posts_num in top_list:
      first_name = member.display_name.split()[0]
      
      if first_name[-1] == ':':
        first_name = first_name[:-1]
      
      output_text += '\n `{0:.<{name}}..{1:.>{num}d}`'.format(
        first_name, posts_num, 
        name=max_name_width, num=max_num_width)
    
    end_time = time()
    
    time_output = 'This command executed in {:.2f} seconds'.format(
                                              end_time - start_time)
    
    if range == 'month':
      await ctx.send('The top posters for the past 30 days are: {} \n {}'.format(
                                  output_text, time_output))
    
    elif range == 'all':
      await ctx.send('The top posters of all time are: {} \n {}'.format(
                                  output_text, time_output))