コード例 #1
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))
コード例 #2
0
ファイル: sprint.py プロジェクト: radse/copywriter-tools
    async def run_leave(self, context):
        """
        Leave the 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 or the user is not joined to it, display an error
        if not sprint.exists() or not sprint.is_user_sprinting(user.get_id()):
            return await context.send(
                user.get_mention() + ', ' +
                lib.get_string('sprint:err:notjoined', user.get_guild()))

        # Remove the user from the sprint
        sprint.leave(user.get_id())

        await context.send(user.get_mention() + ', ' +
                           lib.get_string('sprint:leave', user.get_guild()))

        # If there are now no users left, cancel the whole sprint
        if len(sprint.get_users()) == 0:

            # Cancel the sprint
            sprint.cancel(context)

            # Decrement sprints_started stat for whoever started this one
            creator = User(sprint.get_createdby(), sprint.get_guild())
            creator.add_stat('sprints_started', -1)

            # Display a message letting users know
            return await context.send(
                lib.get_string('sprint:leave:cancelled', user.get_guild()))
コード例 #3
0
ファイル: sprint.py プロジェクト: radse/copywriter-tools
    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()))
コード例 #4
0
    async def run_join(self, context, starting_wc=None, shortname=None):
        """
        Join the sprint, with an optional starting word count and project shortname
        :param starting_wc:
        :param shortname: Shortname of Project
        :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()))

        # Convert starting_wc to int if we can
        starting_wc = lib.is_number(starting_wc)
        if starting_wc is False:
            starting_wc = 0

        # If the user is already sprinting, then just update their starting wordcount
        if sprint.is_user_sprinting(user.get_id()):

            # Update the sprint_users record. We set their current_wc to the same as starting_wc here, otherwise if they join with, say 50 and their current remains 0
            # then if they run a status, or in the ending calculations, it will say they wrote -50.
            sprint.update_user(user.get_id(), start=starting_wc, current=starting_wc)

            # Send message back to channel letting them know their starting word count was updated
            await context.send(user.get_mention() + ', ' + lib.get_string('sprint:join:update', user.get_guild()).format(starting_wc))

        else:

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

            # Send message back to channel letting them know their starting word count was updated
            await context.send(user.get_mention() + ', ' + lib.get_string('sprint:join', user.get_guild()).format(starting_wc))

        # If a project shortname is supplied, try to set that as what the user is sprinting for.
        if shortname is not None:

            # Convert to lowercase for searching.
            shortname = shortname.lower()

            # 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))

            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()))
コード例 #5
0
ファイル: sprint.py プロジェクト: radse/copywriter-tools
    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)
コード例 #6
0
ファイル: event.py プロジェクト: radse/copywriter-tools
    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))
