about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNakidai <plaza521@inbox.ru>2024-09-04 19:34:45 +0300
committerNakidai <plaza521@inbox.ru>2024-09-04 19:37:18 +0300
commit5ae48feb9cc03241a5c6b2578a357db5736ba359 (patch)
tree75f43caee6f3dd1a942ac25415b3cf8b67f9e4b3 /src
downloadpetthecord-5ae48feb9cc03241a5c6b2578a357db5736ba359.tar.gz
petthecord-5ae48feb9cc03241a5c6b2578a357db5736ba359.zip
Initial commit
Diffstat (limited to 'src')
-rw-r--r--src/petthecord/__init__.py4
-rw-r--r--src/petthecord/bot.py21
-rw-r--r--src/petthecord/main.py36
-rw-r--r--src/petthecord/server.py37
4 files changed, 98 insertions, 0 deletions
diff --git a/src/petthecord/__init__.py b/src/petthecord/__init__.py
new file mode 100644
index 0000000..afd0ec5
--- /dev/null
+++ b/src/petthecord/__init__.py
@@ -0,0 +1,4 @@
+from .main import Bot, main
+
+
+__all__ = ["main"]
diff --git a/src/petthecord/bot.py b/src/petthecord/bot.py
new file mode 100644
index 0000000..de1277b
--- /dev/null
+++ b/src/petthecord/bot.py
@@ -0,0 +1,21 @@
+from aiohttp.web import AppRunner, TCPSite
+from discord import Intents
+from discord.ext import commands
+
+from .server import Server
+
+
+class Bot(commands.Bot):
+    def __init__(self, host: str = "127.0.0.1", port: int = 8080) -> None:
+        super().__init__(
+            command_prefix="!",
+            intents=Intents.default()
+        )
+        self._host = host
+        self._port = port
+
+    async def on_ready(self) -> None:
+        runner = AppRunner(Server(self))
+        await runner.setup()
+        site = TCPSite(runner, self._host, self._port)
+        await site.start()
diff --git a/src/petthecord/main.py b/src/petthecord/main.py
new file mode 100644
index 0000000..0e3056f
--- /dev/null
+++ b/src/petthecord/main.py
@@ -0,0 +1,36 @@
+from argparse import ArgumentParser
+from os import getenv
+from sys import argv, stderr
+
+from .bot import Bot
+
+
+def main() -> None:
+    parser = ArgumentParser(
+        prog="petthecord",
+        description="Web API for petting any user you want"
+    )
+    parser.add_argument(
+        "-p", "--port",
+        default=8000,
+        type=int,
+        metavar="PORT",
+        help="Bind port"
+    )
+    parser.add_argument(
+        "-i", "--host",
+        default="127.0.0.1",
+        metavar="HOST",
+        help="Bind IP"
+    )
+    args = parser.parse_args()
+
+    bot = Bot()
+    if (token := getenv("PETTHECORD_TOKEN")) is not None:
+        bot.run(token)
+    elif (token_path := getenv("PETTHECORD_TOKEN_FILE")) is not None:
+        with open(token_path) as f:
+            token = f.read()
+        bot.run(token, args.host, args.port)
+    else:
+        print(f"{argv[0]}: Neither PETTHECORD_TOKEN nor PETTHECORD_TOKEN_FILE are set", file=stderr)
diff --git a/src/petthecord/server.py b/src/petthecord/server.py
new file mode 100644
index 0000000..8c3d8a2
--- /dev/null
+++ b/src/petthecord/server.py
@@ -0,0 +1,37 @@
+from io import BytesIO
+
+from aiohttp.web import Application, StreamResponse, get, Request, Response
+from discord import NotFound, HTTPException
+from discord.ext import commands
+from petpetgif import petpet
+
+
+class Server(Application):
+    def __init__(self, client: commands.Bot) -> None:
+        self.client = client
+        super().__init__()
+
+        self.add_routes([get("/{uid}", self.root)])
+
+    async def root(self, request: Request) -> StreamResponse:
+        try:
+            uid = int(request.match_info["uid"][:request.match_info["uid"].find('.')])
+        except ValueError:
+            return Response(status=400)
+
+        try:
+            user = await self.client.fetch_user(uid)
+        except NotFound:
+            return Response(status=404)
+        except HTTPException:
+            return Response(status=403)
+
+        if user.avatar is None:
+            return Response(status=404)
+
+        image = await user.avatar.read()
+        dest = BytesIO()
+        petpet.make(BytesIO(image), dest)
+        dest.seek(0)
+
+        return Response(body=dest.getvalue(), content_type="image/png")