import discord, asyncio from discord.ext import commands from core.database import Servers from core.embeds import Embeds from core.files import Data class BumpSetup(commands.Cog): def __init__(self, bot): self.bot = bot self.config = Data("config").yaml_read() self.settings = Data("settings").json_read() global setting_up setting_up = [] @commands.Cog.listener('on_guild_remove') async def remove_guild(self, guild): Servers(guild.id).delete() @commands.guild_only() @commands.has_permissions(manage_guild=True) @commands.check(lambda ctx: ctx.guild not in setting_up) @commands.command() async def setup(self, ctx): server = Servers(ctx.guild.id) custom_prefix = server.get_prefix() prefix = custom_prefix if custom_prefix else self.config["prefix"] if server.get(): return await ctx.send(embed=Embeds(f"This server was already setup! Use `{prefix}delete` to initialize another setup!").error()) embed = discord.Embed( title="🔄 Setting Up...", color=discord.Color.green() ) embed.set_author(name=str(ctx.author), icon_url=ctx.author.display_avatar.url) embed.description = "Enter your **Server's Description**! Remember that it must be between **10** and **2048** characters long!" await ctx.send(embed=embed) try: description = (await self.bot.wait_for( 'message', timeout=120, check=lambda message: message.author.id == ctx.author.id and len(message.content) and message.channel.id == ctx.channel.id )).content if len(description) > 2048: return await ctx.send(embed=Embeds("Setup canceled, your description is too long!").error()) elif len(description) < 10: return await ctx.send(embed=Embeds("Setup canceled, your description is too short!").error()) except asyncio.TimeoutError: return await ctx.send(embed=Embeds("Setup canceled, timeout!").error()) embed.description = "Enter your **Server's Tags**, separated by commas (e.g., `gaming, fun, community`)." await ctx.send(embed=embed) try: tags_input = (await self.bot.wait_for( 'message', timeout=120, check=lambda message: message.author.id == ctx.author.id and len(message.content) and message.channel.id == ctx.channel.id )).content if len(tags_input) > 200: return await ctx.send(embed=Embeds("Setup canceled, your tag list is too long! (Max 200 characters)").error()) except asyncio.TimeoutError: return await ctx.send(embed=Embeds("Setup canceled, timeout!").error()) # --- NEW VANITY URL STEP --- embed.description = "Enter your server's **vanity URL code** (the part after `discord.gg/`).\nType `none` if you don't have one." await ctx.send(embed=embed) try: vanity_code = (await self.bot.wait_for('message', timeout=120, check=lambda m: m.author == ctx.author and m.channel == ctx.channel)).content if vanity_code.lower() in ['none', 'skip', 'no']: vanity_code = None except asyncio.TimeoutError: return await ctx.send(embed=Embeds("Setup canceled, timeout!").error()) # --- END OF NEW STEP --- embed.description = "Enter the channel to fetch invites from. Make sure the bot has permission to **Create Instant Invite** for it!" await ctx.send(embed=embed) try: invite_channel = await commands.TextChannelConverter().convert(ctx, (await self.bot.wait_for( 'message', timeout=120, check=lambda message: message.author.id == ctx.author.id and len(message.content) and message.channel.id == ctx.channel.id )).content) if not invite_channel.permissions_for(ctx.me).create_instant_invite: return await ctx.send(embed=Embeds("Setup canceled, I cannot **Create Instant Invites** for that channel!").error()) new_invite = await invite_channel.create_invite(max_uses=0, reason="Server listing invite") except asyncio.TimeoutError: return await ctx.send(embed=Embeds("Setup canceled, timeout!").error()) except commands.ChannelNotFound: return await ctx.send(embed=Embeds("Setup canceled, channel not found!").error()) embed.description = "Enter the channel to send bumps at. Make sure the bot has permission to **Manage Webhooks** for it!" await ctx.send(embed=embed) try: listing = await commands.TextChannelConverter().convert(ctx, (await self.bot.wait_for( 'message', timeout=120, check=lambda message: message.author.id == ctx.author.id and len(message.content) and message.channel.id == ctx.channel.id )).content) if not listing.permissions_for(ctx.me).manage_webhooks: return await ctx.send(embed=Embeds("Setup canceled, I cannot **Manage Webhooks** for that channel!").error()) except asyncio.TimeoutError: return await ctx.send(embed=Embeds("Setup canceled, timeout!").error()) except commands.ChannelNotFound: return await ctx.send(embed=Embeds("Setup canceled, channel not found!").error()) embed.description = "Enter a `HEX` color for your bump embed!" await ctx.send(embed=embed) try: color = int((await self.bot.wait_for( 'message', timeout=120, check=lambda message: message.author.id == ctx.author.id and len(message.content) and message.channel.id == ctx.channel.id )).content.replace("#", ""), 16) except asyncio.TimeoutError: return await ctx.send(embed=Embeds("Setup canceled, timeout!").error()) except ValueError: return await ctx.send(embed=Embeds("Setup canceled, invalid color!").error()) webhook = await listing.create_webhook(name=self.config.get('bot_name', 'Bump Bot')) server.add( webhook=webhook.id, invite_code=new_invite.code, vanity_code=vanity_code, color=color, description=description, icon_url=str(ctx.guild.icon.url if ctx.guild.icon else None), server_name=ctx.guild.name, tags=tags_input ) description_text = "The server was added to the Database and can now be bumped! Good luck on your server's growth! You can always use the delete command to remove it." if self.settings.get('enable_serverlist'): server_name_url = ctx.guild.name.replace(' ', '-') serverlist_url = self.settings.get('serverlist_url', '') description_text += f"\n\nYour server was also added to our Server List! [Check it out!]({serverlist_url}server/{server_name_url})" return await ctx.send(embed=discord.Embed( title="👌 Setup Complete", description=description_text, color=discord.Color.green() )) @commands.guild_only() @commands.has_permissions(manage_guild=True) @commands.check(lambda ctx: ctx.guild not in setting_up) @commands.command() async def delete(self, ctx): server = Servers(ctx.guild.id) if not server.get(): return await ctx.send(embed=Embeds("The server does not have any data in the Database!").error()) confirmation_message = await ctx.send(embed=discord.Embed( title="⚠️ Confirmation Required ⚠️", description=f"**{ctx.author}**, you're about to delete your server from the database! This will remove all data. **Are you sure?**", color=discord.Color.orange() )) emojis = ["✅", "❎"] for emoji in emojis: await confirmation_message.add_reaction(emoji) try: reaction, user = await self.bot.wait_for( 'reaction_add', timeout=120, check=lambda r, u: r.emoji in emojis and r.message.id == confirmation_message.id and u.id == ctx.author.id ) except asyncio.TimeoutError: await ctx.send(embed=Embeds("Server deletion canceled due to timeout!").error()) return await confirmation_message.delete() if reaction.emoji == emojis[1]: return await ctx.send(embed=Embeds("Server deletion canceled.").error()) cache_data = server.get() server.delete() setting_up.remove(ctx.guild) del_message = await ctx.send(embed=discord.Embed( title="🗑️ Server Deleted", description="The server was deleted from the database! You also can react below within one minute to restore it.", color=discord.Color.green() )) await del_message.add_reaction("♻️") try: await self.bot.wait_for( 'reaction_add', timeout=60, check=lambda r,u: r.emoji == "♻️" and r.message.id == del_message.id and u.id == ctx.author.id ) except asyncio.TimeoutError: try: if 'webhook' in cache_data: wh = await self.bot.fetch_webhook(cache_data['webhook']) await wh.delete() except: pass return await del_message.remove_reaction("♻️", self.bot.user) if Servers(ctx.guild.id).get(): try: if 'webhook' in cache_data: wh = await self.bot.fetch_webhook(cache_data['webhook']) await wh.delete() except: pass return await ctx.send(embed=discord.Embed( title="❎ Restore Failed", description="The server seems to have been setup from the beginning, therefore restore is not possible.", color=discord.Color.red() )) Servers(ctx.guild.id).add(**cache_data) return await ctx.send(embed=discord.Embed( title="♻️ Server Restored", description="Your server was restored, all data are safe and sound.", color=discord.Color.green() )) @setup.before_invoke @delete.before_invoke async def add_to_setting_up(self, ctx): setting_up.append(ctx.guild) @setup.after_invoke @delete.after_invoke async def remove_from_setting_up(self, ctx): try: setting_up.remove(ctx.guild) except: pass async def setup(bot): await bot.add_cog(BumpSetup(bot))