diff --git a/ccrole/ccrole.py b/ccrole/ccrole.py index 2ca5b91..df034d4 100644 --- a/ccrole/ccrole.py +++ b/ccrole/ccrole.py @@ -19,191 +19,196 @@ class CCRole: def __init__(self, bot): self.bot = bot - self.file_path = "data/ccrole/commands.json" - self.c_commands = dataIO.load_json(self.file_path) + self.config = Config.get_conf(self, identifier=9999114111108101) + + self.config.register_guild(**{cmdlist : {}, settings: {} ) + - @commands.group(pass_context=True, no_pm=True) + @commands.group(no_pm=True) async def ccrole(self, ctx): """Custom commands management""" - if ctx.invoked_subcommand is None: - await self.bot.send_cmd_help(ctx) + if not ctx.invoked_subcommand: + await ctx.send_help() - @ccrole.command(name="add", pass_context=True) + @ccrole.command(name="add") @checks.mod_or_permissions(administrator=True) async def ccrole_add(self, ctx, command : str): """Adds a custom command with roles""" command = command.lower() - if command in self.bot.commands: - await self.bot.say("That command is already a standard command.") + if command in self.bot.all_commands: + await ctx.send("That command is already a standard command.") return - server = ctx.message.server - author = ctx.message.author + guild = ctx.guild + author = ctx.author + channel = ctx.channel - if server.id not in self.c_commands: - self.c_commands[server.id] = {} - cmdlist = self.c_commands[server.id] - if command in cmdlist: - await self.bot.say("This command already exists. Delete" - "`it with {}ccrole delete` first." - "".format(ctx.prefix)) + cmdlist = self.config.guild(ctx.guild).cmdlist + + if await cmdlist.get_raw(command, default=None): + await ctx.send("This command already exists. Delete it with `{}ccrole delete` first.".format(ctx.prefix)) return # Roles to add - await self.bot.say('What roles should it add? (Must be comma separated)\nSay `None` to skip adding roles') + await ctx.send('What roles should it add? (Must be **comma separated**)\nSay `None` to skip adding roles') - answer = await self.bot.wait_for_message(timeout=120, author=author) - if not answer: - await self.bot.say("Timed out, canceling") - return + def check(m): + return m.author == author and m.channel=channel + + try: + answer = await self.bot.wait_for('message', timeout=120, check=check) + except asyncio.TimeoutError: + await ctx.send("Timed out, canceling") + arole_list = [] if answer.content.upper()!="NONE": - arole_list = answer.content.split(",") - - try: - arole_list = [discord.utils.get(server.roles, name=role.strip(' ')).id for role in arole_list] - except: - await self.bot.say("Invalid answer, canceling") + arole_list = await self._get_roles_from_content(ctx, answer.content) + if arole_list is None: + await ctx.send("Invalid answer, canceling") return # Roles to remove - await self.bot.say('What roles should it remove? (Must be comma separated)\nSay `None` to skip removing roles') - - answer = await self.bot.wait_for_message(timeout=120, author=author) - if not answer: - await self.bot.say("Timed out, canceling") - return + await ctx.send('What roles should it remove? (Must be comma separated)\nSay `None` to skip removing roles') + try: + answer = await self.bot.wait_for('message', timeout=120, check=check) + except asyncio.TimeoutError: + await ctx.send("Timed out, canceling") rrole_list = [] if answer.content.upper()!="NONE": - rrole_list = answer.content.split(",") - - try: - rrole_list = [discord.utils.get(server.roles, name=role.strip(' ')).id for role in rrole_list] - except: - await self.bot.say("Invalid answer, canceling") + rrole_list = await self._get_roles_from_content(ctx, answer.content) + if rrole_list is None: + await ctx.send("Invalid answer, canceling") return # Roles to use - await self.bot.say('What roles are allowed to use this command? (Must be comma separated)\nSay `None` to allow all roles') + await ctx.send('What roles are allowed to use this command? (Must be comma separated)\nSay `None` to allow all roles') - answer = await self.bot.wait_for_message(timeout=120, author=author) - if not answer: - await self.bot.say("Timed out, canceling") - return + try: + answer = await self.bot.wait_for('message', timeout=120, check=check) + except asyncio.TimeoutError: + await ctx.send("Timed out, canceling") prole_list = [] if answer.content.upper()!="NONE": - prole_list = answer.content.split(",") - - try: - prole_list = [discord.utils.get(server.roles, name=role.strip(' ')).id for role in prole_list] - except: - await self.bot.say("Invalid answer, canceling") + prole_list = await self._get_roles_from_content(ctx, answer.content) + if prole_list is None: + await ctx.send("Invalid answer, canceling") return # Selfrole - await self.bot.say('Is this a targeted command?(yes/no)\nNo will make this a selfrole command') + await ctx.send('Is this a targeted command?(yes/no)\nNo will make this a selfrole command') - answer = await self.bot.wait_for_message(timeout=120, author=author) - if not answer: - await self.bot.say("Timed out, canceling") - return + try: + answer = await self.bot.wait_for('message', timeout=120, check=check) + except asyncio.TimeoutError: + await ctx.send("Timed out, canceling") if answer.content.upper() in ["Y", "YES"]: targeted = True - await self.bot.say("This command will be targeted") + await ctx.send("This command will be **`targeted`**") else: targeted = False - await self.bot.say("This command will be selfrole") + await ctx.send("This command will be **`selfrole`**") # Message to send - await self.bot.say('What message should the bot send?\nSay `None` to send the default `Success!` message') + await ctx.send('What message should the bot say when using this command?\nSay `None` to send the default `Success!` message') - answer = await self.bot.wait_for_message(timeout=120, author=author) - if not answer: - await self.bot.say("Timed out, canceling") - return + try: + answer = await self.bot.wait_for('message', timeout=120, check=check) + except asyncio.TimeoutError: + await ctx.send("Timed out, canceling") text = "Success!" if answer.content.upper()!="NONE": text = answer.content # Save the command - cmdlist[command] = {'text': text, 'aroles': arole_list, 'rroles': rrole_list, "proles": prole_list, "targeted": targeted} + out = {'text': text, 'aroles': arole_list, 'rroles': rrole_list, "proles": prole_list, "targeted": targeted} - self.c_commands[server.id] = cmdlist - dataIO.save_json(self.file_path, self.c_commands) - await self.bot.say("Custom command successfully added.") + await cmdlist.set_raw(command, value=out) - @ccrole.command(name="delete", pass_context=True) + @ccrole.command(name="delete") @checks.mod_or_permissions(administrator=True) async def ccrole_delete(self, ctx, command : str): """Deletes a custom command Example: [p]ccrole delete yourcommand""" - server = ctx.message.server + guild = ctx.guild command = command.lower() - if server.id in self.c_commands: - cmdlist = self.c_commands[server.id] - if command in cmdlist: - cmdlist.pop(command, None) - self.c_commands[server.id] = cmdlist - dataIO.save_json(self.file_path, self.c_commands) - await self.bot.say("Custom command successfully deleted.") - else: - await self.bot.say("That command doesn't exist.") + if not await self.config.guild(ctx.guild).cmdlist.get_raw(command, default=None): + await ctx.send("That command doesn't exist") else: - await self.bot.say("There are no custom commands in this server." - " Use `{}ccrole add` to start adding some." - "".format(ctx.prefix)) + await self.config.guild(ctx.guild).cmdlist.set_raw(command, value=None) + await ctx.send("Custom command successfully deleted.") - @ccrole.command(name="list", pass_context=True) + @ccrole.command(name="list") async def ccrole_list(self, ctx): """Shows custom commands list""" - server = ctx.message.server - commands = self.c_commands.get(server.id, {}) + guild = ctx.guild + commands = await self.config.guild(ctx.guild).cmdlist if not commands: - await self.bot.say("There are no custom commands in this server." - " Use `{}ccrole add` to start adding some." - "".format(ctx.prefix)) + await ctx.send("There are no custom commands in this server. Use `{}ccrole add` to start adding some.".format(ctx.prefix)) return commands = ", ".join([ctx.prefix + c for c in sorted(commands.keys())]) commands = "Custom commands:\n\n" + commands if len(commands) < 1500: - await self.bot.say(box(commands)) + await ctx.send(box(commands)) else: for page in pagify(commands, delims=[" ", "\n"]): - await self.bot.whisper(box(page)) + await ctx.author.send(box(page)) + await ctx.send("Command list DM'd") async def on_message(self, message): - if len(message.content) < 2 or message.channel.is_private: + if len(message.content) < 2 or message.guild is None: return - server = message.server - prefix = self.get_prefix(message) - - if not prefix: + guild = message.guild + try: + prefix = await self.get_prefix(message) + except ValueError: return - if server.id in self.c_commands and self.bot.user_allowed(message): - cmdlist = self.c_commands[server.id] - cmd = message.content[len(prefix):].split()[0] - if cmd in cmdlist: - cmd = cmdlist[cmd] - await self.eval_cc(cmd, message) - elif cmd.lower() in cmdlist: - cmd = cmdlist[cmd.lower()] - await self.eval_cc(cmd, message) - - def get_prefix(self, message): - for p in self.bot.settings.get_prefixes(message.server): - if message.content.startswith(p): + + cmdlist = self.config.guild(guild).cmdlist + cmd = message.content[len(prefix):].split()[0] + cmd = await cmdlist.get_raw(cmd.lower(), default=None) + + if cmd: + await self.eval_cc(cmd, message) + + async def _get_roles_from_content(ctx, content): + content_list = content.split(",") + role_list = [] + try: + role_list = [discord.utils.get(ctx.guild.roles, name=role.strip(' ')).id for role in content_list] + except: + return None + else: + return role_list + + async def get_prefix(self, message: discord.Message) -> str: + """ + Borrowed from alias cog + Tries to determine what prefix is used in a message object. + Looks to identify from longest prefix to smallest. + + Will raise ValueError if no prefix is found. + :param message: Message object + :return: + """ + content = message.content + prefix_list = await self.bot.command_prefix(self.bot, message) + prefixes = sorted(prefix_list, + key=lambda pfx: len(pfx), + reverse=True) + for p in prefixes: + if content.startswith(p): return p - return False + raise ValueError(_("No prefix found.")) async def eval_cc(self, cmd, message): if cmd['proles'] and not (set(role.id for role in message.author.roles) & set(cmd['proles'])): @@ -211,32 +216,32 @@ class CCRole: if cmd['targeted']: try: - target = discord.utils.get(message.server.members, mention=message.content.split()[1]) + target = discord.utils.get(message.guild.members, mention=message.content.split()[1]) except: target = None if not target: out_message = "This command is targeted! @mention a target\n`{} `".format(message.content.split()[0]) - await self.bot.send_message(message.channel, out_message) + await message.channel.send(out_message) return else: target = message.author if cmd['aroles']: - arole_list = [discord.utils.get(message.server.roles, id=roleid) for roleid in cmd['aroles']] + arole_list = [discord.utils.get(message.guild.roles, id=roleid) for roleid in cmd['aroles']] # await self.bot.send_message(message.channel, "Adding: "+str([str(arole) for arole in arole_list])) - await self.bot.add_roles(target, *arole_list) + await target.add_roles(*arole_list) await asyncio.sleep(1) if cmd['rroles']: - rrole_list = [discord.utils.get(message.server.roles, id=roleid) for roleid in cmd['rroles']] + rrole_list = [discord.utils.get(message.guild.roles, id=roleid) for roleid in cmd['rroles']] # await self.bot.send_message(message.channel, "Removing: "+str([str(rrole) for rrole in rrole_list])) - await self.bot.remove_roles(target, *rrole_list) + await target.remove_roles(*rrole_list) - await self.bot.send_message(message.channel, cmd['text']) + await message.channel.send(cmd['text']) # {'text': text, 'aroles': arole_list, 'rroles': rrole_list, "proles", prole_list, "targeted": targeted} @@ -269,23 +274,4 @@ class CCRole: # first = objects[first] # else: # return raw_result - # return str(getattr(first, second, raw_result)) - - -def check_folders(): - if not os.path.exists("data/ccrole"): - print("Creating data/ccrole folder...") - os.makedirs("data/ccrole") - - -def check_files(): - f = "data/ccrole/commands.json" - if not dataIO.is_valid_json(f): - print("Creating empty commands.json...") - dataIO.save_json(f, {}) - - -def setup(bot): - check_folders() - check_files() - bot.add_cog(CCRole(bot)) \ No newline at end of file + # return str(getattr(first, second, raw_result)) \ No newline at end of file