diff --git a/.gitignore b/.gitignore index d9005f2..de4cdb3 100644 --- a/.gitignore +++ b/.gitignore @@ -112,7 +112,7 @@ celerybeat.pid *.sage.py # Environments -.env +.env* .venv env/ venv/ diff --git a/app/cogs/errors.py b/app/cogs/errors.py index a931448..92b3633 100644 --- a/app/cogs/errors.py +++ b/app/cogs/errors.py @@ -17,7 +17,8 @@ class Errors(Cog, name="errors"): def __init__(self, bot: DiscordBot) -> None: self.bot = bot super().__init__() - bot.tree.on_error = self.on_app_command_error + if self.bot.config.is_prod(): + bot.tree.on_error = self.on_app_command_error async def on_app_command_error( self, @@ -26,9 +27,6 @@ async def on_app_command_error( ) -> None: await self.send_default_error_message(interaction) - if str(interaction.user.id) == self.bot.owner_id: - return - command_name = logconstants.UNKNOWN_COMMAND if interaction.command: command_name = interaction.command.qualified_name diff --git a/app/config.py b/app/config.py index c9b79a9..18a4bc1 100644 --- a/app/config.py +++ b/app/config.py @@ -17,6 +17,7 @@ def __init__(self): load_dotenv(dotenv_path, override=True) self.ENVIRONMENT = os.getenv("APPLICATION_ENVIRONMENT") + self.DEBUG = os.getenv("DEBUG") self.get_ssm_configs() if self.is_prod() else self.get_local_configs() def get_local_configs(self): @@ -92,7 +93,7 @@ def is_prod(self) -> bool: return self.ENVIRONMENT.upper() == "PROD" def is_debug(self) -> bool: - return self.ENVIRONMENT.upper() == "TEST" + return self.DEBUG.lower() == "true" def run_local_webhook_api(self) -> bool: return self.RUN_LOCAL_WEBHOOK_API.lower() == "true" diff --git a/app/constants.py b/app/constants.py index c63e6f5..8fcb354 100644 --- a/app/constants.py +++ b/app/constants.py @@ -198,3 +198,15 @@ class LogTypes: class Emojis: FRISBEE_EMOJI: Final[str] = ":flying_disc:" EDIT_EMOJI: Final[str] = ":pencil:" + +default_allowed_links: Final[Dict[str, str]] = { + "facebook": "https://facebook.com", + "instagram": "https://instagram.com", + "twitter": "https://twitter.com", + "twitch": "https://twitch.tv", + "youtube": "https://youtube.com", + "discord": "https://discord.gg", + "spotify": "https://open.spotify.com", + "tiktok": "https://tiktok.com", + "reddit": "https://reddit.com", +} diff --git a/app/languages/form/block_links.yml b/app/languages/form/block_links.yml index 0a6d9ec..e694d4d 100644 --- a/app/languages/form/block_links.yml +++ b/app/languages/form/block_links.yml @@ -60,6 +60,7 @@ steps: - "Twitch" - "Tiktok" - "Reddit" + - "Discord" - action: modal key: answer diff --git a/app/services/block_links.py b/app/services/block_links.py index 5df3b7d..9bfa7b6 100644 --- a/app/services/block_links.py +++ b/app/services/block_links.py @@ -1,13 +1,34 @@ +from typing import List + import discord from app.constants import Commands as constants +from app.constants import default_allowed_links from app.services import cache from app.services.moderations import ( send_command_form_message, send_command_manager_message, ) -from .utils import check_message_has_link, check_two_lists_intersection, list_roles_id +from .utils import check_two_lists_intersection, get_message_links, list_roles_id + + +def remove_allowed_links(links: List[str], allowed_links: List[str]) -> List[str]: + allowed_link_list = [] + + for allowed_link in allowed_links: + allowed_link_list.append(default_allowed_links[allowed_link.lower()]) + + for link in links: + link = link.replace("www.", "") + + if link.endswith("/"): + link = link[:-1] + + if link in allowed_link_list: + links.remove(link) + + return links async def check_message(guild_id: str, message: discord.Message) -> None: @@ -27,11 +48,15 @@ async def check_message(guild_id: str, message: discord.Message) -> None: allowed_chats = cogs[constants.BLOCK_LINKS_ALLOWED_CHATS_KEY].get("values") allowed_links = cogs[constants.BLOCK_LINKS_ALLOWED_LINKS_KEY] + + if isinstance(allowed_links, str): + allowed_links = [allowed_links] - message_has_link = check_message_has_link(message, allowed_links) + message_links = get_message_links(message.content) + parsed_links = remove_allowed_links(message_links, allowed_links) message_chat = str(message.channel.id) - if message_has_link and message_chat not in allowed_chats: + if parsed_links and message_chat not in allowed_chats: await message.delete() await message.channel.send( cogs[constants.BLOCK_LINKS_ANSWER_KEY], delete_after=5 @@ -39,7 +64,9 @@ async def check_message(guild_id: str, message: discord.Message) -> None: async def manager(interaction: discord.Interaction, guild_id: str) -> None: - cogs = cache.get_cog_data_or_populate(guild_id, constants.BLOCK_LINKS_KEY, manager=True) + cogs = cache.get_cog_data_or_populate( + guild_id, constants.BLOCK_LINKS_KEY, manager=True + ) if cogs == None: return await send_command_form_message(interaction, constants.BLOCK_LINKS_KEY) diff --git a/app/services/utils.py b/app/services/utils.py index c49cdf9..9d0a443 100644 --- a/app/services/utils.py +++ b/app/services/utils.py @@ -19,15 +19,8 @@ from app.constants import LogTypes as logconstants -def check_message_has_link(message: str, allowed_links: List[str]) -> List[str]: - links = [ - link - for link in findall( - "http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+", - message.content.lower(), - ) - if not any(allowed.lower() in link.lower() for allowed in allowed_links) - ] +def get_message_links(message: str) -> List[str]: + links = findall(r"http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*(),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+", message.lower()) return links @@ -141,17 +134,19 @@ async def wrapper(self, interaction: discord.Interaction, *args, **kwargs): return decorator -def parse_settings_with_database_values(cog_data: List[Dict[str, str]], form_steps: Dict[str, str], locale: str) -> List[Dict[str, str]]: +def parse_settings_with_database_values(cog_data: Dict[str, str], form_steps: Dict[str, str], locale: str) -> List[Dict[str, str]]: response = [] cogs_title = parse_form_steps_titles(form_steps, locale) for cog_key, value in cog_data.items(): - if cogs_title.get(cog_key): - if value["style"] == "composition": - value = parse_settings_with_database_values_composition(form_steps, locale, value["values"]) - response.append({"title": cogs_title[cog_key], "value": value, "style": "composition"}) - else: - response.append({"title": cogs_title[cog_key], "value": value}) + if not cogs_title.get(cog_key): + continue + + if isinstance(value, dict) and value.get("style") == "composition": + value = parse_settings_with_database_values_composition(form_steps, locale, value["values"]) + response.append({"title": cogs_title[cog_key], "value": value, "style": "composition"}) + else: + response.append({"title": cogs_title[cog_key], "value": value}) return response