async def run_set(self, context, type, opts): """ Set the value of something for the event, such as description or image url :param context: :param type: :param opts: :return: """ user = User(context.message.author.id, context.guild.id, context) # Do they have the permissions to set an event option? self.check_permissions(context) # Check if there is an event running event = Event.get_by_guild(user.get_guild()) if event is None or not event.is_valid(): return await context.send(user.get_mention() + ', ' + lib.get_string('event:err:noexists', user.get_guild())) value = " ".join(opts[0:]) if type == 'description': event.set_description(value) elif type == 'image': if len(value) > 255: return await context.send(user.get_mention() + ', ' + lib.get_string('event:err:img', user.get_guild())) event.set_image(value) elif type == 'colour': event.set_colour(value) # Save the changes event.save() return await context.send(user.get_mention() + ', ' + lib.get_string('event:set', user.get_guild()).format(type, value))
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_time(self, context): """ Check how much time is left in the event :param context: :return: """ user = User(context.message.author.id, context.guild.id, context) event = Event.get_by_guild(user.get_guild()) now = int(time.time()) # Make sure the event exists if event is None or not event.is_valid(): return await context.send(user.get_mention() + ', ' + lib.get_string('event:err:noexists', user.get_guild())) # Is the event scheduled to start, but has not yet started? if not event.is_running() and event.is_scheduled(): left = lib.secs_to_days(event.get_start_time() - now) return await context.send(user.get_mention() + ', ' + lib.get_string('event:timetostart', user.get_guild()).format(left)) # If the event is not running and it is NOT scheduled, then we don't know what time it will start. elif not event.is_running(): return await context.send(user.get_mention() + ', ' + lib.get_string('event:err:noexists', user.get_guild())) # At this point, the event must be running. If it is scheduled, then we can get the time left from the end time. Otherwise, we don't know. elif event.is_scheduled(): left = lib.secs_to_days(event.get_end_time() - now) return await context.send(user.get_mention() + ', ' + lib.get_string('event:timeleft', user.get_guild()).format(left)) else: return await context.send(user.get_mention() + ', ' + lib.get_string('event:noendtime', user.get_guild()))
async def run_rename(self, context, opts): """ Rename the event :param context: :param opts: :return: """ user = User(context.message.author.id, context.guild.id, context) # Do they have the permissions to rename an event? self.check_permissions(context) # Check if there is an event running event = Event.get_by_guild(user.get_guild()) if event is None or not event.is_valid(): return await context.send( user.get_mention() + ', ' + lib.get_string('event:err:noexists', user.get_guild())) # Get the title out of the arguments title = " ".join(opts[0:]) # Make sure they specified a title. if len(title) == 0 or len(title) > 255: return await context.send( user.get_mention() + ', ' + lib.get_string('event:err:rename:title', user.get_guild())) # Create the event event.set_title(title) event.save() return await context.send( user.get_mention() + ', ' + lib.get_string('event:renamed', user.get_guild()).format(title))
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()))
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)
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)
async def run_create(self, context, opts): """ Create an event on the server :param context: :param opts: :return: """ user = User(context.message.author.id, context.guild.id, context) # Do they have the permissions to create an event? self.check_permissions(context) # Get the title out of the arguments title = " ".join(opts[0:]) # Check if there is already an event running event = Event.get_by_guild(user.get_guild()) if event is not None: return await context.send( user.get_mention() + ', ' + lib.get_string('event:err:alreadyexists', user.get_guild())) # Make sure they specified a title. if len(title) == 0 or len(title) > 255: return await context.send( user.get_mention() + ', ' + lib.get_string('event:err:title', user.get_guild())) # Create the event Event.create(guild=user.get_guild(), channel=context.message.channel.id, title=title) return await context.send( user.get_mention() + ', ' + lib.get_string('event:created', user.get_guild()).format(title))
async def run_unschedule(self, context): """ Unschedule the event :param context: :return: """ user = User(context.message.author.id, context.guild.id, context) event = Event.get_by_guild(user.get_guild()) # Do they have the permissions to rename an event? self.check_permissions(context) # Make sure the event is running if event is None: return await context.send( user.get_mention() + ', ' + lib.get_string('event:err:noexists', user.get_guild())) # Unschedule the event event.set_startdate(None) event.set_enddate(None) event.save() # Remove any tasks we already had saved for this event. Task.cancel('event', event.get_id()) return await context.send(user.get_mention() + ', ' + lib.get_string( 'event:unscheduled', user.get_guild()).format(event.get_title()))
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))
async def run_time(self, context): """ Get how long is left in 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, 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())) now = int(time.time()) # If the sprint has not yet started, display the time until it starts if not sprint.has_started(): left = lib.secs_to_mins(sprint.get_start() - now) return await context.send(user.get_mention() + ', ' + lib.get_string('sprint:startsin', user.get_guild()).format(left['m'], left['s'])) # If it's currently still running, display how long is left elif not sprint.is_finished(): left = lib.secs_to_mins(sprint.get_end() - now) return await context.send(user.get_mention() + ', ' + lib.get_string('sprint:timeleft', user.get_guild()).format(left['m'], left['s'])) # If it's finished but not yet marked as completed, we must be waiting for word counts elif sprint.is_finished(): return await context.send(user.get_mention() + ', ' + lib.get_string('sprint:waitingforwc', user.get_guild()))
async def run_genre(self, context, opts): """ Update the genre of a project @param context: @param opts: @return: """ user = User(context.message.author.id, context.guild.id, context) shortname = opts[0].lower() if opts else None genre = opts[1].lower() if len(opts) > 1 else None # Make sure the project exists. project = user.get_project(shortname) if not project: return await context.send( user.get_mention() + ', ' + lib.get_string('project:err:noexists', user.get_guild()).format(shortname)) # Make sure the genre is valid. if not genre in self._genres: return await context.send( user.get_mention() + ', ' + lib.get_string('project:err:genre', user.get_guild()).format( genre, ', '.join(self._genres))) project.set_genre(genre) return await context.send( user.get_mention() + ', ' + lib.get_string('project:genre', user.get_guild()).format( lib.get_string('project:genre:' + genre, user.get_guild())))
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))
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_description(self, context, opts): """ Update the description of a project @param context: @param opts: @return: """ user = User(context.message.author.id, context.guild.id, context) shortname = opts[0].lower() description = " ".join(opts[1:]) # Make sure the project exists. project = user.get_project(shortname) if not project: return await context.send( user.get_mention() + ', ' + lib.get_string('project:err:noexists', user.get_guild()).format(shortname)) # Description cannot be longer than 200 words. words = description.split(' ') if len(words) > 200: return await context.send( user.get_mention() + ', ' + lib.get_string('project:err:desc:length', user.get_guild()).format(len(words))) project.set_description(description) return await context.send( user.get_mention() + ', ' + lib.get_string('project:description', user.get_guild()))
async def run_image(self, context, opts): """ Update the image link of a project @param context: @param opts: @return: """ user = User(context.message.author.id, context.guild.id, context) shortname = opts[0].lower() if opts else None img = opts[1] if len(opts) > 1 else None # Make sure the project exists. project = user.get_project(shortname) if not project: return await context.send( user.get_mention() + ', ' + lib.get_string('project:err:noexists', user.get_guild()).format(shortname)) # Check it's a valid image link. if not checkers.is_url(img) and img is not None: return await context.send( user.get_mention() + ', ' + lib.get_string( 'project:err:link', user.get_guild()).format(img)) project.set_image(img) return await context.send( user.get_mention() + ', ' + lib.get_string('project:image', user.get_guild()))
async def run_complete(self, context, opts): """ Mark a project as completed :param context: :param opts: :return: """ user = User(context.message.author.id, context.guild.id, context) shortname = opts[0].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)) already_completed = project.is_completed() project.complete() # Was this the first time they completed it? if already_completed == 0: # Calculate how much XP to give them (1xp per 100 words). Min 10. Max 5000. xp = math.ceil(project.get_words() / 100) if xp < 10: xp = 10 elif xp > 5000: xp = 5000 # Give them the xp and print the message. await user.add_xp(xp) return await context.send(user.get_mention() + ', ' + lib.get_string('project:completed', user.get_guild()).format(project.get_title(), xp)) else: return await context.send(user.get_mention() + ', ' + lib.get_string('project:recompleted', user.get_guild()))
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()))
async def run_create(self, context, opts): """ Try to create a project with the given names :param context: :param shortname: :param title: :return: """ user = User(context.message.author.id, context.guild.id, context) # Get the shortname and title out of the argument list. shortname = opts[0].lower() title = " ".join(opts[1:]) # Every argument after the first one, joined with spaces. # Make sure the shortname and title are set. if len(shortname) == 0 or len(title) == 0: return await context.send(user.get_mention() + ', ' + lib.get_string('project:err:names', user.get_guild())) # Make sure they don't already have a project with this shortname project = user.get_project(shortname) if project is not None: return await context.send(user.get_mention() + ', ' + lib.get_string('project:err:exists', user.get_guild()).format(shortname)) # Create the project user.create_project(shortname, title) return await context.send(user.get_mention() + ', ' + lib.get_string('project:created', user.get_guild()).format(title, shortname))
async def run_rename(self, context, opts): """ Rename a project :param context: :param opts: :return: """ user = User(context.message.author.id, context.guild.id, context) original_shortname = opts[0].lower() new_shortname = opts[1].lower() new_title = " ".join(opts[2:]) # Make sure the project exists project = user.get_project(original_shortname) if not project: return await context.send(user.get_mention() + ', ' + lib.get_string('project:err:noexists', user.get_guild()).format(original_shortname)) # Make sure they don't already have one with that new shortname. project_with_new_shortname = user.get_project(new_shortname) if project_with_new_shortname is not None and project_with_new_shortname.get_id() != project.get_id(): return await context.send(user.get_mention() + ', ' + lib.get_string('project:err:exists', user.get_guild()).format(new_shortname)) # Get the original title. original_title = project.get_name() # Rename it. project.rename(new_shortname, new_title) return await context.send(user.get_mention() + ', ' + lib.get_string('project:renamed', user.get_guild()).format(original_title, original_shortname, new_title, new_shortname))
async def run_time(self, context): """ Check how long until the goal resets :param context: :return: """ user = User(context.message.author.id, context.guild.id, context) # Currently only daily goals implemented type = 'daily' # Get the goal of this type for this user goal = user.get_goal(type) if goal: now = int(time.time()) reset = goal['reset'] left = lib.secs_to_days(reset - now) return await context.send( user.get_mention() + ', ' + lib.get_string( 'goal:timeleft', user.get_guild()).format(left, type)) else: return await context.send( user.get_mention() + ', ' + lib.get_string('goal:nogoal', user.get_guild()).format(type))
async def goal(self, context, option=None, type=None, value=None): """ Sets a daily goal which resets every 24 hours at midnight in your timezone. Examples: !goal - Print a table of all your goals, with their progress and next reset time. !goal check daily - Checks how close you are to your daily goal !goal set weekly 500 - Sets your weekly goal to be 500 words per day !goal cancel monthly - Deletes your monthly goal !goal time daily - Checks how long until your daily goal resets """ user = User(context.message.author.id, context.guild.id, context) # If no option is sent and we just do `goal` then display a table of all their goals. if option is None: return await self.run_check_all(context) # Otherwise, we must specify a type. if type is None or type not in self.types: return await context.send( user.get_mention() + ', ' + lib.get_string('goal:invalidtype', user.get_guild())) if option == 'set': return await self.run_set(context, type, value) elif option == 'cancel' or option == 'delete' or option == 'reset': return await self.run_cancel(context, type) elif option == 'time': return await self.run_time(context, type) elif option == 'check': return await self.run_check(context, type) else: return await context.send( user.get_mention() + ', ' + lib.get_string('goal:invalidoption', user.get_guild()))
async def my_setting(self, context, setting=None, value=None): """ Lets you update a setting for your user account. **Note:** For the timezone setting, make sure the value you specify is a valid TZ Database Name from this wikipedia page: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones Examples: !mysetting timezone Europe/London !mysetting timezone America/Phoenix """ user = User(context.message.author.id, context.guild.id, context) # If we want to list the setting, do that instead. if setting is not None and setting.lower() == 'list': settings = user.get_settings() output = '```ini\n' if settings: for setting, value in settings.items(): output += setting + '=' + str(value) + '\n' else: output += lib.get_string('setting:none', guild.get_id()) output += '```' return await context.send(user.get_mention() + ',\n' + output) # Check the arguments are valid args = await self.check_arguments(context, setting=setting, value=value) if not args: return setting = args['setting'].lower() value = args['value'] # If the setting is timezone convert the value if setting == 'timezone': try: timezone = pytz.timezone(value) time = datetime.now(timezone) offset = datetime.now(timezone).strftime('%z') await context.send( lib.get_string('event:timezoneupdated', user.get_guild()).format( value, time.ctime(), offset)) except pytz.exceptions.UnknownTimeZoneError: await context.send( lib.get_string('mysetting:timezone:help', user.get_guild())) return # Update the setting and post the success message user.update_setting(setting, value) await context.send(user.get_mention() + ', ' + lib.get_string( 'mysetting:updated', user.get_guild()).format(setting, value))
async def run_check(self, context, type): 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) if user_goal: progress = user.get_goal_progress(type) return await context.send(user.get_mention() + ', ' + lib.get_string('goal:status', user.get_guild()).format(progress['percent'], type_string, progress['current'], progress['goal'])) else: return await context.send(user.get_mention() + ', ' + lib.get_string('goal:nogoal', user.get_guild()).format(type_string, type))
async def run_view(self, context, opts=None): """ View a list of the user's projects :return: """ user = User(context.message.author.id, context.guild.id, context) projects = user.get_projects() # If they have no projects, then we can't display them. if not projects: return await context.send( user.get_mention() + ', ' + lib.get_string('project:noprojects', user.get_guild())) # Did they specify a shortname to look at? if opts: shortname = opts[0].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)) # Re-create the array, but with just this one element in it. projects = [project] message = '' for project in projects: if project.is_completed(): message += ':sparkler: ' message += '**' + project.get_name( ) + '** (' + project.get_shortname() + ')\n' message += lib.get_string('wordcount', user.get_guild()) + ': ' + str( project.get_words()) + '\n\n' # Project lists can get very long. If it is over 2000 characters, we need to split it. if len(message) >= 2000: return await self.split_send( context, user, lib.get_string('project:list', user.get_guild()) + message) else: return await context.send( user.get_mention() + ', ' + lib.get_string('project:list', user.get_guild()) + message)
async def run_pb(self, context): """ Get the user's personal best for sprinting :param context: :return: """ user = User(context.message.author.id, context.guild.id, context) record = user.get_record('wpm') if record is None: return await context.send(user.get_mention() + ', ' + lib.get_string('sprint:pb:none', user.get_guild())) else: return await context.send(user.get_mention() + ', ' + lib.get_string('sprint:pb', user.get_guild()).format(int(record)))
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 reset(self, context, what=None, confirm=None): """ Lets you reset your statistics/records. Examples: !reset pb: Resets your wpm personal best !reset wc: Resets your total word count !reset xp: Resets your xp/level to 0 !reset all: Resets your xp/levels, stats, records, goals and challenges """ if not Guild(context.guild).is_command_enabled('reset'): return await context.send( lib.get_string('err:disabled', context.guild.id)) user = User(context.message.author.id, context.guild.id, context) # Check the arguments are valid args = await self.check_arguments(context, what=what, confirm=confirm) if not args: return what = args['what'].lower() confirm = args['confirm'].lower() # Make sure they confirmed it, otherwise just stop and display an OK message if confirm not in ('y', 'yes'): output = 'OK' return await context.send(user.get_mention() + ', ' + output) # Personal Best if what == 'pb': user.update_record('wpm', 0) output = lib.get_string('reset:pb', user.get_guild()) elif what == 'wc': user.update_stat('total_words_written', 0) output = lib.get_string('reset:wc', user.get_guild()) elif what == 'xp': await user.update_xp(0) output = lib.get_string('reset:xp', user.get_guild()) elif what == 'projects': user.reset_projects() output = lib.get_string('reset:projects', user.get_guild()) elif what == 'all': user.reset() output = lib.get_string('reset:done', user.get_guild()) return await context.send(user.get_mention() + ', ' + output)
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))