for drew

 avatar
hisoka
python
2 years ago
6.9 kB
3
Indexable
Never
import contextlib
import json
import logging
import os
import platform
import random
import string
import time
import traceback
from typing import Union

import discord
from captcha.image import ImageCaptcha
from colorama import Back, Fore, Style
from discord import ui
from discord.ext import commands

import settings

logger = settings.logging.getLogger("bot")

config = None
verify_channel = None
verify_role = None
verify_guild = None
length = 6


def run():
    class PersistentViewBot(commands.Bot):
        def __init__(self):
            intents = discord.Intents().all()
            super().__init__(command_prefix="-", intents=intents)

        async def setup_hook(self) -> None:
            self.add_view(VerifyButton())

    bot = PersistentViewBot()

    @bot.event
    async def on_ready():
        global config
        global verify_channel
        global verify_role
        global verify_guild
        prfx = (
            Fore.BLUE
            + time.strftime("%H:%M:%S PST", time.localtime())
            + Back.RESET
            + Fore.WHITE
            + Style.BRIGHT
        )
        print(f"{prfx} Loading config... ")
        for cog_file in settings.COGS_DIR.glob("*.py"):
            if cog_file != "__init__.py":
                await bot.load_extension(f"cogs.{cog_file.name[:-3]}")
        for cmd_file in settings.CMDS_DIR.glob("*.py"):
            if cmd_file.name != "__init__.py":
                await bot.load_extension(f"cmds.{cmd_file.name[:-3]}")
        try:
            config = json.loads(open("config.json", "r").read())
        except Exception:
            print(f"{prfx} No config found! Run -setup in your server!")
        else:
            verify_guild = bot.get_guild(config["guild"])
            verify_channel = bot.get_channel(config["channel"])
            verify_role = verify_guild.get_role(config["role"])

        synced = await bot.tree.sync()
        print(f"{prfx} Discord Version {Fore.CYAN}{discord.__version__}")
        print(f"{prfx} Python Version {Fore.CYAN}{str(platform.python_version())}")
        print(f"{prfx} Synced {Fore.CYAN}{len(synced)} Slash Command(s)")
        print(f"{prfx} Logged in as {Fore.CYAN}{bot.user} (ID #{bot.user.id})")
        print(f"{prfx} {Fore.LIGHTGREEN_EX} Bot is ready to go!")
        print("--------------------------------------------------- ")
        # logger.info(f"User: {bot.user} (ID: {bot.user.id})")

    class VerifyButton(discord.ui.View):
        def __init__(self):
            super().__init__(timeout=None)

        @discord.ui.button(label="Verify", custom_id="verify_button")
        async def verify(
            self,
            interaction: discord.Interaction,
            Button: discord.ui.Button,
        ):
            global config
            global verify_channel
            global verify_role
            global verify_guild
            global text
            text = "".join(
                random.choice(
                    string.ascii_uppercase + string.digits + string.ascii_lowercase
                )
                for _ in range(length)
            )
            file_name = "".join(
                random.choice(
                    string.ascii_uppercase + string.digits + string.ascii_lowercase
                )
                for _ in range(20)
            )
            image = ImageCaptcha(width=280, height=90)
            captcha = image.generate(text)
            # Print Captcha Text
            print(f"Captcha Code: {text}")

            image.write(text, f"captchas\\{file_name}.png")
            file = discord.File(
                f"captchas//{file_name}.png", filename=f"{file_name}.png"
            )
            embed = discord.Embed(
                title="Verification",
                description="This server is using Captcha Verification\n to protect their server.\n\nPlease type out the letters you see in\nthe captcha below.\n\n**Note:** The captcha is **case-sensitive.**",
                color=0x000001,
            )
            embed.set_footer(text="Captcha Verification by /bran#6666")
            embed.set_image(url=f"attachment://{file_name}.png")
            await interaction.response.send_message(
                embed=embed,
                file=file,
                ephemeral=True,
                view=MyView2(),
            )

    class MyView2(discord.ui.View):
        def __init__(self):
            super().__init__(timeout=None)

        # THIS MUST BE IN LINE WITH THE ABOVE DEF
        @discord.ui.button(
            label="Input Code",
            row=0,
            style=discord.ButtonStyle.secondary,
            custom_id="InputCode",
        )
        # SEND MODAL TO THE USER
        async def button_callback(self, interaction, button):
            await interaction.response.send_modal(MyModal())

    class MyModal(ui.Modal, title="Verification"):
        code = ui.TextInput(
            label="Captcha",
            placeholder="Input Captcha Code",
            style=discord.TextStyle.short,
        )

        async def on_submit(self, interaction: discord.Interaction):
            try:
                if self.code.value == text:
                    await interaction.user.add_roles(verify_role)
                    await interaction.response.send_message(
                        "You have been verified!", ephemeral=True
                    )
                    print("Correct code was submitted!")
                    return
                if self.code.value != text:
                    await interaction.response.send_message(
                        "Incorrect captcha code, please try again.", ephemeral=True
                    )
                    print("Incorrect code has been submitted.")
                return
            except Exception:
                await interaction.response.send_message(
                    "An error has occured, please try again.", ephemeral=True
                )
                print("_____________________________________")
                print("Captcha Code on_submit error")
                return

    @bot.tree.command(name="verify")
    async def verify(interaction: discord.Interaction):
        buttembed = discord.Embed(
            title="Server Verification",
            description="To access the server,, you need to pass verification first.",
            color=0x000001,
        )
        buttembed.set_footer(text="Captcha Verification by /bran#6666")
        await interaction.channel.send(
            content="",
            embed=buttembed,
            view=VerifyButton(),
        )

    bot.run(settings.DISCORD_TOKEN, root_logger=True)


if __name__ == "__main__":
    run()