From ea55180f5fce7178cc6c699f678c62208c5e32f6 Mon Sep 17 00:00:00 2001 From: Xynnix Date: Tue, 25 Jul 2023 21:55:19 -0400 Subject: [PATCH] PY Rewrite + EXE (Releases) --- .env.example | 4 + index.py | 261 +++++++++++++++++++++++++++++++++++++++++++++++ pm2.json | 8 ++ requirements.txt | 4 + start.bat | 43 ++++++++ utils/config.py | 36 +++++++ utils/http.py | 48 +++++++++ 7 files changed, 404 insertions(+) create mode 100644 .env.example create mode 100644 index.py create mode 100644 pm2.json create mode 100644 requirements.txt create mode 100644 start.bat create mode 100644 utils/config.py create mode 100644 utils/http.py diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..38a65d3 --- /dev/null +++ b/.env.example @@ -0,0 +1,4 @@ +REVOLT_TOKEN = token +REVOLT_PREFIX = ; +REVOLT_OWNER_ID = uID1,uID2 +LEWDS_API_URL = https://kyra.tk \ No newline at end of file diff --git a/index.py b/index.py new file mode 100644 index 0000000..eb443ee --- /dev/null +++ b/index.py @@ -0,0 +1,261 @@ +from revolt.ext import commands +import aiohttp +import revolt +import asyncio +import filetype +from io import BytesIO +from utils import http, config + +config = config.Config.from_env(".env") +print("Logging in...") + + +async def randomimageapi( + ctx: revolt.Message, + url: str, *endpoint: str +) -> revolt.Message: + try: + r = await http.get(url, res_method="json") + async with aiohttp.ClientSession() as session: + async with session.get(r.response) as resp: + buffer = BytesIO(await resp.read()) + + except aiohttp.ClientConnectorError: + return await ctx.channel.send("The API seems to be down...") + except aiohttp.ContentTypeError: + return await ctx.channel.send("The API returned an error...") + + fileinfo = filetype.guess(buffer) + fileExt = fileinfo.extension + await ctx.channel.send(attachments=[revolt.File(buffer.read(), filename=f"SPOILER_NSFW.{fileExt}")]) + return resp.close() + + +class Client(commands.CommandsClient): + async def get_prefix(self, client: revolt.Client): + return config.revolt_prefix + + async def on_ready(self): + print(f"Ready as: {self.user.name}#{self.user.discriminator}") + + @commands.command() + async def ping(self, ctx: commands.Context): + """ I wonder what this will do... """ + await ctx.send("pong") + + @commands.group(name="nsfw", aliases=[]) + async def nsfw(self, ctx: commands.Context): + """ Posts the requested type of NSFW Image """ + if ctx.channel.nsfw: + await ctx.channel.send(":-1:") + + @nsfw.command(name="hass") + async def _hass(self, ctx: commands.Context): + """ Posts the requested type of NSFW Image """ + if ctx.channel.nsfw: + await randomimageapi(ctx, "https://kyra.tk/nsfw/?hass", "file") + else: + return await ctx.channel.send("This channel must be an NSFW channel for this to work!") + + @nsfw.command(name="assgif") + async def _assgif(self, ctx: commands.Context): + """ Posts the requested type of NSFW Image """ + if ctx.channel.nsfw: + await randomimageapi(ctx, "https://kyra.tk/nsfw/?assgif", "file") + else: + return await ctx.channel.send("This channel must be an NSFW channel for this to work!") + + @nsfw.command(name="ass") + async def _ass(self, ctx: commands.Context): + """ Posts the requested type of NSFW Image """ + if ctx.channel.nsfw: + await randomimageapi(ctx, "https://kyra.tk/nsfw/?ass", "file") + else: + return await ctx.channel.send("This channel must be an NSFW channel for this to work!") + + @nsfw.command(name="boobs") + async def _boobs(self, ctx: commands.Context): + """ Posts the requested type of NSFW Image """ + if ctx.channel.nsfw: + await randomimageapi(ctx, "https://kyra.tk/nsfw/?boobs", "file") + else: + return await ctx.channel.send("This channel must be an NSFW channel for this to work!") + + @nsfw.command(name="hboobs") + async def _hboobs(self, ctx: commands.Context): + """ Posts the requested type of NSFW Image """ + if ctx.channel.nsfw: + await randomimageapi(ctx, "https://kyra.tk/nsfw/?hboobs", "file") + else: + return await ctx.channel.send("This channel must be an NSFW channel for this to work!") + + @nsfw.command(name="bbw") + async def _bbw(self, ctx: commands.Context): + """ Posts the requested type of NSFW Image """ + if ctx.channel.nsfw: + await randomimageapi(ctx, "https://kyra.tk/nsfw/?bbw", "file") + else: + return await ctx.channel.send("This channel must be an NSFW channel for this to work!") + + @nsfw.command(name="bdsm") + async def _bdsm(self, ctx: commands.Context): + """ Posts the requested type of NSFW Image """ + if ctx.channel.nsfw: + await randomimageapi(ctx, "https://kyra.tk/nsfw/?bdsm", "file") + else: + return await ctx.channel.send("This channel must be an NSFW channel for this to work!") + + @nsfw.command(name="blow") + async def _blow(self, ctx: commands.Context): + """ Posts the requested type of NSFW Image """ + if ctx.channel.nsfw: + await randomimageapi(ctx, "https://kyra.tk/nsfw/?blow", "file") + else: + return await ctx.channel.send("This channel must be an NSFW channel for this to work!") + + @nsfw.command(name="feet") + async def _feet(self, ctx: commands.Context): + """ Posts the requested type of NSFW Image """ + if ctx.channel.nsfw: + await randomimageapi(ctx, "https://kyra.tk/nsfw/?feet", "file") + else: + return await ctx.channel.send("This channel must be an NSFW channel for this to work!") + + @nsfw.command(name="hfeet") + async def _hfeet(self, ctx: commands.Context): + """ Posts the requested type of NSFW Image """ + if ctx.channel.nsfw: + await randomimageapi(ctx, "https://kyra.tk/nsfw/?hfeet", "file") + else: + return await ctx.channel.send("This channel must be an NSFW channel for this to work!") + + @nsfw.command(name="furfuta") + async def _furfuta(self, ctx: commands.Context): + """ Posts the requested type of NSFW Image """ + if ctx.channel.nsfw: + await randomimageapi(ctx, "https://kyra.tk/nsfw/?furfuta", "file") + else: + return await ctx.channel.send("This channel must be an NSFW channel for this to work!") + + @nsfw.command(name="furgif") + async def _furgif(self, ctx: commands.Context): + """ Posts the requested type of NSFW Image """ + if ctx.channel.nsfw: + await randomimageapi(ctx, "https://kyra.tk/nsfw/?furgif", "file") + else: + return await ctx.channel.send("This channel must be an NSFW channel for this to work!") + + @nsfw.command(name="futa") + async def _futa(self, ctx: commands.Context): + """ Posts the requested type of NSFW Image """ + if ctx.channel.nsfw: + await randomimageapi(ctx, "https://kyra.tk/nsfw/?futa", "file") + else: + return await ctx.channel.send("This channel must be an NSFW channel for this to work!") + + @nsfw.command(name="hthighs") + async def _hthighs(self, ctx: commands.Context): + """ Posts the requested type of NSFW Image """ + if ctx.channel.nsfw: + await randomimageapi(ctx, "https://kyra.tk/nsfw/?athighs", "file") + else: + return await ctx.channel.send("This channel must be an NSFW channel for this to work!") + + @nsfw.command(name="thighs") + async def _thighs(self, ctx: commands.Context): + """ Posts the requested type of NSFW Image """ + if ctx.channel.nsfw: + await randomimageapi(ctx, "https://kyra.tk/nsfw/?thighs", "file") + else: + return await ctx.channel.send("This channel must be an NSFW channel for this to work!") + + @nsfw.command(name="gifs") + async def _gifs(self, ctx: commands.Context): + """ Posts the requested type of NSFW Image """ + if ctx.channel.nsfw: + await randomimageapi(ctx, "https://kyra.tk/nsfw/?gifs", "file") + else: + return await ctx.channel.send("This channel must be an NSFW channel for this to work!") + + @nsfw.command(name="sex") + async def _sex(self, ctx: commands.Context): + """ Posts the requested type of NSFW Image """ + if ctx.channel.nsfw: + await randomimageapi(ctx, "https://kyra.tk/nsfw/?sex", "file") + else: + return await ctx.channel.send("This channel must be an NSFW channel for this to work!") + + @nsfw.command(name="femboy") + async def _femboy(self, ctx: commands.Context): + """ Posts the requested type of NSFW Image """ + if ctx.channel.nsfw: + await randomimageapi(ctx, "https://kyra.tk/nsfw/?irlfemb", "file") + else: + return await ctx.channel.send("This channel must be an NSFW channel for this to work!") + + @nsfw.command(name="hfemboy") + async def _hfemboy(self, ctx: commands.Context): + """ Posts the requested type of NSFW Image """ + if ctx.channel.nsfw: + await randomimageapi(ctx, "https://kyra.tk/nsfw/?femboy", "file") + else: + return await ctx.channel.send("This channel must be an NSFW channel for this to work!") + + @nsfw.command(name="slime") + async def _slime(self, ctx: commands.Context): + """ Posts the requested type of NSFW Image """ + if ctx.channel.nsfw: + await randomimageapi(ctx, "https://kyra.tk/nsfw/?slime", "file") + else: + return await ctx.channel.send("This channel must be an NSFW channel for this to work!") + + @nsfw.command(name="pantsu") + async def _pantsu(self, ctx: commands.Context): + """ Posts the requested type of NSFW Image """ + if ctx.channel.nsfw: + await randomimageapi(ctx, "https://kyra.tk/nsfw/?pantsu", "file") + else: + return await ctx.channel.send("This channel must be an NSFW channel for this to work!") + + @nsfw.command(name="milk") + async def _milk(self, ctx: commands.Context): + """ Posts the requested type of NSFW Image """ + if ctx.channel.nsfw: + await randomimageapi(ctx, "https://kyra.tk/nsfw/?milk", "file") + else: + return await ctx.channel.send("This channel must be an NSFW channel for this to work!") + + @nsfw.command(name="latex") + async def _latex(self, ctx: commands.Context): + """ Posts the requested type of NSFW Image """ + if ctx.channel.nsfw: + await randomimageapi(ctx, "https://kyra.tk/nsfw/?latex", "file") + else: + return await ctx.channel.send("This channel must be an NSFW channel for this to work!") + + @nsfw.command(name="hentai") + async def _hentai(self, ctx: commands.Context): + """ Posts the requested type of NSFW Image """ + if ctx.channel.nsfw: + await randomimageapi(ctx, "https://kyra.tk/nsfw/?hentai", "file") + else: + return await ctx.channel.send("This channel must be an NSFW channel for this to work!") + + @nsfw.command(name="yuri") + async def _yuri(self, ctx: commands.Context): + """ Posts the requested type of NSFW Image """ + if ctx.channel.nsfw: + await randomimageapi(ctx, "https://kyra.tk/nsfw/?yuri", "file") + else: + return await ctx.channel.send("This channel must be an NSFW channel for this to work!") + + +async def main(): + async with aiohttp.ClientSession() as session: + client = Client(session, config.revolt_token) + await client.start() + +try: + asyncio.run(main()) +except: + "" diff --git a/pm2.json b/pm2.json new file mode 100644 index 0000000..041f0ad --- /dev/null +++ b/pm2.json @@ -0,0 +1,8 @@ +{ + "apps": [{ + "name": "AhniRevolt.py", + "script": "index.py", + "interpreter": "python3.10", + "interpreter_args": "-u" + }] +} diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..624e183 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +revolt.py +psutil +python-dotenv +filetype \ No newline at end of file diff --git a/start.bat b/start.bat new file mode 100644 index 0000000..1021a9d --- /dev/null +++ b/start.bat @@ -0,0 +1,43 @@ +@echo off + +:MENU +cls +echo Welcome to Akrasio/AhniRevolt.py +echo 1 Start the bot +echo 2 Install dependencies +echo 3 Exit menu +echo. + +echo Type the number to choose an option and press enter +SET /P item="> " +cls + +IF %item%==1 ( + GOTO START_BOT +) ELSE IF %item%==2 ( + GOTO UPDATE_PIP +) ELSE IF %item%==3 ( + GOTO EOF +) ELSE ( + GOTO MENU +) + +:START_BOT + python index.py + pause + GOTO EOF + +:UPDATE_PIP + where pip + cls + IF %ERRORLEVEL% NEQ 0 ( + ECHO You might need to install pip first or add it to your PATH + pause + exit + ) + CALL pip install -r requirements.txt --upgrade + pause + GOTO MENU + +:EOF + exit diff --git a/utils/config.py b/utils/config.py new file mode 100644 index 0000000..9d4c849 --- /dev/null +++ b/utils/config.py @@ -0,0 +1,36 @@ +from dataclasses import dataclass +from dotenv import dotenv_values + + +@dataclass +class Config: + """ + This class is used to store the bot's configuration. + You can load it from a dictionary or from a .env file (recommended). + By default in this Discord bot template, we use from_env classmethod. + """ + revolt_token: str + revolt_prefix: str + revolt_owner_ids: list[str] = None + lewds_api_url: str = None + lewds_api_key: str = None + + @classmethod + def from_dict(self, **kwargs) -> "Config": + """ Create a Config object from a dictionary. """ + kwargs_overwrite = {} + + for k, v in kwargs.items(): + new_key = k.lower() + + if v.isdigit(): + kwargs_overwrite[new_key] = int(v) + else: + kwargs_overwrite[new_key] = v + + return Config(**kwargs_overwrite) + + @classmethod + def from_env(self, filename: str = ".env") -> "Config": + """ Create a Config object from a .env file. """ + return Config.from_dict(**dotenv_values(filename)) diff --git a/utils/http.py b/utils/http.py new file mode 100644 index 0000000..00e384a --- /dev/null +++ b/utils/http.py @@ -0,0 +1,48 @@ +import aiohttp +import json +from utils import config +from aiohttp.client_exceptions import ContentTypeError + +apikey = { "authorization": config.Config.from_env(".env").lewds_api_key } +class HTTPResponse: + def __init__( + self, status: int, response: str, + res_method: str, headers: dict[str, str] + ): + self.status = status + self.response = response + self.res_method = res_method + self.headers = headers + + def __repr__(self) -> str: + return f"" + +async def query(url, method="get", res_method="text", *args, **kwargs) -> HTTPResponse: + """ Make a HTTP request using aiohttp """ + session = aiohttp.ClientSession(headers=apikey) + + async with getattr(session, method.lower())(url, *args, **kwargs) as res: + try: + r = await getattr(res, res_method)() + except ContentTypeError: + if res_method == "json": + r = json.loads(await res.text()) + + output = HTTPResponse( + status=res.status, + response=r, + res_method=res_method, + headers=res.headers + ) + + await session.close() + return output + +async def get(url, *args, **kwargs) -> HTTPResponse: + """ Shortcut for query(url, "get", *args, **kwargs) """ + return await query(url, "get", *args, **kwargs) + + +async def post(url, *args, **kwargs) -> HTTPResponse: + """ Shortcut for query(url, "post", *args, **kwargs) """ + return await query(url, "post", *args, **kwargs)