Ejemplo n.º 1
0
    async def run_genre(self, context, opts):
        """
        Update the genre of a project
        @param context:
        @param opts:
        @return:
        """
        user = User(context.message.author.id, context.guild.id, context)
        shortname = opts[0].lower() if opts else None
        genre = opts[1].lower() if len(opts) > 1 else None

        # Make sure the project exists.
        project = user.get_project(shortname)
        if not project:
            return await context.send(
                user.get_mention() + ', ' +
                lib.get_string('project:err:noexists',
                               user.get_guild()).format(shortname))

        # Make sure the genre is valid.
        if not genre in self._genres:
            return await context.send(
                user.get_mention() + ', ' +
                lib.get_string('project:err:genre', user.get_guild()).format(
                    genre, ', '.join(self._genres)))

        project.set_genre(genre)
        return await context.send(
            user.get_mention() + ', ' +
            lib.get_string('project:genre', user.get_guild()).format(
                lib.get_string('project:genre:' + genre, user.get_guild())))
Ejemplo n.º 2
0
    async def run_project(self, context, shortname):
        """
        Set the project the user wants to sprint in.
        :param context:
        :param shortname:
        :return:
        """
        user = User(context.message.author.id, context.guild.id, context)
        sprint = Sprint(user.get_guild())

        # If there is no active sprint, then just display an error
        if not sprint.exists():
            return await context.send(user.get_mention() + ', ' + lib.get_string('sprint:err:noexists', user.get_guild()))

        # If the user is not sprinting, then again, just display that error
        if not sprint.is_user_sprinting(user.get_id()):
            return await context.send(user.get_mention() + ', ' + lib.get_string('sprint:err:notjoined', user.get_guild()))

        # Make sure the project exists.
        shortname = shortname.lower() if shortname is not None else None
        project = user.get_project(shortname)
        if not project:
            return await context.send(user.get_mention() + ', ' + lib.get_string('project:err:noexists', user.get_guild()).format(shortname))

        sprint.set_project(project.get_id(), user.get_id())
        return await context.send(user.get_mention() + ', ' + lib.get_string('sprint:project', user.get_guild()).format(project.get_title()))
Ejemplo n.º 3
0
    async def admin(self, context, cmd=None, *opts):
        """
        Runs admin commands on the bot
        :param context:
        :param opts:
        :return:
        """

        user = User(context.message.author.id,
                    context.guild.id,
                    context=context,
                    bot=self.bot)
        if not user.is_owner():
            raise commands.errors.MissingPermissions(['Bot owner'])

        # Check the arguments were all supplied and get a dict list of them and their values, after any prompts
        args = await self.check_arguments(context, cmd=cmd)
        if not args:
            return

        # Overwrite the variables passed in, with the values from the prompt and convert to lowercase
        cmd = args['cmd'].lower()

        if cmd == 'status':
            return await self.run_status(context, opts)
Ejemplo n.º 4
0
    async def run_update(self, context, amount):
        """
        Update the user's word count on the event
        :param context:
        :param amount:
        :return:
        """
        user = User(context.message.author.id, context.guild.id, context)
        event = Event.get_by_guild(user.get_guild())

        amount = lib.is_number(amount[0])
        if amount is False or amount < 0:
            return await context.send(
                user.get_mention() + ', ' +
                lib.get_string('err:validamount', user.get_guild()))

        # Make sure the event is running
        if event is None or not event.is_running():
            return await context.send(
                user.get_mention() + ', ' +
                lib.get_string('event:err:noexists', user.get_guild()))

        event.update_wordcount(user.get_id(), amount)
        return await context.send(
            user.get_mention() + ', ' +
            lib.get_string('event:updated', user.get_guild()).format(
                event.get_title(), amount))
Ejemplo n.º 5
0
    async def run_history(self, context, type):
        """
        Get the user's goal history, so they can look back and see how they did for previous goals
        @param context:
        @param type:
        @return:
        """
        user = User(context.message.author.id, context.guild.id, context)
        type_string = lib.get_string('goal:' + type, user.get_guild()).lower()
        history = user.get_goal_history(type)

        # Build embedded response.
        embed = discord.Embed(title=lib.get_string(
            'goal:history', user.get_guild()).format(type_string),
                              color=10038562)

        # Loop through each history record.
        for record in history:

            title = record['date']
            text = str(record['result']) + '/' + str(record['goal'])
            text += ' :white_check_mark:' if record['completed'] else ''
            embed.add_field(name=title, value=text, inline=False)

        await context.send(embed=embed)
