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