-
Notifications
You must be signed in to change notification settings - Fork 10
Optional cog "simplewriter" that enforces xkcd's simple writer in a text channel #367
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 18 commits
2546a86
a78a749
23769b7
eb04125
4d83980
1dad752
c21699c
acb73fa
1cbf577
df4686c
3da7740
967d3c3
210e310
778b4ce
e03260a
a9d3462
09a4b99
c8aae0b
33b7c35
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| # | ||
| # cogs/optional/simplewriter/__init__.py | ||
| # | ||
| # futaba - A Discord Mod bot for the Programming server | ||
| # Copyright (c) 2017-2020 Jake Richardson, Ammon Smith, jackylam5 | ||
| # | ||
| # futaba is available free of charge under the terms of the MIT | ||
| # License. You are free to redistribute and/or modify it under those | ||
| # terms. It is distributed in the hopes that it will be useful, but | ||
| # WITHOUT ANY WARRANTY. See the LICENSE file for more details. | ||
| # | ||
|
|
||
| from .core import SimplewriterCog | ||
|
|
||
|
|
||
| def setup(bot): | ||
| setup_simplewriter(bot) | ||
|
|
||
|
|
||
| def setup_simplewriter(bot): | ||
| cog = SimplewriterCog(bot) | ||
| bot.add_listener(cog.on_message, "on_message") | ||
| bot.add_listener(cog.on_message_edit, "on_message_edit") | ||
| bot.add_cog(cog) | ||
|
|
||
|
|
||
| def teardown(bot): | ||
| teardown_simplewriter(bot) | ||
|
|
||
|
|
||
| def teardown_simplewriter(bot): | ||
| bot.remove_cog(SimplewriterCog.__name__) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| # | ||
| # cogs/optional/simplewriter/core.py | ||
| # | ||
| # futaba - A Discord Mod bot for the Programming server | ||
| # Copyright (c) 2017-2020 Jake Richardson, Ammon Smith, jackylam5 | ||
| # | ||
| # futaba is available free of charge under the terms of the MIT | ||
| # License. You are free to redistribute and/or modify it under those | ||
| # terms. It is distributed in the hopes that it will be useful, but | ||
| # WITHOUT ANY WARRANTY. See the LICENSE file for more details. | ||
| # | ||
|
|
||
| """ | ||
| A thing that lets you write stuff in one word box, but only if it's made up of | ||
| the first ten hundred most used words of the language. | ||
|
|
||
| (https://xkcd.com/simplewriter) | ||
| """ | ||
|
|
||
| from futaba.utils import async_partial | ||
| from futaba.cogs.abc import AbstractCog | ||
|
|
||
| from .listeners import on_message, on_message_edit | ||
|
|
||
|
|
||
| class SimplewriterCog(AbstractCog): | ||
| __slots__ = ("journal", "on_message", "on_message_edit", "channel_id") | ||
|
|
||
| def __init__(self, bot): | ||
| super().__init__(bot) | ||
| self.journal = bot.get_broadcaster("/simplewriter") | ||
| self.on_message = async_partial(on_message, self) | ||
| self.on_message_edit = async_partial(on_message_edit, self) | ||
| self.channel_id = int(bot.config.optional_cogs["simplewriter"]["channel-id"]) | ||
|
|
||
| def setup(self): | ||
| pass | ||
|
|
||
| def cog_unload(self): | ||
| self.bot.remove_listener(self.on_message, "on_message") | ||
| self.bot.remove_listener(self.on_message_edit, "on_message_edit") | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| # | ||
| # cogs/optional/simplewriter/listeners.py | ||
| # | ||
| # futaba - A Discord Mod bot for the Programming server | ||
| # Copyright (c) 2017-2020 Jake Richardson, Ammon Smith, jackylam5 | ||
| # | ||
| # futaba is available free of charge under the terms of the MIT | ||
| # License. You are free to redistribute and/or modify it under those | ||
| # terms. It is distributed in the hopes that it will be useful, but | ||
| # WITHOUT ANY WARRANTY. See the LICENSE file for more details. | ||
| # | ||
|
|
||
| """ | ||
| discord.py listeners for simplewriter | ||
| """ | ||
|
|
||
| from .simple_filter import simple_filter | ||
|
|
||
| __all__ = ["on_message", "on_message_edit"] | ||
|
|
||
|
|
||
| async def on_message(cog, message): | ||
| await simple_filter(cog, message) | ||
|
|
||
|
|
||
| async def on_message_edit(cog, before, after): | ||
| if after: | ||
| await simple_filter(cog, after) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| # | ||
| # cogs/optional/simplewriter/simple_filter.py | ||
| # | ||
| # futaba - A Discord Mod bot for the Programming server | ||
| # Copyright (c) 2017-2020 Jake Richardson, Ammon Smith, jackylam5 | ||
| # | ||
| # futaba is available free of charge under the terms of the MIT | ||
| # License. You are free to redistribute and/or modify it under those | ||
| # terms. It is distributed in the hopes that it will be useful, but | ||
| # WITHOUT ANY WARRANTY. See the LICENSE file for more details. | ||
| # | ||
|
|
||
| """ | ||
| Filters messages through the allowed wordlist, deleting unallowed words. | ||
| """ | ||
|
|
||
| import logging | ||
| import re | ||
| from datetime import datetime | ||
|
|
||
| import discord | ||
| from discord import MessageType | ||
|
|
||
| from futaba.utils import plural | ||
|
|
||
| from .words import core_words_list | ||
|
|
||
| logger = logging.getLogger(__name__) | ||
| REGEX_SPLIT = r"[^a-zA-Z0-9_']" | ||
|
|
||
| __all__ = ["simple_filter"] | ||
|
|
||
|
|
||
| async def simple_filter(cog, message): | ||
| """ | ||
| Filter Discord messages for the simplewriter channel | ||
| """ | ||
|
|
||
| # Message is in designated channel | ||
| if message.channel.id != cog.channel_id: | ||
| return | ||
|
|
||
| # Don't filter bot messages | ||
| if message.author.id == cog.bot.user.id: | ||
| return | ||
|
|
||
| # Not a special message type | ||
| if message.type != MessageType.default: | ||
| return | ||
|
|
||
| # Make sure we actually can remove this message | ||
| if not message.channel.permissions_for(message.guild.me).manage_messages: | ||
| return | ||
|
|
||
| logger.debug( | ||
| "Checking message id %d (by '%s' (%d)) against simplewriter core words list", | ||
| message.id, | ||
| message.author.name, | ||
| message.author.id, | ||
| ) | ||
|
|
||
| split = re.split(REGEX_SPLIT, message.content) | ||
| bad_words = [] | ||
| for word in split: | ||
| cleaned = word.strip() | ||
| if not cleaned: | ||
| continue | ||
| if not cleaned.lower() in core_words_list: | ||
| if not cleaned in bad_words: | ||
| try: # test to see if input is a number | ||
| int(cleaned) | ||
| except ValueError: | ||
| bad_words.append(cleaned) | ||
|
|
||
| if len(bad_words) > 0: | ||
| await message.delete() | ||
|
|
||
| content = ( | ||
| f"Message id {message.id} (by '{message.author.name}' ({message.author.id})) filtered from " | ||
| "simplewriter channel" | ||
| ) | ||
| cog.journal.send( | ||
| "message/delete", | ||
| message.guild, | ||
| content, | ||
| icon="delete", | ||
| channel=message.channel, | ||
| message=message, | ||
| ) | ||
|
|
||
| bad_words_plural = plural(len(bad_words)) | ||
| article = "some" if len(bad_words) > 1 else "a" | ||
|
|
||
| help_embed = discord.Embed() | ||
| help_embed.color = discord.Color.red() | ||
| help_embed.title = f"You used {article} less simple word{bad_words_plural}." | ||
| help_embed.description = ( | ||
| f"Your message in {message.channel.mention} has been removed.\n" | ||
| "You can use [xkcd's simplewriter](https://xkcd.com/simplewriter) " | ||
| "to see what words are valid in this channel." | ||
| ) | ||
| help_embed.timestamp = datetime.now() | ||
| help_embed.add_field(name="Full message", value=message.content) | ||
| help_embed.add_field( | ||
| name=f"Bad word{bad_words_plural}", value=", ".join(bad_words) | ||
| ) | ||
| help_embed.set_footer(text=message.id) | ||
|
|
||
| dm_channel = message.author.dm_channel or await message.author.create_dm() | ||
| await dm_channel.send(embed=help_embed) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| # | ||
| # cogs/optional/simplewriter/words/__init__.py | ||
| # | ||
| # futaba - A Discord Mod bot for the Programming server | ||
| # Copyright (c) 2017-2020 Jake Richardson, Ammon Smith, jackylam5 | ||
| # | ||
| # futaba is available free of charge under the terms of the MIT | ||
| # License. You are free to redistribute and/or modify it under those | ||
| # terms. It is distributed in the hopes that it will be useful, but | ||
| # WITHOUT ANY WARRANTY. See the LICENSE file for more details. | ||
| # | ||
|
|
||
| __all__ = ["core_words_list"] | ||
|
|
||
| from .words import core_words_list |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| # | ||
| # cogs/optional/simplewriter/words/words.py | ||
| # | ||
| # futaba - A Discord Mod bot for the Programming server | ||
| # Copyright (c) 2017-2020 Jake Richardson, Ammon Smith, jackylam5 | ||
| # | ||
| # futaba is available free of charge under the terms of the MIT | ||
| # License. You are free to redistribute and/or modify it under those | ||
| # terms. It is distributed in the hopes that it will be useful, but | ||
| # WITHOUT ANY WARRANTY. See the LICENSE file for more details. | ||
| # | ||
|
|
||
| import os | ||
|
|
||
| __all__ = ["core_words_list"] | ||
|
|
||
| core_words_list = [] | ||
| core_words_list_path = os.path.join(os.path.dirname(__file__), "core_words_list.txt") | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can't always expect this directory to be writeable, it might be in
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is for a read operation of a text file in the same directory as this source file. The text file will not change and is not configurable through means other than a commit due to the static nature of the source. |
||
|
|
||
| with open(core_words_list_path, "r") as f: | ||
| core_words_list = f.read().split(",") | ||
Uh oh!
There was an error while loading. Please reload this page.