Beispiel #1
0
    async def check_content(self, argument, content, context):

        result = True

        # Do we need to check the type?
        # The only type checking we do is str or int, as that's basically all they can supply.
        # Assumption is that str is anything that is not a number.
        if 'type' in argument and argument[
                'type'] is int and not lib.is_number(content):
            result = False
        elif 'type' in argument and argument['type'] is str and lib.is_number(
                content):
            result = False

        # Do we need to do any extra checks?
        if 'check' in argument and callable(argument['check']):
            content = str(content).lower()
            if not argument['check'](content):
                result = False

        # If the result is false and the argument specifies an error message, send that.
        if result is False and 'error' in argument:
            await context.send(
                context.message.author.mention + ', ' +
                lib.get_string(argument['error'], context.guild.id))

        return result
    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)
    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()))
Beispiel #4
0
    async def run_update(self, context, type, amount):
        """
        Update the value of a goal, without affecting the others or updating XP, etc...
        Useful for if you want to record the writing you have done, before you started using Writer-Bot.
        @param context:
        @param type:
        @param amount:
        @return:
        """
        user = User(context.message.author.id, context.guild.id, context)
        type_string = lib.get_string('goal:' + type, user.get_guild())
        user_goal = user.get_goal(type)

        # Check if we can convert the amount to an int
        amount = lib.is_number(amount)
        if not amount:
            return await context.send(
                user.get_mention() + ', ' +
                lib.get_string('err:validamount', user.get_guild()))

        # Set the goal's current amount.
        if user_goal and user.update_goal(type, amount):
            return await context.send(
                user.get_mention() + ', ' +
                lib.get_string('goal:updated', user.get_guild()).format(
                    type_string, amount))
        else:
            return await context.send(
                user.get_mention() + ', ' + lib.get_string(
                    'goal:nogoal', user.get_guild()).format(type_string, type))
Beispiel #5
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))
Beispiel #6
0
def television(args):

    command = args.get("command")

    command = parseCommand(command)

    multiplier = 0
    if ("UP" in command) or ("DOWN" in command) or ("RIGHT" in command) or (
            "LEFT" in command):
        multString = re.search('(\d+)$', command)
        if (multString is not None):
            multString = multString.group(0)
            multiplier = int(multString)
            command = command.replace(multString, "")
            print(multiplier)

    command = decodeCommand(command)

    if lib.is_number(command):
        for i in range(0, len(command)):
            samsungctl.Remote(config.tvconfig).control("KEY_" + command[i])
            print("KEY_" + command[i])
    else:
        if (multiplier > 0):
            for i in range(0, multiplier):
                samsungctl.Remote(config.tvconfig).control(command)
                print(command)
        else:
            samsungctl.Remote(config.tvconfig).control(command)
            print(command)

    return "TV Control OK"
Beispiel #7
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', user.get_guild())
            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

        elif setting == 'maxwpm':
            # Must be a number.
            value = lib.is_number(value)
            if not value or value <= 0:
                return await context.send(user.get_mention() + ', ' + lib.get_string('mysetting:err:maxwpm', user.get_guild()))

        # 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) )
    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))
Beispiel #9
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()))
    async def run_set(self, context, type, amount):

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

        # Check if we can convert the amount to an int
        amount = lib.is_number(amount)
        if not amount:
            return await context.send(user.get_mention() + ', ' + lib.get_string('err:validamount', user.get_guild()))

        # Set the user's goal
        user.set_goal(type, amount)
        timezone = user.get_setting('timezone') or 'UTC'

        reset_every = lib.get_string('goal:set:'+type, user.get_guild())
        return await context.send(user.get_mention() + ', ' + lib.get_string('goal:set', user.get_guild()).format(type, amount, reset_every, timezone))
Beispiel #11
0
    async def run_delete(self, context, user):
        """
        Delete a reminder
        @param context:
        @param user:
        @return:
        """
        reminders = user.get_reminders()
        message = lib.get_string('remind:list', user.get_guild())

        map = {}

        x = 1
        for reminder in reminders:
            message += '**' + str(x) + '.** ' + reminder.info(context) + '\n'
            map[x] = reminder
            x += 1

        await self.split_send(context, user, message)

        # Prompt for reminder numbers to delete
        answer = await self.delete_wait_for_response(context)
        if not answer:
            return

        delete = [x.strip() for x in answer.split(',')]
        deleted = 0

        # If we say 'all' we want to delete all of them so get all of the numbers
        if answer.lower() == 'all':
            delete = range(x)

        for d in delete:
            number = lib.is_number(d)
            if number and number in list(map.keys()):
                map[number].delete()
                deleted += 1

        return await context.send(
            user.get_mention() + ', ' +
            lib.get_string('remind:deleted', user.get_guild()).format(deleted))
Beispiel #12
0
def identify_ptvs2():
    """
    Attempts to identify PTVs.

    Ignores case.  Expects 'PTV' at the beginning of the ROI name, then
    characters which can be represented as a number (the prescription dose).
    """
    patient = lib.get_current_patient()
    roi_names = [x.Name for x in patient.PatientModel.RegionsOfInterest]
    candidates = [
        x for x in roi_names
        if (x.replace(' ', '').upper().startswith('PTV')
            and lib.is_number(x.replace(' ', '').upper()[3:]))
    ]

    if len(candidates) == 0:
        logger.warning('No ROIs could be identified as a PTV.')
        return None

    logger.info('Possible PTVs identified as %s', candidates)
    return candidates
Beispiel #13
0
    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()))
