initial commit.
This commit is contained in:
commit
df167f832c
48
README
Normal file
48
README
Normal file
@ -0,0 +1,48 @@
|
||||
diakonos
|
||||
========
|
||||
diakonos is a repository of in-house cogs for self-hosted RedBot instances. It gets its name from the Greek word for "deacon", "διάκονος."
|
||||
|
||||
Requirements
|
||||
------------
|
||||
diakonos has been tested and modified to ensure compatibility with:
|
||||
- Python 3.11
|
||||
- Red-DiscordBot 3.5.5
|
||||
|
||||
diakonos requires the following Python packages:
|
||||
- feedparser
|
||||
- beautifulsoup4
|
||||
|
||||
Installation
|
||||
------------
|
||||
For feature parity with our instances, the following internal RedBot cogs need to be enabled with the following command:
|
||||
```
|
||||
.load admin alias cleanup customcom downloader economy general mod modlog mutes trivia warnings
|
||||
```
|
||||
|
||||
The following cogs from the following sources:
|
||||
- `avatar` from https://github.com/skeith/MayuYukirin
|
||||
- `compliment` from https://github.com/TrustyJAID/Trusty-cogs
|
||||
- `dictionary` from https://github.com/aikaterna/aikaterna-cogs
|
||||
- `disboardreminder` from https://github.com/phenom4n4n/phen-cogs
|
||||
- `errorlogs` from https://github.com/Tobotimus/Tobo-Cogs
|
||||
- `extendedmodlog` from https://github.com/TrustyJAID/Trusty-cogs
|
||||
- `forcemention` from https://github.com/phenom4n4n/phen-cogs
|
||||
- `hangman` from https://github.com/Flame442/FlameCogs
|
||||
- `hunting` from https://github.com/vertyco/vrt-cogs
|
||||
- `levelup` from https://github.com/vertyco/vrt-cogs
|
||||
- `msgvote` from https://github.com/flapjax/FlapJack-Cogs
|
||||
- `reactpoll` from https://github.com/flapjax/FlapJack-Cogs
|
||||
- `rekt` from https://github.com/TrustyJAID/Trusty-cogs
|
||||
- `remindme` from https://github.com/PhasecoreX/PCXCogs
|
||||
- `say` from https://github.com/laggron42/Laggrons-Dumb-Cogs
|
||||
- `seen` from https://github.com/aikaterna/aikaterna-cogs
|
||||
- `smartreact` from https://github.com/flapjax/FlapJack-Cogs
|
||||
- `starboard` from https://github.com/TrustyJAID/Trusty-cogs
|
||||
- `userinfo` from https://github.com/flaree/flare-cogs
|
||||
- `uwu` from https://github.com/PhasecoreX/PCXCogs
|
||||
- `wikipedia` from https://github.com/PhasecoreX/PCXCogs
|
||||
|
||||
For the remaining cogs, provided within this repository:
|
||||
```
|
||||
.load autorole cherubim reactrole rss stickyroles
|
||||
```
|
19
autorole/LICENSE
Normal file
19
autorole/LICENSE
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2017 TrustyJAID
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
14
autorole/__init__.py
Normal file
14
autorole/__init__.py
Normal file
@ -0,0 +1,14 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from .autorole import Autorole
|
||||
|
||||
with open(Path(__file__).parent / "info.json") as fp:
|
||||
__red_end_user_data_statement__ = json.load(fp)["end_user_data_statement"]
|
||||
|
||||
|
||||
def setup(bot):
|
||||
n = Autorole(bot)
|
||||
bot.add_cog(n)
|
||||
# bot.add_listener(n._roler, "on_member_join")
|
||||
# bot.add_listener(n._verify_json, "on_error")
|
470
autorole/autorole.py
Normal file
470
autorole/autorole.py
Normal file
@ -0,0 +1,470 @@
|
||||
import logging
|
||||
import random
|
||||
import string
|
||||
from typing import Optional, cast
|
||||
|
||||
import discord
|
||||
from redbot import VersionInfo, version_info
|
||||
from redbot.core import Config, checks, commands
|
||||
from redbot.core.i18n import Translator, cog_i18n
|
||||
|
||||
default_settings = {
|
||||
"ENABLED": False,
|
||||
"ROLE": [],
|
||||
"AGREE_CHANNEL": None,
|
||||
"AGREE_MSG": None,
|
||||
"AGREE_KEY": None,
|
||||
"DELETE_KEY": False,
|
||||
}
|
||||
|
||||
log = logging.getLogger("red.Trusty-cogs.autorole")
|
||||
|
||||
_ = Translator("Autorole", __file__)
|
||||
listener = getattr(commands.Cog, "listener", None) # red 3.0 backwards compatibility support
|
||||
|
||||
if listener is None: # thanks Sinbad
|
||||
|
||||
def listener(name=None):
|
||||
return lambda x: x
|
||||
|
||||
|
||||
@cog_i18n(_)
|
||||
class Autorole(commands.Cog):
|
||||
"""
|
||||
Autorole commands. Rewritten for V3 from
|
||||
https://github.com/Lunar-Dust/Dusty-Cogs/blob/master/autorole/autorole.py
|
||||
"""
|
||||
|
||||
__author__ = ["Lunar-Dust", "TrustyJAID"]
|
||||
__version__ = "1.3.2"
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
self.config = Config.get_conf(self, 45463543548)
|
||||
self.config.register_guild(**default_settings)
|
||||
self.users = {}
|
||||
|
||||
def format_help_for_context(self, ctx: commands.Context) -> str:
|
||||
"""
|
||||
Thanks Sinbad!
|
||||
"""
|
||||
pre_processed = super().format_help_for_context(ctx)
|
||||
return f"{pre_processed}\n\nCog Version: {self.__version__}"
|
||||
|
||||
async def red_delete_data_for_user(self, **kwargs):
|
||||
"""
|
||||
Nothing to delete
|
||||
"""
|
||||
return
|
||||
|
||||
async def _no_perms(self, channel: Optional[discord.TextChannel] = None) -> None:
|
||||
m = _(
|
||||
"It appears that you haven't given this "
|
||||
"bot enough permissions to use autorole. "
|
||||
'The bot requires the "Manage Roles" and '
|
||||
'the "Manage Messages" permissions in'
|
||||
"order to use autorole. You can change the "
|
||||
'permissions in the "Roles" tab of the '
|
||||
"guild settings."
|
||||
)
|
||||
if channel is None:
|
||||
log.info(m)
|
||||
return
|
||||
if channel.permissions_for(channel.guild.me).send_messages:
|
||||
await channel.send(m)
|
||||
else:
|
||||
log.info(m + _("\n I also don't have permission to speak in #") + channel.name)
|
||||
|
||||
async def get_colour(self, channel: discord.TextChannel) -> discord.Colour:
|
||||
try:
|
||||
return await self.bot.get_embed_colour(channel)
|
||||
except AttributeError:
|
||||
if await self.bot.db.guild(channel.guild).use_bot_color():
|
||||
return channel.guild.me.colour
|
||||
else:
|
||||
return await self.bot.db.color()
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_message(self, message: discord.Message) -> None:
|
||||
guild = message.guild
|
||||
if not guild:
|
||||
return
|
||||
|
||||
if version_info >= VersionInfo.from_str("3.4.0"):
|
||||
if await self.bot.cog_disabled_in_guild(self, guild):
|
||||
return
|
||||
user = cast(discord.Member, message.author)
|
||||
channel = message.channel
|
||||
agree_channel = cast(
|
||||
discord.TextChannel, guild.get_channel(await self.config.guild(guild).AGREE_CHANNEL())
|
||||
)
|
||||
if guild is None:
|
||||
return
|
||||
if agree_channel is None:
|
||||
return
|
||||
if channel.id != agree_channel.id:
|
||||
return
|
||||
if user.bot:
|
||||
return
|
||||
|
||||
if user.id in self.users:
|
||||
if not guild.me.guild_permissions.manage_roles:
|
||||
await self._no_perms(agree_channel)
|
||||
return
|
||||
if self.users[user.id]["key"].lower() in message.content.lower():
|
||||
perms = agree_channel.permissions_for(guild.me)
|
||||
roles_id = await self.config.guild(guild).ROLE()
|
||||
roles = [role for role in guild.roles if role.id in roles_id]
|
||||
for role in roles:
|
||||
await user.add_roles(role, reason=_("Agreed to the rules"))
|
||||
if perms.manage_messages and await self.config.guild(guild).DELETE_KEY():
|
||||
try:
|
||||
await message.delete()
|
||||
except Exception:
|
||||
pass
|
||||
if self.users[user.id]["message"].guild:
|
||||
try:
|
||||
await self.users[user.id]["message"].delete()
|
||||
except Exception:
|
||||
pass
|
||||
elif perms.add_reactions:
|
||||
await message.add_reaction("✅")
|
||||
del self.users[user.id]
|
||||
|
||||
async def _agree_maker(self, member: discord.Member) -> None:
|
||||
guild = member.guild
|
||||
self.last_guild = guild
|
||||
# await self._verify_json(None)
|
||||
key = await self.config.guild(guild).AGREE_KEY()
|
||||
if key is None:
|
||||
key = "".join(random.choice(string.ascii_uppercase + string.digits) for _ in range(6))
|
||||
# <3 Stackoverflow http://stackoverflow.com/questions/2257441/random-string-generation-with-upper-case-letters-and-digits-in-python/23728630#23728630
|
||||
|
||||
ch = cast(
|
||||
discord.TextChannel, guild.get_channel(await self.config.guild(guild).AGREE_CHANNEL())
|
||||
)
|
||||
msg = await self.config.guild(guild).AGREE_MSG()
|
||||
if msg is None:
|
||||
msg = "{mention} please enter {key} in {channel}"
|
||||
try:
|
||||
msg = msg.format(
|
||||
key=key,
|
||||
member=member,
|
||||
name=member.name,
|
||||
mention=member.mention,
|
||||
guild=guild.name,
|
||||
channel=ch.mention,
|
||||
)
|
||||
except Exception:
|
||||
log.error("Error formatting agreement message", exc_info=True)
|
||||
|
||||
try:
|
||||
msg = await member.send(msg)
|
||||
except discord.Forbidden:
|
||||
msg = await ch.send(msg)
|
||||
except discord.HTTPException:
|
||||
return
|
||||
self.users[member.id] = {"key": key, "message": msg}
|
||||
|
||||
async def _auto_give(self, member: discord.Member) -> None:
|
||||
guild = member.guild
|
||||
roles_id = await self.config.guild(guild).ROLE()
|
||||
roles = [role for role in guild.roles if role.id in roles_id]
|
||||
if not guild.me.guild_permissions.manage_roles:
|
||||
await self._no_perms()
|
||||
return
|
||||
for role in roles:
|
||||
await member.add_roles(role, reason=_("Joined the server"))
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_member_join(self, member: discord.Member) -> None:
|
||||
if "h0nde" in member.name or "h0nda" in member.name:
|
||||
await member.ban(reason="Anti-spam measure.")
|
||||
guild = member.guild
|
||||
if await self.config.guild(guild).ENABLED():
|
||||
if await self.config.guild(guild).AGREE_CHANNEL() is not None:
|
||||
await self._agree_maker(member)
|
||||
elif member.guild.name != "BibleBot": # Immediately give the new user the role
|
||||
await self._auto_give(member)
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_member_update(self, before: discord.Member, after: discord.Member) -> None:
|
||||
if before.guild.name == "BibleBot":
|
||||
if before.pending == True and after.pending == False:
|
||||
await after.add_roles(before.guild.get_role(366901317924290562))
|
||||
|
||||
@commands.guild_only()
|
||||
@commands.group(name="autorole")
|
||||
@commands.bot_has_permissions(manage_roles=True)
|
||||
async def autorole(self, ctx: commands.Context) -> None:
|
||||
"""
|
||||
Change settings for autorole
|
||||
|
||||
Requires the manage roles permission
|
||||
"""
|
||||
pass
|
||||
|
||||
@autorole.command(name="info")
|
||||
async def autorole_info(self, ctx: commands.Context) -> None:
|
||||
"""
|
||||
Display current autorole info
|
||||
"""
|
||||
guild = ctx.message.guild
|
||||
enabled = await self.config.guild(guild).ENABLED()
|
||||
roles = await self.config.guild(guild).ROLE()
|
||||
msg = await self.config.guild(guild).AGREE_MSG()
|
||||
key = await self.config.guild(guild).AGREE_KEY()
|
||||
ch_id = await self.config.guild(guild).AGREE_CHANNEL()
|
||||
delete = await self.config.guild(guild).DELETE_KEY()
|
||||
channel = guild.get_channel(ch_id)
|
||||
chn_name = channel.name if channel is not None else "None"
|
||||
chn_mention = channel.mention if channel is not None else "None"
|
||||
role_name_str = ", ".join(role.mention for role in guild.roles if role.id in roles)
|
||||
if not role_name_str:
|
||||
role_name_str = "None"
|
||||
if ctx.channel.permissions_for(ctx.me).embed_links:
|
||||
embed = discord.Embed(colour=await self.get_colour(ctx.channel))
|
||||
embed.set_author(name=_("Autorole settings for ") + guild.name)
|
||||
embed.add_field(name=_("Current autorole state: "), value=str(enabled))
|
||||
embed.add_field(name=_("Current Roles: "), value=str(role_name_str))
|
||||
if msg:
|
||||
embed.add_field(name=_("Agreement message: "), value=str(msg))
|
||||
if key:
|
||||
embed.add_field(name=_("Agreement key: "), value=str(key))
|
||||
if channel:
|
||||
embed.add_field(name=_("Agreement channel: "), value=str(chn_mention))
|
||||
await ctx.send(embed=embed)
|
||||
else:
|
||||
send_msg = (
|
||||
"```"
|
||||
+ _("Current autorole state: ")
|
||||
+ f"{enabled}\n"
|
||||
+ _("Current Roles: ")
|
||||
+ f"{role_name_str}\n"
|
||||
+ _("Agreement message: ")
|
||||
+ f"{msg}\n"
|
||||
+ _("Agreement key: ")
|
||||
+ f"{key}\n"
|
||||
+ _("Delete Agreement: ")
|
||||
+ f"{delete}\n"
|
||||
+ _("Agreement channel: ")
|
||||
+ f"{chn_name}"
|
||||
+ "```"
|
||||
)
|
||||
await ctx.send(send_msg)
|
||||
|
||||
@autorole.command()
|
||||
@checks.admin_or_permissions(manage_roles=True)
|
||||
async def toggle(self, ctx: commands.Context) -> None:
|
||||
"""
|
||||
Enables/Disables autorole
|
||||
"""
|
||||
guild = ctx.message.guild
|
||||
if await self.config.guild(guild).ROLE() is None:
|
||||
msg = _("You haven't set a " "role to give to new users!")
|
||||
await ctx.send(msg)
|
||||
else:
|
||||
if await self.config.guild(guild).ENABLED():
|
||||
await self.config.guild(guild).ENABLED.set(False)
|
||||
await ctx.send(_("Autorole is now disabled."))
|
||||
else:
|
||||
await self.config.guild(guild).ENABLED.set(True)
|
||||
await ctx.send(_("Autorole is now enabled."))
|
||||
|
||||
@autorole.command(name="add", aliases=["role"])
|
||||
@checks.admin_or_permissions(manage_roles=True)
|
||||
async def role(self, ctx: commands.Context, *, role: discord.Role) -> None:
|
||||
"""
|
||||
Add a role for autorole to assign.
|
||||
|
||||
You can use this command multiple times to add multiple roles.
|
||||
"""
|
||||
guild = ctx.message.guild
|
||||
roles = await self.config.guild(guild).ROLE()
|
||||
if ctx.author.top_role < role:
|
||||
msg = _(
|
||||
" is higher than your highest role. "
|
||||
"You can't assign autoroles higher than your own"
|
||||
)
|
||||
await ctx.send(role.name + msg)
|
||||
if role.id in roles:
|
||||
await ctx.send(role.name + _(" is already in the autorole list."))
|
||||
return
|
||||
if guild.me.top_role < role:
|
||||
msg = _(" is higher than my highest role" " in the Discord hierarchy.")
|
||||
await ctx.send(role.name + msg)
|
||||
return
|
||||
roles.append(role.id)
|
||||
await self.config.guild(guild).ROLE.set(roles)
|
||||
await ctx.send(role.name + _(" role added to the autorole."))
|
||||
|
||||
@autorole.command()
|
||||
@checks.admin_or_permissions(manage_roles=True)
|
||||
async def remove(self, ctx: commands.Context, *, role: discord.Role) -> None:
|
||||
"""
|
||||
Remove a role from the autorole.
|
||||
"""
|
||||
guild = ctx.message.guild
|
||||
roles = await self.config.guild(guild).ROLE()
|
||||
if role.id not in roles:
|
||||
await ctx.send(role.name + _(" is not in the autorole list."))
|
||||
return
|
||||
roles.remove(role.id)
|
||||
await self.config.guild(guild).ROLE.set(roles)
|
||||
await ctx.send(role.name + _(" role removed from the autorole."))
|
||||
|
||||
@autorole.group()
|
||||
@checks.admin_or_permissions(manage_roles=True)
|
||||
async def agreement(self, ctx: commands.Context) -> None:
|
||||
"""
|
||||
Set the channel and message that will be used for accepting the rules.
|
||||
|
||||
`channel` is the channel they must type the key in to get the role.
|
||||
`key` is the message they must type to gain access and must be in quotes.
|
||||
`msg` is the message DM'd to them when they join.
|
||||
|
||||
`{key}` must be included in the message so a user knows what to type in the channel.
|
||||
|
||||
Optional additions to the message include:
|
||||
`{channel}` Mentions the channel where they must include the agreement message.
|
||||
`{mention}` Mentions the user incase they have DM permissions turned off this should be used.
|
||||
`{name}` Says the member name if you don't want to ping them.
|
||||
`{guild}` Says the servers current name.
|
||||
|
||||
Entering nothing will disable these.
|
||||
"""
|
||||
pass
|
||||
|
||||
@agreement.command(name="channel")
|
||||
@checks.admin_or_permissions(manage_roles=True)
|
||||
async def set_agreement_channel(
|
||||
self, ctx: commands.Context, channel: discord.TextChannel = None
|
||||
) -> None:
|
||||
"""
|
||||
Set the agreement channel
|
||||
|
||||
Entering nothing will clear this.
|
||||
"""
|
||||
guild = ctx.message.guild
|
||||
if await self.config.guild(guild).ROLE() == []:
|
||||
await ctx.send(_("No roles have been set for autorole."))
|
||||
return
|
||||
if not await self.config.guild(guild).ENABLED():
|
||||
await ctx.send(_("Autorole has been disabled, enable it first."))
|
||||
return
|
||||
if channel is None:
|
||||
await self.config.guild(guild).AGREE_CHANNEL.set(None)
|
||||
await ctx.send(_("Agreement channel cleared"))
|
||||
else:
|
||||
await self.config.guild(guild).AGREE_CHANNEL.set(channel.id)
|
||||
await ctx.send(_("Agreement channel set to ") + channel.mention)
|
||||
|
||||
@agreement.command(name="delete")
|
||||
@checks.admin_or_permissions(manage_roles=True)
|
||||
async def set_agreement_delete(self, ctx: commands.Context) -> None:
|
||||
"""
|
||||
Toggle automatically deleting the agreement message.
|
||||
"""
|
||||
delete_key = await self.config.guild(ctx.guild).DELETE_KEY()
|
||||
await self.config.guild(ctx.guild).DELETE_KEY.set(not delete_key)
|
||||
if delete_key:
|
||||
await ctx.send(_("No longer automatically deleting agreement key."))
|
||||
else:
|
||||
await ctx.send(_("Automatically deleting agreement key."))
|
||||
|
||||
@agreement.command(name="key")
|
||||
@checks.admin_or_permissions(manage_roles=True)
|
||||
async def set_agreement_key(self, ctx: commands.Context, *, key: str = None) -> None:
|
||||
"""
|
||||
Set the agreement key
|
||||
|
||||
Entering nothing will clear this.
|
||||
"""
|
||||
|
||||
guild = ctx.message.guild
|
||||
if await self.config.guild(guild).ROLE() == []:
|
||||
await ctx.send(_("No roles have been set for autorole."))
|
||||
return
|
||||
if not await self.config.guild(guild).ENABLED():
|
||||
await ctx.send(_("Autorole has been disabled, enable it first."))
|
||||
return
|
||||
if key is None:
|
||||
await self.config.guild(guild).AGREE_KEY.set(None)
|
||||
await ctx.send(_("Agreement key cleared"))
|
||||
else:
|
||||
await self.config.guild(guild).AGREE_KEY.set(key)
|
||||
await ctx.send(_("Agreement key set to ") + key)
|
||||
|
||||
@agreement.command(name="message", aliases=["msg"])
|
||||
@checks.admin_or_permissions(manage_roles=True)
|
||||
async def set_agreement_msg(self, ctx: commands.Context, *, message: str = None) -> None:
|
||||
"""
|
||||
Set the agreement message
|
||||
`{key}` must be included in the message so a user knows what to type in the channel.
|
||||
|
||||
Optional additions to the message include:
|
||||
`{channel}` Mentions the channel where they must include the agreement message.
|
||||
`{mention}` Mentions the user incase they have DM permissions turned off this should be used.
|
||||
`{name}` Says the member name if you don't want to ping them.
|
||||
`{guild}` Says the servers current name.
|
||||
|
||||
Entering nothing will clear this.
|
||||
"""
|
||||
guild = ctx.message.guild
|
||||
if await self.config.guild(guild).ROLE() == []:
|
||||
await ctx.send(_("No roles have been set for autorole."))
|
||||
return
|
||||
if not await self.config.guild(guild).ENABLED():
|
||||
await ctx.send(_("Autorole has been disabled, enable it first."))
|
||||
return
|
||||
if message is None:
|
||||
await self.config.guild(guild).AGREE_MSG.set(None)
|
||||
await ctx.send(_("Agreement message cleared"))
|
||||
else:
|
||||
await self.config.guild(guild).AGREE_MSG.set(message)
|
||||
await ctx.send(_("Agreement message set to ") + message)
|
||||
|
||||
@agreement.command(name="setup")
|
||||
@checks.admin_or_permissions(manage_roles=True)
|
||||
async def agreement_setup(
|
||||
self,
|
||||
ctx: commands.Context,
|
||||
channel: discord.TextChannel = None,
|
||||
key: str = None,
|
||||
*,
|
||||
msg: str = None,
|
||||
) -> None:
|
||||
"""
|
||||
Set the channel and message that will be used for accepting the rules.
|
||||
|
||||
`channel` is the channel they must type the key in to get the role.
|
||||
`key` is the message they must type to gain access and must be in quotes.
|
||||
`msg` is the message DM'd to them when they join.
|
||||
|
||||
`{key}` must be included in the message so a user knows what to type in the channel.
|
||||
|
||||
Optional additions to the message include:
|
||||
`{channel}` Mentions the channel where they must include the agreement message.
|
||||
`{mention}` Mentions the user incase they have DM permissions turned off this should be used.
|
||||
`{name}` Says the member name if you don't want to ping them.
|
||||
`{guild}` Says the servers current name.
|
||||
|
||||
Entering nothing will disable this.
|
||||
"""
|
||||
guild = ctx.message.guild
|
||||
if await self.config.guild(guild).ROLE() == []:
|
||||
await ctx.send(_("No roles have been set for autorole."))
|
||||
return
|
||||
if not await self.config.guild(guild).ENABLED():
|
||||
await ctx.send(_("Autorole has been disabled, enable it first."))
|
||||
return
|
||||
if channel is None:
|
||||
await self.config.guild(guild).AGREE_CHANNEL.set(None)
|
||||
await self.config.guild(guild).AGREE_MSG.set(None)
|
||||
await self.config.guild(guild).AGREE_KEY.set(None)
|
||||
await ctx.send(_("Agreement channel cleared"))
|
||||
else:
|
||||
await self.config.guild(guild).AGREE_CHANNEL.set(channel.id)
|
||||
await self.config.guild(guild).AGREE_MSG.set(msg)
|
||||
await self.config.guild(guild).AGREE_KEY.set(key)
|
||||
await ctx.send(_("Agreement channel set to ") + channel.mention)
|
27
autorole/info.json
Normal file
27
autorole/info.json
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"author" : [
|
||||
"Lunar Dust",
|
||||
"TrustyJAID"
|
||||
],
|
||||
"description" : "Automatically apply roles when a user joins the server.",
|
||||
"disabled" : false,
|
||||
"end_user_data_statement" : "This cog does not persistently store data or metadata about users.",
|
||||
"hidden" : true,
|
||||
"install_msg" : "Thanks for installing.",
|
||||
"max_bot_version" : "0.0.0",
|
||||
"min_bot_version" : "3.1.8",
|
||||
"min_python_version" : [
|
||||
3,
|
||||
7,
|
||||
2
|
||||
],
|
||||
"name" : "Autorole",
|
||||
"permissions" : [
|
||||
"manage_roles"
|
||||
],
|
||||
"required_cogs" : {},
|
||||
"requirements" : [],
|
||||
"short" : "Automatically apply a role to new users",
|
||||
"tags" : [],
|
||||
"type" : "COG"
|
||||
}
|
249
autorole/locales/messages.pot
Normal file
249
autorole/locales/messages.pot
Normal file
@ -0,0 +1,249 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR ORGANIZATION
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2018-12-20 10:32-0700\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: redgettext 2.1\n"
|
||||
|
||||
|
||||
#: autorole.py:20
|
||||
#, docstring
|
||||
msgid ""
|
||||
"\n"
|
||||
" Autorole commands. Rewritten for V3 from \n"
|
||||
" https://github.com/Lunar-Dust/Dusty-Cogs/blob/master/autorole/autorole.py\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:32
|
||||
msgid "It appears that you haven't given this bot enough permissions to use autorole. The bot requires the \"Manage Roles\" and the \"Manage Messages\" permissions inorder to use autorole. You can change the permissions in the \"Roles\" tab of the guild settings."
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:45
|
||||
msgid ""
|
||||
"\n"
|
||||
" I also don't have permission to speak in #"
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:79
|
||||
msgid "Agreed to the rules"
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:125
|
||||
msgid "Joined the server"
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:139
|
||||
#, docstring
|
||||
msgid ""
|
||||
"\n"
|
||||
" Change settings for autorole\n"
|
||||
"\n"
|
||||
" Requires the manage roles permission\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:159
|
||||
msgid "Autorole settings for "
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:160 autorole.py:172
|
||||
msgid "Current autorole state: "
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:161 autorole.py:173
|
||||
msgid "Current Roles: "
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:163 autorole.py:174
|
||||
msgid "Agreement message: "
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:165 autorole.py:175
|
||||
msgid "Agreement key: "
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:167 autorole.py:176
|
||||
msgid "Agreement channel: "
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:183
|
||||
#, docstring
|
||||
msgid ""
|
||||
"\n"
|
||||
" Enables/Disables autorole\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:188
|
||||
msgid "You haven't set a role to give to new users!"
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:194
|
||||
msgid "Autorole is now disabled."
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:197
|
||||
msgid "Autorole is now enabled."
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:202
|
||||
#, docstring
|
||||
msgid ""
|
||||
"\n"
|
||||
" Add a role for autorole to assign.\n"
|
||||
" \n"
|
||||
" You can use this command multiple times to add multiple roles.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:210
|
||||
msgid " is higher than your highest role. You can't assign autoroles higher than your own"
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:214
|
||||
msgid " is already in the autorole list."
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:217
|
||||
msgid " is higher than my highest role in the Discord hierarchy."
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:223
|
||||
msgid " role added to the autorole."
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:228
|
||||
#, docstring
|
||||
msgid ""
|
||||
"\n"
|
||||
" Remove a role from the autorole.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:234
|
||||
msgid " is not in the autorole list."
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:238
|
||||
msgid " role removed from the autorole."
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:244
|
||||
#, docstring
|
||||
msgid ""
|
||||
"\n"
|
||||
" Set the channel and message that will be used for accepting the rules.\n"
|
||||
" \n"
|
||||
" `channel` is the channel they must type the key in to get the role.\n"
|
||||
" `key` is the message they must type to gain access and must be in quotes.\n"
|
||||
" `msg` is the message DM'd to them when they join.\n"
|
||||
"\n"
|
||||
" `{key}` must be included in the message so a user knows what to type in the channel.\n"
|
||||
" \n"
|
||||
" Optional additions to the message include:\n"
|
||||
" `{channel}` Mentions the channel where they must include the agreement message.\n"
|
||||
" `{mention}` Mentions the user incase they have DM permissions turned off this should be used.\n"
|
||||
" `{name}` Says the member name if you don't want to ping them.\n"
|
||||
" `{guild}` Says the servers current name.\n"
|
||||
" \n"
|
||||
" Entering nothing will disable these.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:269
|
||||
#, docstring
|
||||
msgid ""
|
||||
"\n"
|
||||
" Set the agreement channel\n"
|
||||
"\n"
|
||||
" Entering nothing will clear this.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:276 autorole.py:299 autorole.py:328 autorole.py:367
|
||||
msgid "No roles have been set for autorole."
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:279 autorole.py:302 autorole.py:331 autorole.py:370
|
||||
msgid "Autorole has been disabled, enable it first."
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:283 autorole.py:376
|
||||
msgid "Agreement channel cleared"
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:286 autorole.py:381
|
||||
msgid "Agreement channel set to "
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:291
|
||||
#, docstring
|
||||
msgid ""
|
||||
"\n"
|
||||
" Set the agreement key\n"
|
||||
"\n"
|
||||
" Entering nothing will clear this.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:306
|
||||
msgid "Agreement key cleared"
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:309 autorole.py:338
|
||||
msgid "Agreement key set to "
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:314
|
||||
#, docstring
|
||||
msgid ""
|
||||
"\n"
|
||||
" Set the agreement message\n"
|
||||
" `{key}` must be included in the message so a user knows what to type in the channel.\n"
|
||||
"\n"
|
||||
" Optional additions to the message include:\n"
|
||||
" `{channel}` Mentions the channel where they must include the agreement message.\n"
|
||||
" `{mention}` Mentions the user incase they have DM permissions turned off this should be used.\n"
|
||||
" `{name}` Says the member name if you don't want to ping them.\n"
|
||||
" `{guild}` Says the servers current name.\n"
|
||||
"\n"
|
||||
" Entering nothing will clear this.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:335
|
||||
msgid "Agreement message cleared"
|
||||
msgstr ""
|
||||
|
||||
#: autorole.py:348
|
||||
#, docstring
|
||||
msgid ""
|
||||
"\n"
|
||||
" Set the channel and message that will be used for accepting the rules.\n"
|
||||
" \n"
|
||||
" `channel` is the channel they must type the key in to get the role.\n"
|
||||
" `key` is the message they must type to gain access and must be in quotes.\n"
|
||||
" `msg` is the message DM'd to them when they join.\n"
|
||||
"\n"
|
||||
" `{key}` must be included in the message so a user knows what to type in the channel.\n"
|
||||
" \n"
|
||||
" Optional additions to the message include:\n"
|
||||
" `{channel}` Mentions the channel where they must include the agreement message.\n"
|
||||
" `{mention}` Mentions the user incase they have DM permissions turned off this should be used.\n"
|
||||
" `{name}` Says the member name if you don't want to ping them.\n"
|
||||
" `{guild}` Says the servers current name.\n"
|
||||
" \n"
|
||||
" Entering nothing will disable this.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
19
cherubim/LICENSE
Normal file
19
cherubim/LICENSE
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2019-2023 Seraphim R. Pardee and contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
26
cherubim/__init__.py
Normal file
26
cherubim/__init__.py
Normal file
@ -0,0 +1,26 @@
|
||||
from .autoprayer import AutoPrayer
|
||||
from .suggestionbox import SuggestionBox
|
||||
from .custom_reactions import CustomReactions
|
||||
|
||||
from .entrycontrolresponder import EntryControlResponder
|
||||
|
||||
from .fun import Fun
|
||||
from .standards import Standards
|
||||
|
||||
from ..reactrole.reactrole import ReactRole
|
||||
from .quotes import Quotes
|
||||
|
||||
async def setup(bot):
|
||||
await bot.add_cog(AutoPrayer(bot))
|
||||
await bot.add_cog(SuggestionBox(bot))
|
||||
await bot.add_cog(CustomReactions())
|
||||
|
||||
await bot.add_cog(Fun())
|
||||
await bot.add_cog(Standards(bot))
|
||||
|
||||
await bot.add_cog(ReactRole(bot))
|
||||
|
||||
ecr = EntryControlResponder()
|
||||
await bot.add_cog(ecr)
|
||||
|
||||
await bot.add_cog(Quotes(bot))
|
102
cherubim/autoprayer.py
Normal file
102
cherubim/autoprayer.py
Normal file
@ -0,0 +1,102 @@
|
||||
import asyncio
|
||||
import os
|
||||
from datetime import datetime
|
||||
|
||||
import discord
|
||||
|
||||
from redbot.core import commands, checks, Config
|
||||
|
||||
class AutoPrayer(commands.Cog):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
self.config = Config.get_conf(self, identifier=(3322665 + 2))
|
||||
|
||||
default_guild = {
|
||||
"channels_enabled": [],
|
||||
"duration": 300,
|
||||
"threshold": 3,
|
||||
"bot": False,
|
||||
"pray": "🙏"
|
||||
}
|
||||
|
||||
self.config.register_guild(**default_guild)
|
||||
|
||||
@commands.group(name="autoprayer", pass_context=True, no_pm=True)
|
||||
@checks.admin_or_permissions(manage_guild=True)
|
||||
async def autoprayer(self, ctx):
|
||||
"""autoprayer cog settings"""
|
||||
|
||||
#if ctx.invoked_subcommand is None:
|
||||
# await ctx.send_help()
|
||||
pass
|
||||
|
||||
@autoprayer.command(name="on", pass_context=True, no_pm=True)
|
||||
async def _autoprayer_on(self, ctx):
|
||||
"""Turn on autoprayer mode in the current channel"""
|
||||
guild_group = self.config.guild(ctx.guild)
|
||||
|
||||
async with guild_group.channels_enabled() as channels_enabled:
|
||||
channel = ctx.message.channel
|
||||
if channel.id in channels_enabled:
|
||||
await ctx.send("AutoPrayer is already on in this channel.")
|
||||
else:
|
||||
channels_enabled.append(channel.id)
|
||||
|
||||
await ctx.send("AutoPrayer is now on in this channel.")
|
||||
|
||||
@autoprayer.command(name="off", pass_context=True, no_pm=True)
|
||||
async def _autoprayer_off(self, ctx):
|
||||
"""Turn off autoprayer mode in the current channel"""
|
||||
guild_group = self.config.guild(ctx.guild)
|
||||
|
||||
async with guild_group.channels_enabled() as channels_enabled:
|
||||
channel = ctx.message.channel
|
||||
if channel.id not in channels_enabled:
|
||||
await ctx.send("AutoPrayer is already off in this channel.")
|
||||
else:
|
||||
channels_enabled.remove(channel.id)
|
||||
|
||||
await ctx.send("AutoPrayer is now off in this channel.")
|
||||
|
||||
@autoprayer.command(name="bot", pass_context=True, no_pm=True)
|
||||
async def _autoprayer_bot(self, ctx):
|
||||
"""Turn on/off reactions to bot's own messages"""
|
||||
await self.config.guild(ctx.guild).bot.set(not await self.config.guild(ctx.guild).bot())
|
||||
|
||||
if await self.config.guild(ctx.guild).bot():
|
||||
await ctx.send("Reactions to bot messages turned on.")
|
||||
else:
|
||||
await ctx.send("Reactions to bot messages turned off.")
|
||||
|
||||
def is_command(self, msg):
|
||||
return msg.content.startswith("--")
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_message(self, message):
|
||||
try:
|
||||
guild_group = self.config.guild(message.guild)
|
||||
|
||||
async with guild_group.channels_enabled() as channels_enabled:
|
||||
if message.channel.id not in channels_enabled:
|
||||
return
|
||||
|
||||
is_bot = await guild_group.bot()
|
||||
if message.author == self.bot.user and not is_bot:
|
||||
return
|
||||
|
||||
if self.is_command(message):
|
||||
return
|
||||
|
||||
try:
|
||||
if message.guild.id == 636984073226813449:
|
||||
pray = [x for x in message.guild.emojis if x.name == "lightacandle"][0]
|
||||
elif message.guild.name == "Orthodox Christian Women":
|
||||
pray = [x for x in message.guild.emojis if x.name == "Candle"][0]
|
||||
else:
|
||||
pray = await guild_group.get_raw("pray")
|
||||
await message.add_reaction(pray)
|
||||
except discord.errors.HTTPException:
|
||||
# Implement a non-spammy way to alert users in future
|
||||
pass
|
||||
except:
|
||||
pass
|
182
cherubim/custom_reactions.py
Normal file
182
cherubim/custom_reactions.py
Normal file
@ -0,0 +1,182 @@
|
||||
from redbot.core import commands, checks, Config
|
||||
import discord
|
||||
import json
|
||||
|
||||
def json_to_embed(data):
|
||||
embed = discord.Embed()
|
||||
embed.type = "rich"
|
||||
|
||||
if "title" in data.keys():
|
||||
embed.title = data["title"]
|
||||
|
||||
if "url" in data.keys():
|
||||
embed.url = data["url"]
|
||||
|
||||
if "description" in data.keys():
|
||||
embed.description = data["description"]
|
||||
|
||||
if "color" in data.keys():
|
||||
embed.colour = data["color"]
|
||||
|
||||
if "author" in data.keys():
|
||||
name = "None"
|
||||
url = discord.Embed.Empty
|
||||
icon_url = discord.Embed.Empty
|
||||
|
||||
if "name" in data["author"].keys():
|
||||
name = data["author"]["name"]
|
||||
|
||||
if "url" in data["author"].keys():
|
||||
url = data["author"]["url"]
|
||||
|
||||
if "icon_url" in data["author"].keys():
|
||||
icon_url = data["author"]["icon_url"]
|
||||
|
||||
embed.set_author(name=name, url=url, icon_url=icon_url)
|
||||
|
||||
if "footer" in data.keys():
|
||||
text = discord.Embed.Empty
|
||||
icon_url = discord.Embed.Empty
|
||||
|
||||
if "text" in data["footer"].keys():
|
||||
text = data["footer"]["text"]
|
||||
|
||||
if "icon_url" in data["footer"].keys():
|
||||
icon_url = data["footer"]["icon_url"]
|
||||
|
||||
embed.set_footer(text=text, icon_url=icon_url)
|
||||
|
||||
if "image" in data.keys():
|
||||
embed.set_image(url=data["image"])
|
||||
|
||||
if "thumbnail" in data.keys():
|
||||
embed.set_thumbnail(url=data["thumbnail"])
|
||||
|
||||
if "fields" in data.keys():
|
||||
for field in data["fields"]:
|
||||
name = "None"
|
||||
value = "None"
|
||||
inline = True
|
||||
|
||||
if "name" in field:
|
||||
name = field["name"]
|
||||
|
||||
if "value" in field:
|
||||
value = field["value"]
|
||||
|
||||
if "inline" in field:
|
||||
inline = field["inline"]
|
||||
|
||||
embed.add_field(name=name, value=value, inline=inline)
|
||||
|
||||
return embed
|
||||
|
||||
|
||||
class CustomReactions(commands.Cog):
|
||||
def __init__(self):
|
||||
self.config = Config.get_conf(self, identifier=(3322665 + 3))
|
||||
|
||||
default_guild = {
|
||||
"custom_reactions": []
|
||||
}
|
||||
|
||||
self.config.register_guild(**default_guild)
|
||||
|
||||
|
||||
@commands.command()
|
||||
@checks.admin_or_permissions(manage_guild=True)
|
||||
async def acr(self, ctx, cr_name: str, *, cr_value: str):
|
||||
group = self.config.guild(ctx.guild)
|
||||
|
||||
async with group.custom_reactions() as custom_reactions:
|
||||
sent = False
|
||||
item = None
|
||||
|
||||
try:
|
||||
json_obj = json.loads(cr_value)
|
||||
name = cr_name
|
||||
embed = json_to_embed(json_obj)
|
||||
|
||||
item = {
|
||||
"name": name,
|
||||
"value": cr_value
|
||||
}
|
||||
|
||||
await ctx.send(f"Created reaction {name}, response:", embed=embed)
|
||||
|
||||
sent = True
|
||||
except:
|
||||
item = None
|
||||
await ctx.send("Failed to create the embed, make sure your JSON is valid as well as any URLs.")
|
||||
|
||||
if sent:
|
||||
custom_reactions.append(item)
|
||||
|
||||
|
||||
@commands.command()
|
||||
@checks.admin_or_permissions(manage_guild=True)
|
||||
async def ecr(self, ctx, cr_name: str, *, cr_value: str):
|
||||
group = self.config.guild(ctx.guild)
|
||||
|
||||
async with group.custom_reactions() as custom_reactions:
|
||||
sent = False
|
||||
item = None
|
||||
|
||||
existing_reaction = [x for x in custom_reactions if x["name"] == cr_name]
|
||||
|
||||
if existing_reaction:
|
||||
custom_reactions.remove(existing_reaction[0])
|
||||
|
||||
try:
|
||||
json_obj = json.loads(cr_value)
|
||||
name = cr_name
|
||||
embed = json_to_embed(json_obj)
|
||||
|
||||
item = {
|
||||
"name": name,
|
||||
"value": cr_value
|
||||
}
|
||||
|
||||
await ctx.send(f"Edited reaction {name}, response:", embed=embed)
|
||||
|
||||
sent = True
|
||||
except:
|
||||
item = None
|
||||
await ctx.send("Failed to create the embed, make sure your JSON is valid as well as any URLs.")
|
||||
|
||||
if sent:
|
||||
custom_reactions.append(item)
|
||||
|
||||
|
||||
@commands.command()
|
||||
@checks.admin_or_permissions(manage_guild=True)
|
||||
async def dcr(self, ctx, cr_name: str):
|
||||
group = self.config.guild(ctx.guild)
|
||||
|
||||
async with group.custom_reactions() as custom_reactions:
|
||||
sent = False
|
||||
item = None
|
||||
|
||||
existing_reaction = [x for x in custom_reactions if x["name"] == cr_name]
|
||||
|
||||
if existing_reaction:
|
||||
custom_reactions.remove(existing_reaction[0])
|
||||
await ctx.send(f"Deleted `{cr_name}`.")
|
||||
else:
|
||||
await ctx.send(f"I don't have a reaction named `{cr_name}`. Are you sure it exists?")
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_message(self, message):
|
||||
try:
|
||||
group = self.config.guild(message.guild)
|
||||
|
||||
async with group.custom_reactions() as custom_reactions:
|
||||
names = [x["name"] for x in custom_reactions]
|
||||
|
||||
if message.content in names:
|
||||
index = names.index(message.content)
|
||||
|
||||
json_obj = json.loads(custom_reactions[index]["value"])
|
||||
await message.channel.send(embed=json_to_embed(json_obj))
|
||||
except Exception:
|
||||
pass
|
15
cherubim/entrycontrolresponder.py
Executable file
15
cherubim/entrycontrolresponder.py
Executable file
@ -0,0 +1,15 @@
|
||||
from redbot.core import commands
|
||||
import discord
|
||||
import os
|
||||
|
||||
dir_path = os.path.dirname(__file__)
|
||||
|
||||
class EntryControlResponder(commands.Cog):
|
||||
@commands.Cog.listener()
|
||||
async def on_message(self, message):
|
||||
if message.guild:
|
||||
if message.guild.id == 858664948266958908 and ("entry-" in message.channel.name or "ticket-" in message.channel.name):
|
||||
if message.author.id == 557628352828014614 and len(message.embeds) > 0:
|
||||
if "welcome to our server!" in message.embeds[0].description:
|
||||
embedToSend = discord.Embed(description="**1. Are you an Orthodox Christian? If yes, are you Eastern or Oriental Orthodox? Are you a catechumen or a baptised member? If no, are you another sort of Christian?**\n\n**2. What is your reason for joining the server?**\n\n**3. What is your biological gender?**\n\n**4. Which of these best describes where you live? \"UK and Ireland\", \"Europe\", \"Americas\", \"Asia\", \"Africa\", \"Australia and NZ\"**\n\n**5. Are you married, and/or do you have any children?**\n\n**6. On a scale of 0 to totally addicted, how do you feel about knitting?**")
|
||||
await message.channel.send(embed=embedToSend)
|
32
cherubim/fun.py
Normal file
32
cherubim/fun.py
Normal file
@ -0,0 +1,32 @@
|
||||
from redbot.core import commands
|
||||
import discord
|
||||
import os
|
||||
|
||||
dir_path = os.path.dirname(__file__)
|
||||
|
||||
class Fun(commands.Cog):
|
||||
@commands.command()
|
||||
async def dab(self, ctx, item: str=None):
|
||||
img = discord.File(f"{dir_path}/horsedabbing.jpg")
|
||||
|
||||
if item:
|
||||
await ctx.send(f"{ctx.author.mention} dabs on {item}.", file=img)
|
||||
else:
|
||||
await ctx.send(f"{ctx.author.mention} dabs.", file=img)
|
||||
|
||||
@commands.command()
|
||||
async def slap(self, ctx, item: str=None):
|
||||
if item:
|
||||
if item == "<@186046294286925824>":
|
||||
item = "a random, poor, innocent angel of God"
|
||||
await ctx.send(f"{ctx.author.mention} slaps {item} with a fish. :fish:")
|
||||
else:
|
||||
await ctx.send(f"{ctx.author.mention} didn't target anything and accidentally slapped themselves with a fish. :fish:")
|
||||
|
||||
|
||||
@commands.command()
|
||||
async def kill(self, ctx, item: str=None):
|
||||
if item:
|
||||
await ctx.send(f"{item} :gun:")
|
||||
else:
|
||||
await ctx.send("How am I supposed to kill nothing?!")
|
BIN
cherubim/horsedabbing.jpg
Normal file
BIN
cherubim/horsedabbing.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.9 KiB |
20
cherubim/imgperms.py
Normal file
20
cherubim/imgperms.py
Normal file
@ -0,0 +1,20 @@
|
||||
from redbot.core import commands
|
||||
import discord
|
||||
import os
|
||||
|
||||
dir_path = os.path.dirname(__file__)
|
||||
|
||||
class ImgPerms(commands.Cog):
|
||||
@commands.command()
|
||||
async def giveimg(self, ctx, user: discord.Member):
|
||||
if ctx.guild.id == 362503610006765568:
|
||||
if len([x for x in ctx.author.roles if x.id == 794373197713375302]) > 0:
|
||||
await user.add_roles([x for x in ctx.guild.roles if x.id == 366885935289204736][0])
|
||||
await ctx.send(f"Given image perms to {user.mention}.")
|
||||
|
||||
@commands.command()
|
||||
async def takeimg(self, ctx, user: discord.Member):
|
||||
if ctx.guild.id == 362503610006765568:
|
||||
if len([x for x in ctx.author.roles if x.id == 794373197713375302]) > 0:
|
||||
await user.remove_roles([x for x in ctx.guild.roles if x.id == 366885935289204736][0])
|
||||
await ctx.send(f"Taken image perms to {user.mention}.")
|
9
cherubim/info.json
Normal file
9
cherubim/info.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"AUTHOR" : "Elliott Pardee (vypr#0001)",
|
||||
"NAME" : "cherubim",
|
||||
"SHORT" : "A full-stack cog for Cherubim.",
|
||||
"DESCRIPTION" : "A full-stack cog for Cherubim.",
|
||||
"TAGS" : ["cherubim", "custom"],
|
||||
"REQUIREMENTS" : ["tabulate", "requests"],
|
||||
"HIDDEN" : false
|
||||
}
|
79
cherubim/quotes.py
Executable file
79
cherubim/quotes.py
Executable file
@ -0,0 +1,79 @@
|
||||
import asyncio
|
||||
import os
|
||||
import random
|
||||
from datetime import datetime
|
||||
from re import split
|
||||
from typing import final
|
||||
|
||||
import discord
|
||||
|
||||
from redbot.core import commands, checks, Config
|
||||
|
||||
class Quotes(commands.Cog):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
self.config = Config.get_conf(self, identifier=(3322665 + 55673))
|
||||
|
||||
default_guild = {
|
||||
"quotes": {},
|
||||
}
|
||||
|
||||
self.config.register_guild(**default_guild)
|
||||
|
||||
@commands.command(name="quote", pass_context=True, no_pm=True)
|
||||
async def quote(self, ctx, user: discord.Member=None, value: int=None):
|
||||
guild_group = self.config.guild(ctx.guild)
|
||||
|
||||
if user is None:
|
||||
user = ctx.author
|
||||
|
||||
async with guild_group.quotes() as quotes:
|
||||
if str(user.id) in quotes:
|
||||
quote = None
|
||||
|
||||
if value is None:
|
||||
quote = random.choice(quotes[str(user.id)])
|
||||
else:
|
||||
value = value - 1
|
||||
if -1 < value < len(quotes[str(user.id)]):
|
||||
quote = quotes[str(user.id)][value]
|
||||
|
||||
if quote is not None:
|
||||
split_paragraphs = quote["text"].split("\n")
|
||||
|
||||
for idx in range(len(split_paragraphs)):
|
||||
split_paragraphs[idx] = f"> {split_paragraphs[idx]}"
|
||||
|
||||
final_quote = "\n".join(split_paragraphs)
|
||||
link = quote["link"]
|
||||
await ctx.send(f"{user.display_name}:\n\n{final_quote}\n\nContext: <{link}>")
|
||||
else:
|
||||
await ctx.send("There are no quotes associated with this user.")
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_reaction_add(self, reaction, user):
|
||||
guild_group = self.config.guild(reaction.message.guild)
|
||||
reacts_needed = 4
|
||||
|
||||
async with guild_group.quotes() as quotes:
|
||||
if reaction.emoji == "⭐":
|
||||
users_reacted_count = 0
|
||||
users_reacted = await reaction.users().flatten()
|
||||
|
||||
for user in users_reacted:
|
||||
if user.id != reaction.message.author.id:
|
||||
users_reacted_count += 1
|
||||
|
||||
if users_reacted_count >= reacts_needed:
|
||||
msg = reaction.message
|
||||
|
||||
final_obj = {
|
||||
"text": msg.content,
|
||||
"link": msg.jump_url
|
||||
}
|
||||
|
||||
if str(msg.author.id) in quotes:
|
||||
if final_obj not in quotes[str(msg.author.id)]:
|
||||
quotes[str(msg.author.id)].append(final_obj)
|
||||
else:
|
||||
quotes[str(msg.author.id)] = [final_obj]
|
18
cherubim/standards.py
Normal file
18
cherubim/standards.py
Normal file
@ -0,0 +1,18 @@
|
||||
from redbot.core import commands
|
||||
import discord
|
||||
import asyncio
|
||||
import os
|
||||
|
||||
dir_path = os.path.dirname(__file__)
|
||||
|
||||
class Standards(commands.Cog):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
# todo: update joining logic
|
||||
async def on_member_update(self, member):
|
||||
pass
|
||||
|
||||
# todo: update leaving logic
|
||||
async def on_member_remove(self, member):
|
||||
pass
|
174
cherubim/suggestionbox.py
Normal file
174
cherubim/suggestionbox.py
Normal file
@ -0,0 +1,174 @@
|
||||
import os
|
||||
import asyncio # noqa: F401
|
||||
import datetime
|
||||
import discord
|
||||
from redbot.core import commands, checks, Config
|
||||
|
||||
|
||||
class SuggestionBox(commands.Cog):
|
||||
"""custom cog for a configurable suggestion box"""
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
self.config = Config.get_conf(self, identifier=(3322665 + 1))
|
||||
self.usercache = []
|
||||
|
||||
default_guild = {
|
||||
"inactive": True,
|
||||
"channels_enabled": [],
|
||||
"cleanup": False,
|
||||
"anonymous": True,
|
||||
"blocked_ids": []
|
||||
}
|
||||
|
||||
self.config.register_guild(**default_guild)
|
||||
|
||||
@commands.group(name="setsuggest", pass_context=True, no_pm=True)
|
||||
@checks.admin_or_permissions(manage_guild=True)
|
||||
async def setsuggest(self, ctx):
|
||||
"""configuration settings"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@setsuggest.command(name="on", pass_context=True, no_pm=True)
|
||||
async def _setsuggest_on(self, ctx):
|
||||
"""Turn on SuggestionBox in the current channel"""
|
||||
guild_group = self.config.guild(ctx.guild)
|
||||
|
||||
async with guild_group.channels_enabled() as channels_enabled:
|
||||
channel = ctx.message.channel
|
||||
if channel.id in channels_enabled:
|
||||
await ctx.send("SuggestionBox is already on in this channel.")
|
||||
else:
|
||||
channels_enabled.append(channel.id)
|
||||
|
||||
await ctx.send("SuggestionBox is now on in this channel.")
|
||||
|
||||
@setsuggest.command(name="off", pass_context=True, no_pm=True)
|
||||
async def _setsuggest_off(self, ctx):
|
||||
"""Turn off SuggestionBox in the current channel"""
|
||||
guild_group = self.config.guild(ctx.guild)
|
||||
|
||||
async with guild_group.channels_enabled() as channels_enabled:
|
||||
channel = ctx.message.channel
|
||||
if channel.id not in channels_enabled:
|
||||
await ctx.send("SuggestionBox is already off in this channel.")
|
||||
else:
|
||||
channels_enabled.remove(channel.id)
|
||||
|
||||
await ctx.send("SuggestionBox is now off in this channel.")
|
||||
|
||||
@setsuggest.command(name="block", pass_context=True, no_pm=True)
|
||||
async def block(self, ctx, user: discord.Member):
|
||||
"""Blocks a user from making suggestions."""
|
||||
guild = ctx.guild
|
||||
group = self.config.guild(guild)
|
||||
|
||||
async with group.blocked_ids() as blocked_ids:
|
||||
if user.id in blocked_ids:
|
||||
await ctx.send("This user is already in the block list, did you mean to `--setsuggest unblock`?")
|
||||
else:
|
||||
blocked_ids.append(user.id)
|
||||