Ejemplo n.º 6
0
    async def run_create(self, context, opts):
        """
        Create an event on the server
        :param context:
        :param opts:
        :return:
        """
        user = User(context.message.author.id, context.guild.id, context)

        # Do they have the permissions to create an event?
        self.check_permissions(context)

        # Get the title out of the arguments
        title = " ".join(opts[0:])

        # Check if there is already an event running
        event = Event.get_by_guild(user.get_guild())
        if event is not None:
            return await context.send(
                user.get_mention() + ', ' +
                lib.get_string('event:err:alreadyexists', user.get_guild()))

        # Make sure they specified a title.
        if len(title) == 0 or len(title) > 255:
            return await context.send(
                user.get_mention() + ', ' +
                lib.get_string('event:err:title', user.get_guild()))

        # Create the event
        Event.create(guild=user.get_guild(),
                     channel=context.message.channel.id,
                     title=title)
        return await context.send(
            user.get_mention() + ', ' +
            lib.get_string('event:created', user.get_guild()).format(title))
Ejemplo n.º 7
0
    async def remind(self, context, *opts):
        """
        Set or configure a reminder
        @param opts:
        @param context:
        @return:
        """
        if not Guild(context.guild).is_command_enabled('remind'):
            return await context.send(lib.get_string('err:disabled', context.guild.id))

        user = User(context.message.author.id, context.guild.id, context)

        # Does the user have a timezone setup? If not, can't do anything.
        if not lib.is_valid_timezone(user.get_setting('timezone')):
            return await context.send(user.get_mention() + ', ' + lib.get_string('err:notimezone', user.get_guild()))

        # Convert the natural language of the command into variables.
        cmd = ' '.join(opts)

        # Check what we are trying to do with reminders.
        if cmd.lower() == 'list':
            return await self.run_list(context, user)
        elif cmd.lower() == 'delete':
            return await self.run_delete(context, user)
        else:
            return await self.run_remind(context, user, cmd)
Ejemplo n.º 8
0
    async def run_unschedule(self, context):
        """
        Unschedule the event
        :param context:
        :return:
        """
        user = User(context.message.author.id, context.guild.id, context)
        event = Event.get_by_guild(user.get_guild())

        # Do they have the permissions to rename an event?
        self.check_permissions(context)

        # Make sure the event is running
        if event is None:
            return await context.send(user.get_mention() + ', ' + lib.get_string('event:err:noexists', user.get_guild()))

        # Unschedule the event
        event.set_startdate(None)
        event.set_enddate(None)
        event.save()

        # Remove any tasks we already had saved for this event.
        Task.cancel('event', event.get_id())

        return await context.send(user.get_mention() + ', ' + lib.get_string('event:unscheduled', user.get_guild()).format(event.get_title()))
Ejemplo n.º 9
0
    async def xp(self, context, who='me'):
        """
        Checks your Experience Points and Level. Use the 'top' flag to see the top 10 on this server.
        Examples:
            !xp - Shows your level/xp
            !xp top - Shows the top 10 users on this server
        """
        if not Guild(context.guild).is_command_enabled('xp'):
            return await context.send(lib.get_string('err:disabled', context.guild.id))

        guild_id = context.guild.id
        user_id = context.message.author.id

        if who == 'top':

            title = context.guild.name + ' - ' + lib.get_string('xp:leaderboard', guild_id)
            embed = discord.Embed(title=title, color=discord.Color.red(), description=None)
            embed.add_field(name=lib.get_string('xp:leaderboard', guild_id), value='Leaderboard temporarily disabled until a fix can be implemented', inline=False)
            return await context.send(embed=embed)

        else:
            user = User(user_id, guild_id)
            xp = user.get_xp()

            # Either display a message saying they have no XP, or display the XP bar for the user
            if xp is None:
                output = context.message.author.mention + ', ' + lib.get_string('xp:noxp', guild_id)
            else:
                output = context.message.author.mention + ', ' + lib.get_string('youare', guild_id) + ' ' + user.get_xp_bar()

        await context.send(output)
