From f7a2861c3b79a4de98cf6ded2925417ff31a3267 Mon Sep 17 00:00:00 2001 From: brandons209 Date: Thu, 7 May 2020 19:16:29 -0400 Subject: [PATCH] added rules cog, fixed formatting in personalroles --- personalroles/personalroles.py | 73 +++++++---------- rules/__init__.py | 5 ++ rules/info.json | 13 +++ rules/rules.py | 139 +++++++++++++++++++++++++++++++++ 4 files changed, 184 insertions(+), 46 deletions(-) create mode 100644 rules/__init__.py create mode 100644 rules/info.json create mode 100644 rules/rules.py diff --git a/personalroles/personalroles.py b/personalroles/personalroles.py index f217fd6..d360d1e 100644 --- a/personalroles/personalroles.py +++ b/personalroles/personalroles.py @@ -25,14 +25,13 @@ async def has_assigned_role(ctx): @cog_i18n(_) class PersonalRoles(commands.Cog): """Assign and edit personal roles""" + __version__ = "2.0.4" # noinspection PyMissingConstructor def __init__(self, bot: commands.Bot): self.bot = bot - self.config = Config.get_conf( - self, identifier=0x3D86BBD3E2B744AE8AA8B5D986EB4DD8, force_registration=True - ) + self.config = Config.get_conf(self, identifier=0x3D86BBD3E2B744AE8AA8B5D986EB4DD8, force_registration=True) default_member = {"role": None} default_guild = {"blacklist": [], "auto_roles": [], "position_role": None, "auto_enabled": False} self.config.register_member(**default_member) @@ -51,9 +50,9 @@ class PersonalRoles(commands.Cog): """Assign personal role to someone""" await self.config.member(user).role.set(role.id) await ctx.send( - _( - "Ok. I just assigned {user.name} ({user.id}) to role {role.name} ({role.id})." - ).format(user=user, role=role) + _("Ok. I just assigned {user.name} ({user.id}) to role {role.name} ({role.id}).").format( + user=user, role=role + ) ) @myrole.command() @@ -79,9 +78,9 @@ class PersonalRoles(commands.Cog): return await ctx.send( - _( - "Ok. I just unassigned {user.name} ({user.id}) from their personal role and deleted the role." - ).format(user=user) + _("Ok. I just unassigned {user.name} ({user.id}) from their personal role and deleted the role.").format( + user=user + ) ) @myrole.command(name="list") @@ -90,9 +89,7 @@ class PersonalRoles(commands.Cog): """Assigned roles list""" members_data = await self.config.all_members(ctx.guild) if not members_data: - await ctx.send( - chat.info(_("There is no assigned personal roles on this server")) - ) + await ctx.send(chat.info(_("There is no assigned personal roles on this server"))) return assigned_roles = [] for member, data in members_data.items(): @@ -101,15 +98,11 @@ class PersonalRoles(commands.Cog): dic = { _("User"): ctx.guild.get_member(member) or f"[X] {member}", _("Role"): shorten( - str(ctx.guild.get_role(data["role"]) or "[X] {}".format(data["role"])), - 32, - placeholder="…", + str(ctx.guild.get_role(data["role"]) or "[X] {}".format(data["role"])), 32, placeholder="…", ), } assigned_roles.append(dic) - pages = list( - chat.pagify(tabulate(assigned_roles, headers="keys", tablefmt="orgtbl")) - ) + pages = list(chat.pagify(tabulate(assigned_roles, headers="keys", tablefmt="orgtbl"))) pages = [chat.box(page) for page in pages] await menu(ctx, pages, DEFAULT_CONTROLS) @@ -168,7 +161,9 @@ class PersonalRoles(commands.Cog): if not_found: await ctx.send( - chat.warning("These roles weren't found, please try again: {}".format(chat.humanize_list(list(not_found)))) + chat.warning( + "These roles weren't found, please try again: {}".format(chat.humanize_list(list(not_found))) + ) ) return @@ -231,16 +226,10 @@ class PersonalRoles(commands.Cog): rolename = rolename.casefold() async with self.config.guild(ctx.guild).blacklist() as blacklist: if rolename in blacklist: - await ctx.send( - chat.error(_("`{}` is already in blacklist").format(rolename)) - ) + await ctx.send(chat.error(_("`{}` is already in blacklist").format(rolename))) else: blacklist.append(rolename) - await ctx.send( - chat.info( - _("Added `{}` to blacklisted roles list").format(rolename) - ) - ) + await ctx.send(chat.info(_("Added `{}` to blacklisted roles list").format(rolename))) @blacklist.command() @checks.admin_or_permissions(manage_roles=True) @@ -249,16 +238,10 @@ class PersonalRoles(commands.Cog): rolename = rolename.casefold() async with self.config.guild(ctx.guild).blacklist() as blacklist: if rolename not in blacklist: - await ctx.send( - chat.error(_("`{}` is not blacklisted").format(rolename)) - ) + await ctx.send(chat.error(_("`{}` is not blacklisted").format(rolename))) else: blacklist.remove(rolename) - await ctx.send( - chat.info( - _("Removed `{}` from blacklisted roles list").format(rolename) - ) - ) + await ctx.send(chat.info(_("Removed `{}` from blacklisted roles list").format(rolename))) @blacklist.command(name="list") @checks.admin_or_permissions(manage_roles=True) @@ -285,9 +268,7 @@ class PersonalRoles(commands.Cog): return try: - await role.edit( - colour=colour, reason=get_audit_reason(ctx.author, _("Personal Role")) - ) + await role.edit(colour=colour, reason=get_audit_reason(ctx.author, _("Personal Role"))) except discord.Forbidden: ctx.command.reset_cooldown(ctx) await ctx.send( @@ -330,9 +311,7 @@ class PersonalRoles(commands.Cog): await ctx.send(chat.error(_("This rolename is blacklisted."))) return try: - await role.edit( - name=name, reason=get_audit_reason(ctx.author, _("Personal Role")) - ) + await role.edit(name=name, reason=get_audit_reason(ctx.author, _("Personal Role"))) except discord.Forbidden: ctx.command.reset_cooldown(ctx) await ctx.send( @@ -348,9 +327,7 @@ class PersonalRoles(commands.Cog): await ctx.send(chat.error(_("Unable to edit role: {}").format(e))) else: await ctx.send( - _("Changed name of {user}'s personal role to {name}").format( - user=ctx.message.author.name, name=name - ) + _("Changed name of {user}'s personal role to {name}").format(user=ctx.message.author.name, name=name) ) @commands.cooldown(1, 30, commands.BucketType.user) @@ -369,7 +346,9 @@ class PersonalRoles(commands.Cog): pos = pos.position if pos else 0 try: - role = await ctx.guild.create_role(name=str(ctx.author), colour=ctx.author.colour, reason=_("Personal role")) + role = await ctx.guild.create_role( + name=str(ctx.author), colour=ctx.author.colour, reason=_("Personal role") + ) await asyncio.sleep(0.3) await role.edit(position=pos) await asyncio.sleep(0.3) @@ -379,7 +358,9 @@ class PersonalRoles(commands.Cog): await ctx.send(chat.warning("Could not create your personal role, please contact an admin.")) return - await ctx.send(f"Role created! You can edit it using `{ctx.prefix}myrole name` and `{ctx.prefix}myrole colour` commands. Pos: {pos}") + await ctx.send( + f"Role created! You can edit it using `{ctx.prefix}myrole name` and `{ctx.prefix}myrole colour` commands. Pos: {pos}" + ) else: await ctx.send(chat.warning("You already have a personal role!")) diff --git a/rules/__init__.py b/rules/__init__.py new file mode 100644 index 0000000..5eeca4d --- /dev/null +++ b/rules/__init__.py @@ -0,0 +1,5 @@ +from .rules import Rules + + +def setup(bot): + bot.add_cog(Rules(bot)) diff --git a/rules/info.json b/rules/info.json new file mode 100644 index 0000000..f48e0cb --- /dev/null +++ b/rules/info.json @@ -0,0 +1,13 @@ +{ + "author": [ + "Brandons209" + ], + "install_msg": "Thanks for install.", + "short": "Quickly list server and channel rules.", + "description": "Quickly list server and channel rules.", + "min_bot_version": "3.2.1", + "tags": [ + "rules", + "rule" + ] +} diff --git a/rules/rules.py b/rules/rules.py new file mode 100644 index 0000000..c1c0703 --- /dev/null +++ b/rules/rules.py @@ -0,0 +1,139 @@ +import discord +from redbot.core import checks, commands, Config +from redbot.core.utils import chat_formatting as chat +from redbot.core.utils.menus import menu, DEFAULT_CONTROLS +import asyncio +from typing import Union + + +class Rules(commands.Cog): + """Simple way to quickly list server and channel rules.""" + + def __init__(self, bot): + self.config = Config.get_conf(self, identifier=875454235448, force_registration=True) + self.bot = bot + + # maps rule number(str) -> rule(str) + default_guild = {"rules": {}} + default_channel = {"rules": {}} + + self.config.register_guild(**default_guild) + self.config.register_channel(**default_channel) + + @commands.group(invoke_without_command=True, aliases=["r"]) + @commands.guild_only() + async def rule(self, ctx, rule_num: int = None): + """ Display guild and channel rules """ + if ctx.invoked_subcommand: + return + elif rule_num is not None: + rules = await self.config.guild(ctx.guild).rules() + try: + await ctx.send(rules[str(rule_num)]) + except KeyError: + await ctx.send(chat.error("That rule doesn't exist!")) + else: + await self.bot.send_help_for(ctx, self.rule) + + @rule.command(name="list") + async def rule_list(self, ctx): + """ List all guild rules """ + rules = await self.config.guild(ctx.guild).rules() + embeds = [] + rules_keys = sorted([int(r) for r in rules.keys()]) + num_rules = len(rules_keys) + for i, rule_num in enumerate(rules_keys): + embed = discord.Embed(title=f"{ctx.guild.name} rules", colour=ctx.guild.me.colour) + embed.add_field(name=f"Rule {rule_num}", value=rules[str(rule_num)]) + embed.set_footer(text=f"Page {i+1} of {num_rules}") + embeds.append(embed) + + if not embeds: + await ctx.send(chat.warning("No rules defined.")) + return + + await menu(ctx, embeds, DEFAULT_CONTROLS) + + @rule.group(invoke_without_command=True, name="channel", aliases=["ch", "c"]) + async def rule_channel(self, ctx, rule_num: int, channel: Union[discord.TextChannel, discord.VoiceChannel] = None): + """ + Display channel rule. Defaults to current channel. + + For voice channels, use the voice channel ID + """ + if ctx.invoked_subcommand: + return + + if channel: + rules = await self.config.channel(channel).rules() + else: + rules = await self.config.channel(ctx.channel).rules() + + try: + await ctx.send(rules[str(rule_num)]) + except KeyError: + await ctx.send(chat.error("That rule doesn't exist!")) + + @rule_channel.command(name="list") + async def rule_channel_list(self, ctx, channel: Union[discord.TextChannel, discord.VoiceChannel] = None): + """ + List all rules for a channel + Defaults to current channel. + + For voice channels, use the voice channel ID + """ + if channel: + rules = await self.config.channel(channel).rules() + else: + channel = ctx.channel + rules = await self.config.channel(channel).rules() + + embeds = [] + rules_keys = sorted([int(r) for r in rules.keys()]) + num_rules = len(rules_keys) + for i, rule_num in enumerate(rules_keys): + embed = discord.Embed(title=f"{channel.name} rules", colour=ctx.guild.me.colour) + embed.add_field(name=f"Rule {rule_num}", value=rules[str(rule_num)]) + embed.set_footer(text=f"Page {i+1} of {num_rules}") + embeds.append(embed) + + if not embeds: + await ctx.send(chat.warning("No rules defined.")) + return + + await menu(ctx, embeds, DEFAULT_CONTROLS) + + @rule.group(invoke_without_command=True, name="set") + @checks.admin_or_permissions(administrator=True) + async def rule_set(self, ctx, rule_num: int = None, *, rule: str = None): + """ + Set a guild rule + Will overwrite an existing rule of the same number. + """ + if ctx.invoked_subcommand: + return + elif rule_num is not None and rule is not None: + async with self.config.guild(ctx.guild).rules() as rules: + rules[str(rule_num)] = rule + await ctx.tick() + elif rule_num is not None: + rules = await self.config.guild(ctx.guild).rules() + try: + await ctx.send(rules[str(rule_num)]) + except KeyError: + await ctx.send(chat.error("That rule doesn't exist!")) + else: + await self.bot.send_help_for(ctx, self.rule_set) + + @rule_set.command(name="channel", aliases=["ch", "c"]) + async def rule_set_channel( + self, ctx, rule_num: int, channel: Union[discord.TextChannel, discord.VoiceChannel], *, rule: str + ): + """ + Set a channel rule. Can use channel mention or ID. + + For voice channels, use the voice channel ID. + """ + async with self.config.channel(channel).rules() as rules: + rules[str(rule_num)] = rule + await ctx.tick()