コード例 #7
0
    async def run_end(self, context):
        """
        Manually force the sprint to end (if the cron hasn't posted the message) and ask for final word counts
        :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:cannotend', user.get_guild()))

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

        # Change the end reference to now, otherwise wpm calculations will be off, as it will use the time in the future when it was supposed to end.
        sprint.update_end_reference(int(time.time()))

        # Since we are forcing the end, we should cancel any pending tasks for this sprint
        Task.cancel('sprint', sprint.get_id())

        # We need to set the bot into the sprint object, as we will need it when trying to get the guild object
        sprint.set_bot(self.bot)
        return await sprint.end(context)
コード例 #8
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)
コード例 #9
0
    async def run_me(self, context):
        """
        Check your own word count for the event so far
        :param context:
        :return:
        """
        user = User(context.message.author.id, context.guild.id, context)
        event = Event.get_by_guild(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()))

        words = event.get_wordcount(user.get_id())
        return await context.send(user.get_mention() + ', ' + lib.get_string('event:wordcount', user.get_guild()).format(event.get_title(), words))
コード例 #10
0
    def cancel(self, context):
        """
        Cancel the sprint and notify the users who were taking part
        :return:
        """

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

        # Delete sprints and sprint_users records
        self.__db.delete('sprint_users', {'sprint': self._id})
        self.__db.delete('sprints', {'id': self._id})

        # Delete pending scheduled tasks
        Task.cancel('sprint', self._id)

        # If the user created this, decrement their created stat
        if user.get_id() == self._createdby:
            user.add_stat('sprints_started', -1)
コード例 #11
0
    async def complete(self, context=None, bot=None):
        """
        Finish the sprint, calculate all the WPM and XP and display results
        :return:
        """

        # Print the 'Results coming up shortly' message
        await self.say(lib.get_string('sprint:resultscomingsoon', self._guild),
                       context, bot)

        # Create array to use for storing the results
        results = []

        # If the sprint has already completed, stop.
        if self._completed != 0:
            return

        # Mark this sprint as complete so the cron doesn't pick it up and start processing it again
        self.set_complete()

        # Get all the users taking part
        users = self.get_users()

        # Loop through them and get their full sprint info
        for user_id in users:

            user = User(user_id,
                        self._guild,
                        context=context,
                        bot=bot,
                        channel=self.get_channel())
            user_sprint = self.get_user_sprint(user_id)

            # If it's a non-word count sprint, we don't need to do anything with word counts.
            if user_sprint['sprint_type'] == Sprint.SPRINT_TYPE_NO_WORDCOUNT:

                # Just give them the completed sprint stat and XP.
                await user.add_xp(Experience.XP_COMPLETE_SPRINT)
                user.add_stat('sprints_completed', 1)

                # Push user to results
                results.append({
                    'user': user,
                    'wordcount': 0,
                    'xp': Experience.XP_COMPLETE_SPRINT,
                    'type': user_sprint['sprint_type']
                })

            else:

                # If they didn't submit an ending word count, use their current one
                if user_sprint['ending_wc'] == 0:
                    user_sprint['ending_wc'] = user_sprint['current_wc']

                # Now we only process their result if they have declared something and it's different to their starting word count
                user_sprint['starting_wc'] = int(user_sprint['starting_wc'])
                user_sprint['current_wc'] = int(user_sprint['current_wc'])
                user_sprint['ending_wc'] = int(user_sprint['ending_wc'])
                user_sprint['timejoined'] = int(user_sprint['timejoined'])

                if user_sprint['ending_wc'] > 0 and user_sprint[
                        'ending_wc'] != user_sprint['starting_wc']:

                    wordcount = user_sprint['ending_wc'] - user_sprint[
                        'starting_wc']
                    time_sprinted = self._end_reference - user_sprint[
                        'timejoined']

                    # If for some reason the timejoined or sprint.end_reference are 0, then use the defined sprint length instead
                    if user_sprint[
                            'timejoined'] <= 0 or self._end_reference == 0:
                        time_sprinted = self._length

                    # Calculate the WPM from their time sprinted
                    wpm = Sprint.calculate_wpm(wordcount, time_sprinted)

                    # See if it's a new record for the user
                    user_record = user.get_record('wpm')
                    wpm_record = True if user_record is None or wpm > int(
                        user_record) else False

                    # If it is a record, update their record in the database
                    if wpm_record:
                        user.update_record('wpm', wpm)

                    # Give them XP for finishing the sprint
                    await user.add_xp(Experience.XP_COMPLETE_SPRINT)

                    # Increment their stats
                    user.add_stat('sprints_completed', 1)
                    user.add_stat('sprints_words_written', wordcount)
                    user.add_stat('total_words_written', wordcount)

                    # Increment their words towards their goal
                    await user.add_to_goals(wordcount)

                    # If they were writing in a Project, update its word count.
                    if user_sprint['project'] is not None:
                        project = Project(user_sprint['project'])
                        project.add_words(wordcount)

                    # is there an event running on this server?
                    event = Event.get_by_guild(self._guild)
                    if event and event.is_running():
                        event.add_words(user.get_id(), wordcount)

                    # Push user to results
                    results.append({
                        'user': user,
                        'wordcount': wordcount,
                        'wpm': wpm,
                        'wpm_record': wpm_record,
                        'xp': Experience.XP_COMPLETE_SPRINT,
                        'type': user_sprint['sprint_type']
                    })

        # Sort the results
        results = sorted(results, key=itemgetter('wordcount'), reverse=True)

        # Now loop through them again and apply extra XP, depending on their position in the results
        position = 1
        highest_word_count = 0

        for result in results:

            if result['wordcount'] > highest_word_count:
                highest_word_count = result['wordcount']
            # If the user finished in the top 5 and they weren't the only one sprinting, earn extra XP
            is_sprint_winner = result['wordcount'] == highest_word_count
            if position <= 5 and len(results) > 1:

                extra_xp = math.ceil(
                    Experience.XP_WIN_SPRINT /
                    (self.WINNING_POSITION if is_sprint_winner else position))
                result['xp'] += extra_xp
                await result['user'].add_xp(extra_xp)

            # If they actually won the sprint, increase their stat by 1
            # Since the results are in order, the highest word count will be set first
            # which means that any subsequent users with the same word count have tied for 1st place
            if position == 1 or result['wordcount'] == highest_word_count:
                result['user'].add_stat('sprints_won', 1)

            position += 1

        # Post the final message with the results
        if len(results) > 0:

            position = 1
            message = lib.get_string('sprint:results:header', self._guild)
            for result in results:

                if result['type'] == Sprint.SPRINT_TYPE_NO_WORDCOUNT:
                    message = message + lib.get_string(
                        'sprint:results:row:nowc', self._guild).format(
                            result['user'].get_mention(), result['xp'])
                else:

                    message = message + lib.get_string(
                        'sprint:results:row', self._guild).format(
                            position, result['user'].get_mention(),
                            result['wordcount'], result['wpm'], result['xp'])

                    # If it's a new PB, append that string as well
                    if result['wpm_record'] is True:
                        message = message + lib.get_string(
                            'sprint:results:pb', self._guild)

                message = message + '\n'
                position += 1

        else:
            message = lib.get_string('sprint:nowordcounts', self._guild)

        # Send the message, either via the context or directly to the channel
        await self.say(message, context, bot)
コード例 #12
0
ファイル: sprint.py プロジェクト: radse/copywriter-tools
    async def run_join(self, context, arg1=None, arg2=None):
        """
        Join the sprint, with an optional starting word count and project shortname
        :param opt1: Argument 1 of the join command
        :param opt2: Argument 2 of the join command
        :return:
        """
        user = User(context.message.author.id, context.guild.id, context)
        sprint = Sprint(user.get_guild())
        project_id = None
        starting_wc = None
        sprint_type = None

        # 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()))

        # Are we using the `same` keyword?
        if arg1 == "same":

            # Okay, check for their most recent sprint record
            most_recent = user.get_most_recent_sprint(sprint)
            if most_recent is not None:
                starting_wc = most_recent['ending_wc']
                project_id = most_recent['project']
                sprint_type = most_recent['sprint_type']

            # Can't use the second argument in this case.
            arg2 = None

        # Are we doing a no wordcount sprint? E.g. we are sprinting or using the functionality for something else.
        elif arg1 in ["edit", "non-wc"]:

            sprint_type = Sprint.SPRINT_TYPE_NO_WORDCOUNT

            # Can't use the second argument in this case.
            arg2 = None

        else:
            # Convert starting_wc to int if we can
            starting_wc = lib.is_number(arg1)

        # If the starting_wc is still False at this point, just set it to 0
        if not starting_wc:
            starting_wc = 0

        # If the user is already sprinting, then just update their starting wordcount
        if sprint.is_user_sprinting(user.get_id()):

            # Update the sprint_users record. We set their current_wc to the same as starting_wc here, otherwise if they join with, say 50 and their current remains 0
            # then if they run a status, or in the ending calculations, it will say they wrote -50.
            sprint.update_user(user.get_id(),
                               start=starting_wc,
                               current=starting_wc,
                               sprint_type=sprint_type)

            # If it's a non-wordcount sprint, send a different message.
            if sprint_type == Sprint.SPRINT_TYPE_NO_WORDCOUNT:
                await context.send(user.get_mention() + ', ' + lib.get_string(
                    'sprint:join:update:no_wordcount', user.get_guild()))
            else:
                # Send message back to channel letting them know their starting word count was updated
                await context.send(user.get_mention() + ', ' + lib.get_string(
                    'sprint:join:update', user.get_guild()).format(starting_wc)
                                   )

        else:

            # Join the sprint
            sprint.join(user.get_id(),
                        starting_wc=starting_wc,
                        sprint_type=sprint_type)

            if sprint_type == Sprint.SPRINT_TYPE_NO_WORDCOUNT:
                await context.send(user.get_mention() + ', ' + lib.get_string(
                    'sprint:join:update:no_wordcount', user.get_guild()))
            else:
                # Send message back to channel letting them know their starting word count was updated
                await context.send(user.get_mention() + ', ' + lib.get_string(
                    'sprint:join', user.get_guild()).format(starting_wc))

        # Currently this is the only usage of argument 2.
        shortname = arg2

        # If a project shortname is supplied, try to set that as what the user is sprinting for.
        if shortname is not None or project_id is not None:

            # Did we supply the project by name?
            if shortname is not None:

                # Convert to lowercase for searching.
                shortname = shortname.lower()

                # Make sure the project exists.
                project = user.get_project(shortname)

            # Or do we already have the ID from using 'same' and getting from previous sprint?
            elif project_id is not None:
                project = Project(project_id)

            # If that did not yield a valid project, send an error message.
            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()))
コード例 #13
0
ファイル: sprint.py プロジェクト: radse/copywriter-tools
    async def run_declare(self, context, amount=None):
        """
        Declare user's current word count for the sprint
        :param context:
        :param amount:
        :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()))

        # Get the user's sprint info
        user_sprint = sprint.get_user_sprint(user.get_id())

        # If they joined without a word count, they can't add one.
        if user_sprint['sprint_type'] == Sprint.SPRINT_TYPE_NO_WORDCOUNT:
            return await context.send(
                user.get_mention() + ', ' +
                lib.get_string('sprint:err:nonwordcount', user.get_guild()))

        # Did they enter something for the amount?
        if amount is None:
            return await context.send(
                user.get_mention() + ', ' +
                lib.get_string('sprint:err:amount', user.get_guild()))

        # Are they trying to do a calculation instead of declaring a number?
        if amount[0] == '+' or amount[0] == '-':

            # Set the calculation variable to True so we know later on that it was not a proper declaration
            calculation = True

            # Convert the amount string to an int
            amount = int(amount)

            # Add that to the current word count, to get the new value
            new_amount = user_sprint['current_wc'] + amount

        else:
            calculation = False
            new_amount = amount

        # Make sure the amount is now a valid number
        if not lib.is_number(new_amount):
            return await context.send(
                user.get_mention() + ', ' +
                lib.get_string('sprint:err:amount', user.get_guild()))

        # Just make sure the new_amount is defintely an int
        new_amount = int(new_amount)

        # If the declared value is less than they started with and it is not a calculation, then that is an error.
        if new_amount < int(user_sprint['starting_wc']) and not calculation:
            diff = user_sprint['current_wc'] - new_amount
            return await context.send(
                user.get_mention() + ', ' +
                lib.get_string('sprint:err:wclessthanstart', user.get_guild(
                )).format(new_amount, user_sprint['starting_wc'], diff))

        # Is the sprint finished? If so this will be an ending_wc declaration, not a current_wc one.
        col = 'ending' if sprint.is_finished() else 'current'

        # Before we actually update it, if the WPM is huge and most likely an error, just check with them if they meant to put that many words.
        written = new_amount - int(user_sprint['starting_wc'])
        seconds = int(sprint.get_end_reference()) - user_sprint['timejoined']
        wpm = Sprint.calculate_wpm(written, seconds)

        # Does the user have a configured setting for max wpm to check?
        max_wpm = user.get_setting('maxwpm')
        if not max_wpm:
            max_wpm = self.WPM_CHECK

        if wpm > int(max_wpm):

            # Make a fake prompt to wait for confirmation.
            argument = {
                'prompt':
                lib.get_string('sprint:wpm:sure',
                               user.get_guild()).format(written, wpm),
                'check':
                lambda resp: resp.lower() in ('y', 'yes', 'n', 'no')
            }

            response = await self.adhoc_prompt(context, argument, True)

            # If they confirm, then delete the event.
            if response is False or response.content.lower() in ('n', 'no'):
                return await context.send(
                    user.get_mention() + ', ' +
                    lib.get_string('sprint:declareagain', user.get_guild()))

        # Update the user's sprint record
        arg = {col: new_amount}
        sprint.update_user(user.get_id(), **arg)

        # Reload the user sprint info
        user_sprint = sprint.get_user_sprint(user.get_id())

        # Which value are we displaying?
        wordcount = user_sprint['ending_wc'] if sprint.is_finished(
        ) else user_sprint['current_wc']
        written = int(wordcount) - int(user_sprint['starting_wc'])

        await context.send(user.get_mention() + ', ' + lib.get_string(
            'sprint:declared', user.get_guild()).format(wordcount, written))

        # Is the sprint now over and has everyone declared?
        if sprint.is_finished() and sprint.is_declaration_finished():
            Task.cancel('sprint', sprint.get_id())
            await sprint.complete(context)