Ejemplo n.º 10
0
    async def task_reset(self, bot):
        """
        The scheduled task to reset user goals at midnight
        :param bot:
        :return:
        """
        # Find all the user_goal records which are due a reset
        now = int(time.time())

        records = self.__db.get_all_sql(
            'SELECT * FROM user_goals WHERE reset <= %s', [now])
        for record in records:

            # Calculate the next reset time for the goal, depending on its type.
            user = User(record['user'], 0)
            try:
                next = user.calculate_user_reset_time(record['type'])
                lib.debug('Setting next ' + record['type'] +
                          ' goal reset time for ' + str(record['user']) +
                          ' to: ' + str(next))
                self.__db.update('user_goals', {
                    'completed': 0,
                    'current': 0,
                    'reset': next
                }, {'id': record['id']})
            except pytz.exceptions.UnknownTimeZoneError:
                lib.out('[ERROR] Invalid timezone (' +
                        user.get_setting('timezone') + ') for user ' +
                        str(record['user']))

        return True
Ejemplo n.º 11
0
    async def todo(self, context):
        """
        Displays current TODO list
        """
        user = User(context.message.author.id, context.guild.id, context)

        todo = lib.get_asset('todo', user.get_guild())

        output = '```ini\n'

        for type in todo.keys():

            output += '********** ' + lib.get_string(
                'todo:' + str(type), user.get_guild()) + ' **********\n'

            items = todo[type]
            if len(items):

                n = 1

                for item in items:
                    output += str(n) + '. ' + item + '\n'
                    n += 1
            else:
                output += '-'

            output += '\n\n'

        output += '```'

        return await context.send(output)
Ejemplo n.º 12
0
    async def xp(self, context, who='me'):
        """
        Checks your Experience Points and Level. Use the 'top' flag to see the top 10 on this server.
        Examples:
            !xp - Shows your level/xp
            !xp top - Shows the top 10 users on this server
        """

        guild_id = context.guild.id
        user_id = context.message.author.id

        if who == 'top':

            guild = Guild(context.guild)
            users = guild.get_top_xp()
            output = ':trophy: **' + lib.get_string(
                'xp:leaderboard', guild_id) + '** :trophy: \n\n'
            for key in range(len(users)):
                user = users[key]
                output += str(key + 1) + '. ' + user.get_name(
                ) + ' - ' + user.get_xp_bar() + '\n'

        else:
            user = User(user_id, guild_id)
            xp = user.get_xp()

            # Either display a message saying they have no XP, or display the XP bar for the user
            if xp is None:
                output = context.message.author.mention + ', ' + lib.get_string(
                    'xp:noxp', guild_id)
            else:
                output = context.message.author.mention + ', ' + lib.get_string(
                    'youare', guild_id) + ' ' + user.get_xp_bar()

        await context.send(output)
Ejemplo n.º 13
0
    async def ask(self, context, type=None):
        """
        Asks you a random question about your character or your world, to get the creative juices flowing.
        Initial questions taken from (novel-software).

        Examples:
            !ask c(haracter) - Asks you a question about your character
            !ask w(orld) - Asks you a question about your world
        """

        user = User(context.message.author.id, context.guild.id, context)

        # Check the arguments were all supplied and get a dict list of them and their values, after any prompts
        args = await self.check_arguments(context, type=type)
        if not args:
            return

        # Overwrite the variables passed in, with the values from the prompt and convert to lowercase
        type = args['type'].lower()

        if type in ('c', 'char', 'character'):
            options = lib.get_asset('q_char', user.get_guild())
        elif type in ('w', 'world'):
            options = lib.get_asset('q_world', user.get_guild())

        max = len(options) - 1
        rand = random.randint(1, max)
        question = options[rand]
        await context.send(f'[{rand}] {question}')
