nightly bot

This commit is contained in:
AF 2023-09-24 09:02:23 +00:00
parent 30c9186385
commit a1ed7f8dd1
8 changed files with 177 additions and 3 deletions

View File

@ -1,8 +1,6 @@
{
"python.analysis.typeCheckingMode": "basic",
"python.analysis.extraPaths": [
"starbot"
],
"python.analysis.extraPaths": ["nightly", "starbot"],
"python.testing.pytestEnabled": false,
"python.testing.unittestEnabled": true,
"search.exclude": {

View File

@ -24,3 +24,22 @@ services:
window: 120s
tty: true
stop_signal: SIGINT
nightly:
build:
context: nightly
volumes:
- "./nightly/nightly:/app/nightly:ro"
env_file:
- .secrets/nightly.env
deploy:
resources:
limits:
cpus: '2'
memory: 200M
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
tty: true
stop_signal: SIGINT

6
nightly/Dockerfile Normal file
View File

@ -0,0 +1,6 @@
FROM python:3.11 as base
WORKDIR /app/
COPY requirements.txt requirements.txt
RUN pip --no-cache-dir install -r requirements.txt
CMD ["python3", "-m", "nightly"]
COPY nightly nightly

View File

@ -0,0 +1,62 @@
from __future__ import annotations
import asyncio
import importlib
import os
import discord
from discord.ext import commands
from .bot import NightlyBot
async def _main():
token = os.getenv("DISCORD_TOKEN")
if token is None:
print(
"""\
DISCORD_TOKEN environment variable is not set
edit .secrets/nightly.env with the following content (substitute <token here> with the token):
DISCORD_TOKEN = <token here>\
"""
)
exit(1)
bot = NightlyBot()
await bot.login(token)
yield bot
await bot.load_extension("nightly.night")
await bot.connect()
yield bot
async def aclose(client: discord.Client):
if not client.is_closed():
await client.change_presence(status=discord.Status.offline)
await client.close()
def close(client: discord.Client, loop: asyncio.AbstractEventLoop):
loop.run_until_complete(aclose(client))
def main():
loop = asyncio.new_event_loop()
gen = _main()
bot: commands.Bot = loop.run_until_complete(anext(gen))
discord.utils.setup_logging()
async def complete():
return await anext(gen)
task = loop.create_task(complete())
try:
loop.run_until_complete(task)
except (KeyboardInterrupt, InterruptedError, RuntimeError):
try:
close(bot, loop)
finally:
loop.run_until_complete(task)
if __name__ == "__main__":
main()

10
nightly/nightly/bot.py Normal file
View File

@ -0,0 +1,10 @@
import discord
from discord.ext import commands
class NightlyBot(commands.Bot):
def __init__(self) -> None:
super().__init__(
command_prefix="🌟",
intents=discord.Intents(message_content=True, guild_messages=True, guild_reactions=True, guilds=True),
)

77
nightly/nightly/night.py Normal file
View File

@ -0,0 +1,77 @@
from __future__ import annotations
import re
import discord
from aiohttp import ClientSession
from discord.ext import commands
class Night(commands.Cog):
@commands.hybrid_command()
@commands.is_owner()
async def reload(self, ctx: commands.Context):
print("reload")
bot: commands.Bot = ctx.bot
try:
await bot.reload_extension("nightly.night")
except commands.ExtensionNotLoaded:
await ctx.reply("not loaded")
print("reloaded")
await ctx.reply("reloaded")
@commands.hybrid_command()
@commands.is_owner()
async def sync(self, ctx: commands.Context):
await ctx.bot.tree.sync()
print("synced")
await ctx.reply("synced")
@commands.hybrid_command()
async def leetcode(self, ctx: commands.Context, url: str):
match = re.search(r"/problems/([a-z0-1\-]*)", url)
if not match:
await ctx.reply("invalid url")
return
name = match.group(1)
async with ClientSession() as session:
async with session.post(
"https://leetcode.com/graphql/",
json={
"query": "\n query consolePanelConfig($titleSlug: String!) {\n question(titleSlug: $titleSlug) {\n questionId\n questionFrontendId\n questionTitle\n enableDebugger\n enableRunCode\n enableSubmit\n enableTestMode\n exampleTestcaseList\n metaData\n }\n}\n ",
"variables": {"titleSlug": name},
"operationName": "consolePanelConfig",
},
) as response:
if not response.ok:
await ctx.reply("error (idk)")
return
match await response.json():
case {"data": {"question": {"questionFrontendId": qfi, "questionTitle": qt}}}:
title = f"{qfi}. {qt}"
print(title)
case _:
await ctx.reply("error (leetcode format wrong)")
return
if not isinstance(ctx.channel, discord.TextChannel):
await ctx.reply("not available outside text channels")
return
thread = await ctx.channel.create_thread(name=title, type=discord.ChannelType.public_thread)
message = await thread.send(f"https://leetcode.com/problems/{name}/")
if not ctx.bot_permissions.manage_messages:
await ctx.reply("cannot pin messages (missing permissions)", mention_author=False)
return
await message.pin()
async def setup(bot: commands.Bot):
global cog
cog = Night()
await bot.add_cog(cog)
async def teardown(bot: commands.Bot):
global cog
await bot.remove_cog(cog.qualified_name)
del cog
print("torn down")

0
nightly/pyproject.toml Normal file
View File

2
nightly/requirements.txt Normal file
View File

@ -0,0 +1,2 @@
aiohttp>=3.7.4,<4
discord.py~=2.3.2