From 52ca316efdf940edb09a84b70cc8477f47f393b1 Mon Sep 17 00:00:00 2001 From: refisio Date: Fri, 1 Feb 2019 22:18:16 -0500 Subject: Added rules cog. Adds a command that allows users and staff to pull specific rules from a command instead of getting a basic embed pointing to a website. That functionality still exists, though. --- bot/cogs/rules.py | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 bot/cogs/rules.py diff --git a/bot/cogs/rules.py b/bot/cogs/rules.py new file mode 100644 index 000000000..6759d07a2 --- /dev/null +++ b/bot/cogs/rules.py @@ -0,0 +1,139 @@ +import re +from typing import Optional + +from bot.constants import Channels, Roles +from bot.decorators import redirect_output +from bot.pagination import LinePaginator + +from discord import Colour, Embed +from discord.ext.commands import Bot, Context, command + + +STAFF = [ + Roles.admin, + Roles.moderator, + Roles.owner, +] + + +class Rules: + + def __init__(self, bot: Bot): + self.bot = bot + # We'll get the rules from the API when the + # site has been updated to the Django Framwork. + # Hard-code the rules for now until the new RulesView is released. + self.rules = [ + "Be polite, and do not spam.", + "Follow the [Discord Community Guidelines]", + "(https://discordapp.com/guidelines).", + ( + "Don't intentionally make other people uncomfortable - if " + "someone asks you to stop discussing something," + " you should stop." + ), + ( + "Be patient both with users asking " + "questions, and the users answering them." + ), + ( + "We will not help you with anything that might break " + "a law or the terms of service of any other community, site," + "service, or otherwise - No piracy, brute-forcing, captcha " + "circumvention, sneaker bots, or anything else of that nature." + ), + ( + "Listen to and respect the staff members - we're " + "here to help, but we're all human beings." + ), + ( + "All discussion should be kept within the relevant " + "channels for the subject - See the " + f"[channels page](https://pythondiscord.com/about/channels) " + "for more information." + ), + ( + "This is an English-speaking server, so please speak English " + f"to the best of your ability - [Google Translate]" + "(https://translate.google.com/) should be fine if " + "you're not sure." + ), + ( + "Keep all discussions safe for work - No gore, nudity, sexual " + "soliciting, references to suicide, or anything else of " + "that nature" + ), + ( + "We do not allow advertisements for communities (including " + "other Discord servers) or commercial projects - Contact " + "us directly if you want to discuss a partnership!" + ) + ] + self.default_desc = "The rules and guidelines that apply to this ", \ + "community can be found on our [rules page],"\ + "(https://pythondiscord.com/about/rules). We "\ + "expect all members of the community to have "\ + "read and understood these." + + @command( + aliases=['r', 'rule'], + name='rules', + ) + @redirect_output( + destination_channel=Channels.bot, + bypass_roles=STAFF) + async def rules_command( + self, ctx: Context, *, rules: Optional[str] = None): + """ + Provides a link to the `rules` endpoint of the website, or displays + specific rules, if they are requested. + :param ctx: The Discord message context + :param rules: The rules a user wants to get. + :return: + """ + rules_embed = Embed( + title='Rules', + color=Colour.blurple() + ) + rules_embed.set_footer(text='https://pythondiscord.com/about/rules') + + if not rules: + # Rules were not submitted. Return the default description. + rules_embed.description = self.default_desc + return await ctx.send(embed=rules_embed) + + # Regex magic time. + # This code block will do the following: + # Split the rules string across the provided characters ('/', ',', ' ') + # Returns a list of numbers based on if the numbers correspond to item + # indices in the rules list + rules_to_get = [] + split_rules = re.split(r'[/, ]', rules) + for item in split_rules: + if not item.isdigit(): + if not item: + continue + rule_match = re.search(r'\d?\d[:|-]1?\d', item) + if rule_match: + a, b = sorted( + [int(x)-1 for x in re.split(r'[:-]', + rule_match.group())]) + rules_to_get.extend(range(a, b+1) + ) + else: + rules_to_get.append(int(item)-1) + final_rules = [f'Rule {i+1}: {self.rules[i]}' + for i in sorted(rules_to_get) if i < len(self.rules)] + + if not final_rules: + # Param rules was processed, but no rules were matched. + # Return the default description. + rules_embed.description = self.default_desc + return await ctx.send(embed=rules_embed) + await LinePaginator.paginate( + final_rules, ctx, rules_embed, max_lines=3 + ) + + +def setup(bot): + bot.add_cog(Rules(bot)) -- cgit v1.2.3 From 1084c8479ad14711236ec5094c77c90c31446604 Mon Sep 17 00:00:00 2001 From: Vincent Gross Date: Fri, 1 Feb 2019 22:28:08 -0500 Subject: Fixed errors after linting Turns out I broke a few things after linting. Whoops. Fixed. --- bot/cogs/rules.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bot/cogs/rules.py b/bot/cogs/rules.py index 6759d07a2..208607573 100644 --- a/bot/cogs/rules.py +++ b/bot/cogs/rules.py @@ -38,7 +38,7 @@ class Rules: ), ( "We will not help you with anything that might break " - "a law or the terms of service of any other community, site," + "a law or the terms of service of any other community, site, " "service, or otherwise - No piracy, brute-forcing, captcha " "circumvention, sneaker bots, or anything else of that nature." ), @@ -69,10 +69,10 @@ class Rules: "us directly if you want to discuss a partnership!" ) ] - self.default_desc = "The rules and guidelines that apply to this ", \ - "community can be found on our [rules page],"\ - "(https://pythondiscord.com/about/rules). We "\ - "expect all members of the community to have "\ + self.default_desc = "The rules and guidelines that apply to this " \ + "community can be found on our [rules page]" \ + "(https://pythondiscord.com/about/rules). We " \ + "expect all members of the community to have " \ "read and understood these." @command( -- cgit v1.2.3 From d66c691688287239735251ad67a27c0b8d7db295 Mon Sep 17 00:00:00 2001 From: Vincent Gross Date: Fri, 1 Feb 2019 22:37:15 -0500 Subject: Forgot to remove this. Almost in hindsight, I almost forgot to remove this before creating the pull request. *Yoink.* --- bot/cogs/site.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/bot/cogs/site.py b/bot/cogs/site.py index 442e80cd2..e5fd645fb 100644 --- a/bot/cogs/site.py +++ b/bot/cogs/site.py @@ -92,22 +92,6 @@ class Site: await ctx.send(embed=embed) - @site_group.command(name="rules") - async def site_rules(self, ctx: Context): - """Info about the server's rules.""" - - url = f"{URLs.site_schema}{URLs.site}/about/rules" - - embed = Embed(title="Rules") - embed.set_footer(text=url) - embed.colour = Colour.blurple() - embed.description = ( - f"The rules and guidelines that apply to this community can be found on our [rules page]({url}). " - "We expect all members of the community to have read and understood these." - ) - - await ctx.send(embed=embed) - def setup(bot): bot.add_cog(Site(bot)) -- cgit v1.2.3 From ce70a29dcfec6b728d9f42bd6b1896ee4087fe7b Mon Sep 17 00:00:00 2001 From: Scragly <29337040+scragly@users.noreply.github.com> Date: Tue, 5 Feb 2019 10:55:34 +1000 Subject: Have invite filter send guild info with mod-alert. --- bot/cogs/filtering.py | 46 ++++++++++++++++++++++++++++++++++++++++------ bot/cogs/modlog.py | 4 +++- 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/bot/cogs/filtering.py b/bot/cogs/filtering.py index 6b4469ceb..d3dc0f66e 100644 --- a/bot/cogs/filtering.py +++ b/bot/cogs/filtering.py @@ -1,6 +1,6 @@ import logging import re -from typing import Optional +from typing import Optional, Union import discord.errors from dateutil.relativedelta import relativedelta @@ -189,7 +189,25 @@ class Filtering: log.debug(message) - additional_embeds = msg.embeds if filter_name == "watch_rich_embeds" else None + additional_embeds = None + additional_embeds_msg = None + + if filter_name == "filter_invites": + additional_embeds = [] + for invite, data in triggered.items(): + embed = discord.Embed(description=( + f"**Members:**\n{data['members']}\n" + f"**Active:**\n{data['active']}" + )) + embed.set_author(name=data["name"]) + embed.set_thumbnail(url=data["icon"]) + embed.set_footer(text=f"Guild Invite Code: {invite}") + additional_embeds.append(embed) + additional_embeds_msg = "For the following guild(s):" + + elif filter_name == "watch_rich_embeds": + additional_embeds = msg.embeds + additional_embeds_msg = "With the following embed(s):" # Send pretty mod log embed to mod-alerts await self.mod_log.send_log_message( @@ -201,6 +219,7 @@ class Filtering: channel_id=Channels.mod_alerts, ping_everyone=Filter.ping_everyone, additional_embeds=additional_embeds, + additional_embeds_msg=additional_embeds_msg ) break # We don't want multiple filters to trigger @@ -282,7 +301,7 @@ class Filtering: return bool(re.search(ZALGO_RE, text)) - async def _has_invites(self, text: str) -> bool: + async def _has_invites(self, text: str) -> Union[dict, bool]: """ Returns True if the text contains an invite which is not on the guild_invite_whitelist in config.yml @@ -295,10 +314,13 @@ class Filtering: text = text.replace("\\", "") invites = re.findall(INVITE_RE, text, re.IGNORECASE) + invite_data = dict() for invite in invites: + if invite in invite_data: + continue response = await self.bot.http_session.get( - f"{URLs.discord_invite_api}/{invite}" + f"{URLs.discord_invite_api}/{invite}", params={"with_counts": "true"} ) response = await response.json() guild = response.get("guild") @@ -311,8 +333,20 @@ class Filtering: guild_id = int(guild.get("id")) if guild_id not in Filter.guild_invite_whitelist: - return True - return False + guild_icon_hash = guild["icon"] + guild_icon = ( + "https://cdn.discordapp.com/icons/" + f"{guild_id}/{guild_icon_hash}.png?size=512" + ) + + invite_data[invite] = { + "name": guild["name"], + "icon": guild_icon, + "members": response["approximate_member_count"], + "active": response["approximate_presence_count"] + } + + return invite_data if invite_data else False @staticmethod async def _has_rich_embed(msg: Message): diff --git a/bot/cogs/modlog.py b/bot/cogs/modlog.py index 495795b6d..65efda5ed 100644 --- a/bot/cogs/modlog.py +++ b/bot/cogs/modlog.py @@ -115,6 +115,7 @@ class ModLog: files: Optional[List[File]] = None, content: Optional[str] = None, additional_embeds: Optional[List[Embed]] = None, + additional_embeds_msg: Optional[str] = None, timestamp_override: Optional[datetime.datetime] = None, footer: Optional[str] = None, ): @@ -143,7 +144,8 @@ class ModLog: log_message = await channel.send(content=content, embed=embed, files=files) if additional_embeds: - await channel.send("With the following embed(s):") + if additional_embeds_msg: + await channel.send(additional_embeds_msg) for additional_embed in additional_embeds: await channel.send(embed=additional_embed) -- cgit v1.2.3 From 9126822f5a9871fe795847a4caf412c0eebecef7 Mon Sep 17 00:00:00 2001 From: "(PC) Refisio" Date: Wed, 6 Feb 2019 19:00:19 -0500 Subject: Code is properly linted. --- bot/cogs/rules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/cogs/rules.py b/bot/cogs/rules.py index 208607573..f44858b04 100644 --- a/bot/cogs/rules.py +++ b/bot/cogs/rules.py @@ -49,7 +49,7 @@ class Rules: ( "All discussion should be kept within the relevant " "channels for the subject - See the " - f"[channels page](https://pythondiscord.com/about/channels) " + f"[channels page](https://pythondiscord.com/about/channels) " "for more information." ), ( -- cgit v1.2.3 From 09731743bf1c8bc334001413cddd16d11a55cf8f Mon Sep 17 00:00:00 2001 From: Scragly <29337040+scragly@users.noreply.github.com> Date: Fri, 8 Feb 2019 01:15:03 +1000 Subject: Update _has_invites method docstring. --- bot/cogs/filtering.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bot/cogs/filtering.py b/bot/cogs/filtering.py index d3dc0f66e..25aaf8420 100644 --- a/bot/cogs/filtering.py +++ b/bot/cogs/filtering.py @@ -303,8 +303,10 @@ class Filtering: async def _has_invites(self, text: str) -> Union[dict, bool]: """ - Returns True if the text contains an invite which is not on the guild_invite_whitelist in - config.yml + Checks if there's any invites in the text content that aren't in the guild whitelist. + + If any are detected, a dictionary of invite data is returned, with a key per invite. + If none are detected, False is returned. Attempts to catch some of common ways to try to cheat the system. """ -- cgit v1.2.3 From a4f877412992142943da30503d45ce7546e3fd08 Mon Sep 17 00:00:00 2001 From: Vincent Gross Date: Thu, 7 Feb 2019 15:49:11 -0500 Subject: Fixed issues pertaining to Import Order. --- bot/cogs/rules.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/bot/cogs/rules.py b/bot/cogs/rules.py index f44858b04..fe920199a 100644 --- a/bot/cogs/rules.py +++ b/bot/cogs/rules.py @@ -1,13 +1,12 @@ import re from typing import Optional -from bot.constants import Channels, Roles -from bot.decorators import redirect_output -from bot.pagination import LinePaginator - from discord import Colour, Embed from discord.ext.commands import Bot, Context, command +from bot.constants import Channels, Roles +from bot.decorators import redirect_output +from bot.pagination import LinePaginator STAFF = [ Roles.admin, -- cgit v1.2.3 From d78c97f5b25120f2988fadecb79e14986ad1ab9f Mon Sep 17 00:00:00 2001 From: "(PC) Refisio" Date: Thu, 7 Feb 2019 21:09:02 -0500 Subject: Updated Rules cog. `rules` has been removed from `alias.py`, and the cog has been added to the list to be loaded. I remembered there being a Pathlib conglomeration that loaded each cog, but I might have been mistaken that from another project. Requested changes have been made. --- bot/__main__.py | 1 + bot/cogs/alias.py | 8 ---- bot/cogs/rules.py | 139 +++++++++++++++++++++--------------------------------- 3 files changed, 54 insertions(+), 94 deletions(-) diff --git a/bot/__main__.py b/bot/__main__.py index c9d6fd61e..568285cc3 100644 --- a/bot/__main__.py +++ b/bot/__main__.py @@ -51,6 +51,7 @@ bot.load_extension("bot.cogs.bot") bot.load_extension("bot.cogs.clean") bot.load_extension("bot.cogs.cogs") bot.load_extension("bot.cogs.help") +bot.load_extension("bot.cogs.rules") # Only load this in production if not DEBUG_MODE: diff --git a/bot/cogs/alias.py b/bot/cogs/alias.py index 0e6b3a7c6..a726e374f 100644 --- a/bot/cogs/alias.py +++ b/bot/cogs/alias.py @@ -105,14 +105,6 @@ class Alias: await self.invoke(ctx, "site faq") - @command(name="rules", hidden=True) - async def site_rules_alias(self, ctx): - """ - Alias for invoking site rules. - """ - - await self.invoke(ctx, "site rules") - @command(name="reload", hidden=True) async def cogs_reload_alias(self, ctx, *, cog_name: str): """ diff --git a/bot/cogs/rules.py b/bot/cogs/rules.py index fe920199a..7582e8c80 100644 --- a/bot/cogs/rules.py +++ b/bot/cogs/rules.py @@ -1,99 +1,73 @@ import re from typing import Optional -from discord import Colour, Embed -from discord.ext.commands import Bot, Context, command - from bot.constants import Channels, Roles from bot.decorators import redirect_output from bot.pagination import LinePaginator -STAFF = [ - Roles.admin, - Roles.moderator, - Roles.owner, -] +from discord import Colour, Embed +from discord.ext.commands import Bot, Context, command + + +STAFF = Roles.admin, Roles.moderator, Roles.owner class Rules: def __init__(self, bot: Bot): self.bot = bot + # We'll get the rules from the API when the - # site has been updated to the Django Framwork. + # site has been updated to the Django Framework. # Hard-code the rules for now until the new RulesView is released. - self.rules = [ + + self.rules = ( "Be polite, and do not spam.", - "Follow the [Discord Community Guidelines]", - "(https://discordapp.com/guidelines).", - ( - "Don't intentionally make other people uncomfortable - if " - "someone asks you to stop discussing something," - " you should stop." - ), - ( - "Be patient both with users asking " - "questions, and the users answering them." - ), - ( - "We will not help you with anything that might break " - "a law or the terms of service of any other community, site, " - "service, or otherwise - No piracy, brute-forcing, captcha " - "circumvention, sneaker bots, or anything else of that nature." - ), - ( - "Listen to and respect the staff members - we're " - "here to help, but we're all human beings." - ), - ( - "All discussion should be kept within the relevant " - "channels for the subject - See the " - f"[channels page](https://pythondiscord.com/about/channels) " - "for more information." - ), - ( - "This is an English-speaking server, so please speak English " - f"to the best of your ability - [Google Translate]" - "(https://translate.google.com/) should be fine if " - "you're not sure." - ), - ( - "Keep all discussions safe for work - No gore, nudity, sexual " - "soliciting, references to suicide, or anything else of " - "that nature" - ), - ( - "We do not allow advertisements for communities (including " - "other Discord servers) or commercial projects - Contact " - "us directly if you want to discuss a partnership!" - ) - ] + + "Follow the [Discord Community Guidelines](https://discordapp.com/guidelines).", + + "Don't intentionally make other people uncomfortable - if someone asks you to stop " + "discussing something, you should stop.", + + "Be patient both with users asking questions, and the users answering them.", + + "We will not help you with anything that might break a law or the terms of service " + "of any other community, site, service, or otherwise - No piracy, brute-forcing, " + "captcha circumvention, sneaker bots, or anything else of that nature.", + + "Listen to and respect the staff members - we're here to help, but we're all human " + "beings.", + + "All discussion should be kept within the relevant channels for the subject - See the " + "[channels page](https://pythondiscord.com/about/channels) for more information.", + + "This is an English-speaking server, so please speak English to the best of your " + "ability - [Google Translate](https://translate.google.com/) should be fine if you're " + "not sure.", + + "Keep all discussions safe for work - No gore, nudity, sexual soliciting, references " + "to suicide, or anything else of that nature", + + "We do not allow advertisements for communities (including other Discord servers) or " + "commercial projects - Contact us directly if you want to discuss a partnership!" + ) self.default_desc = "The rules and guidelines that apply to this " \ "community can be found on our [rules page]" \ "(https://pythondiscord.com/about/rules). We " \ "expect all members of the community to have " \ "read and understood these." - @command( - aliases=['r', 'rule'], - name='rules', - ) - @redirect_output( - destination_channel=Channels.bot, - bypass_roles=STAFF) - async def rules_command( - self, ctx: Context, *, rules: Optional[str] = None): + @command(aliases=['r', 'rule'], name='rules') + @redirect_output(destination_channel=Channels.bot, bypass_roles=STAFF) + async def rules_command(self, ctx: Context, *, rules: Optional[str] = None): """ Provides a link to the `rules` endpoint of the website, or displays specific rules, if they are requested. - :param ctx: The Discord message context - :param rules: The rules a user wants to get. - :return: + + **`ctx`:** The Discord message context + **`rules`:** The rules a user wants to get. """ - rules_embed = Embed( - title='Rules', - color=Colour.blurple() - ) + rules_embed = Embed(title='Rules', color=Colour.blurple()) rules_embed.set_footer(text='https://pythondiscord.com/about/rules') if not rules: @@ -101,11 +75,8 @@ class Rules: rules_embed.description = self.default_desc return await ctx.send(embed=rules_embed) - # Regex magic time. - # This code block will do the following: - # Split the rules string across the provided characters ('/', ',', ' ') - # Returns a list of numbers based on if the numbers correspond to item - # indices in the rules list + # Split the rules input by slash, comma or space + # Returns a list of ints if they're in range of rules index rules_to_get = [] split_rules = re.split(r'[/, ]', rules) for item in split_rules: @@ -115,23 +86,19 @@ class Rules: rule_match = re.search(r'\d?\d[:|-]1?\d', item) if rule_match: a, b = sorted( - [int(x)-1 for x in re.split(r'[:-]', - rule_match.group())]) - rules_to_get.extend(range(a, b+1) - ) + [int(x)-1 for x in re.split(r'[:-]', rule_match.group())]) + rules_to_get.extend(range(a, b+1)) else: rules_to_get.append(int(item)-1) - final_rules = [f'Rule {i+1}: {self.rules[i]}' - for i in sorted(rules_to_get) if i < len(self.rules)] + final_rules = [ + f'**{i+1}.** {self.rules[i]}' for i in sorted(rules_to_get) if i < len(self.rules) + ] if not final_rules: - # Param rules was processed, but no rules were matched. - # Return the default description. + # No valid rules in rules input. Return the default description. rules_embed.description = self.default_desc return await ctx.send(embed=rules_embed) - await LinePaginator.paginate( - final_rules, ctx, rules_embed, max_lines=3 - ) + await LinePaginator.paginate(final_rules, ctx, rules_embed, max_lines=3) def setup(bot): -- cgit v1.2.3 From e992fef0b55469cb66219c54637da4593807bf56 Mon Sep 17 00:00:00 2001 From: Vincent Gross Date: Thu, 7 Feb 2019 21:21:40 -0500 Subject: Swapped around import statements. ***Again.*** --- bot/cogs/rules.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/bot/cogs/rules.py b/bot/cogs/rules.py index 7582e8c80..f940d22b9 100644 --- a/bot/cogs/rules.py +++ b/bot/cogs/rules.py @@ -1,13 +1,12 @@ import re from typing import Optional +bot.load_extension("bot.cogs.rules") + from bot.constants import Channels, Roles from bot.decorators import redirect_output from bot.pagination import LinePaginator -from discord import Colour, Embed -from discord.ext.commands import Bot, Context, command - STAFF = Roles.admin, Roles.moderator, Roles.owner -- cgit v1.2.3 From 0998392651a5e10f04f5b6e031988ff5dd233612 Mon Sep 17 00:00:00 2001 From: Vincent Gross Date: Thu, 7 Feb 2019 21:25:03 -0500 Subject: Update rules.py --- bot/cogs/rules.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bot/cogs/rules.py b/bot/cogs/rules.py index f940d22b9..59f28615c 100644 --- a/bot/cogs/rules.py +++ b/bot/cogs/rules.py @@ -1,7 +1,8 @@ import re from typing import Optional -bot.load_extension("bot.cogs.rules") +from discord import Colour, Embed +from discord.ext.commands import Bot, Context, command from bot.constants import Channels, Roles from bot.decorators import redirect_output -- cgit v1.2.3 From 32f5ceeae2f4c9c1c4c9c140945ad28743ce2222 Mon Sep 17 00:00:00 2001 From: "(PC) Refisio" Date: Sat, 9 Feb 2019 22:24:07 -0500 Subject: Updated Rules cog. --- bot/cogs/rules.py | 20 +++++++++----------- tox.ini | 2 +- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/bot/cogs/rules.py b/bot/cogs/rules.py index 7582e8c80..666f7b1b6 100644 --- a/bot/cogs/rules.py +++ b/bot/cogs/rules.py @@ -1,13 +1,13 @@ import re from typing import Optional -from bot.constants import Channels, Roles -from bot.decorators import redirect_output -from bot.pagination import LinePaginator - from discord import Colour, Embed from discord.ext.commands import Bot, Context, command +from bot.pagination import LinePaginator +from bot.constants import Channels, Roles +from bot.decorators import redirect_output + STAFF = Roles.admin, Roles.moderator, Roles.owner @@ -51,11 +51,10 @@ class Rules: "We do not allow advertisements for communities (including other Discord servers) or " "commercial projects - Contact us directly if you want to discuss a partnership!" ) - self.default_desc = "The rules and guidelines that apply to this " \ - "community can be found on our [rules page]" \ - "(https://pythondiscord.com/about/rules). We " \ - "expect all members of the community to have " \ - "read and understood these." + self.default_desc = ("The rules and guidelines that apply to this community can be found on" + " our [rules page](https://pythondiscord.com/about/rules). We expect" + " all members of the community to have read and understood these." + ) @command(aliases=['r', 'rule'], name='rules') @redirect_output(destination_channel=Channels.bot, bypass_roles=STAFF) @@ -85,8 +84,7 @@ class Rules: continue rule_match = re.search(r'\d?\d[:|-]1?\d', item) if rule_match: - a, b = sorted( - [int(x)-1 for x in re.split(r'[:-]', rule_match.group())]) + a, b = sorted([int(x)-1 for x in re.split(r'[:-]', rule_match.group())]) rules_to_get.extend(range(a, b+1)) else: rules_to_get.append(int(item)-1) diff --git a/tox.ini b/tox.ini index c6fa513f4..67f0ffd81 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [flake8] -max-line-length=120 +max-line-length=100 application_import_names=bot exclude=.cache,.venv ignore=B311,W503,E226,S311 -- cgit v1.2.3 From 2b97f7050370af4e83bef09acd227fa4fe3a9a76 Mon Sep 17 00:00:00 2001 From: "(PC) Refisio" Date: Sat, 9 Feb 2019 22:31:05 -0500 Subject: Updated Rules cog. Also, accidentally changed the max-line-length in the linter to 100 so that I could properly lint my code without having Pycharm yell at me. Reverted that change, as the main repo still hasn't moved to that style yet. --- bot/cogs/rules.py | 12 +++++++----- tox.ini | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/bot/cogs/rules.py b/bot/cogs/rules.py index 666f7b1b6..0e0c5699a 100644 --- a/bot/cogs/rules.py +++ b/bot/cogs/rules.py @@ -51,10 +51,11 @@ class Rules: "We do not allow advertisements for communities (including other Discord servers) or " "commercial projects - Contact us directly if you want to discuss a partnership!" ) - self.default_desc = ("The rules and guidelines that apply to this community can be found on" - " our [rules page](https://pythondiscord.com/about/rules). We expect" - " all members of the community to have read and understood these." - ) + self.default_desc = "The rules and guidelines that apply to this " \ + "community can be found on our [rules page]" \ + "(https://pythondiscord.com/about/rules). We " \ + "expect all members of the community to have " \ + "read and understood these." @command(aliases=['r', 'rule'], name='rules') @redirect_output(destination_channel=Channels.bot, bypass_roles=STAFF) @@ -84,7 +85,8 @@ class Rules: continue rule_match = re.search(r'\d?\d[:|-]1?\d', item) if rule_match: - a, b = sorted([int(x)-1 for x in re.split(r'[:-]', rule_match.group())]) + a, b = sorted( + [int(x)-1 for x in re.split(r'[:-]', rule_match.group())]) rules_to_get.extend(range(a, b+1)) else: rules_to_get.append(int(item)-1) diff --git a/tox.ini b/tox.ini index 67f0ffd81..c6fa513f4 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [flake8] -max-line-length=100 +max-line-length=120 application_import_names=bot exclude=.cache,.venv ignore=B311,W503,E226,S311 -- cgit v1.2.3 From 6fc5e87ab8ded59439c8f9ab22554f5ea5a86c11 Mon Sep 17 00:00:00 2001 From: "(PC) Refisio" Date: Sat, 9 Feb 2019 22:48:22 -0500 Subject: Re-made changes. --- bot/cogs/rules.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/bot/cogs/rules.py b/bot/cogs/rules.py index ff754be93..eee506810 100644 --- a/bot/cogs/rules.py +++ b/bot/cogs/rules.py @@ -50,11 +50,10 @@ class Rules: "We do not allow advertisements for communities (including other Discord servers) or " "commercial projects - Contact us directly if you want to discuss a partnership!" ) - self.default_desc = "The rules and guidelines that apply to this " \ - "community can be found on our [rules page]" \ - "(https://pythondiscord.com/about/rules). We " \ - "expect all members of the community to have " \ - "read and understood these." + self.default_desc = ("The rules and guidelines that apply to this community can be found on" + " our [rules page](https://pythondiscord.com/about/rules). We expect" + " all members of the community to have read and understood these." + ) @command(aliases=['r', 'rule'], name='rules') @redirect_output(destination_channel=Channels.bot, bypass_roles=STAFF) @@ -84,8 +83,7 @@ class Rules: continue rule_match = re.search(r'\d?\d[:|-]1?\d', item) if rule_match: - a, b = sorted( - [int(x)-1 for x in re.split(r'[:-]', rule_match.group())]) + a, b = sorted([int(x)-1 for x in re.split(r'[:-]', rule_match.group())]) rules_to_get.extend(range(a, b+1)) else: rules_to_get.append(int(item)-1) -- cgit v1.2.3 From 3d66a2574479129f2caa3b92410e4484ffb2de17 Mon Sep 17 00:00:00 2001 From: Thomas Petersson Date: Wed, 13 Feb 2019 15:18:11 +0100 Subject: Added alias for tags get traceback - !exception. I find myself writing !exception by mistake too often and just figured i'd see if others would want this alias in. --- bot/cogs/alias.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/bot/cogs/alias.py b/bot/cogs/alias.py index 0e6b3a7c6..1df9e0265 100644 --- a/bot/cogs/alias.py +++ b/bot/cogs/alias.py @@ -139,6 +139,14 @@ class Alias: await self.invoke(ctx, "defcon disable") + @command(name="exception", hidden=True) + async def tags_get_traceback_alias(self, ctx): + """ + Alias for invoking tags get traceback. + """ + + await self.invoke(ctx, "tags get traceback") + @group(name="get", aliases=("show", "g"), hidden=True, -- cgit v1.2.3 From 3d2d53ee2675871919719b3a6fe303096852531f Mon Sep 17 00:00:00 2001 From: Thomas Petersson Date: Wed, 13 Feb 2019 15:23:27 +0100 Subject: Github editor snuck in a few blanklines --- bot/cogs/alias.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bot/cogs/alias.py b/bot/cogs/alias.py index 1df9e0265..73091f962 100644 --- a/bot/cogs/alias.py +++ b/bot/cogs/alias.py @@ -144,9 +144,9 @@ class Alias: """ Alias for invoking tags get traceback. """ - + await self.invoke(ctx, "tags get traceback") - + @group(name="get", aliases=("show", "g"), hidden=True, -- cgit v1.2.3 From 5ac0ecb79326c7f9d7442976aa71fa3207b7808e Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Thu, 14 Feb 2019 00:30:43 +0100 Subject: Whitelisting domains. Adding gentoo, adafruit and kennethreitz.org to the whitelist. --- config-default.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config-default.yml b/config-default.yml index 3ce01916e..747fa7fab 100644 --- a/config-default.yml +++ b/config-default.yml @@ -162,6 +162,9 @@ filter: - 273944235143593984 # STEM - 348658686962696195 # RLBot - 531221516914917387 # Pallets + - 249111029668249601 # Gentoo + - 327254708534116352 # Adafruit + - 544525886180032552 # kennethreitz.org domain_blacklist: - pornhub.com -- cgit v1.2.3 From 8190279b2bee9eca1d07915215c7d85d655460b4 Mon Sep 17 00:00:00 2001 From: Joseph Banks Date: Sat, 16 Feb 2019 14:41:49 +0000 Subject: Add team creator command, createteam --- bot/cogs/jams.py | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 bot/cogs/jams.py diff --git a/bot/cogs/jams.py b/bot/cogs/jams.py new file mode 100644 index 000000000..c664d759a --- /dev/null +++ b/bot/cogs/jams.py @@ -0,0 +1,72 @@ +import logging + +from discord import PermissionOverwrite, Member, utils +from discord.ext import commands + +from bot.decorators import with_role +from bot.constants import Roles + +log = logging.getLogger(__name__) + +class CodeJams: + """ + A cog for managing the code-jam related parts of our server + """ + + def __init__(self, bot: commands.Bot): + self.bot = bot + + @commands.command() + @with_role(Roles.admin) + async def createteam( + self, ctx: commands.Context, + team_name: str, members: commands.Greedy[Member] + ): + code_jam_category = utils.get(ctx.guild.categories, name="Code Jam") + + if code_jam_category is None: + log.info("Code Jam category not found, creating it.") + + category_overwrites = { + ctx.guild.default_role: PermissionOverwrite(read_messages=False), + ctx.guild.me: PermissionOverwrite(read_messages=True) + } + + code_jam_category = await ctx.guild.create_category_channel( + "Code Jam", + overwrites=category_overwrites, + reason="It's code jam time!" + ) + + # First member is always the team leader + team_channel_overwrites = { + members[0]: PermissionOverwrite(manage_messages=True, read_messages=True, manage_webhooks=True), + ctx.guild.default_role: PermissionOverwrite(read_messages=False), + ctx.guild.get_role(Roles.developer): PermissionOverwrite(read_messages=False) + } + + # Rest of members should just have read_messages + for member in members[1:]: + team_channel_overwrites[member] = PermissionOverwrite(read_messages=True) + + # Create a channel for the team + team_channel = await ctx.guild.create_text_channel( + team_name, + overwrites=team_channel_overwrites, + category=code_jam_category + ) + + # Assign team leader role + await members[0].add_roles(ctx.guild.get_role(Roles.team_leader)) + + # Assign rest of roles + jammer_role = ctx.guild.get_role(Roles.jammer) + for member in members: + await member.add_roles(jammer_role) + + await ctx.send(f":ok_hand: Team created: {team_channel.mention}") + + +def setup(bot): + bot.add_cog(CodeJams(bot)) + log.info("Cog loaded: CodeJams") \ No newline at end of file -- cgit v1.2.3 From c573de17197bb269f70ad0d179a20ae1162de95a Mon Sep 17 00:00:00 2001 From: Joseph Banks Date: Sat, 16 Feb 2019 14:42:09 +0000 Subject: Add team_leaders to roles config --- bot/constants.py | 1 + config-default.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/bot/constants.py b/bot/constants.py index ab62cd79d..5b9b45c1c 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -372,6 +372,7 @@ class Roles(metaclass=YAMLGetter): owner: int verified: int helpers: int + team_leader: int class Guild(metaclass=YAMLGetter): diff --git a/config-default.yml b/config-default.yml index 747fa7fab..110dd12dd 100644 --- a/config-default.yml +++ b/config-default.yml @@ -134,6 +134,7 @@ guild: verified: 352427296948486144 helpers: 267630620367257601 rockstars: &ROCKSTARS_ROLE 458226413825294336 + team_leader: 501324292341104650 filter: -- cgit v1.2.3 From 73694f8a790bde8ca67e7b0821f0a92ddec84e10 Mon Sep 17 00:00:00 2001 From: Joseph Banks Date: Sat, 16 Feb 2019 14:42:21 +0000 Subject: Enable loading of the jams cog --- bot/__main__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bot/__main__.py b/bot/__main__.py index 568285cc3..acb4c372d 100644 --- a/bot/__main__.py +++ b/bot/__main__.py @@ -78,6 +78,7 @@ bot.load_extension("bot.cogs.token_remover") bot.load_extension("bot.cogs.utils") bot.load_extension("bot.cogs.wolfram") bot.load_extension("bot.cogs.free") +bot.load_extension("bot.cogs.jams") if has_rmq: bot.load_extension("bot.cogs.rmq") -- cgit v1.2.3 From 4dcc9724817ffd9d85d78dd50d85f084ed7ac677 Mon Sep 17 00:00:00 2001 From: Joseph Banks Date: Sat, 16 Feb 2019 14:48:15 +0000 Subject: Add a docstring to the createteam command --- bot/cogs/jams.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/bot/cogs/jams.py b/bot/cogs/jams.py index c664d759a..746f42106 100644 --- a/bot/cogs/jams.py +++ b/bot/cogs/jams.py @@ -22,6 +22,12 @@ class CodeJams: self, ctx: commands.Context, team_name: str, members: commands.Greedy[Member] ): + """ + Create a team channel in the Code Jams category, assign roles and then add + overwrites for the team. + + The first user passed will always be the team leader. + """ code_jam_category = utils.get(ctx.guild.categories, name="Code Jam") if code_jam_category is None: -- cgit v1.2.3 From 21913619f40b3a253602d7ee107c144ad6b02d04 Mon Sep 17 00:00:00 2001 From: Joseph Banks Date: Sat, 16 Feb 2019 14:49:16 +0000 Subject: Change a particularly nasty line --- bot/cogs/jams.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bot/cogs/jams.py b/bot/cogs/jams.py index 746f42106..a88d80c32 100644 --- a/bot/cogs/jams.py +++ b/bot/cogs/jams.py @@ -46,7 +46,11 @@ class CodeJams: # First member is always the team leader team_channel_overwrites = { - members[0]: PermissionOverwrite(manage_messages=True, read_messages=True, manage_webhooks=True), + members[0]: PermissionOverwrite( + manage_messages=True, + read_messages=True, + manage_webhooks=True + ), ctx.guild.default_role: PermissionOverwrite(read_messages=False), ctx.guild.get_role(Roles.developer): PermissionOverwrite(read_messages=False) } -- cgit v1.2.3 From 5a9a135bd1f69b0ca79c0a45aa432d125bba5cf7 Mon Sep 17 00:00:00 2001 From: Joseph Banks Date: Sat, 16 Feb 2019 14:52:47 +0000 Subject: Flake8 --- bot/cogs/jams.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/bot/cogs/jams.py b/bot/cogs/jams.py index a88d80c32..ec16d0448 100644 --- a/bot/cogs/jams.py +++ b/bot/cogs/jams.py @@ -1,13 +1,14 @@ import logging -from discord import PermissionOverwrite, Member, utils +from discord import Member, PermissionOverwrite, utils from discord.ext import commands -from bot.decorators import with_role from bot.constants import Roles +from bot.decorators import with_role log = logging.getLogger(__name__) + class CodeJams: """ A cog for managing the code-jam related parts of our server @@ -43,7 +44,7 @@ class CodeJams: overwrites=category_overwrites, reason="It's code jam time!" ) - + # First member is always the team leader team_channel_overwrites = { members[0]: PermissionOverwrite( @@ -79,4 +80,4 @@ class CodeJams: def setup(bot): bot.add_cog(CodeJams(bot)) - log.info("Cog loaded: CodeJams") \ No newline at end of file + log.info("Cog loaded: CodeJams") -- cgit v1.2.3 From 24610458a3c0379129552b4ed6204b261cbc243b Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Sat, 16 Feb 2019 15:01:42 +0000 Subject: Update bot/cogs/jams.py Co-Authored-By: jos-b --- bot/cogs/jams.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/cogs/jams.py b/bot/cogs/jams.py index ec16d0448..e68aa3d2f 100644 --- a/bot/cogs/jams.py +++ b/bot/cogs/jams.py @@ -11,7 +11,7 @@ log = logging.getLogger(__name__) class CodeJams: """ - A cog for managing the code-jam related parts of our server + Manages the code-jam related parts of our server """ def __init__(self, bot: commands.Bot): -- cgit v1.2.3 From 228ac4f3df1e1b127cb4c767ce6a222ce94d2a9a Mon Sep 17 00:00:00 2001 From: Joseph Banks Date: Sat, 16 Feb 2019 15:02:24 +0000 Subject: Sort the loading of cogs --- bot/__main__.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bot/__main__.py b/bot/__main__.py index acb4c372d..6928a3960 100644 --- a/bot/__main__.py +++ b/bot/__main__.py @@ -38,11 +38,11 @@ else: log.warning("Timed out while waiting for RabbitMQ") # Internal/debug -bot.load_extension("bot.cogs.logging") -bot.load_extension("bot.cogs.security") bot.load_extension("bot.cogs.events") bot.load_extension("bot.cogs.filtering") +bot.load_extension("bot.cogs.logging") bot.load_extension("bot.cogs.modlog") +bot.load_extension("bot.cogs.security") # Commands, etc bot.load_extension("bot.cogs.antispam") @@ -60,12 +60,13 @@ if not DEBUG_MODE: # Feature cogs bot.load_extension("bot.cogs.alias") -bot.load_extension("bot.cogs.deployment") bot.load_extension("bot.cogs.defcon") +bot.load_extension("bot.cogs.deployment") bot.load_extension("bot.cogs.eval") +bot.load_extension("bot.cogs.free") bot.load_extension("bot.cogs.fun") -bot.load_extension("bot.cogs.superstarify") bot.load_extension("bot.cogs.information") +bot.load_extension("bot.cogs.jams") bot.load_extension("bot.cogs.moderation") bot.load_extension("bot.cogs.off_topic_names") bot.load_extension("bot.cogs.reddit") @@ -73,12 +74,11 @@ bot.load_extension("bot.cogs.reminders") bot.load_extension("bot.cogs.site") bot.load_extension("bot.cogs.snakes") bot.load_extension("bot.cogs.snekbox") +bot.load_extension("bot.cogs.superstarify") bot.load_extension("bot.cogs.tags") bot.load_extension("bot.cogs.token_remover") bot.load_extension("bot.cogs.utils") bot.load_extension("bot.cogs.wolfram") -bot.load_extension("bot.cogs.free") -bot.load_extension("bot.cogs.jams") if has_rmq: bot.load_extension("bot.cogs.rmq") -- cgit v1.2.3