Ejemplo n.º 14
0
    async def project(self, context, cmd=None, *opts):
        """
        The project command allows you to create different projects and store word counts against them separately. They also integrate with the `wrote` and `sprint` commands, allowing you to define words written against a chosen project. (See the help information for those commands for more info).

        Examples:
            `project create sword The Sword in the Stone` - Creates a new project with the shortname "sword" (used to reference the project when you want to update it), and the full title "The Sword in the Stone".
            `project delete sword` - Deletes the project with the shortname "sword"
            `project rename sword sword2 The Sword in the Stone Two` - Renames the project with the shortname "sword" to - shortname:sword2, title:The Sword in the Stone Two (If you want to keep the same shortname but change the title, just put the same shortname, e.g. `project rename sword sword The Sword in the Stone Two`.
            `project update sword 65000` - Sets the word count for the project with the shortname "sword" to 65000.
            `project list` - Views a list of all your projects.
            `project list status published` - Views a list of all your projects with the `published` status.
            `project list genre fantasy` - Views a list of all your projects with the `fantasy` genre.
            `project view sword` - Views the information about the project with the shortname "sword".
            `project status sword published` - Sets the status of the project to `published`.
            `project genre sword fantasy` - Sets the genre of the project to `fantasy`.
            `project description sword Young boy finds sword, becomes king` - Sets the description/blurb of the project.
            `project link sword http://website.com/your-book` - Sets the hyperlink for your project's web/store page.
            `project img sword http://website.com/picture.png` - Sets the thumbnail picture to use for this project.
        """
        user = User(context.message.author.id, context.guild.id, context)

        # Check the arguments were all supplied and get a dict list of them and their values, after any prompts
        args = await self.check_arguments(context, cmd=cmd)
        if not args:
            return

        # Overwrite the variables passed in, with the values from the prompt and convert to lowercase
        cmd = args['cmd'].lower()

        # Make sure some options have been sent through
        if len(opts) == 0 and cmd != 'view' and cmd != 'list':
            return await context.send(
                user.get_mention() + ', ' +
                lib.get_string('project:err:options', user.get_guild()))

        # Check which command is being run and run it.
        # Since the options can have spaces in them, we need to send the whole thing through as a list and then work out what is what in the command.
        if cmd == 'create':
            return await self.run_create(context, opts)
        elif cmd == 'delete':
            return await self.run_delete(context, opts)
        elif cmd == 'rename':
            return await self.run_rename(context, opts)
        elif cmd == 'update':
            return await self.run_update(context, opts)
        elif cmd == 'view':
            return await self.run_view(context, opts)
        elif cmd == 'list':
            return await self.run_list(context, opts)
        elif cmd == 'status':
            return await self.run_status(context, opts)
        elif cmd == 'genre':
            return await self.run_genre(context, opts)
        elif cmd == 'description':
            return await self.run_description(context, opts)
        elif cmd == 'link':
            return await self.run_link(context, opts)
        elif cmd == 'image' or cmd == 'img':
            return await self.run_image(context, opts)
Ejemplo n.º 15
0
 async def run_forget(self, context):
     """
     Set a user to no longer be notified of upcoming sprints on this server.
     :param context:
     :return:
     """
     user = User(context.message.author.id, context.guild.id, context)
     user.set_guild_setting('sprint_notify', 0)
     return await context.send(user.get_mention() + ', ' + lib.get_string('sprint:forgot', user.get_guild()))
Ejemplo n.º 16
0
 def get_notifications(self, users):
     """
     Get an array of user mentions for each person in the supplied array of userids
     :return:
     """
     notify = []
     for user_id in users:
         usr = User(user_id, self._guild)
         notify.append(usr.get_mention())
     return notify