Beispiel #14
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()))

        # 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)
    async def run_remind(self, context, user, cmd):
        """
        Set or configure a reminder
        @param context:
        @param user:
        @param cmd:
        @return:
        """
        now = int(time.time())

        remind_time = None
        message = None
        channel = None
        repeat = None

        # Check the first format: in x send y to #z. E.g. in 15 send Hi there everyone to #channel. Or: in 25 send Hey there
        regex = {
            'in': '^in\s(\d+)\ssend\s(.*?)(\sto\s\<\#([0-9]+)\>)?$',
            'at': '^at\s(\d{4}|\d{2}\:\d{2})(\son\s(.*?))?\ssend\s(.*?)(\sto\s\<\#([0-9]+)\>)?$',
            'every': '^every\s(day|hour|week)\s(from|at)\s(\d{4}|\d{2}\:\d{2})\ssend\s(.*?)(\sto\s\<\#([0-9]+)\>)?$'
        }
        if re.search(regex['in'], cmd, re.IGNORECASE):

            matches = re.findall(regex['in'], cmd, re.IGNORECASE)

            # Make sure the time in mins is valid.
            if int(matches[0][0]) <= 0:
                return await context.send(lib.get_string('remind:err:time', user.get_guild()))

            remind_time = now + (60 * int(matches[0][0]))

            message = matches[0][1]
            if lib.is_number(matches[0][3]):
                channel = int(matches[0][3])
            else:
                channel = context.message.channel.id

        # Next format to check: at hh:mm send y to #z. E.g. at 17:00 send Hello there to #channel.
        elif re.search(regex['at'], cmd, re.IGNORECASE):

            matches = re.findall(regex['at'], cmd, re.IGNORECASE)

            requested_time = matches[0][0]
            requested_date = matches[0][2] if matches[0][2] != '' else None

            # If they passed the time through with a colon, remove that.
            if ':' in requested_time:
                requested_time = requested_time.replace(':', '')

            # Now convert the time to an int.
            requested_time = int(requested_time)

            timezone = pytz.timezone(user.get_setting('timezone'))
            timezone_date = datetime.now(timezone).strftime('%d-%m-%Y') if requested_date is None else requested_date
            timezone_time = int(datetime.now(timezone).strftime('%H%M'))

            # Build the datetime object for the current date (in user's timezone) and the requested time.
            try:
                reminder_time = datetime.strptime(timezone_date + ' ' + str(requested_time), '%d-%m-%Y %H%M')
            except ValueError:
                return await context.send(lib.get_string('remind:err:date', user.get_guild()))

            # If they manually specified a date and it is in the past, send an error.
            if requested_date is not None and int(timezone.localize(reminder_time).timestamp()) <= now:
                return await context.send(lib.get_string('remind:err:date', user.get_guild()))

            # If the time they requested has already passed (but they did not specify a date), alter the date ahead by 1 day.
            if requested_time <= timezone_time:
                reminder_time += timedelta(days=1)

            # Convert it to a UTC timestamp.
            remind_time = int(timezone.localize(reminder_time).timestamp())

            message = matches[0][3]
            if lib.is_number(matches[0][5]):
                channel = int(matches[0][5])
            else:
                channel = context.message.channel.id

        elif re.search(regex['every'], cmd, re.IGNORECASE):

            matches = re.findall(regex['every'], cmd, re.IGNORECASE)

            interval = matches[0][0]
            requested_time = matches[0][2]
            message = matches[0][3]
            if lib.is_number(matches[0][5]):
                channel = int(matches[0][5])
            else:
                channel = context.message.channel.id

            # If they passed the time through with a colon, remove that.
            if ':' in requested_time:
                requested_time = requested_time.replace(':', '')

            # Check interval is valid.
            if interval not in list(self._reminder_intervals.keys()):
                return await context.send(lib.get_string('remind:err:interval', user.get_guild()))

            # Now convert the time to an int.
            requested_time = int(requested_time)

            timezone = pytz.timezone(user.get_setting('timezone'))
            timezone_date = datetime.now(timezone).strftime('%d-%m-%Y')
            timezone_time = int(datetime.now(timezone).strftime('%H%M'))

            # Build the datetime object for the current date (in user's timezone) and the requested time.
            try:
                reminder_time = datetime.strptime(timezone_date + ' ' + str(requested_time), '%d-%m-%Y %H%M')
            except ValueError:
                return await context.send(lib.get_string('remind:err:date', user.get_guild()))

            # If the time they requested has already passed (but they did not specify a date), alter the date ahead by 1 day.
            if requested_time <= timezone_time:
                reminder_time += timedelta(days=1)

            # Convert it to a UTC timestamp.
            remind_time = int(timezone.localize(reminder_time).timestamp())

            # Now get the interval time to add each time the reminder is set.
            repeat = self._reminder_intervals[interval]

        else:
            return await context.send(user.get_mention() + ', ' + lib.get_string('remind:err:format', user.get_guild()))

        # Check the channel is valid.
        if not context.guild.get_channel(channel):
            return await context.send(lib.get_string('remind:err:channel', user.get_guild()))

        # Check that the message is not too long?
        if len(message) > 255:
            return await context.send(lib.get_string('remind:err:message', user.get_guild()).format(len(message)))

        # If we get this far, we have parsed the command into variables.
        params = {
            'user': user.get_id(),
            'guild': user.get_guild(),
            'time': remind_time,
            'channel': channel,
            'message': message,
            'intervaltime': repeat
        }

        reminder = Reminder.create(params)
        if reminder:
            return await context.send(user.get_mention() + ', ' + lib.get_string('remind:created', user.get_guild()).format(
                lib.secs_to_days(remind_time - now))
            )
Beispiel #16
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)