mirror of
https://github.com/brandons209/Red-bot-Cogs.git
synced 2024-05-26 07:11:41 +12:00
improve up suggestion cog: added listing number of for/against, reasons for approved, and change color based on status
This commit is contained in:
parent
d73c61232b
commit
e8ac2875c3
5
suggestion/__init__.py
Normal file
5
suggestion/__init__.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
from .suggestion import Suggestion
|
||||||
|
|
||||||
|
|
||||||
|
def setup(bot):
|
||||||
|
bot.add_cog(Suggestion(bot))
|
8
suggestion/info.json
Normal file
8
suggestion/info.json
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"author" : ["saurichable", "brandons209"],
|
||||||
|
"install_msg" : "Thank you for installing my cog! Only admins can approve or reject suggestions.",
|
||||||
|
"name" : "Suggestion",
|
||||||
|
"short" : "Simple suggestion box.",
|
||||||
|
"description" : "Just a simple suggestion box with voting system.",
|
||||||
|
"tags" : ["suggestion"]
|
||||||
|
}
|
724
suggestion/suggestion.py
Normal file
724
suggestion/suggestion.py
Normal file
|
@ -0,0 +1,724 @@
|
||||||
|
import asyncio
|
||||||
|
import discord
|
||||||
|
|
||||||
|
from typing import Optional
|
||||||
|
from discord.utils import get
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
from redbot.core import Config, checks, commands
|
||||||
|
from redbot.core.utils.predicates import MessagePredicate, ReactionPredicate
|
||||||
|
from redbot.core.utils.menus import start_adding_reactions
|
||||||
|
from redbot.core.utils.antispam import AntiSpam
|
||||||
|
|
||||||
|
from redbot.core.bot import Red
|
||||||
|
|
||||||
|
|
||||||
|
class Suggestion(commands.Cog):
|
||||||
|
"""
|
||||||
|
Simple suggestion box, basically.
|
||||||
|
|
||||||
|
**Use `[p]setsuggest setup` first.**
|
||||||
|
Only admins can approve or reject suggestions.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__author__ = "saurichable"
|
||||||
|
__version__ = "1.4.0"
|
||||||
|
|
||||||
|
def __init__(self, bot: Red):
|
||||||
|
self.bot = bot
|
||||||
|
self.config = Config.get_conf(self, identifier=2115656421364, force_registration=True)
|
||||||
|
self.antispam = {}
|
||||||
|
self.config.register_guild(
|
||||||
|
same=False,
|
||||||
|
suggest_id=None,
|
||||||
|
approve_id=None,
|
||||||
|
reject_id=None,
|
||||||
|
next_id=1,
|
||||||
|
up_emoji=None,
|
||||||
|
down_emoji=None,
|
||||||
|
delete_suggest=False,
|
||||||
|
)
|
||||||
|
self.config.register_global(toggle=False, server_id=None, channel_id=None, next_id=1, ignore=[])
|
||||||
|
self.config.init_custom("SUGGESTION", 2)
|
||||||
|
self.config.register_custom(
|
||||||
|
"SUGGESTION",
|
||||||
|
author=[],
|
||||||
|
msg_id=0,
|
||||||
|
finished=False,
|
||||||
|
approved=False,
|
||||||
|
rejected=False,
|
||||||
|
reason=False,
|
||||||
|
stext=None,
|
||||||
|
rtext=None,
|
||||||
|
num_up=0,
|
||||||
|
num_down=0,
|
||||||
|
)
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
@commands.guild_only()
|
||||||
|
@checks.bot_has_permissions(add_reactions=True)
|
||||||
|
async def suggest(self, ctx: commands.Context, *, suggestion: str):
|
||||||
|
"""Suggest something. Message is required."""
|
||||||
|
suggest_id = await self.config.guild(ctx.guild).suggest_id()
|
||||||
|
if not suggest_id:
|
||||||
|
if await self.config.toggle():
|
||||||
|
if ctx.guild.id in await self.config.ignore():
|
||||||
|
return await ctx.send("Uh oh, suggestions aren't enabled.")
|
||||||
|
global_guild = self.bot.get_guild(await self.config.server_id())
|
||||||
|
channel = get(global_guild.text_channels, id=await self.config.channel_id())
|
||||||
|
else:
|
||||||
|
return await ctx.send("Uh oh, suggestions aren't enabled.")
|
||||||
|
else:
|
||||||
|
channel = get(ctx.guild.text_channels, id=suggest_id)
|
||||||
|
if not channel:
|
||||||
|
return await ctx.send("Uh oh, looks like your Admins haven't added the required channel.")
|
||||||
|
if ctx.guild not in self.antispam:
|
||||||
|
self.antispam[ctx.guild] = {}
|
||||||
|
if ctx.author not in self.antispam[ctx.guild]:
|
||||||
|
self.antispam[ctx.guild][ctx.author] = AntiSpam([(timedelta(days=1), 6)])
|
||||||
|
if self.antispam[ctx.guild][ctx.author].spammy:
|
||||||
|
return await ctx.send("Uh oh, you're doing this way too frequently.")
|
||||||
|
embed = discord.Embed(color=await ctx.embed_colour(), description=suggestion)
|
||||||
|
embed.set_author(
|
||||||
|
name=f"Suggestion by {ctx.author.display_name}",
|
||||||
|
icon_url=ctx.author.avatar_url,
|
||||||
|
)
|
||||||
|
embed.set_footer(text=f"Suggested by {ctx.author.name}#{ctx.author.discriminator} ({ctx.author.id})")
|
||||||
|
|
||||||
|
if not suggest_id:
|
||||||
|
if await self.config.toggle():
|
||||||
|
s_id = await self.config.next_id()
|
||||||
|
await self.config.next_id.set(s_id + 1)
|
||||||
|
server = 1
|
||||||
|
content = f"Global suggestion #{s_id}"
|
||||||
|
else:
|
||||||
|
s_id = await self.config.guild(ctx.guild).next_id()
|
||||||
|
await self.config.guild(ctx.guild).next_id.set(s_id + 1)
|
||||||
|
server = ctx.guild.id
|
||||||
|
content = f"Suggestion #{s_id}"
|
||||||
|
msg = await channel.send(content=content, embed=embed)
|
||||||
|
|
||||||
|
up_emoji = self.bot.get_emoji(await self.config.guild(ctx.guild).up_emoji())
|
||||||
|
if not up_emoji:
|
||||||
|
up_emoji = "✅"
|
||||||
|
down_emoji = self.bot.get_emoji(await self.config.guild(ctx.guild).down_emoji())
|
||||||
|
if not down_emoji:
|
||||||
|
down_emoji = "❎"
|
||||||
|
await msg.add_reaction(up_emoji)
|
||||||
|
await msg.add_reaction(down_emoji)
|
||||||
|
|
||||||
|
async with self.config.custom("SUGGESTION", server, s_id).author() as author:
|
||||||
|
author.append(ctx.author.id)
|
||||||
|
author.append(ctx.author.name)
|
||||||
|
author.append(ctx.author.discriminator)
|
||||||
|
await self.config.custom("SUGGESTION", server, s_id).stext.set(suggestion)
|
||||||
|
await self.config.custom("SUGGESTION", server, s_id).msg_id.set(msg.id)
|
||||||
|
|
||||||
|
self.antispam[ctx.guild][ctx.author].stamp()
|
||||||
|
if await self.config.guild(ctx.guild).delete_suggest():
|
||||||
|
await ctx.message.delete()
|
||||||
|
else:
|
||||||
|
await ctx.tick()
|
||||||
|
try:
|
||||||
|
await ctx.author.send(content="Your suggestion has been sent for approval!", embed=embed)
|
||||||
|
except discord.Forbidden:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@checks.admin_or_permissions(administrator=True)
|
||||||
|
@commands.command()
|
||||||
|
@commands.guild_only()
|
||||||
|
@checks.bot_has_permissions(manage_messages=True)
|
||||||
|
async def approve(
|
||||||
|
self,
|
||||||
|
ctx: commands.Context,
|
||||||
|
suggestion_id: int,
|
||||||
|
is_global: Optional[bool] = False,
|
||||||
|
*,
|
||||||
|
reason: str = "",
|
||||||
|
):
|
||||||
|
"""Approve a suggestion."""
|
||||||
|
if is_global:
|
||||||
|
if await self.config.toggle():
|
||||||
|
if ctx.author.id != self.bot.owner_id:
|
||||||
|
return await ctx.send("Uh oh, you're not my owner.")
|
||||||
|
server = 1
|
||||||
|
global_guild = self.bot.get_guild(await self.config.server_id())
|
||||||
|
oldchannel = get(global_guild.text_channels, id=await self.config.channel_id())
|
||||||
|
else:
|
||||||
|
return await ctx.send("Global suggestions aren't enabled.")
|
||||||
|
else:
|
||||||
|
server = ctx.guild.id
|
||||||
|
oldchannel = get(
|
||||||
|
ctx.guild.text_channels,
|
||||||
|
id=await self.config.guild(ctx.guild).suggest_id(),
|
||||||
|
)
|
||||||
|
channel = get(
|
||||||
|
ctx.guild.text_channels,
|
||||||
|
id=await self.config.guild(ctx.guild).approve_id(),
|
||||||
|
)
|
||||||
|
msg_id = await self.config.custom("SUGGESTION", server, suggestion_id).msg_id()
|
||||||
|
if msg_id != 0:
|
||||||
|
if await self.config.custom("SUGGESTION", server, suggestion_id).finished():
|
||||||
|
return await ctx.send("This suggestion has been finished already.")
|
||||||
|
try:
|
||||||
|
oldmsg = await oldchannel.fetch_message(id=msg_id)
|
||||||
|
except discord.NotFound:
|
||||||
|
return await ctx.send("Uh oh, message with this ID doesn't exist.")
|
||||||
|
if not oldmsg:
|
||||||
|
return await ctx.send("Uh oh, message with this ID doesn't exist.")
|
||||||
|
embed = oldmsg.embeds[0]
|
||||||
|
content = oldmsg.content
|
||||||
|
# change to green for Approved
|
||||||
|
embed.color = discord.Color.from_rgb(0, 255, 0)
|
||||||
|
op_info = await self.config.custom("SUGGESTION", server, suggestion_id).author()
|
||||||
|
op_id = int(op_info[0])
|
||||||
|
op = await self.bot.fetch_user(op_id)
|
||||||
|
op_name = op.name
|
||||||
|
op_avatar = op.avatar_url
|
||||||
|
if not op:
|
||||||
|
op_name = str(op_info[1])
|
||||||
|
op_avatar = ctx.guild.icon_url
|
||||||
|
embed.set_author(name=f"Approved suggestion by {op_name}", icon_url=op_avatar)
|
||||||
|
# get number of reactions for approved / denied
|
||||||
|
up_emoji = self.bot.get_emoji(await self.config.guild(ctx.guild).up_emoji())
|
||||||
|
if not up_emoji:
|
||||||
|
up_emoji = "✅"
|
||||||
|
down_emoji = self.bot.get_emoji(await self.config.guild(ctx.guild).down_emoji())
|
||||||
|
if not down_emoji:
|
||||||
|
down_emoji = "❎"
|
||||||
|
reactions = oldmsg.reactions
|
||||||
|
num_up = 0
|
||||||
|
num_down = 0
|
||||||
|
for react in reactions:
|
||||||
|
if react.emoji == up_emoji:
|
||||||
|
num_up = react.count - 1 # minus 1 for bot
|
||||||
|
elif react.emoji == down_emoji:
|
||||||
|
num_down = react.count - 1 # minus 1 for bot
|
||||||
|
|
||||||
|
await self.config.custom("SUGGESTION", server, suggestion_id).num_up.set(num_up)
|
||||||
|
await self.config.custom("SUGGESTION", server, suggestion_id).num_down.set(num_down)
|
||||||
|
embed.add_field(name="Votes:", value=f"For: `{num_up}`, Against: `{num_down}`", inline=False)
|
||||||
|
|
||||||
|
if reason:
|
||||||
|
embed.add_field(name="Reason:", value=reason, inline=False)
|
||||||
|
await self.config.custom("SUGGESTION", server, suggestion_id).reason.set(True)
|
||||||
|
await self.config.custom("SUGGESTION", server, suggestion_id).rtext.set(reason)
|
||||||
|
if is_global:
|
||||||
|
await oldmsg.edit(content=content, embed=embed)
|
||||||
|
try:
|
||||||
|
await oldmsg.clear_reactions()
|
||||||
|
except discord.Forbidden:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if channel:
|
||||||
|
await oldmsg.delete()
|
||||||
|
nmsg = await channel.send(content=content, embed=embed)
|
||||||
|
await self.config.custom("SUGGESTION", server, suggestion_id).msg_id.set(nmsg.id)
|
||||||
|
else:
|
||||||
|
if not await self.config.guild(ctx.guild).same():
|
||||||
|
await oldmsg.delete()
|
||||||
|
await self.config.custom("SUGGESTION", server, suggestion_id).msg_id.set(1)
|
||||||
|
else:
|
||||||
|
await oldmsg.edit(content=content, embed=embed)
|
||||||
|
try:
|
||||||
|
await oldmsg.clear_reactions()
|
||||||
|
except discord.Forbidden:
|
||||||
|
pass
|
||||||
|
await self.config.custom("SUGGESTION", server, suggestion_id).finished.set(True)
|
||||||
|
await self.config.custom("SUGGESTION", server, suggestion_id).approved.set(True)
|
||||||
|
await ctx.tick()
|
||||||
|
|
||||||
|
try:
|
||||||
|
await op.send(content="Your suggestion has been approved!", embed=embed)
|
||||||
|
except discord.Forbidden:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@checks.admin_or_permissions(administrator=True)
|
||||||
|
@commands.command()
|
||||||
|
@commands.guild_only()
|
||||||
|
@checks.bot_has_permissions(manage_messages=True)
|
||||||
|
async def reject(
|
||||||
|
self,
|
||||||
|
ctx: commands.Context,
|
||||||
|
suggestion_id: int,
|
||||||
|
is_global: Optional[bool] = False,
|
||||||
|
*,
|
||||||
|
reason: str = "",
|
||||||
|
):
|
||||||
|
"""Reject a suggestion. Reason is optional."""
|
||||||
|
if is_global:
|
||||||
|
if await self.config.toggle():
|
||||||
|
if ctx.author.id != self.bot.owner_id:
|
||||||
|
return await ctx.send("Uh oh, you're not my owner.")
|
||||||
|
server = 1
|
||||||
|
global_guild = self.bot.get_guild(await self.config.server_id())
|
||||||
|
oldchannel = get(global_guild.text_channels, id=await self.config.channel_id())
|
||||||
|
else:
|
||||||
|
return await ctx.send("Global suggestions aren't enabled.")
|
||||||
|
else:
|
||||||
|
server = ctx.guild.id
|
||||||
|
oldchannel = get(
|
||||||
|
ctx.guild.text_channels,
|
||||||
|
id=await self.config.guild(ctx.guild).suggest_id(),
|
||||||
|
)
|
||||||
|
channel = get(
|
||||||
|
ctx.guild.text_channels,
|
||||||
|
id=await self.config.guild(ctx.guild).reject_id(),
|
||||||
|
)
|
||||||
|
msg_id = await self.config.custom("SUGGESTION", server, suggestion_id).msg_id()
|
||||||
|
if msg_id != 0:
|
||||||
|
if await self.config.custom("SUGGESTION", server, suggestion_id).finished():
|
||||||
|
return await ctx.send("This suggestion has been finished already.")
|
||||||
|
try:
|
||||||
|
oldmsg = await oldchannel.fetch_message(id=msg_id)
|
||||||
|
except discord.NotFound:
|
||||||
|
return await ctx.send("Uh oh, message with this ID doesn't exist.")
|
||||||
|
if not oldmsg:
|
||||||
|
return await ctx.send("Uh oh, message with this ID doesn't exist.")
|
||||||
|
embed = oldmsg.embeds[0]
|
||||||
|
content = oldmsg.content
|
||||||
|
# change to red for denied
|
||||||
|
embed.color = discord.Color.from_rgb(255, 0, 0)
|
||||||
|
op_info = await self.config.custom("SUGGESTION", server, suggestion_id).author()
|
||||||
|
op_id = int(op_info[0])
|
||||||
|
op = await self.bot.fetch_user(op_id)
|
||||||
|
op_name = op.name
|
||||||
|
op_avatar = op.avatar_url
|
||||||
|
if not op:
|
||||||
|
op_name = str(op_info[1])
|
||||||
|
op_avatar = ctx.guild.icon_url
|
||||||
|
embed.set_author(name=f"Rejected suggestion by {op_name}", icon_url=op_avatar)
|
||||||
|
|
||||||
|
# get number of reactions for approved / denied
|
||||||
|
up_emoji = self.bot.get_emoji(await self.config.guild(ctx.guild).up_emoji())
|
||||||
|
if not up_emoji:
|
||||||
|
up_emoji = "✅"
|
||||||
|
down_emoji = self.bot.get_emoji(await self.config.guild(ctx.guild).down_emoji())
|
||||||
|
if not down_emoji:
|
||||||
|
down_emoji = "❎"
|
||||||
|
|
||||||
|
reactions = oldmsg.reactions
|
||||||
|
num_up = 0
|
||||||
|
num_down = 0
|
||||||
|
for react in reactions:
|
||||||
|
if react.emoji == up_emoji:
|
||||||
|
num_up = react.count - 1 # minus 1 for bot
|
||||||
|
elif react.emoji == down_emoji:
|
||||||
|
num_down = react.count - 1 # minus 1 for bot
|
||||||
|
|
||||||
|
await self.config.custom("SUGGESTION", server, suggestion_id).num_up.set(num_up)
|
||||||
|
await self.config.custom("SUGGESTION", server, suggestion_id).num_down.set(num_down)
|
||||||
|
embed.add_field(name="Votes:", value=f"For: `{num_up}`, Against: `{num_down}`", inline=False)
|
||||||
|
if reason:
|
||||||
|
embed.add_field(name="Reason:", value=reason, inline=False)
|
||||||
|
await self.config.custom("SUGGESTION", server, suggestion_id).reason.set(True)
|
||||||
|
await self.config.custom("SUGGESTION", server, suggestion_id).rtext.set(reason)
|
||||||
|
if is_global:
|
||||||
|
await oldmsg.edit(content=content, embed=embed)
|
||||||
|
try:
|
||||||
|
await oldmsg.clear_reactions()
|
||||||
|
except discord.Forbidden:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if channel:
|
||||||
|
await oldmsg.delete()
|
||||||
|
nmsg = await channel.send(content=content, embed=embed)
|
||||||
|
await self.config.custom("SUGGESTION", server, suggestion_id).msg_id.set(nmsg.id)
|
||||||
|
else:
|
||||||
|
if not await self.config.guild(ctx.guild).same():
|
||||||
|
await oldmsg.delete()
|
||||||
|
await self.config.custom("SUGGESTION", server, suggestion_id).msg_id.set(1)
|
||||||
|
else:
|
||||||
|
await oldmsg.edit(content=content, embed=embed)
|
||||||
|
try:
|
||||||
|
await oldmsg.clear_reactions()
|
||||||
|
except discord.Forbidden:
|
||||||
|
pass
|
||||||
|
await self.config.custom("SUGGESTION", server, suggestion_id).finished.set(True)
|
||||||
|
await self.config.custom("SUGGESTION", server, suggestion_id).rejected.set(True)
|
||||||
|
await ctx.tick()
|
||||||
|
|
||||||
|
try:
|
||||||
|
await op.send(content="Your suggestion has been rejected!", embed=embed)
|
||||||
|
except discord.Forbidden:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@checks.admin_or_permissions(administrator=True)
|
||||||
|
@commands.command()
|
||||||
|
@commands.guild_only()
|
||||||
|
@checks.bot_has_permissions(manage_messages=True)
|
||||||
|
async def addreason(
|
||||||
|
self,
|
||||||
|
ctx: commands.Context,
|
||||||
|
suggestion_id: int,
|
||||||
|
is_global: Optional[bool] = False,
|
||||||
|
*,
|
||||||
|
reason: str,
|
||||||
|
):
|
||||||
|
"""Add a reason to a suggestion.
|
||||||
|
|
||||||
|
Only works for non global suggestions."""
|
||||||
|
if is_global:
|
||||||
|
if await self.config.toggle():
|
||||||
|
if ctx.author.id != self.bot.owner_id:
|
||||||
|
return await ctx.send("Uh oh, you're not my owner.")
|
||||||
|
server = 1
|
||||||
|
global_guild = self.bot.get_guild(await self.config.server_id())
|
||||||
|
channel = get(global_guild.text_channels, id=await self.config.channel_id())
|
||||||
|
else:
|
||||||
|
return await ctx.send("Global suggestions aren't enabled.")
|
||||||
|
else:
|
||||||
|
server = ctx.guild.id
|
||||||
|
if not await self.config.guild(ctx.guild).same():
|
||||||
|
channel = get(
|
||||||
|
ctx.guild.text_channels,
|
||||||
|
id=await self.config.guild(ctx.guild).reject_id(),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
channel = get(
|
||||||
|
ctx.guild.text_channels,
|
||||||
|
id=await self.config.guild(ctx.guild).suggest_id(),
|
||||||
|
)
|
||||||
|
msg_id = await self.config.custom("SUGGESTION", server, suggestion_id).msg_id()
|
||||||
|
if msg_id != 0:
|
||||||
|
if await self.config.custom("SUGGESTION", server, suggestion_id).reason():
|
||||||
|
return await ctx.send("This suggestion already has a reason.")
|
||||||
|
content, embed = await self._build_suggestion(ctx, ctx.author.id, ctx.guild.id, suggestion_id, is_global)
|
||||||
|
embed.add_field(name="Reason:", value=reason, inline=False)
|
||||||
|
msg = await channel.fetch_message(id=msg_id)
|
||||||
|
if msg:
|
||||||
|
await msg.edit(content=content, embed=embed)
|
||||||
|
await self.config.custom("SUGGESTION", server, suggestion_id).reason.set(True)
|
||||||
|
await self.config.custom("SUGGESTION", server, suggestion_id).rtext.set(reason)
|
||||||
|
await ctx.tick()
|
||||||
|
|
||||||
|
@checks.admin_or_permissions(administrator=True)
|
||||||
|
@commands.command()
|
||||||
|
@commands.guild_only()
|
||||||
|
async def showsuggestion(
|
||||||
|
self,
|
||||||
|
ctx: commands.Context,
|
||||||
|
suggestion_id: int,
|
||||||
|
is_global: Optional[bool] = False,
|
||||||
|
):
|
||||||
|
"""Show a suggestion."""
|
||||||
|
content, embed = await self._build_suggestion(ctx, ctx.author.id, ctx.guild.id, suggestion_id, is_global)
|
||||||
|
await ctx.send(content=content, embed=embed)
|
||||||
|
|
||||||
|
@checks.admin_or_permissions(administrator=True)
|
||||||
|
@commands.group(autohelp=True)
|
||||||
|
@commands.guild_only()
|
||||||
|
async def setsuggest(self, ctx: commands.Context):
|
||||||
|
"""Suggestion settings"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@checks.bot_has_permissions(manage_channels=True)
|
||||||
|
@setsuggest.command(name="setup")
|
||||||
|
async def setsuggest_setup(self, ctx: commands.Context):
|
||||||
|
""" Go through the initial setup process. """
|
||||||
|
await self.config.guild(ctx.guild).same.set(False)
|
||||||
|
await self.config.guild(ctx.guild).suggest_id.set(None)
|
||||||
|
await self.config.guild(ctx.guild).approve_id.set(None)
|
||||||
|
await self.config.guild(ctx.guild).reject_id.set(None)
|
||||||
|
predchan = MessagePredicate.valid_text_channel(ctx)
|
||||||
|
overwrites = {
|
||||||
|
ctx.guild.default_role: discord.PermissionOverwrite(send_messages=False),
|
||||||
|
ctx.guild.me: discord.PermissionOverwrite(send_messages=True),
|
||||||
|
}
|
||||||
|
msg = await ctx.send("Do you already have your channel(s) done?")
|
||||||
|
start_adding_reactions(msg, ReactionPredicate.YES_OR_NO_EMOJIS)
|
||||||
|
pred = ReactionPredicate.yes_or_no(msg, ctx.author)
|
||||||
|
try:
|
||||||
|
await self.bot.wait_for("reaction_add", timeout=30, check=pred)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
await msg.delete()
|
||||||
|
return await ctx.send("You took too long. Try again, please.")
|
||||||
|
if not pred.result:
|
||||||
|
await msg.delete()
|
||||||
|
suggestions = get(ctx.guild.text_channels, name="suggestions")
|
||||||
|
if not suggestions:
|
||||||
|
suggestions = await ctx.guild.create_text_channel(
|
||||||
|
"suggestions", overwrites=overwrites, reason="Suggestion cog setup"
|
||||||
|
)
|
||||||
|
await self.config.guild(ctx.guild).suggest_id.set(suggestions.id)
|
||||||
|
|
||||||
|
msg = await ctx.send(
|
||||||
|
"Do you want to use the same channel for approved and rejected suggestions? (If yes, they won't be reposted anywhere, only their title will change accordingly.)"
|
||||||
|
)
|
||||||
|
start_adding_reactions(msg, ReactionPredicate.YES_OR_NO_EMOJIS)
|
||||||
|
pred = ReactionPredicate.yes_or_no(msg, ctx.author)
|
||||||
|
try:
|
||||||
|
await self.bot.wait_for("reaction_add", timeout=30, check=pred)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
await msg.delete()
|
||||||
|
return await ctx.send("You took too long. Try again, please.")
|
||||||
|
if pred.result:
|
||||||
|
await msg.delete()
|
||||||
|
await self.config.guild(ctx.guild).same.set(True)
|
||||||
|
else:
|
||||||
|
await msg.delete()
|
||||||
|
approved = get(ctx.guild.text_channels, name="approved-suggestions")
|
||||||
|
if not approved:
|
||||||
|
msg = await ctx.send("Do you want to have an approved suggestions channel?")
|
||||||
|
start_adding_reactions(msg, ReactionPredicate.YES_OR_NO_EMOJIS)
|
||||||
|
pred = ReactionPredicate.yes_or_no(msg, ctx.author)
|
||||||
|
try:
|
||||||
|
await self.bot.wait_for("reaction_add", timeout=30, check=pred)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
await msg.delete()
|
||||||
|
return await ctx.send("You took too long. Try again, please.")
|
||||||
|
if pred.result:
|
||||||
|
approved = await ctx.guild.create_text_channel(
|
||||||
|
"approved-suggestions",
|
||||||
|
overwrites=overwrites,
|
||||||
|
reason="Suggestion cog setup",
|
||||||
|
)
|
||||||
|
await self.config.guild(ctx.guild).approve_id.set(approved.id)
|
||||||
|
await msg.delete()
|
||||||
|
else:
|
||||||
|
await self.config.guild(ctx.guild).approve_id.set(approved.id)
|
||||||
|
rejected = get(ctx.guild.text_channels, name="rejected-suggestions")
|
||||||
|
if not rejected:
|
||||||
|
msg = await ctx.send("Do you want to have a rejected suggestions channel?")
|
||||||
|
start_adding_reactions(msg, ReactionPredicate.YES_OR_NO_EMOJIS)
|
||||||
|
pred = ReactionPredicate.yes_or_no(msg, ctx.author)
|
||||||
|
try:
|
||||||
|
await self.bot.wait_for("reaction_add", timeout=30, check=pred)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
await msg.delete()
|
||||||
|
return await ctx.send("You took too long. Try again, please.")
|
||||||
|
if pred.result:
|
||||||
|
rejected = await ctx.guild.create_text_channel(
|
||||||
|
"rejected-suggestions",
|
||||||
|
overwrites=overwrites,
|
||||||
|
reason="Suggestion cog setup",
|
||||||
|
)
|
||||||
|
await self.config.guild(ctx.guild).reject_id.set(rejected.id)
|
||||||
|
await msg.delete()
|
||||||
|
else:
|
||||||
|
await self.config.guild(ctx.guild).reject_id.set(rejected.id)
|
||||||
|
else:
|
||||||
|
await msg.delete()
|
||||||
|
msg = await ctx.send("Mention the channel where you want me to post new suggestions.")
|
||||||
|
try:
|
||||||
|
await self.bot.wait_for("message", timeout=30, check=predchan)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
await msg.delete()
|
||||||
|
return await ctx.send("You took too long. Try again, please.")
|
||||||
|
suggestion = predchan.result
|
||||||
|
await self.config.guild(ctx.guild).suggest_id.set(suggestion.id)
|
||||||
|
await msg.delete()
|
||||||
|
|
||||||
|
msg = await ctx.send(
|
||||||
|
"Do you want to use the same channel for approved and rejected suggestions? (If yes, they won't be reposted anywhere, only their title will change accordingly.)"
|
||||||
|
)
|
||||||
|
start_adding_reactions(msg, ReactionPredicate.YES_OR_NO_EMOJIS)
|
||||||
|
pred = ReactionPredicate.yes_or_no(msg, ctx.author)
|
||||||
|
try:
|
||||||
|
await self.bot.wait_for("reaction_add", timeout=30, check=pred)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
await msg.delete()
|
||||||
|
return await ctx.send("You took too long. Try again, please.")
|
||||||
|
if pred.result:
|
||||||
|
await msg.delete()
|
||||||
|
await self.config.guild(ctx.guild).same.set(True)
|
||||||
|
else:
|
||||||
|
await msg.delete()
|
||||||
|
msg = await ctx.send("Do you want to have an approved suggestions channel?")
|
||||||
|
start_adding_reactions(msg, ReactionPredicate.YES_OR_NO_EMOJIS)
|
||||||
|
pred = ReactionPredicate.yes_or_no(msg, ctx.author)
|
||||||
|
try:
|
||||||
|
await self.bot.wait_for("reaction_add", timeout=30, check=pred)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
await msg.delete()
|
||||||
|
return await ctx.send("You took too long. Try again, please.")
|
||||||
|
if pred.result:
|
||||||
|
await msg.delete()
|
||||||
|
msg = await ctx.send("Mention the channel where you want me to post approved suggestions.")
|
||||||
|
try:
|
||||||
|
await self.bot.wait_for("message", timeout=30, check=predchan)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
await msg.delete()
|
||||||
|
return await ctx.send("You took too long. Try again, please.")
|
||||||
|
approved = predchan.result
|
||||||
|
await self.config.guild(ctx.guild).approve_id.set(approved.id)
|
||||||
|
await msg.delete()
|
||||||
|
|
||||||
|
msg = await ctx.send("Do you want to have a rejected suggestions channel?")
|
||||||
|
start_adding_reactions(msg, ReactionPredicate.YES_OR_NO_EMOJIS)
|
||||||
|
pred = ReactionPredicate.yes_or_no(msg, ctx.author)
|
||||||
|
try:
|
||||||
|
await self.bot.wait_for("reaction_add", timeout=30, check=pred)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
await msg.delete()
|
||||||
|
return await ctx.send("You took too long. Try again, please.")
|
||||||
|
if pred.result:
|
||||||
|
await msg.delete()
|
||||||
|
msg = await ctx.send("Mention the channel where you want me to post rejected suggestions.")
|
||||||
|
try:
|
||||||
|
await self.bot.wait_for("message", timeout=30, check=predchan)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
await msg.delete()
|
||||||
|
return await ctx.send("You took too long. Try again, please.")
|
||||||
|
rejected = predchan.result
|
||||||
|
await self.config.guild(ctx.guild).reject_id.set(rejected.id)
|
||||||
|
await msg.delete()
|
||||||
|
await ctx.send("You have finished the setup! Please, move your channels to the category you want them in.")
|
||||||
|
|
||||||
|
@checks.bot_has_permissions(add_reactions=True)
|
||||||
|
@setsuggest.command(name="upemoji")
|
||||||
|
async def setsuggest_upemoji(self, ctx: commands.Context, up_emoji: discord.Emoji = None):
|
||||||
|
""" Set custom reactions emoji instead of ✅. """
|
||||||
|
if not up_emoji:
|
||||||
|
await self.config.guild(ctx.guild).up_emoji.set(None)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
await ctx.message.add_reaction(up_emoji)
|
||||||
|
except discord.HTTPException:
|
||||||
|
return await ctx.send("Uh oh, I cannot use that emoji.")
|
||||||
|
await self.config.guild(ctx.guild).up_emoji.set(up_emoji.id)
|
||||||
|
await ctx.tick()
|
||||||
|
|
||||||
|
@checks.bot_has_permissions(add_reactions=True)
|
||||||
|
@setsuggest.command(name="downemoji")
|
||||||
|
async def setsuggest_downemoji(self, ctx: commands.Context, down_emoji: discord.Emoji = None):
|
||||||
|
""" Set custom reactions emoji instead of ❎. """
|
||||||
|
if not down_emoji:
|
||||||
|
await self.config.guild(ctx.guild).up_emoji.set(None)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
await ctx.message.add_reaction(down_emoji)
|
||||||
|
except discord.HTTPException:
|
||||||
|
return await ctx.send("Uh oh, I cannot use that emoji.")
|
||||||
|
await self.config.guild(ctx.guild).down_emoji.set(down_emoji.id)
|
||||||
|
await ctx.tick()
|
||||||
|
|
||||||
|
@checks.bot_has_permissions(manage_messages=True)
|
||||||
|
@setsuggest.command(name="autodelete")
|
||||||
|
async def setsuggest_autodelete(self, ctx: commands.Context, on_off: bool = None):
|
||||||
|
""" Toggle whether after `[p]suggest`, the bot deletes the message. """
|
||||||
|
target_state = on_off if on_off else not (await self.config.guild(ctx.guild).delete_suggest())
|
||||||
|
await self.config.guild(ctx.guild).delete_suggest.set(target_state)
|
||||||
|
if target_state:
|
||||||
|
await ctx.send("Auto deletion is now enabled.")
|
||||||
|
else:
|
||||||
|
await ctx.send("Auto deletion is now disabled.")
|
||||||
|
|
||||||
|
@setsuggest.group(autohelp=True)
|
||||||
|
@checks.is_owner()
|
||||||
|
@commands.guild_only()
|
||||||
|
async def setglobal(self, ctx: commands.Context):
|
||||||
|
"""Global suggestions settings.
|
||||||
|
|
||||||
|
There is nothing like approved or rejected channels because global suggestions are meant to be for the bot only and will only work if it is sent in a server where normal suggestions are disabled."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@setglobal.command(name="toggle")
|
||||||
|
async def setsuggest_setglobal_toggle(self, ctx: commands.Context, on_off: bool = None):
|
||||||
|
"""Toggle global suggestions.
|
||||||
|
If `on_off` is not provided, the state will be flipped."""
|
||||||
|
target_state = on_off if on_off else not (await self.config.toggle())
|
||||||
|
await self.config.toggle.set(target_state)
|
||||||
|
if target_state:
|
||||||
|
await ctx.send("Global suggestions are now enabled.")
|
||||||
|
else:
|
||||||
|
await ctx.send("Global suggestions are now disabled.")
|
||||||
|
|
||||||
|
@setglobal.command(name="channel")
|
||||||
|
async def setsuggest_setglobal_channel(
|
||||||
|
self,
|
||||||
|
ctx: commands.Context,
|
||||||
|
server: discord.Guild = None,
|
||||||
|
channel: discord.TextChannel = None,
|
||||||
|
):
|
||||||
|
"""Add channel where global suggestions should be sent."""
|
||||||
|
if not server:
|
||||||
|
server = ctx.guild
|
||||||
|
if not channel:
|
||||||
|
channel = ctx.channel
|
||||||
|
await self.config.server_id.set(server.id)
|
||||||
|
await self.config.channel_id.set(channel.id)
|
||||||
|
await ctx.send(f"{channel.mention} has been saved for global suggestions.")
|
||||||
|
|
||||||
|
@setglobal.command(name="ignore")
|
||||||
|
async def setsuggest_setglobal_ignore(self, ctx: commands.Context, server: discord.Guild = None):
|
||||||
|
""" Ignore suggestions from the server. """
|
||||||
|
if not server:
|
||||||
|
server = ctx.guild
|
||||||
|
if server.id not in await self.config.ignore():
|
||||||
|
async with self.config.ignore() as ignore:
|
||||||
|
ignore.append(server.id)
|
||||||
|
await ctx.send(f"{server.name} has been added into the ignored list.")
|
||||||
|
else:
|
||||||
|
await ctx.send(f"{server.name} is already in the ignored list.")
|
||||||
|
|
||||||
|
@setglobal.command(name="unignore")
|
||||||
|
async def setsuggest_setglobal_unignore(self, ctx: commands.Context, server: discord.Guild = None):
|
||||||
|
""" Remove server from the ignored list. """
|
||||||
|
if not server:
|
||||||
|
server = ctx.guild
|
||||||
|
if server.id in await self.config.ignore():
|
||||||
|
async with self.config.ignore() as ignore:
|
||||||
|
ignore.remove(server.id)
|
||||||
|
await ctx.send(f"{server.name} has been removed from the ignored list.")
|
||||||
|
else:
|
||||||
|
await ctx.send(f"{server.name} already isn't in the ignored list.")
|
||||||
|
|
||||||
|
async def _build_suggestion(self, ctx, author_id, server_id, suggestion_id, is_global):
|
||||||
|
if is_global:
|
||||||
|
if await self.config.toggle():
|
||||||
|
if author_id != self.bot.owner_id:
|
||||||
|
return await ctx.send("Uh oh, you're not my owner.")
|
||||||
|
server = 1
|
||||||
|
if await self.config.custom("SUGGESTION", server, suggestion_id).msg_id() != 0:
|
||||||
|
content = f"Global suggestion #{suggestion_id}"
|
||||||
|
else:
|
||||||
|
return await ctx.send("Uh oh, that suggestion doesn't seem to exist.")
|
||||||
|
else:
|
||||||
|
return await ctx.send("Global suggestions aren't enabled.")
|
||||||
|
if not is_global:
|
||||||
|
server = server_id
|
||||||
|
if await self.config.custom("SUGGESTION", server, suggestion_id).msg_id() != 0:
|
||||||
|
content = f"Suggestion #{suggestion_id}"
|
||||||
|
else:
|
||||||
|
return await ctx.send("Uh oh, that suggestion doesn't seem to exist.")
|
||||||
|
op_info = await self.config.custom("SUGGESTION", server, suggestion_id).author()
|
||||||
|
op_id = int(op_info[0])
|
||||||
|
op = await self.bot.fetch_user(op_id)
|
||||||
|
if op:
|
||||||
|
op_name = op.name
|
||||||
|
op_discriminator = op.discriminator
|
||||||
|
op_avatar = op.avatar_url
|
||||||
|
else:
|
||||||
|
op_name = str(op_info[1])
|
||||||
|
op_discriminator = int(op_info[2])
|
||||||
|
op_avatar = ctx.guild.icon_url
|
||||||
|
|
||||||
|
if not await self.config.custom("SUGGESTION", server, suggestion_id).finished():
|
||||||
|
atext = f"Suggestion by {op_name}"
|
||||||
|
else:
|
||||||
|
if await self.config.custom("SUGGESTION", server, suggestion_id).approved():
|
||||||
|
atext = f"Approved suggestion by {op_name}"
|
||||||
|
elif await self.config.custom("SUGGESTION", server, suggestion_id).rejected():
|
||||||
|
atext = f"Rejected suggestion by {op_name}"
|
||||||
|
|
||||||
|
embed = discord.Embed(
|
||||||
|
color=await ctx.embed_colour(),
|
||||||
|
description=await self.config.custom("SUGGESTION", server, suggestion_id).stext(),
|
||||||
|
)
|
||||||
|
embed.set_author(name=atext, icon_url=op_avatar)
|
||||||
|
embed.set_footer(text=f"Suggested by {op_name}#{op_discriminator} ({op_id})")
|
||||||
|
|
||||||
|
if await self.config.custom("SUGGESTION", server, suggestion_id).reason():
|
||||||
|
embed.add_field(
|
||||||
|
name="Reason:",
|
||||||
|
value=await self.config.custom("SUGGESTION", server, suggestion_id).rtext(),
|
||||||
|
inline=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
if await self.config.custom("SUGGESTION", server, suggestion_id).finished():
|
||||||
|
num_up = await self.config.custom("SUGGESTION", server, suggestion_id).num_up()
|
||||||
|
num_down = await self.config.custom("SUGGESTION", server, suggestion_id).num_down()
|
||||||
|
embed.add_field(name="Votes:", value=f"For: `{num_up}`, Against: `{num_down}`", inline=False)
|
||||||
|
|
||||||
|
return content, embed
|
Loading…
Reference in a new issue