Ejemplo n.º 17
0
    async def run_check_all(self, context):
        """
        Print a table of all the user's goals.
        @param context:
        @return:
        """

        now = int(time.time())
        user = User(context.message.author.id, context.guild.id, context)
        embed = discord.Embed(title=lib.get_string('goals', user.get_guild()),
                              color=10038562)

        for type in self.types:

            type_string = lib.get_string('goal:' + type, user.get_guild())
            goal = user.get_goal(type)
            if goal is not None:
                progress = user.get_goal_progress(type)
                left = lib.secs_to_days(goal['reset'] - now)
                text = lib.get_string('goal:yourgoal',
                                      user.get_guild()).format(
                                          type_string, goal['goal']) + "\n"
                text += lib.get_string('goal:status', user.get_guild()).format(
                    progress['percent'], type_string, progress['current'],
                    progress['goal']) + "\n"
                text += lib.get_string('goal:timeleft',
                                       user.get_guild()).format(
                                           left, type_string)
            else:
                text = None

            embed.add_field(name=type_string, value=text, inline=False)

        # Send the message
        await context.send(embed=embed)
Ejemplo n.º 18
0
    async def run_cancel(self, context):
        """
        Cancel a running sprint on the server
        :param context:
        :return:
        """
        user = User(context.message.author.id, context.guild.id, context)
        sprint = Sprint(user.get_guild())

        # If there is no active sprint, then just display an error
        if not sprint.exists():
            return await context.send(
                user.get_mention() + ', ' +
                lib.get_string('sprint:err:noexists', user.get_guild()))

        # If they do not have permission to cancel this sprint, display an error
        if int(sprint.get_createdby()) != user.get_id(
        ) and context.message.author.permissions_in(
                context.message.channel).manage_messages is not True:
            return await context.send(
                user.get_mention() + ', ' +
                lib.get_string('sprint:err:cannotcancel', user.get_guild()))

        # Get the users sprinting and create an array of mentions
        users = sprint.get_users()
        notify = sprint.get_notifications(users)

        # Cancel the sprint
        sprint.cancel(context)

        # Display the cancellation message
        message = lib.get_string('sprint:cancelled', user.get_guild())
        message = message + ', '.join(notify)
        return await context.send(message)
Ejemplo n.º 19
0
    async def generate(self, context, type=None, amount=None):
        """
        Random generator for various things (character names, place names, land names, book titles, story ideas, prompts).
        Define the type of item you wanted generated and then optionally, the amount of items to generate.

        Examples:
            !generate char - generates 10 character names
            !generate place 20 - generates 20 fantasy place names
            !generate land - generates 10 fantasy land/world names
            !generate book - generates 10 general fiction book titles
            !generate book_fantasy - generates 10 fantasy book titles
            !generate book_sf - generates 10 sci-fi book titles
            !generate book_horror - generates 10 horror book titles
            !generate book_rom - generates 10 romance/erotic book titles
            !generate book_mystery - generates 10 mystery book titles
            !generate book_hp - generates 10 Harry Potter book title
            !generate idea - generates a random story idea
            !generate prompt - generates a story prompt
            !generate face - generates a random person's face
        """
        if not Guild(context.guild).is_command_enabled('generate'):
            return await context.send(
                lib.get_string('err:disabled', context.guild.id))

        user = User(context.message.author.id, context.guild.id, context)

        # If no amount specified, use the default
        if amount is None:
            amount = NameGenerator.DEFAULT_AMOUNT

        # Check the arguments are valid
        args = await self.check_arguments(context, type=type, amount=amount)
        if not args:
            return

        type = args['type'].lower()
        amount = int(args['amount'])

        # For faces, we want to just call an API url.
        if type == 'face':
            return await context.send(self._urls['face'] + '?t=' +
                                      str(int(time.time())))

        generator = NameGenerator(type, context)
        results = generator.generate(amount)
        join = '\n'

        # For prompts, add an extra line between them.
        if type == 'prompt':
            join += '\n'

        names = join.join(results['names'])

        return await context.send(user.get_mention() + ', ' +
                                  results['message'] + names)
Ejemplo n.º 20
0
    async def run_complete(self, context):

        user = User(context.message.author.id, context.guild.id, context)

        # Do they have an active challenge to mark as complete?
        challenge = user.get_challenge()
        if challenge:

            # Update the challenge with the time completed
            user.complete_challenge(challenge['id'])

            # Add the XP
            await user.add_xp(challenge['xp'])

            # Increment the challenges_completed stat
            user.add_stat('challenges_completed', 1)

            output = lib.get_string('challenge:completed', user.get_guild(
            )) + ' **' + challenge['challenge'] + '**          +' + str(
                challenge['xp']) + 'xp'

        else:
            output = lib.get_string('challenge:noactive', user.get_guild())

        await context.send(f'{context.message.author.mention}, {output}')
