WIP: Refactor Aurora (3.0.0) #29
9 changed files with 127 additions and 116 deletions
100
aurora/aurora.py
100
aurora/aurora.py
|
@ -7,11 +7,11 @@
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import sqlite3
|
|
||||||
import time
|
import time
|
||||||
from datetime import datetime, timedelta, timezone
|
from datetime import datetime, timedelta, timezone
|
||||||
from math import ceil
|
from math import ceil
|
||||||
|
|
||||||
|
import aiosqlite
|
||||||
import discord
|
import discord
|
||||||
from discord import Object
|
from discord import Object
|
||||||
from discord.ext import tasks
|
from discord.ext import tasks
|
||||||
|
@ -50,21 +50,21 @@ class Aurora(commands.Cog):
|
||||||
if requester == "discord_deleted_user":
|
if requester == "discord_deleted_user":
|
||||||
await config.user_from_id(user_id).clear()
|
await config.user_from_id(user_id).clear()
|
||||||
|
|
||||||
database = connect()
|
database = await connect()
|
||||||
cursor = database.cursor()
|
cursor = await database.cursor()
|
||||||
|
|
||||||
cursor.execute("SHOW TABLES;")
|
await cursor.execute("SHOW TABLES;")
|
||||||
tables = [table[0] for table in cursor.fetchall()]
|
tables = [table[0] for table in cursor.fetchall()]
|
||||||
|
|
||||||
condition = "target_id = %s OR moderator_id = %s;"
|
condition = "target_id = %s OR moderator_id = %s;"
|
||||||
|
|
||||||
for table in tables:
|
for table in tables:
|
||||||
delete_query = f"DELETE FROM {table[0]} WHERE {condition}"
|
delete_query = f"DELETE FROM {table[0]} WHERE {condition}"
|
||||||
cursor.execute(delete_query, (user_id, user_id))
|
await cursor.execute(delete_query, (user_id, user_id))
|
||||||
|
|
||||||
database.commit()
|
await database.commit()
|
||||||
cursor.close()
|
await cursor.close()
|
||||||
database.close()
|
await database.close()
|
||||||
if requester == "owner":
|
if requester == "owner":
|
||||||
await config.user_from_id(user_id).clear()
|
await config.user_from_id(user_id).clear()
|
||||||
if requester == "user":
|
if requester == "user":
|
||||||
|
@ -121,15 +121,13 @@ class Aurora(commands.Cog):
|
||||||
async def addrole_on_member_join(self, member: discord.Member):
|
async def addrole_on_member_join(self, member: discord.Member):
|
||||||
"""This method automatically adds roles to users when they join the server."""
|
"""This method automatically adds roles to users when they join the server."""
|
||||||
if not await self.bot.cog_disabled_in_guild(self, member.guild):
|
if not await self.bot.cog_disabled_in_guild(self, member.guild):
|
||||||
|
async with connect() as database:
|
||||||
query = f"""SELECT moderation_id, role_id, reason FROM moderation_{member.guild.id} WHERE target_id = ? AND moderation_type = 'ADDROLE' AND expired = 0 AND resolved = 0;"""
|
query = f"""SELECT moderation_id, role_id, reason FROM moderation_{member.guild.id} WHERE target_id = ? AND moderation_type = 'ADDROLE' AND expired = 0 AND resolved = 0;"""
|
||||||
database = connect()
|
async with database.execute(query, (member.id,)) as cursor:
|
||||||
cursor = database.cursor()
|
async for row in cursor:
|
||||||
cursor.execute(query, (member.id,))
|
role = member.guild.get_role(row[1])
|
||||||
results = cursor.fetchall()
|
reason = row[2]
|
||||||
for result in results:
|
await member.add_roles(role, reason=f"Role automatically added on member rejoin for: {reason} (Case #{row[0]:,})")
|
||||||
role = member.guild.get_role(result[1])
|
|
||||||
reason = result[2]
|
|
||||||
await member.add_roles(role, reason=f"Role automatically added on member rejoin for: {reason} (Case #{result[0]:,})")
|
|
||||||
|
|
||||||
@commands.Cog.listener("on_audit_log_entry_create")
|
@commands.Cog.listener("on_audit_log_entry_create")
|
||||||
async def autologger(self, entry: discord.AuditLogEntry):
|
async def autologger(self, entry: discord.AuditLogEntry):
|
||||||
|
@ -175,7 +173,7 @@ class Aurora(commands.Cog):
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
Moderation.log(
|
await Moderation.log(
|
||||||
self.bot,
|
self.bot,
|
||||||
entry.guild.id,
|
entry.guild.id,
|
||||||
entry.user.id,
|
entry.user.id,
|
||||||
|
@ -233,7 +231,7 @@ class Aurora(commands.Cog):
|
||||||
except discord.errors.HTTPException:
|
except discord.errors.HTTPException:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
moderation = Moderation.log(
|
moderation = await Moderation.log(
|
||||||
interaction.client,
|
interaction.client,
|
||||||
interaction.guild.id,
|
interaction.guild.id,
|
||||||
interaction.user.id,
|
interaction.user.id,
|
||||||
|
@ -292,7 +290,7 @@ class Aurora(commands.Cog):
|
||||||
except discord.errors.HTTPException:
|
except discord.errors.HTTPException:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
moderation = Moderation.log(
|
moderation = await Moderation.log(
|
||||||
interaction.client,
|
interaction.client,
|
||||||
interaction.guild.id,
|
interaction.guild.id,
|
||||||
interaction.user.id,
|
interaction.user.id,
|
||||||
|
@ -398,7 +396,7 @@ class Aurora(commands.Cog):
|
||||||
content=f"{target.mention} has been given the {role.mention} role{' for ' + humanize_timedelta(timedelta=parsed_time) if parsed_time != 'NULL' else ''}!\n**Reason** - `{reason}`"
|
content=f"{target.mention} has been given the {role.mention} role{' for ' + humanize_timedelta(timedelta=parsed_time) if parsed_time != 'NULL' else ''}!\n**Reason** - `{reason}`"
|
||||||
)
|
)
|
||||||
|
|
||||||
moderation = Moderation.log(
|
moderation = await Moderation.log(
|
||||||
interaction.client,
|
interaction.client,
|
||||||
interaction.guild.id,
|
interaction.guild.id,
|
||||||
interaction.user.id,
|
interaction.user.id,
|
||||||
|
@ -504,7 +502,7 @@ class Aurora(commands.Cog):
|
||||||
content=f"{target.mention} has had the {role.mention} role removed{' for ' + humanize_timedelta(timedelta=parsed_time) if parsed_time != 'NULL' else ''}!\n**Reason** - `{reason}`"
|
content=f"{target.mention} has had the {role.mention} role removed{' for ' + humanize_timedelta(timedelta=parsed_time) if parsed_time != 'NULL' else ''}!\n**Reason** - `{reason}`"
|
||||||
)
|
)
|
||||||
|
|
||||||
moderation = Moderation.log(
|
moderation = await Moderation.log(
|
||||||
interaction.client,
|
interaction.client,
|
||||||
interaction.guild.id,
|
interaction.guild.id,
|
||||||
interaction.user.id,
|
interaction.user.id,
|
||||||
|
@ -592,7 +590,7 @@ class Aurora(commands.Cog):
|
||||||
except discord.errors.HTTPException:
|
except discord.errors.HTTPException:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
moderation = Moderation.log(
|
moderation = await Moderation.log(
|
||||||
interaction.client,
|
interaction.client,
|
||||||
interaction.guild.id,
|
interaction.guild.id,
|
||||||
interaction.user.id,
|
interaction.user.id,
|
||||||
|
@ -728,7 +726,7 @@ class Aurora(commands.Cog):
|
||||||
|
|
||||||
await target.kick(reason=f"Kicked by {interaction.user.id} for: {reason}")
|
await target.kick(reason=f"Kicked by {interaction.user.id} for: {reason}")
|
||||||
|
|
||||||
moderation = Moderation.log(
|
moderation = await Moderation.log(
|
||||||
interaction.client,
|
interaction.client,
|
||||||
interaction.guild.id,
|
interaction.guild.id,
|
||||||
interaction.user.id,
|
interaction.user.id,
|
||||||
|
@ -836,7 +834,7 @@ class Aurora(commands.Cog):
|
||||||
delete_message_seconds=delete_messages_seconds,
|
delete_message_seconds=delete_messages_seconds,
|
||||||
)
|
)
|
||||||
|
|
||||||
moderation = Moderation.log(
|
moderation = await Moderation.log(
|
||||||
interaction.client,
|
interaction.client,
|
||||||
interaction.guild.id,
|
interaction.guild.id,
|
||||||
interaction.user.id,
|
interaction.user.id,
|
||||||
|
@ -880,7 +878,7 @@ class Aurora(commands.Cog):
|
||||||
delete_message_seconds=delete_messages_seconds,
|
delete_message_seconds=delete_messages_seconds,
|
||||||
)
|
)
|
||||||
|
|
||||||
moderation = Moderation.log(
|
moderation = await Moderation.log(
|
||||||
interaction.client,
|
interaction.client,
|
||||||
interaction.guild.id,
|
interaction.guild.id,
|
||||||
interaction.user.id,
|
interaction.user.id,
|
||||||
|
@ -957,7 +955,7 @@ class Aurora(commands.Cog):
|
||||||
except discord.errors.HTTPException:
|
except discord.errors.HTTPException:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
moderation = Moderation.log(
|
moderation = await Moderation.log(
|
||||||
interaction.client,
|
interaction.client,
|
||||||
interaction.guild.id,
|
interaction.guild.id,
|
||||||
interaction.user.id,
|
interaction.user.id,
|
||||||
|
@ -1001,7 +999,7 @@ class Aurora(commands.Cog):
|
||||||
await channel.edit(slowmode_delay=interval)
|
await channel.edit(slowmode_delay=interval)
|
||||||
await interaction.response.send_message(f"Slowmode in {channel.mention} has been set to {interval} seconds!\n**Reason** - `{reason}`")
|
await interaction.response.send_message(f"Slowmode in {channel.mention} has been set to {interval} seconds!\n**Reason** - `{reason}`")
|
||||||
|
|
||||||
moderation = Moderation.log(
|
moderation = await Moderation.log(
|
||||||
interaction.client,
|
interaction.client,
|
||||||
interaction.guild.id,
|
interaction.guild.id,
|
||||||
interaction.user.id,
|
interaction.user.id,
|
||||||
|
@ -1089,7 +1087,7 @@ class Aurora(commands.Cog):
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
database = connect()
|
database = await connect()
|
||||||
|
|
||||||
if export:
|
if export:
|
||||||
try:
|
try:
|
||||||
|
@ -1099,7 +1097,7 @@ class Aurora(commands.Cog):
|
||||||
+ f"moderation_{interaction.guild.id}.json"
|
+ f"moderation_{interaction.guild.id}.json"
|
||||||
)
|
)
|
||||||
|
|
||||||
cases = Moderation.get_latest(bot=interaction.client, guild_id=interaction.guild.id)
|
cases = await Moderation.get_latest(bot=interaction.client, guild_id=interaction.guild.id)
|
||||||
|
|
||||||
with open(filename, "w", encoding="utf-8") as f:
|
with open(filename, "w", encoding="utf-8") as f:
|
||||||
dump(obj=cases, fp=f, indent=2)
|
dump(obj=cases, fp=f, indent=2)
|
||||||
|
@ -1120,15 +1118,15 @@ class Aurora(commands.Cog):
|
||||||
+ box(e, "py"),
|
+ box(e, "py"),
|
||||||
ephemeral=ephemeral,
|
ephemeral=ephemeral,
|
||||||
)
|
)
|
||||||
database.close()
|
await database.close()
|
||||||
return
|
return
|
||||||
|
|
||||||
if target:
|
if target:
|
||||||
moderations = Moderation.find_by_target(interaction.client, interaction.guild.id, target.id)
|
moderations = await Moderation.find_by_target(interaction.client, interaction.guild.id, target.id)
|
||||||
elif moderator:
|
elif moderator:
|
||||||
moderations = Moderation.find_by_moderator(interaction.client, interaction.guild.id, moderator.id)
|
moderations = await Moderation.find_by_moderator(interaction.client, interaction.guild.id, moderator.id)
|
||||||
else:
|
else:
|
||||||
moderations = Moderation.get_latest(interaction.client, interaction.guild.id)
|
moderations = await Moderation.get_latest(interaction.client, interaction.guild.id)
|
||||||
|
|
||||||
case_quantity = len(moderations)
|
case_quantity = len(moderations)
|
||||||
page_quantity = ceil(case_quantity / pagesize)
|
page_quantity = ceil(case_quantity / pagesize)
|
||||||
|
@ -1214,7 +1212,7 @@ class Aurora(commands.Cog):
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
moderation = Moderation.find_by_id(interaction.client, case, interaction.guild.id)
|
moderation = await Moderation.find_by_id(interaction.client, case, interaction.guild.id)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
await interaction.response.send_message(
|
await interaction.response.send_message(
|
||||||
content=error(f"Case #{case:,} does not exist!"), ephemeral=True
|
content=error(f"Case #{case:,} does not exist!"), ephemeral=True
|
||||||
|
@ -1298,7 +1296,7 @@ class Aurora(commands.Cog):
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
mod = Moderation.find_by_id(interaction.client, case, interaction.guild.id)
|
mod = await Moderation.find_by_id(interaction.client, case, interaction.guild.id)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
await interaction.response.send_message(
|
await interaction.response.send_message(
|
||||||
content=error(f"Case #{case:,} does not exist!"), ephemeral=True
|
content=error(f"Case #{case:,} does not exist!"), ephemeral=True
|
||||||
|
@ -1391,7 +1389,7 @@ class Aurora(commands.Cog):
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
moderation = Moderation.find_by_id(interaction.client, case, interaction.guild.id)
|
moderation = await Moderation.find_by_id(interaction.client, case, interaction.guild.id)
|
||||||
old_moderation = moderation
|
old_moderation = moderation
|
||||||
except ValueError:
|
except ValueError:
|
||||||
await interaction.response.send_message(
|
await interaction.response.send_message(
|
||||||
|
@ -1469,7 +1467,7 @@ class Aurora(commands.Cog):
|
||||||
"end_timestamp": moderation.end_timestamp,
|
"end_timestamp": moderation.end_timestamp,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
moderation.update()
|
await moderation.update()
|
||||||
embed = await case_factory(interaction=interaction, moderation=moderation)
|
embed = await case_factory(interaction=interaction, moderation=moderation)
|
||||||
|
|
||||||
await interaction.response.send_message(
|
await interaction.response.send_message(
|
||||||
|
@ -1485,8 +1483,8 @@ class Aurora(commands.Cog):
|
||||||
async def handle_expiry(self):
|
async def handle_expiry(self):
|
||||||
await self.bot.wait_until_red_ready()
|
await self.bot.wait_until_red_ready()
|
||||||
current_time = time.time()
|
current_time = time.time()
|
||||||
database = connect()
|
database = await connect()
|
||||||
cursor = database.cursor()
|
cursor = await database.cursor()
|
||||||
global_unban_num = 0
|
global_unban_num = 0
|
||||||
global_addrole_num = 0
|
global_addrole_num = 0
|
||||||
global_removerole_num = 0
|
global_removerole_num = 0
|
||||||
|
@ -1499,9 +1497,9 @@ class Aurora(commands.Cog):
|
||||||
tempban_query = f"SELECT target_id, moderation_id FROM moderation_{guild.id} WHERE end_timestamp IS NOT NULL 0 AND end_timestamp <= ? AND moderation_type = 'TEMPBAN' AND expired = 0"
|
tempban_query = f"SELECT target_id, moderation_id FROM moderation_{guild.id} WHERE end_timestamp IS NOT NULL 0 AND end_timestamp <= ? AND moderation_type = 'TEMPBAN' AND expired = 0"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cursor.execute(tempban_query, (time.time(),))
|
await cursor.execute(tempban_query, (time.time(),))
|
||||||
result = cursor.fetchall()
|
result = cursor.fetchall()
|
||||||
except sqlite3.OperationalError:
|
except aiosqlite.OperationalError:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
target_ids = [row[0] for row in result]
|
target_ids = [row[0] for row in result]
|
||||||
|
@ -1558,9 +1556,9 @@ class Aurora(commands.Cog):
|
||||||
removerole_num = 0
|
removerole_num = 0
|
||||||
addrole_query = f"SELECT target_id, moderation_id, role_id FROM moderation_{guild.id} WHERE end_timestamp IS NOT NULL AND end_timestamp <= ? AND moderation_type = 'ADDROLE' AND expired = 0"
|
addrole_query = f"SELECT target_id, moderation_id, role_id FROM moderation_{guild.id} WHERE end_timestamp IS NOT NULL AND end_timestamp <= ? AND moderation_type = 'ADDROLE' AND expired = 0"
|
||||||
try:
|
try:
|
||||||
cursor.execute(addrole_query, (time.time(),))
|
await cursor.execute(addrole_query, (time.time(),))
|
||||||
result = cursor.fetchall()
|
result = await cursor.fetchall()
|
||||||
except sqlite3.OperationalError:
|
except aiosqlite.OperationalError:
|
||||||
continue
|
continue
|
||||||
target_ids = [row[0] for row in result]
|
target_ids = [row[0] for row in result]
|
||||||
moderation_ids = [row[1] for row in result]
|
moderation_ids = [row[1] for row in result]
|
||||||
|
@ -1593,9 +1591,9 @@ class Aurora(commands.Cog):
|
||||||
addrole_num = 0
|
addrole_num = 0
|
||||||
removerole_query = f"SELECT target_id, moderation_id, role_id FROM moderation_{guild.id} WHERE end_timestamp IS NOT NULL 0 AND end_timestamp <= ? AND moderation_type = 'REMOVEROLE' AND expired = 0"
|
removerole_query = f"SELECT target_id, moderation_id, role_id FROM moderation_{guild.id} WHERE end_timestamp IS NOT NULL 0 AND end_timestamp <= ? AND moderation_type = 'REMOVEROLE' AND expired = 0"
|
||||||
try:
|
try:
|
||||||
cursor.execute(removerole_query, (time.time(),))
|
await cursor.execute(removerole_query, (time.time(),))
|
||||||
result = cursor.fetchall()
|
result = await cursor.fetchall()
|
||||||
except sqlite3.OperationalError:
|
except aiosqlite.OperationalError:
|
||||||
continue
|
continue
|
||||||
target_ids = [row[0] for row in result]
|
target_ids = [row[0] for row in result]
|
||||||
moderation_ids = [row[1] for row in result]
|
moderation_ids = [row[1] for row in result]
|
||||||
|
@ -1621,7 +1619,7 @@ class Aurora(commands.Cog):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
expiry_query = f"UPDATE `moderation_{guild.id}` SET expired = 1 WHERE (end_timestamp IS NOT NULL AND end_timestamp <= ? AND expired = 0) OR (expired = 0 AND resolved = 1);"
|
expiry_query = f"UPDATE `moderation_{guild.id}` SET expired = 1 WHERE (end_timestamp IS NOT NULL AND end_timestamp <= ? AND expired = 0) OR (expired = 0 AND resolved = 1);"
|
||||||
cursor.execute(expiry_query, (time.time(),))
|
await cursor.execute(expiry_query, (time.time(),))
|
||||||
|
|
||||||
per_guild_completion_time = (time.time() - time_per_guild) * 1000
|
per_guild_completion_time = (time.time() - time_per_guild) * 1000
|
||||||
logger.debug(
|
logger.debug(
|
||||||
|
@ -1637,9 +1635,9 @@ class Aurora(commands.Cog):
|
||||||
global_addrole_num = global_addrole_num + addrole_num
|
global_addrole_num = global_addrole_num + addrole_num
|
||||||
global_removerole_num = global_removerole_num + removerole_num
|
global_removerole_num = global_removerole_num + removerole_num
|
||||||
|
|
||||||
database.commit()
|
await database.commit()
|
||||||
cursor.close()
|
await cursor.close()
|
||||||
database.close()
|
await database.close()
|
||||||
|
|
||||||
completion_time = (time.time() - current_time) * 1000
|
completion_time = (time.time() - current_time) * 1000
|
||||||
logger.debug(
|
logger.debug(
|
||||||
|
|
|
@ -27,13 +27,9 @@ class ImportAuroraView(ui.View):
|
||||||
"Deleting original table...", ephemeral=True
|
"Deleting original table...", ephemeral=True
|
||||||
)
|
)
|
||||||
|
|
||||||
database = connect()
|
async with connect() as database:
|
||||||
cursor = database.cursor()
|
|
||||||
|
|
||||||
query = f"DROP TABLE IF EXISTS moderation_{self.ctx.guild.id};"
|
query = f"DROP TABLE IF EXISTS moderation_{self.ctx.guild.id};"
|
||||||
cursor.execute(query)
|
database.execute(query)
|
||||||
|
|
||||||
cursor.close()
|
|
||||||
database.commit()
|
database.commit()
|
||||||
|
|
||||||
await interaction.edit_original_response(content="Creating new table...")
|
await interaction.edit_original_response(content="Creating new table...")
|
||||||
|
@ -96,7 +92,7 @@ class ImportAuroraView(ui.View):
|
||||||
duration = None
|
duration = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
Moderation.log(
|
await Moderation.log(
|
||||||
bot=interaction.client,
|
bot=interaction.client,
|
||||||
guild_id=self.ctx.guild.id,
|
guild_id=self.ctx.guild.id,
|
||||||
moderator_id=case["moderator_id"],
|
moderator_id=case["moderator_id"],
|
||||||
|
|
|
@ -26,14 +26,14 @@ class ImportGalacticBotView(ui.View):
|
||||||
"Deleting original table...", ephemeral=True
|
"Deleting original table...", ephemeral=True
|
||||||
)
|
)
|
||||||
|
|
||||||
database = connect()
|
database = await connect()
|
||||||
cursor = database.cursor()
|
cursor = await database.cursor()
|
||||||
|
|
||||||
query = f"DROP TABLE IF EXISTS moderation_{self.ctx.guild.id};"
|
query = f"DROP TABLE IF EXISTS moderation_{self.ctx.guild.id};"
|
||||||
cursor.execute(query)
|
await cursor.execute(query)
|
||||||
|
|
||||||
cursor.close()
|
await cursor.close()
|
||||||
database.commit()
|
await database.commit()
|
||||||
|
|
||||||
await interaction.edit_original_response(content="Creating new table...")
|
await interaction.edit_original_response(content="Creating new table...")
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ class ImportGalacticBotView(ui.View):
|
||||||
else:
|
else:
|
||||||
reason = None
|
reason = None
|
||||||
|
|
||||||
Moderation.log(
|
await Moderation.log(
|
||||||
self.ctx.guild.id,
|
self.ctx.guild.id,
|
||||||
case["executor"],
|
case["executor"],
|
||||||
case["type"],
|
case["type"],
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
"disabled": false,
|
"disabled": false,
|
||||||
"min_bot_version": "3.5.0",
|
"min_bot_version": "3.5.0",
|
||||||
"min_python_version": [3, 10, 0],
|
"min_python_version": [3, 10, 0],
|
||||||
"requirements": ["pydantic"],
|
"requirements": ["pydantic", "aiosqlite"],
|
||||||
"tags": [
|
"tags": [
|
||||||
"mod",
|
"mod",
|
||||||
"moderate",
|
"moderate",
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import json
|
import json
|
||||||
import sqlite3
|
import sqlite3
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from sqlite3 import Cursor
|
|
||||||
from time import time
|
from time import time
|
||||||
from typing import Dict, Iterable, List, Optional, Tuple, Union
|
from typing import Dict, Iterable, List, Optional, Tuple, Union
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
|
from aiosqlite import Cursor
|
||||||
from discord import NotFound
|
from discord import NotFound
|
||||||
from redbot.core.bot import Red
|
from redbot.core.bot import Red
|
||||||
|
|
||||||
|
@ -115,15 +115,15 @@ class Moderation(AuroraGuildModel):
|
||||||
"user_id": resolved_by,
|
"user_id": resolved_by,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
self.update()
|
await self.update()
|
||||||
|
|
||||||
def update(self) -> None:
|
async def update(self) -> None:
|
||||||
from ..utilities.database import connect
|
from ..utilities.database import connect
|
||||||
from ..utilities.json import dumps
|
from ..utilities.json import dumps
|
||||||
query = f"UPDATE moderation_{self.guild_id} SET timestamp = ?, moderation_type = ?, target_type = ?, moderator_id = ?, role_id = ?, duration = ?, end_timestamp = ?, reason = ?, resolved = ?, resolved_by = ?, resolve_reason = ?, expired = ?, changes = ?, metadata = ? WHERE moderation_id = ?;"
|
query = f"UPDATE moderation_{self.guild_id} SET timestamp = ?, moderation_type = ?, target_type = ?, moderator_id = ?, role_id = ?, duration = ?, end_timestamp = ?, reason = ?, resolved = ?, resolved_by = ?, resolve_reason = ?, expired = ?, changes = ?, metadata = ? WHERE moderation_id = ?;"
|
||||||
|
|
||||||
with connect() as database:
|
async with connect() as database:
|
||||||
database.execute(query, (
|
await database.execute(query, (
|
||||||
self.timestamp.timestamp(),
|
self.timestamp.timestamp(),
|
||||||
self.moderation_type,
|
self.moderation_type,
|
||||||
self.target_type,
|
self.target_type,
|
||||||
|
@ -206,7 +206,7 @@ class Moderation(AuroraGuildModel):
|
||||||
return cls.from_dict(bot=bot, data=case)
|
return cls.from_dict(bot=bot, data=case)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def execute(cls, bot: Red, guild_id: int, query: str, parameters: tuple | None = None, cursor: Cursor | None = None) -> Tuple["Moderation"]:
|
async def execute(cls, bot: Red, guild_id: int, query: str, parameters: tuple | None = None, cursor: Cursor | None = None) -> Tuple["Moderation"]:
|
||||||
from ..utilities.database import connect
|
from ..utilities.database import connect
|
||||||
logger.trace("Executing query: %s", query)
|
logger.trace("Executing query: %s", query)
|
||||||
logger.trace("With parameters: %s", parameters)
|
logger.trace("With parameters: %s", parameters)
|
||||||
|
@ -214,16 +214,16 @@ class Moderation(AuroraGuildModel):
|
||||||
parameters = ()
|
parameters = ()
|
||||||
if not cursor:
|
if not cursor:
|
||||||
no_cursor = True
|
no_cursor = True
|
||||||
database = connect()
|
database = await connect()
|
||||||
cursor = database.cursor()
|
cursor = await database.cursor()
|
||||||
else:
|
else:
|
||||||
no_cursor = False
|
no_cursor = False
|
||||||
|
|
||||||
cursor.execute(query, parameters)
|
await cursor.execute(query, parameters)
|
||||||
results = cursor.fetchall()
|
results = await cursor.fetchall()
|
||||||
if no_cursor:
|
if no_cursor:
|
||||||
cursor.close()
|
await cursor.close()
|
||||||
database.close()
|
await database.close()
|
||||||
|
|
||||||
if results:
|
if results:
|
||||||
cases = []
|
cases = []
|
||||||
|
@ -235,7 +235,7 @@ class Moderation(AuroraGuildModel):
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_latest(cls, bot: Red, guild_id: int, limit: int | None = None, offset: int = 0, types: Iterable | None = None, cursor: Cursor | None = None) -> Tuple["Moderation"]:
|
async def get_latest(cls, bot: Red, guild_id: int, limit: int | None = None, offset: int = 0, types: Iterable | None = None, cursor: Cursor | None = None) -> Tuple["Moderation"]:
|
||||||
params = []
|
params = []
|
||||||
query = f"SELECT * FROM moderation_{guild_id} ORDER BY moderation_id DESC"
|
query = f"SELECT * FROM moderation_{guild_id} ORDER BY moderation_id DESC"
|
||||||
if types:
|
if types:
|
||||||
|
@ -245,41 +245,41 @@ class Moderation(AuroraGuildModel):
|
||||||
query += " LIMIT ? OFFSET ?"
|
query += " LIMIT ? OFFSET ?"
|
||||||
params.extend((limit, offset))
|
params.extend((limit, offset))
|
||||||
query += ";"
|
query += ";"
|
||||||
return cls.execute(bot=bot, guild_id=guild_id, query=query, parameters=tuple(params) if params else (), cursor=cursor)
|
return await cls.execute(bot=bot, guild_id=guild_id, query=query, parameters=tuple(params) if params else (), cursor=cursor)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_next_case_number(cls, bot: Red, guild_id: int, cursor: Cursor | None = None) -> int:
|
async def get_next_case_number(cls, bot: Red, guild_id: int, cursor: Cursor | None = None) -> int:
|
||||||
result = cls.get_latest(bot=bot, guild_id=guild_id, cursor=cursor, limit=1)
|
result = await cls.get_latest(bot=bot, guild_id=guild_id, cursor=cursor, limit=1)
|
||||||
return (result[0].moderation_id + 1) if result else 1
|
return (result[0].moderation_id + 1) if result else 1
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def find_by_id(cls, bot: Red, moderation_id: int, guild_id: int, cursor: Cursor | None = None) -> "Moderation":
|
async def find_by_id(cls, bot: Red, moderation_id: int, guild_id: int, cursor: Cursor | None = None) -> "Moderation":
|
||||||
query = f"SELECT * FROM moderation_{guild_id} WHERE moderation_id = ?;"
|
query = f"SELECT * FROM moderation_{guild_id} WHERE moderation_id = ?;"
|
||||||
case = cls.execute(bot=bot, guild_id=guild_id, query=query, parameters=(moderation_id,), cursor=cursor)
|
case = await cls.execute(bot=bot, guild_id=guild_id, query=query, parameters=(moderation_id,), cursor=cursor)
|
||||||
if case:
|
if case:
|
||||||
return case[0]
|
return case[0]
|
||||||
raise ValueError(f"Case {moderation_id} not found in moderation_{guild_id}!")
|
raise ValueError(f"Case {moderation_id} not found in moderation_{guild_id}!")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def find_by_target(cls, bot: Red, guild_id: int, target: int, types: Iterable | None = None, cursor: Cursor | None = None) -> Tuple["Moderation"]:
|
async def find_by_target(cls, bot: Red, guild_id: int, target: int, types: Iterable | None = None, cursor: Cursor | None = None) -> Tuple["Moderation"]:
|
||||||
query = f"SELECT * FROM moderation_{guild_id} WHERE target_id = ?"
|
query = f"SELECT * FROM moderation_{guild_id} WHERE target_id = ?"
|
||||||
if types:
|
if types:
|
||||||
query += f" AND moderation_type IN ({', '.join(['?' for _ in types])})"
|
query += f" AND moderation_type IN ({', '.join(['?' for _ in types])})"
|
||||||
query += " ORDER BY moderation_id DESC;"
|
query += " ORDER BY moderation_id DESC;"
|
||||||
|
|
||||||
return cls.execute(bot=bot, guild_id=guild_id, query=query, parameters=(target, *types) if types else (target,), cursor=cursor)
|
return await cls.execute(bot=bot, guild_id=guild_id, query=query, parameters=(target, *types) if types else (target,), cursor=cursor)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def find_by_moderator(cls, bot: Red, guild_id: int, moderator: int, types: Iterable | None = None, cursor: Cursor | None = None) -> Tuple["Moderation"]:
|
async def find_by_moderator(cls, bot: Red, guild_id: int, moderator: int, types: Iterable | None = None, cursor: Cursor | None = None) -> Tuple["Moderation"]:
|
||||||
query = f"SELECT * FROM moderation_{guild_id} WHERE moderator_id = ?"
|
query = f"SELECT * FROM moderation_{guild_id} WHERE moderator_id = ?"
|
||||||
if types:
|
if types:
|
||||||
query += f" AND moderation_type IN ({', '.join(['?' for _ in types])})"
|
query += f" AND moderation_type IN ({', '.join(['?' for _ in types])})"
|
||||||
query += " ORDER BY moderation_id DESC;"
|
query += " ORDER BY moderation_id DESC;"
|
||||||
|
|
||||||
return cls.execute(bot=bot, guild_id=guild_id, query=query, parameters=(moderator, *types) if types else (moderator,), cursor=cursor)
|
return await cls.execute(bot=bot, guild_id=guild_id, query=query, parameters=(moderator, *types) if types else (moderator,), cursor=cursor)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def log(
|
async def log(
|
||||||
cls,
|
cls,
|
||||||
bot: Red,
|
bot: Red,
|
||||||
guild_id: int,
|
guild_id: int,
|
||||||
|
@ -335,13 +335,12 @@ class Moderation(AuroraGuildModel):
|
||||||
role_id = None
|
role_id = None
|
||||||
|
|
||||||
if not database:
|
if not database:
|
||||||
database = connect()
|
database = await connect()
|
||||||
close_db = True
|
close_db = True
|
||||||
else:
|
else:
|
||||||
close_db = False
|
close_db = False
|
||||||
cursor = database.cursor()
|
|
||||||
|
|
||||||
moderation_id = cls.get_next_case_number(bot=bot, guild_id=guild_id, cursor=cursor)
|
moderation_id = cls.get_next_case_number(bot=bot, guild_id=guild_id)
|
||||||
|
|
||||||
case = {
|
case = {
|
||||||
"moderation_id": moderation_id,
|
"moderation_id": moderation_id,
|
||||||
|
@ -363,12 +362,12 @@ class Moderation(AuroraGuildModel):
|
||||||
}
|
}
|
||||||
|
|
||||||
sql = f"INSERT INTO `moderation_{guild_id}` (moderation_id, timestamp, moderation_type, target_type, target_id, moderator_id, role_id, duration, end_timestamp, reason, resolved, resolved_by, resolve_reason, expired, changes, metadata) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
|
sql = f"INSERT INTO `moderation_{guild_id}` (moderation_id, timestamp, moderation_type, target_type, target_id, moderator_id, role_id, duration, end_timestamp, reason, resolved, resolved_by, resolve_reason, expired, changes, metadata) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
|
||||||
cursor.execute(sql, tuple(case.values()))
|
await database.execute(sql, tuple(case.values()))
|
||||||
|
|
||||||
cursor.close()
|
await database.close()
|
||||||
database.commit()
|
await database.commit()
|
||||||
if close_db:
|
if close_db:
|
||||||
database.close()
|
await database.close()
|
||||||
|
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Row inserted into moderation_%s!\n%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s",
|
"Row inserted into moderation_%s!\n%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s",
|
||||||
|
@ -392,5 +391,5 @@ class Moderation(AuroraGuildModel):
|
||||||
)
|
)
|
||||||
|
|
||||||
if return_obj:
|
if return_obj:
|
||||||
return cls.find_by_id(bot=bot, moderation_id=moderation_id, guild_id=guild_id)
|
return await cls.find_by_id(bot=bot, moderation_id=moderation_id, guild_id=guild_id)
|
||||||
return moderation_id
|
return moderation_id
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
# pylint: disable=cyclic-import
|
# pylint: disable=cyclic-import
|
||||||
import json
|
import json
|
||||||
import sqlite3
|
|
||||||
|
|
||||||
|
import aiosqlite
|
||||||
from discord import Guild
|
from discord import Guild
|
||||||
from redbot.core import data_manager
|
from redbot.core import data_manager
|
||||||
|
|
||||||
from .logger import logger
|
from .logger import logger
|
||||||
|
|
||||||
|
|
||||||
def connect() -> sqlite3.Connection:
|
async def connect() -> aiosqlite.Connection:
|
||||||
"""Connects to the SQLite database, and returns a connection object."""
|
"""Connects to the SQLite database, and returns a connection object."""
|
||||||
try:
|
try:
|
||||||
connection = sqlite3.connect(
|
connection = await aiosqlite.connect(
|
||||||
database=data_manager.cog_data_path(raw_name="Aurora") / "aurora.db"
|
database=data_manager.cog_data_path(raw_name="Aurora") / "aurora.db"
|
||||||
)
|
)
|
||||||
return connection
|
return connection
|
||||||
|
|
||||||
except sqlite3.OperationalError as e:
|
except aiosqlite.OperationalError as e:
|
||||||
logger.error("Unable to access the SQLite database!\nError:\n%s", e.msg)
|
logger.error("Unable to access the SQLite database!\nError:\n%s", e.msg)
|
||||||
raise ConnectionRefusedError(
|
raise ConnectionRefusedError(
|
||||||
f"Unable to access the SQLite Database!\n{e.msg}"
|
f"Unable to access the SQLite Database!\n{e.msg}"
|
||||||
|
@ -24,14 +24,13 @@ def connect() -> sqlite3.Connection:
|
||||||
|
|
||||||
|
|
||||||
async def create_guild_table(guild: Guild):
|
async def create_guild_table(guild: Guild):
|
||||||
database = connect()
|
database = await connect()
|
||||||
cursor = database.cursor()
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cursor.execute(f"SELECT * FROM `moderation_{guild.id}`")
|
await database.execute(f"SELECT * FROM `moderation_{guild.id}`")
|
||||||
logger.debug("SQLite Table exists for server %s (%s)", guild.name, guild.id)
|
logger.debug("SQLite Table exists for server %s (%s)", guild.name, guild.id)
|
||||||
|
|
||||||
except sqlite3.OperationalError:
|
except aiosqlite.OperationalError:
|
||||||
query = f"""
|
query = f"""
|
||||||
CREATE TABLE `moderation_{guild.id}` (
|
CREATE TABLE `moderation_{guild.id}` (
|
||||||
moderation_id INTEGER PRIMARY KEY,
|
moderation_id INTEGER PRIMARY KEY,
|
||||||
|
@ -52,16 +51,16 @@ async def create_guild_table(guild: Guild):
|
||||||
metadata JSON NOT NULL
|
metadata JSON NOT NULL
|
||||||
)
|
)
|
||||||
"""
|
"""
|
||||||
cursor.execute(query)
|
await database.execute(query)
|
||||||
|
|
||||||
index_query_1 = f"CREATE INDEX IF NOT EXISTS idx_target_id ON moderation_{guild.id}(target_id);"
|
index_query_1 = f"CREATE INDEX IF NOT EXISTS idx_target_id ON moderation_{guild.id}(target_id);"
|
||||||
cursor.execute(index_query_1)
|
await database.execute(index_query_1)
|
||||||
|
|
||||||
index_query_2 = f"CREATE INDEX IF NOT EXISTS idx_moderator_id ON moderation_{guild.id}(moderator_id);"
|
index_query_2 = f"CREATE INDEX IF NOT EXISTS idx_moderator_id ON moderation_{guild.id}(moderator_id);"
|
||||||
cursor.execute(index_query_2)
|
await database.execute(index_query_2)
|
||||||
|
|
||||||
index_query_3 = f"CREATE INDEX IF NOT EXISTS idx_moderation_id ON moderation_{guild.id}(moderation_id);"
|
index_query_3 = f"CREATE INDEX IF NOT EXISTS idx_moderation_id ON moderation_{guild.id}(moderation_id);"
|
||||||
cursor.execute(index_query_3)
|
await database.execute(index_query_3)
|
||||||
|
|
||||||
insert_query = f"""
|
insert_query = f"""
|
||||||
INSERT INTO `moderation_{guild.id}`
|
INSERT INTO `moderation_{guild.id}`
|
||||||
|
@ -86,9 +85,9 @@ async def create_guild_table(guild: Guild):
|
||||||
json.dumps([]),
|
json.dumps([]),
|
||||||
json.dumps({}),
|
json.dumps({}),
|
||||||
)
|
)
|
||||||
cursor.execute(insert_query, insert_values)
|
await database.execute(insert_query, insert_values)
|
||||||
|
|
||||||
database.commit()
|
await database.commit()
|
||||||
|
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"SQLite Table (moderation_%s) created for %s (%s)",
|
"SQLite Table (moderation_%s) created for %s (%s)",
|
||||||
|
|
|
@ -120,7 +120,7 @@ async def log(interaction: Interaction, moderation_id: int, resolved: bool = Fal
|
||||||
logging_channel = interaction.guild.get_channel(logging_channel_id)
|
logging_channel = interaction.guild.get_channel(logging_channel_id)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
moderation = Moderation.find_by_id(interaction.client, moderation_id, interaction.guild_id)
|
moderation = await Moderation.find_by_id(interaction.client, moderation_id, interaction.guild_id)
|
||||||
embed = await log_factory(
|
embed = await log_factory(
|
||||||
interaction=interaction, moderation=moderation, resolved=resolved
|
interaction=interaction, moderation=moderation, resolved=resolved
|
||||||
)
|
)
|
||||||
|
@ -145,7 +145,7 @@ async def send_evidenceformat(interaction: Interaction, moderation_id: int) -> N
|
||||||
if send_evidence_bool is False:
|
if send_evidence_bool is False:
|
||||||
return
|
return
|
||||||
|
|
||||||
moderation = Moderation.find_by_id(interaction.client, moderation_id, interaction.guild.id)
|
moderation = await Moderation.find_by_id(interaction.client, moderation_id, interaction.guild.id)
|
||||||
content = await evidenceformat_factory(moderation=moderation)
|
content = await evidenceformat_factory(moderation=moderation)
|
||||||
await interaction.followup.send(content=content, ephemeral=True)
|
await interaction.followup.send(content=content, ephemeral=True)
|
||||||
|
|
||||||
|
|
20
poetry.lock
generated
20
poetry.lock
generated
|
@ -123,6 +123,24 @@ files = [
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
frozenlist = ">=1.1.0"
|
frozenlist = ">=1.1.0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aiosqlite"
|
||||||
|
version = "0.20.0"
|
||||||
|
description = "asyncio bridge to the standard sqlite3 module"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.8"
|
||||||
|
files = [
|
||||||
|
{file = "aiosqlite-0.20.0-py3-none-any.whl", hash = "sha256:36a1deaca0cac40ebe32aac9977a6e2bbc7f5189f23f4a54d5908986729e5bd6"},
|
||||||
|
{file = "aiosqlite-0.20.0.tar.gz", hash = "sha256:6d35c8c256637f4672f843c31021464090805bf925385ac39473fb16eaaca3d7"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
typing_extensions = ">=4.0"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
dev = ["attribution (==1.7.0)", "black (==24.2.0)", "coverage[toml] (==7.4.1)", "flake8 (==7.0.0)", "flake8-bugbear (==24.2.6)", "flit (==3.9.0)", "mypy (==1.8.0)", "ufmt (==2.3.0)", "usort (==1.0.8.post1)"]
|
||||||
|
docs = ["sphinx (==7.2.6)", "sphinx-mdinclude (==0.5.3)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "annotated-types"
|
name = "annotated-types"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
|
@ -2655,4 +2673,4 @@ multidict = ">=4.0"
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = ">=3.11,<3.12"
|
python-versions = ">=3.11,<3.12"
|
||||||
content-hash = "3f732c0b0b0eb2a31fb9484c7cf699cd3c26474d6779528102af4c509a48351e"
|
content-hash = "22b824824f73dc3dc1a9a0a01060371ee1f6414e5bef39cb7455d21121988b47"
|
||||||
|
|
|
@ -18,6 +18,7 @@ pydantic = "^2.7.1"
|
||||||
colorthief = "^0.2.1"
|
colorthief = "^0.2.1"
|
||||||
beautifulsoup4 = "^4.12.3"
|
beautifulsoup4 = "^4.12.3"
|
||||||
markdownify = "^0.12.1"
|
markdownify = "^0.12.1"
|
||||||
|
aiosqlite = "^0.20.0"
|
||||||
|
|
||||||
[tool.poetry.group.dev]
|
[tool.poetry.group.dev]
|
||||||
optional = true
|
optional = true
|
||||||
|
|
Loading…
Reference in a new issue