async def configure_channel_command(command, db_channel): """ Configure a channel with the given settings. If this channel does not yet exit in the DB, then create it. :param command: the command used. :param db_channel: the corresponding channel entry in the DB. """ # Make sure the user changing the channel settings is an admin if not command.author.guild_permissions.administrator: msg = 'Only server administrators can change a channel\'s settings.' await auxiliary.send_temp_message(msg, command.channel) return # The ids of the Discord channel and server where the message was sent discord_channel_id = command.channel.id discord_server_id = command.guild.id # Get the list of parameters in the message params = auxiliary.parse_command_parameters(command.content) # If the command has an invalid number of parameters if len(params) != 2: return # Filter the chosen setting delete_commands = False delete_all = False if params[1] == '-dc': delete_commands = True elif params[1] == '-da': delete_all = True elif params[1] == '-ka': delete_all = False delete_commands = False # Create or modify the channel with the correct configurations if db_channel is None: db_channel = models.Channel(discord_channel_id, discord_server_id, delete_commands, delete_all) config.session.add(db_channel) else: db_channel.delete_commands = delete_commands db_channel.delete_all = delete_all config.session.commit() print('Channel %s from %s was configured -> %s!' % (command.channel.name, command.guild.name, command.content))
async def close_poll_command(command, db_channel): """ Close a poll. :param command: the command used. :param db_channel: the corresponding channel entry in the DB. """ # If the channel does not exist in the DB if db_channel is None: msg = 'There\'s no poll in this channel for you to close!' await auxiliary.send_temp_message(msg, command.channel) return # Get the list of parameters in the message params = auxiliary.parse_command_parameters(command.content) # If the command has an invalid number of parameters if len(params) != 3: msg = 'Invalid parameters in command: **%s**' % command.content await auxiliary.send_temp_message(msg, command.channel) return poll_key = params[1] # Split the selected options list_options = params[2].split(',') # Options are all numbers try: # Verify if the options are numbers selected_options = [] for o in list_options: selected_options.append(int(o)) # Select the current poll poll = config.session.query( models.Poll).filter(models.Poll.poll_key == poll_key).first() # Edit the message with the poll if poll is not None: # Only the author can close the poll if poll.discord_author_id == command.author.id: options = config.session.query(models.Option).filter(models.Option.poll_id == poll.id) \ .order_by(models.Option.position).all() # Send a private message to all participants in the poll await auxiliary.send_closed_poll_message( options, command.guild, poll, command.channel) await auxiliary.close_poll(poll, db_channel, selected_options) config.session.commit() print('Poll %s closed -> %s!' % (poll.poll_key, command.content)) else: msg = 'There\'s no poll with that id for you to close.\nYour command: **%s**' % command.content await auxiliary.send_temp_message(msg, command.channel) except ValueError: pass
async def edit_poll_command(command, db_channel): """ Edit a poll. :param command: the command used. :param db_channel: the corresponding channel entry in the DB. """ # If the channel does not exist in the DB if db_channel is None: msg = 'There\'s no poll in this channel for you to edit!' await auxiliary.send_temp_message(msg, command.channel) return # Get the list of parameters in the message params = auxiliary.parse_command_parameters(command.content) add = False remove = False lock = False unlock = False multiple_options = False only_numbers = False new_options = False allow_external = False poll_params = [] # Filter the available options for polls for i in range(len(params)): if i == 0: continue if params[i] == '-add': add = True remove = False lock = False unlock = False elif params[i] == '-rm': remove = True add = False lock = False unlock = False elif params[i] == '-lock': remove = False add = False lock = True unlock = False elif params[i] == '-unlock': remove = False add = False lock = False unlock = True elif params[i].startswith('-'): if params[i].__contains__('m'): multiple_options = True if params[i].__contains__('o'): only_numbers = True if params[i].__contains__('n'): new_options = True if params[i].__contains__('e'): allow_external = True else: # Add all non configuration parameters, ignoring quotation marks poll_params.append(params[i].replace('"', '')) # If the command has an invalid number of parameters if (len(poll_params) < 2 and (add or remove or lock or unlock)) or \ (len(poll_params) < 1 and not add and not remove and not lock and not unlock): msg = 'Invalid parameters in command: **%s**' % command.content await auxiliary.send_temp_message(msg, command.channel) return poll_key = poll_params[0] # Select the current poll poll = config.session.query( models.Poll).filter(models.Poll.poll_key == poll_key).first() # If no poll was found with that id if poll is None: msg = 'There\'s no poll with that id for you to edit.\nYour command: **%s**' % command.content await auxiliary.send_temp_message(msg, command.channel) return # Only the author can edit if poll.discord_author_id != command.author.id: msg = 'Only the author of a poll can edit it!' await auxiliary.send_temp_message(msg, command.channel) return edited = '' # Get all options available in the poll db_options = config.session.query(models.Option).filter(models.Option.poll_id == poll.id) \ .order_by(models.Option.position).all() # Add the new options if add: new_options = poll_params[1:] options = [] edited = 'new options added %s' % new_options # Create the options for option in new_options: options.append( models.Option(poll.id, len(db_options) + len(options) + 1, option)) config.session.add_all(options) # Get the message corresponding to the poll c = config.client.get_channel(db_channel.discord_id) discord_poll_msg = await c.fetch_message(poll.discord_message_id) # Add a reaction for each new option emoji = chr(ord(u'\u0031') + len(db_options)) # Max number of reactions that can be added num_react = min(9, len(db_options) + len(options)) for i in range(max(0, num_react - len(db_options))): await discord_poll_msg.add_reaction(emoji + u'\u20E3') emoji = chr(ord(emoji) + 1) db_options.extend(options) # Remove, lock or unlock options elif remove or lock or unlock: rm_options = poll_params[1] # Option is a number try: # Verify if the options are numbers selected_options = [] for o in rm_options.split(','): selected_options.append(int(o)) # Removes duplicates in the list selected_options = list(set(selected_options)) if remove: options = config.session.query(models.Option) \ .filter(models.Option.poll_id == poll.id) \ .filter(models.Option.position.in_(selected_options)) \ .all() num_reactions = max(10 - len(db_options) - len(options), 0) edited = 'options removed %s' % options for option in options: config.session.delete(option) # Get the message corresponding to the poll c = config.client.get_channel(db_channel.discord_id) discord_poll_msg = await c.fetch_message( poll.discord_message_id) db_options = config.session.query(models.Option).filter(models.Option.poll_id == poll.id) \ .order_by(models.Option.position).all() for i in range(num_reactions): emoji = chr(ord(u'\u0031') + len(db_options) + i) await auxiliary.remove_reaction(discord_poll_msg, emoji) # Update the positions pos = 1 for option in db_options: option.position = pos pos += 1 elif lock or unlock: if lock: edited = 'options %s locked' % selected_options else: edited = 'options %s unlocked' % selected_options for option in selected_options: num_options = len(db_options) # If it is a valid option if 0 < option <= num_options: if lock: db_options[option - 1].locked = True elif unlock: db_options[option - 1].locked = False # Option is not a number except ValueError: pass else: # Edit poll question if len(poll_params) > 1: poll.question = poll_params[1] edited = 'question is now %s' % poll.question # Edit poll settings else: poll.multiple_options = multiple_options poll.only_numbers = only_numbers poll.new_options = new_options poll.allow_external = allow_external edited = 'settings multiple_options=%r, only_numbers=%r, new_options=%r, allow_external=%r changed' \ % (multiple_options, only_numbers, new_options, allow_external) # Edit message c = config.client.get_channel(db_channel.discord_id) try: m = await c.fetch_message(poll.discord_message_id) await m.edit(content=auxiliary.create_message(poll, db_options)) except discord.errors.NotFound: config.session.delete(poll) config.session.commit() print('Poll %s was edited for %s -> %s!' % (poll.poll_key, edited, command.content))