コード例 #14
0
    async def wrote(self, context, amount=None, shortname=None):
        """
        Adds to your total words written statistic.

        Examples:
            !wrote 250 - Adds 250 words to your total words written
            !wrote 200 sword - Adds 200 words to your Project with the shortname "sword". (See: Projects for more info).
        """

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

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

        amount = args['amount']
        shortname = args['shortname']
        message = None

        # If they were writing in a Project, update its word count.
        if shortname is not None:

            project = user.get_project(shortname.lower())

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

            project.add_words(amount)

            written_stat = user.get_stat('total_words_written')
            if written_stat is None:
                written_stat = 0
            total = int(written_stat) + int(amount)

            message = lib.get_string('wrote:addedtoproject',
                                     user.get_guild()).format(
                                         str(amount), project.get_title(),
                                         project.get_words(), total)

        # # Is there an Event running?
        event = Event.get_by_guild(user.get_guild())
        if event and event.is_running():
            event.add_words(user.get_id(), amount)

        # Increment their words written statistic
        user.add_stat('total_words_written', amount)

        # Update their words towards their daily goal
        await user.add_to_goal('daily', amount)

        # Output message
        if message is None:
            total = user.get_stat('total_words_written')
            message = lib.get_string('wrote:added', user.get_guild()).format(
                str(amount), str(total))

        await context.send(user.get_mention() + ', ' + message)