Ejemplo n.º 21
0
    async def run_status(self, context):
        """
        Get the user's status in this sprint
        :param context:
        :return:
        """
        user = User(context.message.author.id, context.guild.id, context)
        sprint = Sprint(user.get_guild())

        # If there is no active sprint, then just display an error
        if not sprint.exists():
            return await context.send(user.get_mention() + ', ' + lib.get_string('sprint:err:noexists', user.get_guild()))

        # If the user is not sprinting, then again, just display that error
        if not sprint.is_user_sprinting(user.get_id()):
            return await context.send(user.get_mention() + ', ' + lib.get_string('sprint:err:notjoined', user.get_guild()))

        # If the sprint hasn't started yet, display error
        if not sprint.has_started():
            return await context.send(user.get_mention() + ', ' + lib.get_string('sprint:err:notstarted', user.get_guild()))

        # If they are sprinting, then display their current status.
        user_sprint = sprint.get_user_sprint(user.get_id())

        # Build the variables to be passed into the status string
        now = int(time.time())
        current = user_sprint['current_wc']
        written = current - user_sprint['starting_wc']
        seconds = now - user_sprint['timejoined']
        elapsed = round(seconds / 60, 1)
        wpm = Sprint.calculate_wpm(written, seconds)
        left = round((sprint.get_end() - now) / 60, 1)

        return await context.send(user.get_mention() + ', ' + lib.get_string('sprint:status', user.get_guild()).format(current, written, elapsed, wpm, left))
Ejemplo n.º 22
0
    async def run_rename(self, context, opts):
        """
        Rename the event
        :param context:
        :param opts:
        :return:
        """
        user = User(context.message.author.id, context.guild.id, context)

        # Do they have the permissions to rename an event?
        self.check_permissions(context)

        # Check if there is an event running
        event = Event.get_by_guild(user.get_guild())
        if event is None or not event.is_valid():
            return await context.send(
                user.get_mention() + ', ' +
                lib.get_string('event:err:noexists', user.get_guild()))

        # Get the title out of the arguments
        title = " ".join(opts[0:])

        # Make sure they specified a title.
        if len(title) == 0 or len(title) > 255:
            return await context.send(
                user.get_mention() + ', ' +
                lib.get_string('event:err:rename:title', user.get_guild()))

        # Create the event
        event.set_title(title)
        event.save()
        return await context.send(
            user.get_mention() + ', ' +
            lib.get_string('event:renamed', user.get_guild()).format(title))
Ejemplo n.º 23
0
    async def my_setting(self, context, setting=None, value=None):
        """
        Lets you update a setting for your user account.

        **Note:** For the timezone setting, make sure the value you specify is a valid TZ Database Name from this wikipedia page:
        https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

        Examples:
            !mysetting timezone Europe/London
            !mysetting timezone America/Phoenix
        """
        user = User(context.message.author.id, context.guild.id, context)

        # If we want to list the setting, do that instead.
        if setting is not None and setting.lower() == 'list':
            settings = user.get_settings()
            output = '```ini\n'
            if settings:
                for setting, value in settings.items():
                    output += setting + '=' + str(value) + '\n'
            else:
                output += lib.get_string('setting:none', guild.get_id())
            output += '```'
            return await context.send(user.get_mention() + ',\n' + output)

        # Check the arguments are valid
        args = await self.check_arguments(context,
                                          setting=setting,
                                          value=value)
        if not args:
            return

        setting = args['setting'].lower()
        value = args['value']

        # If the setting is timezone convert the value
        if setting == 'timezone':
            try:
                timezone = pytz.timezone(value)
                time = datetime.now(timezone)
                offset = datetime.now(timezone).strftime('%z')
                await context.send(
                    lib.get_string('event:timezoneupdated',
                                   user.get_guild()).format(
                                       value, time.ctime(), offset))
            except pytz.exceptions.UnknownTimeZoneError:
                await context.send(
                    lib.get_string('mysetting:timezone:help',
                                   user.get_guild()))
                return

        # Update the setting and post the success message
        user.update_setting(setting, value)
        await context.send(user.get_mention() + ', ' + lib.get_string(
            'mysetting:updated', user.get_guild()).format(setting, value))
