college-bot-v1/cogs/.mcdonalds.py.old

208 lines
8.3 KiB
Python
Raw Permalink Normal View History

2023-12-05 12:04:27 +00:00
import asyncio
2023-12-05 18:34:42 +00:00
import logging
2023-12-05 14:37:59 +00:00
import pathlib
2023-12-05 14:19:11 +00:00
import re
2023-12-05 14:37:59 +00:00
import typing
2023-12-05 14:19:11 +00:00
2023-12-05 14:07:49 +00:00
import aiosqlite
2023-12-05 12:04:27 +00:00
import discord
from discord.ext import commands
2023-12-05 14:37:59 +00:00
class McDataBase:
def __init__(self):
2023-12-05 14:49:47 +00:00
self.db = pathlib.Path.home() / ".cache" / "lcc-bot" / "McDataBase.db"
2023-12-05 14:37:59 +00:00
self._conn: typing.Optional[aiosqlite.Connection] = None
async def init_db(self):
if self._conn:
conn = self._conn
2023-12-05 16:17:01 +00:00
now = round(discord.utils.utcnow().timestamp(), 2)
2023-12-05 14:37:59 +00:00
await conn.execute(
2023-12-05 16:17:01 +00:00
f"""
2023-12-05 14:37:59 +00:00
CREATE TABLE IF NOT EXISTS breaks (
user_id INTEGER PRIMARY KEY,
2023-12-05 16:17:01 +00:00
since FLOAT NOT NULL,
started FLOAT NOT NULL DEFAULT {now}
2023-12-05 14:37:59 +00:00
);
"""
)
await conn.execute(
"""
CREATE TABLE IF NOT EXISTS cooldowns (
user_id INTEGER PRIMARY KEY,
expires FLOAT NOT NULL
);
"""
)
2023-12-05 16:17:01 +00:00
async def get_break(self, user_id: int) -> typing.Optional[tuple[float, float]]:
2023-12-05 14:37:59 +00:00
async with self._conn.execute(
"""
2023-12-05 16:17:01 +00:00
SELECT since, started FROM breaks WHERE user_id = ?;
2023-12-05 14:37:59 +00:00
""",
2023-12-05 21:12:33 +00:00
(user_id,),
2023-12-05 14:37:59 +00:00
) as cursor:
return await cursor.fetchone()
2023-12-05 18:22:01 +00:00
async def set_break(self, user_id: int, since: float, started: float = None) -> None:
if not started:
started = discord.Object(discord.utils.generate_snowflake()).created_at.timestamp()
2023-12-05 14:37:59 +00:00
await self._conn.execute(
"""
2023-12-05 18:22:01 +00:00
INSERT INTO breaks (user_id, since, started) VALUES (?, ?, ?)
ON CONFLICT(user_id) DO UPDATE SET since = excluded.since, started = excluded.started
2023-12-05 14:37:59 +00:00
""",
2023-12-05 21:12:33 +00:00
(user_id, since, started),
2023-12-05 14:37:59 +00:00
)
2023-12-05 14:52:32 +00:00
async def remove_break(self, user_id: int) -> None:
2023-12-05 14:37:59 +00:00
now = discord.utils.utcnow().timestamp()
await self._conn.execute(
"""
DELETE FROM breaks WHERE user_id = ?;
""",
2023-12-05 21:12:33 +00:00
(user_id,),
2023-12-05 14:37:59 +00:00
)
await self.set_cooldown(user_id, now)
2023-12-05 14:52:32 +00:00
async def get_cooldown(self, user_id: int) -> typing.Optional[tuple[float]]:
2023-12-05 14:37:59 +00:00
async with self._conn.execute(
"""
SELECT expires FROM cooldowns WHERE user_id = ?;
""",
2023-12-05 21:12:33 +00:00
(user_id,),
2023-12-05 14:37:59 +00:00
) as cursor:
return await cursor.fetchone()
2023-12-05 14:52:32 +00:00
async def set_cooldown(self, user_id: int, expires: float) -> None:
2023-12-05 14:37:59 +00:00
await self._conn.execute(
"""
INSERT INTO cooldowns (user_id, expires) VALUES (?, ?)
ON CONFLICT(user_id) DO UPDATE SET expires = excluded.expires;
""",
2023-12-05 21:12:33 +00:00
(user_id, expires),
2023-12-05 14:37:59 +00:00
)
2023-12-05 14:52:32 +00:00
async def remove_cooldown(self, user_id: int) -> None:
2023-12-05 14:37:59 +00:00
await self._conn.execute(
"""
DELETE FROM cooldowns WHERE user_id = ?;
""",
2023-12-05 21:12:33 +00:00
(user_id,),
2023-12-05 14:37:59 +00:00
)
async def __aenter__(self) -> "McDataBase":
self._conn = await aiosqlite.connect(self.db)
await self.init_db()
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
await self._conn.commit()
await self._conn.close()
self._conn = None
2023-12-05 12:04:27 +00:00
class McDonaldsCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.lock = asyncio.Lock()
2023-12-05 18:34:42 +00:00
self.log = logging.getLogger("jimmy.cogs.mcdonalds")
2023-12-05 12:04:27 +00:00
@commands.Cog.listener()
async def on_message(self, message: discord.Message):
2023-12-05 14:19:11 +00:00
author = message.author
2023-12-05 12:11:14 +00:00
me = message.guild.me if message.guild else self.bot.user
if not message.channel.permissions_for(me).manage_messages:
2023-12-05 18:34:42 +00:00
self.log.debug("McDonalds disabled in %s, no manage messages permissions.", message.channel)
2023-12-05 12:04:27 +00:00
return
async with self.lock:
2023-12-05 14:37:59 +00:00
async with McDataBase() as db:
if (last_info := await db.get_break(author.id)) is not None:
if message.content.upper() != "MCDONALDS!":
2023-12-05 16:17:01 +00:00
if (message.created_at.timestamp() - last_info[1]) > 300:
2023-12-05 21:12:33 +00:00
self.log.debug("Ad break expired for %s (%s).", author.name, author.id)
2023-12-05 16:17:01 +00:00
await db.remove_break(author.id)
await message.reply(
f"Thank you for your patience during this commercial break. You may now resume your"
f" activity.",
2023-12-05 21:12:33 +00:00
delete_after=120,
2023-12-05 16:17:01 +00:00
)
elif (message.created_at.timestamp() - last_info[0]) > 10:
2023-12-05 18:34:42 +00:00
self.log.info(
2023-12-05 21:12:33 +00:00
"Deleting message %r by %r as they need to skip the ad first.", message, author
2023-12-05 18:34:42 +00:00
)
2023-12-05 16:17:01 +00:00
await message.delete(delay=0)
2023-12-05 14:37:59 +00:00
await message.channel.send(
2023-12-05 21:12:33 +00:00
f"{message.author.mention} Please say `MCDONALDS!` to end commercial.", delete_after=30
2023-12-05 14:37:59 +00:00
)
await db.set_break(author.id, message.created_at.timestamp())
2023-12-05 15:06:41 +00:00
elif message.author.bot is False:
2023-12-05 18:34:42 +00:00
self.log.info("%r skipped the ad break.", author)
2023-12-05 14:37:59 +00:00
await db.remove_break(author.id)
2023-12-05 21:12:33 +00:00
await message.reply("Thank you. You may now resume your activity.", delete_after=120)
2023-12-05 12:04:27 +00:00
@commands.user_command(name="Commercial Break")
@commands.cooldown(2, 60, commands.BucketType.member)
2023-12-05 12:04:27 +00:00
async def commercial_break(self, ctx: discord.ApplicationContext, member: discord.Member):
2023-12-05 12:07:45 +00:00
await ctx.defer(ephemeral=True)
2023-12-05 14:07:49 +00:00
2023-12-05 12:14:17 +00:00
if not ctx.channel.permissions_for(ctx.me).manage_messages:
return await ctx.respond("I don't have permission to manage messages in this channel.", ephemeral=True)
2023-12-05 14:07:49 +00:00
2023-12-05 12:13:08 +00:00
if member.bot or member == ctx.user:
return await ctx.respond("No.", ephemeral=True)
2023-12-05 14:07:49 +00:00
2023-12-05 14:37:59 +00:00
async with McDataBase() as db:
if await db.get_break(member.id) is not None:
await ctx.respond(f"{member.mention} is already in a commercial break.")
2023-12-05 14:07:49 +00:00
return
2023-12-05 14:37:59 +00:00
elif (cooldown := await db.get_cooldown(member.id)) is not None:
2023-12-05 14:52:32 +00:00
expires = cooldown[0] + 300
2023-12-05 14:37:59 +00:00
if expires > discord.utils.utcnow().timestamp():
await ctx.respond(
f"{member.mention} is not due another ad break yet. Their next commercial break will start "
f"<t:{int(expires)}:R> at the earliest."
)
return
else:
await db.remove_cooldown(member.id)
await db.set_break(member.id, discord.utils.utcnow().timestamp())
await ctx.send(
f"{member.mention} Commercial break! Please say `MCDONALDS!` to end commercial.\n"
f"*This commercial break is sponsored by {ctx.user.mention}.*",
delete_after=300,
2023-12-05 21:12:33 +00:00
allowed_mentions=discord.AllowedMentions(users=True, roles=False, everyone=False),
2023-12-05 14:37:59 +00:00
)
await ctx.respond("Commercial break started.", ephemeral=True)
await ctx.delete(delay=120)
2023-12-05 12:04:27 +00:00
2023-12-05 15:06:41 +00:00
@commands.command(name="commercial-break")
@commands.is_owner()
async def _force_com_break(self, ctx: commands.Context, *, member: discord.Member):
"""Forces a member to go on commercial break."""
async with McDataBase() as db:
await db.set_break(member.id, discord.utils.utcnow().timestamp())
await ctx.reply(
f"{member.mention} Commercial break! Please say `MCDONALDS!` to end commercial.\n"
f"*This commercial break is sponsored by {ctx.author.mention}.*",
delete_after=300,
2023-12-05 21:12:33 +00:00
allowed_mentions=discord.AllowedMentions(users=True, roles=False, everyone=False),
2023-12-05 15:06:41 +00:00
)
await ctx.message.delete(delay=120)
@commands.command(name="end-break")
@commands.is_owner()
async def _unforce_com_break(self, ctx: commands.Context, *, member: discord.Member):
"""Forces a member to finish their commercial break."""
async with McDataBase() as db:
await db.remove_break(member.id)
await ctx.reply(f"{member.mention} Commercial break ended.", delete_after=10)
2023-12-05 12:04:27 +00:00
def setup(bot):
bot.add_cog(McDonaldsCog(bot))