コード例 #15
0
    async def run_declare(self, context, amount=None):
        """
        Declare user's current word count for the sprint
        :param context:
        :param amount:
        :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()))

        # Did they enter something for the amount?
        if amount is None:
            return await context.send(user.get_mention() + ', ' + lib.get_string('sprint:err:amount', user.get_guild()))

        # Get the user's sprint info
        user_sprint = sprint.get_user_sprint(user.get_id())

        # Are they trying to do a calculation instead of declaring a number?
        if amount[0] == '+' or amount[0] == '-':

            # Set the calculation variable to True so we know later on that it was not a proper declaration
            calculation = True

            # Convert the amount string to an int
            amount = int(amount)

            # Add that to the current word count, to get the new value
            new_amount = user_sprint['current_wc'] + amount

        else:
            calculation = False
            new_amount = amount

        # Make sure the amount is now a valid number
        if not lib.is_number(new_amount):
            return await context.send(user.get_mention() + ', ' + lib.get_string('sprint:err:amount', user.get_guild()))

        # Just make sure the new_amount is defintely an int
        new_amount = int(new_amount)

        # If the declared value is less than they started with and it is not a calculation, then that is an error.
        if new_amount < int(user_sprint['starting_wc']) and not calculation:
            diff = user_sprint['current_wc'] - new_amount
            return await context.send(user.get_mention() + ', ' + lib.get_string('sprint:err:wclessthanstart', user.get_guild()).format(new_amount, user_sprint['starting_wc'], diff))

        # Is the sprint finished? If so this will be an ending_wc declaration, not a current_wc one.
        col = 'ending' if sprint.is_finished() else 'current'
        arg = {col: new_amount}

        # Update the user's sprint record
        sprint.update_user(user.get_id(), **arg)

        # Reload the user sprint info
        user_sprint = sprint.get_user_sprint(user.get_id())

        # Which value are we displaying?
        wordcount = user_sprint['ending_wc'] if sprint.is_finished() else user_sprint['current_wc']
        written = int(wordcount) - int(user_sprint['starting_wc'])

        await context.send(user.get_mention() + ', ' + lib.get_string('sprint:declared', user.get_guild()).format(wordcount, written))

        # Is the sprint now over and has everyone declared?
        if sprint.is_finished() and sprint.is_declaration_finished():
            Task.cancel('sprint', sprint.get_id())
            await sprint.complete(context)