Ejemplo n.º 24
0
    async def run_image(self, context, opts):
        """
        Update the image link of a project
        @param context:
        @param opts:
        @return:
        """
        user = User(context.message.author.id, context.guild.id, context)
        shortname = opts[0].lower() if opts else None
        img = opts[1] if len(opts) > 1 else None

        # Make sure the project exists.
        project = user.get_project(shortname)
        if not project:
            return await context.send(
                user.get_mention() + ', ' +
                lib.get_string('project:err:noexists',
                               user.get_guild()).format(shortname))

        # Check it's a valid image link.
        if not checkers.is_url(img) and img is not None:
            return await context.send(
                user.get_mention() + ', ' + lib.get_string(
                    'project:err:link', user.get_guild()).format(img))

        project.set_image(img)
        return await context.send(
            user.get_mention() + ', ' +
            lib.get_string('project:image', user.get_guild()))
Ejemplo n.º 25
0
    async def run_update(self, context, opts):
        """
        Update a project's word count
        :param context:
        :param opts:
        :return:
        """
        user = User(context.message.author.id, context.guild.id, context)

        shortname = opts[0].lower()
        amount = opts[1] if len(opts) > 1 else None

        # Make sure the amount is valid.
        amount = lib.is_number(amount)
        if not amount:
            return await context.send(
                user.get_mention() + ', ' +
                lib.get_string('project:err:amount', user.get_guild()))

        # Make sure the project exists.
        project = user.get_project(shortname)
        if not project:
            return await context.send(
                user.get_mention() + ', ' +
                lib.get_string('project:err:noexists',
                               user.get_guild()).format(shortname))

        # Update the word count.
        project.update(amount)
        return await context.send(
            user.get_mention() + ', ' +
            lib.get_string('project:updated', user.get_guild()).format(
                amount, project.get_name(), project.get_shortname()))
Ejemplo n.º 26
0
    async def run_description(self, context, opts):
        """
        Update the description of a project
        @param context:
        @param opts:
        @return:
        """
        user = User(context.message.author.id, context.guild.id, context)
        shortname = opts[0].lower()
        description = " ".join(opts[1:])

        # Make sure the project exists.
        project = user.get_project(shortname)
        if not project:
            return await context.send(
                user.get_mention() + ', ' +
                lib.get_string('project:err:noexists',
                               user.get_guild()).format(shortname))

        # Description cannot be longer than 200 words.
        words = description.split(' ')
        if len(words) > 200:
            return await context.send(
                user.get_mention() +
                ', ' + lib.get_string('project:err:desc:length',
                                      user.get_guild()).format(len(words)))

        project.set_description(description)
        return await context.send(
            user.get_mention() + ', ' +
            lib.get_string('project:description', user.get_guild()))
