mirror of
https://github.com/brandons209/Red-bot-Cogs.git
synced 2024-05-19 03:42:33 +12:00
remove welcome cog, official version has all needed features
This commit is contained in:
parent
d27a8d0af0
commit
7e4b0c18b8
|
@ -1,7 +0,0 @@
|
|||
from redbot.core.bot import Red
|
||||
|
||||
from .welcome import Welcome
|
||||
|
||||
|
||||
def setup(bot: Red):
|
||||
bot.add_cog(Welcome(bot))
|
|
@ -1,8 +0,0 @@
|
|||
from enum import Enum
|
||||
|
||||
|
||||
class WhisperType(Enum):
|
||||
OFF = 'off'
|
||||
ONLY = 'only'
|
||||
BOTH = 'both'
|
||||
FALLBACK = 'fall'
|
|
@ -1,9 +0,0 @@
|
|||
{
|
||||
"author" : ["tmerc"],
|
||||
"install_msg" : "Thanks for installing!",
|
||||
"name" : "Welcome",
|
||||
"short" : "Announces membership events.",
|
||||
"description" : "Announces members joining, leaving, getting banned, and getting unbanned, in a customizable text channel and with customizable messages.",
|
||||
"requirements" : [],
|
||||
"tags": ["welcome", "greetings", "leave", "ban", "utility"]
|
||||
}
|
|
@ -1,951 +0,0 @@
|
|||
import asyncio
|
||||
import logging
|
||||
import random
|
||||
from datetime import date
|
||||
from typing import Union
|
||||
|
||||
import discord
|
||||
from redbot.core import Config, commands, checks
|
||||
from redbot.core.bot import Red
|
||||
from redbot.core.utils.chat_formatting import box, pagify
|
||||
|
||||
from .enums import WhisperType
|
||||
|
||||
__author__ = "tmerc"
|
||||
|
||||
log = logging.getLogger('red.tmerc.welcome')
|
||||
|
||||
ENABLED = 'enabled'
|
||||
DISABLED = 'disabled'
|
||||
|
||||
class WhisperError(Exception):
|
||||
pass
|
||||
|
||||
class Welcome(getattr(commands, "Cog", object)):
|
||||
"""Announce when users join or leave a server."""
|
||||
|
||||
default_join = "Welcome {member.mention} to {server.name}!"
|
||||
default_leave = "{member.name} has left {server.name}!"
|
||||
default_ban = "{member.name} has been banned from {server.name}!"
|
||||
default_unban = "{member.name} has been unbanned from {server.name}!"
|
||||
default_whisper = "Hey there {member.name}, welcome to {server.name}!"
|
||||
|
||||
guild_defaults = {
|
||||
'enabled': False,
|
||||
'channel': None,
|
||||
'date': None,
|
||||
'join': {
|
||||
'enabled': True,
|
||||
'delete': False,
|
||||
'last': None,
|
||||
'channel': None,
|
||||
'counter': 0,
|
||||
'whisper': {
|
||||
'state': 'off',
|
||||
'message': default_whisper
|
||||
},
|
||||
'messages': [default_join],
|
||||
'bot': None
|
||||
},
|
||||
'leave': {
|
||||
'enabled': True,
|
||||
'delete': False,
|
||||
'channel': None,
|
||||
'last': None,
|
||||
'messages': [default_leave],
|
||||
},
|
||||
'ban': {
|
||||
'enabled': True,
|
||||
'delete': False,
|
||||
'channel': None,
|
||||
'last': None,
|
||||
'messages': [default_ban],
|
||||
},
|
||||
'unban': {
|
||||
'enabled': True,
|
||||
'delete': False,
|
||||
'channel': None,
|
||||
'last': None,
|
||||
'messages': [default_unban],
|
||||
}
|
||||
}
|
||||
|
||||
def __init__(self, bot: Red):
|
||||
self.bot = bot
|
||||
self.config = Config.get_conf(self, 86345009)
|
||||
self.config.register_guild(**self.guild_defaults)
|
||||
|
||||
@commands.group()
|
||||
@commands.guild_only()
|
||||
@checks.admin_or_permissions(manage_guild=True)
|
||||
async def welcomeset(self, ctx: commands.Context):
|
||||
"""Change Welcome settings."""
|
||||
|
||||
await ctx.trigger_typing()
|
||||
|
||||
if ctx.invoked_subcommand is None:
|
||||
guild = ctx.guild
|
||||
c = await self.config.guild(guild).all()
|
||||
|
||||
channel = await self.__get_channel(guild, "default")
|
||||
join_channel = await self.__get_channel(guild, "join")
|
||||
leave_channel = await self.__get_channel(guild, "leave")
|
||||
ban_channel = await self.__get_channel(guild, "ban")
|
||||
unban_channel = await self.__get_channel(guild, "unban")
|
||||
|
||||
j = c['join']
|
||||
jw = j['whisper']
|
||||
v = c['leave']
|
||||
b = c['ban']
|
||||
u = c['unban']
|
||||
|
||||
if await ctx.embed_requested():
|
||||
emb = discord.Embed(color=await ctx.embed_color(), title="Current Welcome Settings")
|
||||
emb.add_field(name="General", value=(
|
||||
"**Enabled:** {}\n"
|
||||
"**Channel:** #{}\n."
|
||||
).format(c['enabled'], channel))
|
||||
emb.add_field(name="Join", value=(
|
||||
"**Enabled:** {}\n"
|
||||
"**Channel:** {}\n"
|
||||
"**Delete previous:** {}\n"
|
||||
"**Whisper state:** {}\n"
|
||||
"**Whisper message:** {}\n"
|
||||
"**Messages:** {}; do `{prefix}welcomeset join msg list` for a list\n"
|
||||
"**Bot message:** {}"
|
||||
).format(j['enabled'], join_channel, j['delete'], jw['state'], jw['message'] if len(jw['message']) <= 50 else jw['message'][:50] + "...", len(j['messages']), j['bot'],
|
||||
prefix=ctx.prefix))
|
||||
emb.add_field(name="Leave", value=(
|
||||
"**Enabled:** {}\n"
|
||||
"**Channel:** {}\n"
|
||||
"**Delete previous:** {}\n"
|
||||
"**Messages:** {}; do `{prefix}welcomeset leave msg list` for a list\n"
|
||||
).format(v['enabled'], leave_channel, v['delete'], len(v['messages']), prefix=ctx.prefix))
|
||||
emb.add_field(name="Ban", value=(
|
||||
"**Enabled:** {}\n"
|
||||
"**Channel:** {}\n"
|
||||
"**Delete previous:** {}\n"
|
||||
"**Messages:** {}; do `{prefix}welcomeset ban msg list` for a list\n"
|
||||
).format(b['enabled'], ban_channel, b['delete'], len(b['messages']), prefix=ctx.prefix))
|
||||
emb.add_field(name="Unban", value=(
|
||||
"**Enabled:** {}\n"
|
||||
"**Channel:** {}\n"
|
||||
"**Delete previous:** {}\n"
|
||||
"**Messages:** {}; do `{prefix}welcomeset unban msg list` for a list\n"
|
||||
).format(u['enabled'], unban_channel, u['delete'], len(u['messages']), prefix=ctx.prefix))
|
||||
|
||||
await ctx.send(embed=emb)
|
||||
else:
|
||||
msg = box(
|
||||
(" Enabled: {}\n"
|
||||
" Channel: {}\n"
|
||||
" Join:\n"
|
||||
" Enabled: {}\n"
|
||||
" Channel: {}\n"
|
||||
" Delete previous: {}\n"
|
||||
" Whisper:\n"
|
||||
" State: {}\n"
|
||||
" Message: {}\n"
|
||||
" Messages: {}; do '{prefix}welcomeset join msg list' for a list\n"
|
||||
" Bot message: {}\n"
|
||||
" Leave:\n"
|
||||
" Enabled: {}\n"
|
||||
" Channel: {}\n"
|
||||
" Delete previous: {}\n"
|
||||
" Messages: {}; do '{prefix}welcomeset leave msg list' for a list\n"
|
||||
" Ban:\n"
|
||||
" Enabled: {}\n"
|
||||
" Channel: {}\n"
|
||||
" Delete previous: {}\n"
|
||||
" Messages: {}; do '{prefix}welcomeset ban msg list' for a list\n"
|
||||
" Unban:\n"
|
||||
" Enabled: {}\n"
|
||||
" Channel: {}\n"
|
||||
" Delete previous: {}\n"
|
||||
" Messages: {}; do '{prefix}welcomeset unban msg list' for a list\n"
|
||||
"").format(c['enabled'], channel,
|
||||
j['enabled'], join_channel, j['delete'], jw['state'], jw['message'], len(j['messages']), j['bot'],
|
||||
v['enabled'], leave_channel, v['delete'], len(v['messages']),
|
||||
b['enabled'], ban_channel, b['delete'], len(b['messages']),
|
||||
u['enabled'], unban_channel, u['delete'], len(u['messages']),
|
||||
prefix=ctx.prefix),
|
||||
"Current Welcome settings:"
|
||||
)
|
||||
|
||||
await ctx.send(msg)
|
||||
|
||||
@welcomeset.command(name='toggle')
|
||||
async def welcomeset_toggle(self, ctx: commands.Context, on_off: bool = None):
|
||||
"""Turns Welcome on or off.
|
||||
|
||||
If `on_off` is not provided, the state will be flipped.
|
||||
"""
|
||||
|
||||
guild = ctx.guild
|
||||
target_state = on_off if on_off is not None else not (await self.config.guild(guild).enabled())
|
||||
|
||||
await self.config.guild(guild).enabled.set(target_state)
|
||||
|
||||
await ctx.send(
|
||||
("Welcome is now {}."
|
||||
"").format(ENABLED if target_state else DISABLED)
|
||||
)
|
||||
|
||||
@welcomeset.command(name='channel')
|
||||
async def welcomeset_channel(self, ctx: commands.Context, channel: discord.TextChannel):
|
||||
"""Sets the channel to be used for event notices."""
|
||||
|
||||
if not self.__can_speak_in(channel):
|
||||
await ctx.send(
|
||||
("I do not have permission to send messages in {0.mention}. Check your permission settings and try again."
|
||||
"").format(channel)
|
||||
)
|
||||
return
|
||||
|
||||
guild = ctx.guild
|
||||
await self.config.guild(guild).channel.set(channel.id)
|
||||
|
||||
await ctx.send(
|
||||
("I will now send event notices to {0.mention}."
|
||||
"").format(channel)
|
||||
)
|
||||
|
||||
@welcomeset.group(name='join')
|
||||
async def welcomeset_join(self, ctx: commands.Context):
|
||||
"""Change settings for join notices."""
|
||||
|
||||
pass
|
||||
|
||||
@welcomeset_join.command(name='toggle')
|
||||
async def welcomeset_join_toggle(self, ctx: commands.Context, on_off: bool = None):
|
||||
"""Turns join notices on or off.
|
||||
|
||||
If `on_off` is not provided, the state will be flipped.
|
||||
"""
|
||||
|
||||
await self.__toggle(ctx, on_off, 'join')
|
||||
|
||||
@welcomeset_join.command(name='toggledelete')
|
||||
async def welcomeset_join_toggledelete(self, ctx: commands.Context, on_off: bool = None):
|
||||
"""Turns deletion of previous join notice on or off.
|
||||
|
||||
If `on_off` is not provided, the state will be flipped.
|
||||
"""
|
||||
|
||||
await self.__toggledelete(ctx, on_off, 'join')
|
||||
|
||||
@welcomeset_join.group(name='whisper')
|
||||
async def welcomeset_join_whisper(self, ctx: commands.Context):
|
||||
"""Change settings for join whispers."""
|
||||
|
||||
pass
|
||||
|
||||
@welcomeset_join_whisper.command(name='type')
|
||||
async def welcomeset_join_whisper_type(self, ctx: commands.Context, choice: WhisperType):
|
||||
"""Set if a DM is sent to the new member.
|
||||
|
||||
Options:
|
||||
off - no DM is sent
|
||||
only - only send a DM to the member, do not send a message to the channel
|
||||
both - send a DM to the member and a message to the channel
|
||||
fall - send a DM to the member, if it fails send the whisper message to the channel instead
|
||||
"""
|
||||
|
||||
guild = ctx.guild
|
||||
whisper_type = choice.value
|
||||
channel = await self.__get_channel(ctx.guild, "join")
|
||||
|
||||
await self.config.guild(guild).join.whisper.state.set(whisper_type)
|
||||
|
||||
if choice == WhisperType.OFF:
|
||||
await ctx.send(
|
||||
("I will no longer DM new members, and will send a notice to {0.mention}."
|
||||
"").format(channel)
|
||||
)
|
||||
elif choice == WhisperType.ONLY:
|
||||
await ctx.send(
|
||||
("I will now only DM new members, and will not send a notice to {0.mention}."
|
||||
"").format(channel)
|
||||
)
|
||||
elif choice == WhisperType.BOTH:
|
||||
await ctx.send(
|
||||
("I will now send a DM to new members, as well as send a notice to {0.mention}."
|
||||
"").format(channel)
|
||||
)
|
||||
elif choice == WhisperType.FALLBACK:
|
||||
await ctx.send(
|
||||
("I will now send a DM to new members, and if that fails I will send the message to {0.mention}."
|
||||
"").format(channel)
|
||||
)
|
||||
|
||||
@welcomeset_join_whisper.command(name='msg')
|
||||
async def welcomeset_join_whisper_msg(self, ctx: commands.Context, *, msg_format: str):
|
||||
"""Set the message DM'd to new members when they join.
|
||||
|
||||
Allows for the following customizations:
|
||||
`{member}` is the member who joined
|
||||
`{server}` is the server
|
||||
"""
|
||||
|
||||
await self.config.guild(ctx.guild).join.whisper.message.set(msg_format)
|
||||
|
||||
await ctx.send(
|
||||
("I will now use that message format when whispering new members, if whisper is enabled."
|
||||
"")
|
||||
)
|
||||
|
||||
@welcomeset_join.group(name='msg')
|
||||
async def welcomeset_join_msg(self, ctx: commands.Context):
|
||||
"""Manage join message formats."""
|
||||
|
||||
pass
|
||||
|
||||
@welcomeset_join_msg.command(name='add')
|
||||
async def welcomeset_join_msg_add(self, ctx: commands.Context, *, msg_format: str):
|
||||
"""Add a new join message format to be chosen.
|
||||
|
||||
Allows for the following customizations:
|
||||
`{member}` is the new member
|
||||
`{server}` is the server
|
||||
`{count}` is the number of members who have joined today
|
||||
`{plural}` is an 's' if `count` is not 1, and nothing if it is
|
||||
|
||||
For example:
|
||||
{member.mention}... What are you doing here???
|
||||
{server.name} has a new member! {member.name}#{member.discriminator} - {member.id}
|
||||
Someone new has joined! Who is it?! D: IS HE HERE TO HURT US?!
|
||||
"""
|
||||
|
||||
await self.__msg_add(ctx, msg_format, 'join')
|
||||
|
||||
@welcomeset_join_msg.command(name='del')
|
||||
async def welcomeset_join_msg_del(self, ctx: commands.Context):
|
||||
"""Delete an existing join message format from the list."""
|
||||
|
||||
await self.__msg_del(ctx, 'join')
|
||||
|
||||
@welcomeset_join_msg.command(name='list')
|
||||
async def welcomeset_join_msg_list(self, ctx: commands.Context):
|
||||
"""Lists the available join message formats."""
|
||||
|
||||
await self.__msg_list(ctx, 'join')
|
||||
|
||||
@welcomeset_join.command(name='botmsg')
|
||||
async def welcomeset_join_botmsg(self, ctx: commands.Context, *, msg_format: str=None):
|
||||
"""Sets the message format to use for join notices for bots.
|
||||
|
||||
Supply no format to use normal join message formats for bots.
|
||||
Allows for the following customizations:
|
||||
`{bot}` is the bot
|
||||
`{server}` is the server
|
||||
`{count}` is the number of members who have joined today
|
||||
`{plural}` is an 's' if `count` is not 1, and nothing if it is
|
||||
|
||||
For example:
|
||||
{bot.mention} beep boop.
|
||||
"""
|
||||
|
||||
await self.config.guild(ctx.guild).join.bot.set(msg_format)
|
||||
|
||||
if msg_format is not None:
|
||||
await ctx.send(
|
||||
("Bot join message format set. I will now greet bots with that message."
|
||||
"")
|
||||
)
|
||||
else:
|
||||
await ctx.send(
|
||||
("Bot join message format removed. I will now greet bots like normal members."
|
||||
"")
|
||||
)
|
||||
|
||||
@welcomeset_join.command(name='channel')
|
||||
async def welcomeset_join_channel(self, ctx: commands.Context, channel: discord.TextChannel):
|
||||
"""Set channel for join notices
|
||||
|
||||
If not set, join notices are sent to the default events channel.
|
||||
"""
|
||||
if not self.__can_speak_in(channel):
|
||||
await ctx.send(
|
||||
("I do not have permission to send messages in {0.mention}. Check your permission settings and try again."
|
||||
"").format(channel)
|
||||
)
|
||||
return
|
||||
|
||||
await self.config.guild(ctx.guild).join.channel.set(channel.id)
|
||||
|
||||
await ctx.send(
|
||||
("I will now send join event notices to {0.mention}."
|
||||
"").format(channel)
|
||||
)
|
||||
|
||||
@welcomeset.group(name='leave')
|
||||
async def welcomeset_leave(self, ctx: commands.Context):
|
||||
"""Change settings for leave notices."""
|
||||
|
||||
pass
|
||||
|
||||
@welcomeset_leave.command(name='toggle')
|
||||
async def welcomeset_leave_toggle(self, ctx: commands.Context, on_off: bool = None):
|
||||
"""Turns leave notices on or off.
|
||||
|
||||
If `on_off` is not provided, the state will be flipped.
|
||||
"""
|
||||
|
||||
await self.__toggle(ctx, on_off, 'leave')
|
||||
|
||||
@welcomeset_leave.command(name='toggledelete')
|
||||
async def welcomeset_leave_toggledelete(self, ctx: commands.Context, on_off: bool = None):
|
||||
"""Turns deletion of previous leave notice on or off.
|
||||
|
||||
If `on_off` is not provided, the state will be flipped.
|
||||
"""
|
||||
|
||||
await self.__toggledelete(ctx, on_off, 'leave')
|
||||
|
||||
@welcomeset_leave.command(name='channel')
|
||||
async def welcomeset_leave_channel(self, ctx: commands.Context, channel: discord.TextChannel):
|
||||
"""Set channel for leave notices
|
||||
|
||||
If not set, leave notices are sent to the default events channel.
|
||||
"""
|
||||
if not self.__can_speak_in(channel):
|
||||
await ctx.send(
|
||||
("I do not have permission to send messages in {0.mention}. Check your permission settings and try again."
|
||||
"").format(channel)
|
||||
)
|
||||
return
|
||||
|
||||
await self.config.guild(ctx.guild).leave.channel.set(channel.id)
|
||||
|
||||
await ctx.send(
|
||||
("I will now send leave event notices to {0.mention}."
|
||||
"").format(channel)
|
||||
)
|
||||
|
||||
@welcomeset_leave.group(name='msg')
|
||||
async def welcomeset_leave_msg(self, ctx: commands.Context):
|
||||
"""Manage leave message formats."""
|
||||
|
||||
pass
|
||||
|
||||
@welcomeset_leave_msg.command(name='add')
|
||||
async def welcomeset_leave_msg_add(self, ctx: commands.Context, *, msg_format: str):
|
||||
"""Add a new leave message format to be chosen.
|
||||
|
||||
Allows for the following customizations:
|
||||
`{member}` is the member who left
|
||||
`{server}` is the server
|
||||
|
||||
For example:
|
||||
{member.name}... Why did you leave???
|
||||
{server.name} has lost a member! {member.name}#{member.discriminator} - {member.id}
|
||||
Someone has left... Aww... Bye :(
|
||||
"""
|
||||
|
||||
await self.__msg_add(ctx, msg_format, 'leave')
|
||||
|
||||
@welcomeset_leave_msg.command(name='del')
|
||||
async def welcomeset_leave_msg_del(self, ctx: commands.Context):
|
||||
"""Delete an existing leave message format from the list."""
|
||||
|
||||
await self.__msg_del(ctx, 'leave')
|
||||
|
||||
@welcomeset_leave_msg.command(name='list')
|
||||
async def welcomeset_leave_msg_list(self, ctx: commands.Context):
|
||||
"""Lists the available leave message formats."""
|
||||
|
||||
await self.__msg_list(ctx, 'leave')
|
||||
|
||||
@welcomeset.group(name='ban')
|
||||
async def welcomeset_ban(self, ctx: commands.Context):
|
||||
"""Change settings for ban notices."""
|
||||
|
||||
pass
|
||||
|
||||
@welcomeset_ban.command(name='toggle')
|
||||
async def welcomeset_ban_toggle(self, ctx: commands.Context, on_off: bool = None):
|
||||
"""Turns ban notices on or off.
|
||||
|
||||
If `on_off` is not provided, the state will be flipped.
|
||||
"""
|
||||
|
||||
await self.__toggle(ctx, on_off, 'ban')
|
||||
|
||||
@welcomeset_ban.command(name='toggledelete')
|
||||
async def welcomeset_ban_toggledelete(self, ctx: commands.Context, on_off: bool = None):
|
||||
"""Turns deletion of previous ban notice on or off.
|
||||
|
||||
If `on_off` is not provided, the state will be flipped.
|
||||
"""
|
||||
|
||||
await self.__toggledelete(ctx, on_off, 'ban')
|
||||
|
||||
@welcomeset_ban.command(name='channel')
|
||||
async def welcomeset_ban_channel(self, ctx: commands.Context, channel: discord.TextChannel):
|
||||
"""Set channel for ban notices
|
||||
|
||||
If not set, ban notices are sent to the default events channel.
|
||||
"""
|
||||
if not self.__can_speak_in(channel):
|
||||
await ctx.send(
|
||||
("I do not have permission to send messages in {0.mention}. Check your permission settings and try again."
|
||||
"").format(channel)
|
||||
)
|
||||
return
|
||||
|
||||
await self.config.guild(ctx.guild).ban.channel.set(channel.id)
|
||||
|
||||
await ctx.send(
|
||||
("I will now send ban event notices to {0.mention}."
|
||||
"").format(channel)
|
||||
)
|
||||
|
||||
@welcomeset_ban.group(name='msg')
|
||||
async def welcomeset_ban_msg(self, ctx: commands.Context):
|
||||
"""Manage ban message formats."""
|
||||
|
||||
pass
|
||||
|
||||
@welcomeset_ban_msg.command(name='add')
|
||||
async def welcomeset_ban_msg_add(self, ctx: commands.Context, *, msg_format: str):
|
||||
"""Add a new ban message format to be chosen.
|
||||
|
||||
Allows for the following customizations:
|
||||
`{member}` is the banned member
|
||||
`{server}` is the server
|
||||
|
||||
For example:
|
||||
{member.name} was banned... What did you do???
|
||||
A member of {server.name} has been banned! {member.name}#{member.discriminator} - {member.id}
|
||||
Someone has been banned. Good riddance!
|
||||
"""
|
||||
|
||||
await self.__msg_add(ctx, msg_format, 'ban')
|
||||
|
||||
@welcomeset_ban_msg.command(name='del')
|
||||
async def welcomeset_ban_msg_del(self, ctx: commands.Context):
|
||||
"""Delete an existing ban message format from the list."""
|
||||
|
||||
await self.__msg_del(ctx, 'ban')
|
||||
|
||||
@welcomeset_ban_msg.command(name='list')
|
||||
async def welcomeset_ban_msg_list(self, ctx: commands.Context):
|
||||
"""Lists the available ban message formats."""
|
||||
|
||||
await self.__msg_list(ctx, 'ban')
|
||||
|
||||
@welcomeset.group(name='unban')
|
||||
async def welcomeset_unban(self, ctx: commands.Context):
|
||||
"""Change settings for unban notices."""
|
||||
|
||||
pass
|
||||
|
||||
@welcomeset_unban.command(name='toggle')
|
||||
async def welcomeset_unban_toggle(self, ctx: commands.Context, on_off: bool = None):
|
||||
"""Turns unban notices on or off.
|
||||
|
||||
If `on_off` is not provided, the state will be flipped.
|
||||
"""
|
||||
|
||||
await self.__toggle(ctx, on_off, 'unban')
|
||||
|
||||
@welcomeset_unban.command(name='toggledelete')
|
||||
async def welcomeset_unban_toggledelete(self, ctx: commands.Context, on_off: bool = None):
|
||||
"""Turns deletion of previous unban notice on or off.
|
||||
|
||||
If `on_off` is not provided, the state will be flipped.
|
||||
"""
|
||||
|
||||
await self.__toggledelete(ctx, on_off, 'unban')
|
||||
|
||||
@welcomeset_unban.command(name='channel')
|
||||
async def welcomeset_unban_channel(self, ctx: commands.Context, channel: discord.TextChannel):
|
||||
"""Set channel for unban notices
|
||||
|
||||
If not set, unban notices are sent to the default events channel.
|
||||
"""
|
||||
if not self.__can_speak_in(channel):
|
||||
await ctx.send(
|
||||
("I do not have permission to send messages in {0.mention}. Check your permission settings and try again."
|
||||
"").format(channel)
|
||||
)
|
||||
return
|
||||
|
||||
await self.config.guild(ctx.guild).unban.channel.set(channel.id)
|
||||
|
||||
await ctx.send(
|
||||
("I will now send unban event notices to {0.mention}."
|
||||
"").format(channel)
|
||||
)
|
||||
|
||||
@welcomeset_unban.group(name='msg')
|
||||
async def welcomeset_unban_msg(self, ctx: commands.Context):
|
||||
"""Manage unban message formats."""
|
||||
|
||||
pass
|
||||
|
||||
@welcomeset_unban_msg.command(name='add')
|
||||
async def welcomeset_unban_msg_add(self, ctx: commands.Context, *, msg_format: str):
|
||||
"""Add a new unban message format to be chosen.
|
||||
|
||||
Allows for the following customizations:
|
||||
`{member}` is the unbanned member
|
||||
`{server}` is the server
|
||||
|
||||
For example:
|
||||
{member.name} was unbanned... Did you learn your lesson???
|
||||
A member of {server.name} has been unbanned! {member.name}#{member.discriminator} - {member.id}
|
||||
Someone has been unbanned. Don't waste your second chance!
|
||||
"""
|
||||
|
||||
await self.__msg_add(ctx, msg_format, 'unban')
|
||||
|
||||
@welcomeset_unban_msg.command(name='del')
|
||||
async def welcomeset_unban_msg_del(self, ctx: commands.Context):
|
||||
"""Delete an existing unban message format from the list."""
|
||||
|
||||
await self.__msg_del(ctx, 'unban')
|
||||
|
||||
@welcomeset_unban_msg.command(name='list')
|
||||
async def welcomeset_unban_msg_list(self, ctx: commands.Context):
|
||||
"""Lists the available unban message formats."""
|
||||
|
||||
await self.__msg_list(ctx, 'unban')
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_member_join(self, member: discord.Member):
|
||||
"""Listens for member joins."""
|
||||
|
||||
guild = member.guild
|
||||
guild_settings = self.config.guild(guild)
|
||||
|
||||
if await guild_settings.enabled() and await guild_settings.join.enabled():
|
||||
# join notice should be sent
|
||||
message_format = None
|
||||
if member.bot:
|
||||
# bot
|
||||
message_format = await guild_settings.join.bot()
|
||||
|
||||
else:
|
||||
# only increment when it isn't a bot
|
||||
await self.__increment_count(guild, 'join')
|
||||
|
||||
whisper_type = await guild_settings.join.whisper.state()
|
||||
if whisper_type != 'off':
|
||||
try:
|
||||
await self.__dm_user(member)
|
||||
except:
|
||||
if whisper_type == 'fall':
|
||||
message_format = await self.config.guild(member.guild).join.whisper.message()
|
||||
await self.__handle_event(guild, member, 'join', message_format=message_format)
|
||||
return
|
||||
|
||||
if whisper_type == 'only' or whisper_type == 'fall':
|
||||
# we're done here
|
||||
return
|
||||
|
||||
await self.__handle_event(guild, member, 'join', message_format=message_format)
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_member_remove(self, member: discord.Member):
|
||||
"""Listens for member leaves."""
|
||||
|
||||
await self.__handle_event(member.guild, member, 'leave')
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_member_ban(self, guild: discord.Guild, member: discord.Member):
|
||||
"""Listens for user bans."""
|
||||
|
||||
await self.__handle_event(guild, member, 'ban')
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_member_unban(self, guild: discord.Guild, user: discord.User):
|
||||
"""Listens for user unbans."""
|
||||
|
||||
await self.__handle_event(guild, user, 'unban')
|
||||
|
||||
#
|
||||
# concrete handlers for settings changes and events
|
||||
#
|
||||
|
||||
async def __toggle(self, ctx: commands.Context, on_off: bool, event: str):
|
||||
"""Handler for setting toggles."""
|
||||
|
||||
guild = ctx.guild
|
||||
target_state = on_off if on_off is not None else not (await self.config.guild(guild).get_attr(event).enabled())
|
||||
|
||||
await self.config.guild(guild).get_attr(event).enabled.set(target_state)
|
||||
|
||||
await ctx.send(
|
||||
("{} notices are now {}."
|
||||
"").format(event.capitalize(), ENABLED if target_state else DISABLED)
|
||||
)
|
||||
|
||||
async def __toggledelete(self, ctx: commands.Context, on_off: bool, event: str):
|
||||
"""Handler for setting delete toggles."""
|
||||
|
||||
guild = ctx.guild
|
||||
target_state = on_off if on_off is not None else not (await self.config.guild(guild).get_attr(event).delete())
|
||||
|
||||
await self.config.guild(guild).get_attr(event).delete.set(target_state)
|
||||
|
||||
await ctx.send(
|
||||
("Deletion of previous {} notice is now {}."
|
||||
"").format(event, ENABLED if target_state else DISABLED)
|
||||
)
|
||||
|
||||
async def __msg_add(self, ctx: commands.Context, msg_format: str, event: str):
|
||||
"""Handler for adding message formats."""
|
||||
|
||||
guild = ctx.guild
|
||||
|
||||
async with self.config.guild(guild).get_attr(event).messages() as messages:
|
||||
messages.append(msg_format)
|
||||
|
||||
await ctx.send(
|
||||
("New message format for {} notices added."
|
||||
"").format(event)
|
||||
)
|
||||
|
||||
async def __msg_del(self, ctx: commands.Context, event: str):
|
||||
"""Handler for deleting message formats."""
|
||||
|
||||
guild = ctx.guild
|
||||
|
||||
async with self.config.guild(guild).get_attr(event).messages() as messages:
|
||||
if len(messages) == 1:
|
||||
await ctx.send(
|
||||
("I only have one {} message format, so I can't let you delete it."
|
||||
"").format(event)
|
||||
)
|
||||
return
|
||||
|
||||
await self.__msg_list(ctx, event)
|
||||
await ctx.send(
|
||||
("Please enter the number of the {} message format you wish to delete."
|
||||
"").format(event)
|
||||
)
|
||||
|
||||
try:
|
||||
num = await self.__get_number_input(ctx, len(messages))
|
||||
except asyncio.TimeoutError:
|
||||
await ctx.send(
|
||||
("Okay, I won't remove any of the {} message formats."
|
||||
"").format(event)
|
||||
)
|
||||
return
|
||||
else:
|
||||
removed = messages.pop(num - 1)
|
||||
|
||||
await ctx.send(
|
||||
("Done. This {} message format was deleted:\n"
|
||||
"`{}`"
|
||||
"").format(event, removed)
|
||||
)
|
||||
|
||||
async def __msg_list(self, ctx: commands.Context, event: str):
|
||||
"""Handler for listing message formats."""
|
||||
|
||||
guild = ctx.guild
|
||||
|
||||
msg = "{} message formats:\n".format(event.capitalize())
|
||||
async with self.config.guild(guild).get_attr(event).messages() as messages:
|
||||
for n, m in enumerate(messages, start=1):
|
||||
msg += ' {}. {}\n'.format(n, m)
|
||||
|
||||
for page in pagify(msg, ['\n', ' '], shorten_by=20):
|
||||
await ctx.send(box(page))
|
||||
|
||||
async def __handle_event(self, guild: discord.guild, user: Union[discord.Member, discord.User], event: str, *,
|
||||
message_format=None):
|
||||
"""Handler for actual events."""
|
||||
|
||||
guild_settings = self.config.guild(guild)
|
||||
|
||||
if await guild_settings.enabled():
|
||||
settings = await guild_settings.get_attr(event).all()
|
||||
if settings['enabled']:
|
||||
# notices for this event are enabled
|
||||
|
||||
if settings['delete'] and settings['last'] is not None:
|
||||
# we need to delete the previous message
|
||||
await self.__delete_message(guild, settings['last'], event)
|
||||
# regardless of success, remove reference to that message
|
||||
await guild_settings.get_attr(event).last.set(None)
|
||||
|
||||
# send a notice to the channel
|
||||
new_message = await self.__send_notice(guild, user, event, message_format=message_format)
|
||||
# store it for (possible) deletion later
|
||||
await guild_settings.get_attr(event).last.set(new_message and new_message.id)
|
||||
|
||||
async def __get_channel(self, guild: discord.Guild, event: str) -> discord.TextChannel:
|
||||
"""Gets the best text channel to use for event notices.
|
||||
|
||||
Order of priority:
|
||||
1. User-defined channel for event
|
||||
2. Cog-defined channel for all events
|
||||
3. Guild's system channel (if bot can speak in it)
|
||||
4. First channel that the bot can speak in
|
||||
"""
|
||||
|
||||
channel = None
|
||||
|
||||
if event == 'join':
|
||||
channel_id = await self.config.guild(guild).join.channel()
|
||||
elif event == 'leave':
|
||||
channel_id = await self.config.guild(guild).leave.channel()
|
||||
elif event == 'ban':
|
||||
channel_id = await self.config.guild(guild).ban.channel()
|
||||
elif event == 'unban':
|
||||
channel_id = await self.config.guild(guild).unban.channel()
|
||||
elif event == 'default':
|
||||
channel_id = await self.config.guild(guild).channel()
|
||||
else:
|
||||
raise TypeError("Wrong event type in __get_channel.")
|
||||
|
||||
if channel_id is not None:
|
||||
channel = guild.get_channel(channel_id)
|
||||
|
||||
if channel is None or not self.__can_speak_in(channel):
|
||||
channel_id = await self.config.guild(guild).channel()
|
||||
channel = guild.get_channel(channel_id)
|
||||
|
||||
if channel is None or not self.__can_speak_in(channel):
|
||||
channel = guild.system_channel
|
||||
|
||||
if channel is None or not self.__can_speak_in(channel):
|
||||
for ch in guild.text_channels:
|
||||
if self.__can_speak_in(ch):
|
||||
channel = ch
|
||||
break
|
||||
|
||||
return channel
|
||||
|
||||
async def __get_number_input(self, ctx: commands.Context, maximum: int, minimum: int=0) -> int:
|
||||
"""Gets a number from the user, minimum < x <= maximum."""
|
||||
|
||||
author = ctx.author
|
||||
channel = ctx.channel
|
||||
|
||||
def check(m: discord.Message):
|
||||
num = None
|
||||
try:
|
||||
num = int(m.content)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
return num is not None \
|
||||
and minimum < num <= maximum \
|
||||
and m.author == author \
|
||||
and m.channel == channel
|
||||
|
||||
try:
|
||||
msg = await self.bot.wait_for('message', check=check, timeout=15.0)
|
||||
except asyncio.TimeoutError:
|
||||
raise
|
||||
else:
|
||||
return int(msg.content)
|
||||
|
||||
async def __delete_message(self, guild: discord.Guild, message_id: int, event: str):
|
||||
"""Attempts to delete the message with the given ID."""
|
||||
|
||||
try:
|
||||
await (await (await self.__get_channel(guild, event)).fetch_message(message_id)).delete()
|
||||
except discord.NotFound:
|
||||
log.warning(
|
||||
("Failed to delete message (ID {}): not found"
|
||||
"").format(message_id)
|
||||
)
|
||||
except discord.Forbidden:
|
||||
log.warning(
|
||||
("Failed to delete message (ID {}): insufficient permissions"
|
||||
"").format(message_id)
|
||||
)
|
||||
except:
|
||||
log.warning(
|
||||
("Failed to delete message (ID {})"
|
||||
"").format(message_id)
|
||||
)
|
||||
|
||||
async def __send_notice(self, guild: discord.guild, user: Union[discord.Member, discord.User], event: str, *,
|
||||
message_format=None) -> Union[discord.Message, None]:
|
||||
"""Sends the notice for the event."""
|
||||
|
||||
format_str = message_format or await self.__get_random_message_format(guild, event)
|
||||
|
||||
count = event == 'join' and await self.config.guild(guild).get_attr(event).counter()
|
||||
plural = ''
|
||||
if count and count != 1:
|
||||
plural = 's'
|
||||
|
||||
channel = await self.__get_channel(guild, event)
|
||||
|
||||
try:
|
||||
return await channel.send(
|
||||
format_str.format(member=user, server=guild, bot=user, count=count or '', plural=plural)
|
||||
)
|
||||
except discord.Forbidden:
|
||||
log.error(
|
||||
("Failed to send {} message to channel ID {1.id} (server ID {2.id}): insufficient permissions"
|
||||
"").format(event, channel, guild)
|
||||
)
|
||||
return None
|
||||
except:
|
||||
log.error(
|
||||
("Failed to send {} message to channel ID {1.id} (server ID {2.id})"
|
||||
"").format(event, channel, guild)
|
||||
)
|
||||
return None
|
||||
|
||||
async def __get_random_message_format(self, guild: discord.guild, event: str) -> str:
|
||||
"""Gets a random message for event of type event."""
|
||||
|
||||
async with self.config.guild(guild).get_attr(event).messages() as messages:
|
||||
return random.choice(messages)
|
||||
|
||||
async def __increment_count(self, guild: discord.Guild, event: str):
|
||||
"""Increments the counter for <event>s today. Handles date changes."""
|
||||
|
||||
guild_settings = self.config.guild(guild)
|
||||
|
||||
if await guild_settings.date() is None:
|
||||
await guild_settings.date.set(self.__today())
|
||||
|
||||
if self.__today() > await guild_settings.date():
|
||||
await guild_settings.date.set(self.__today())
|
||||
await guild_settings.get_attr(event).counter.set(0)
|
||||
|
||||
count = await guild_settings.get_attr(event).counter()
|
||||
await guild_settings.get_attr(event).counter.set(count + 1)
|
||||
|
||||
async def __dm_user(self, member: discord.Member):
|
||||
"""Sends a DM to the user with a filled-in message_format."""
|
||||
|
||||
message_format = await self.config.guild(member.guild).join.whisper.message()
|
||||
|
||||
try:
|
||||
await member.send(message_format.format(member=member, server=member.guild))
|
||||
except discord.Forbidden:
|
||||
log.error(
|
||||
("Failed to send DM to member ID {0.id} (server ID {1.id}): insufficient permissions"
|
||||
"").format(member, member.guild)
|
||||
)
|
||||
raise WhisperError("Error.")
|
||||
except:
|
||||
log.error(
|
||||
("Failed to send DM to member ID {0.id} (server ID {1.id})"
|
||||
"").format(member, member.guild)
|
||||
)
|
||||
raise WhisperError("Error.")
|
||||
|
||||
@staticmethod
|
||||
def __can_speak_in(channel: discord.TextChannel) -> bool:
|
||||
"""Indicates whether the bot has permission to speak in channel."""
|
||||
|
||||
return channel.permissions_for(channel.guild.me).send_messages
|
||||
|
||||
@staticmethod
|
||||
def __today() -> int:
|
||||
"""Gets today's date in ordinal form."""
|
||||
|
||||
return date.today().toordinal()
|
Loading…
Reference in a new issue