Ejemplo n.º 27
0
    async def run_start(self, context, length=None, start=None):
        """
        Try to start a sprint on the server
        :param context
        :param length: Length of time (in minutes) the sprint should last
        :param start: Time in minutes from now, that the sprint should start
        :return:
        """
        user = User(context.message.author.id, context.guild.id, context)
        sprint = Sprint(user.get_guild())

        # Check if sprint is finished but not marked as completed, in which case we can mark it as complete
        if sprint.is_finished():
            # Mark the sprint as complete
            await sprint.complete()
            # Reload the sprint object, as now there shouldn't be a pending one
            sprint = Sprint(user.get_guild())

        # If a sprint is currently running, we cannot start a new one
        if sprint.exists():
            return await context.send(user.get_mention() + ', ' + lib.get_string('sprint:err:alreadyexists', user.get_guild()))

        # Must be okay to continue #

        # If the length argument is not valid, use the default
        if length is None or lib.is_number(length) is False or lib.is_number(length) <= 0 or lib.is_number(length) > self.MAX_LENGTH:
            length = self.DEFAULT_LENGTH

        # Same goes for the start argument
        if start is None or lib.is_number(start) is False or lib.is_number(start) < 0 or lib.is_number(start) > self.MAX_DELAY:
            start = self.DEFAULT_DELAY

        # Make sure we are using ints and not floats passed through in the command
        length = int(length)
        start = int(start)

        # Calculate the start and end times based on the current timestamp
        now = int(time.time())
        start_time = now + (start * 60)
        end_time = start_time + (length * 60)

        # Create the sprint
        sprint = Sprint.create(guild=user.get_guild(), channel=context.message.channel.id, start=start_time, end=end_time, end_reference=end_time, length=length, createdby=user.get_id(), created=now)

        # Join the sprint
        sprint.join(user.get_id())

        # Increment the user's stat for sprints created
        user.add_stat('sprints_started', 1)

        # Are we starting immediately or after a delay?
        if start == 0:
            # Immediately. That means we need to schedule the end task.
            Task.schedule(sprint.TASKS['end'], end_time, 'sprint', sprint.get_id())
            return await sprint.post_start(context)
        else:
            # Delay. That means we need to schedule the start task, which will in turn schedule the end task once it's run.
            Task.schedule(sprint.TASKS['start'], start_time, 'sprint', sprint.get_id())
            return await sprint.post_delayed_start(context)
Ejemplo n.º 28
0
 async def run_purge(self, context):
     """
     Purge any users who asked for notifications but aren't on the server any more.
     @param context:
     @return:
     """
     user = User(context.message.author.id, context.guild.id, context)
     purged = await Sprint.purge_notifications(context)
     if purged > 0:
         return await context.send(lib.get_string('sprint:purged', user.get_guild()).format(purged))
     else:
         return await context.send(lib.get_string('sprint:purged:none', user.get_guild()))
Ejemplo n.º 29
0
    async def run_pb(self, context):
        """
        Get the user's personal best for sprinting
        :param context:
        :return:
        """
        user = User(context.message.author.id, context.guild.id, context)
        record = user.get_record('wpm')

        if record is None:
            return await context.send(user.get_mention() + ', ' + lib.get_string('sprint:pb:none', user.get_guild()))
        else:
            return await context.send(user.get_mention() + ', ' + lib.get_string('sprint:pb', user.get_guild()).format(int(record)))
Ejemplo n.º 30
0
    async def setting(self, context, setting=None, value=None):
        """
        Lets you update a setting for the server, if you have the permissions to manage_guild

        Examples:
            !setting lang en - Set the language to be used. Available language packs: en
            !setting sprint_delay_end 5 - Set the timer delay between the sprint finishing and the final word counts being tallied. Max time: 15 mins. Default: 2 mins.
            !setting list - Displays a list of all the custom server settings
        """
        user = User(context.message.author.id, context.guild.id, context)
        guild = Guild(context.guild)

        # If we want to list the setting, do that instead.
        if setting is not None and setting.lower() == 'list':
            settings = guild.get_settings()
            output = '```ini\n'
            if settings:
                for setting, value in settings.items():
                    output += setting + '=' + str(value) + '\n'
            else:
                output += lib.get_string('setting:none', guild.get_id())
            output += '```'
            return await context.send(output)

        # Otherwise, continue on as we must be trying to set a setting value
        # Check the arguments are valid
        args = await self.check_arguments(context,
                                          setting=setting,
                                          value=value)
        if not args:
            return

        setting = args['setting'].lower()
        value = args['value']

        # Check that the value is valid for the setting they are updating
        if setting == 'sprint_delay_end' and (not lib.is_number(value)
                                              or int(value) < 1):
            return await context.send(
                user.get_mention() + ', ' +
                lib.get_string('setting:err:sprint_delay_end', guild.get_id()))

        if setting == 'lang' and not lib.is_supported_language(value):
            return await context.send(
                user.get_mention() + ', ' +
                lib.get_string('setting:err:lang', guild.get_id()).format(
                    ', '.join(lib.get_supported_languages())))

        guild.update_setting(setting, value)
        return await context.send(user.get_mention() + ', ' + lib.get_string(
            'setting:updated', guild.get_id()).format(setting, value))