From ca1722fee33ebf41301c15526b85e7a7e67f86b5 Mon Sep 17 00:00:00 2001 From: SeaswimmerTheFsh Date: Sat, 4 May 2024 15:05:50 -0400 Subject: [PATCH] feat(aurora): migrated to a custom json encoder --- aurora/aurora.py | 30 ++++++++++-------------------- aurora/models.py | 12 ------------ aurora/utilities/encoder.py | 15 +++++++++++++++ aurora/utilities/utils.py | 10 ++++++++++ 4 files changed, 35 insertions(+), 32 deletions(-) create mode 100644 aurora/utilities/encoder.py diff --git a/aurora/aurora.py b/aurora/aurora.py index 15a9b2f..463de76 100644 --- a/aurora/aurora.py +++ b/aurora/aurora.py @@ -19,8 +19,7 @@ from redbot.core import app_commands, commands, data_manager from redbot.core.app_commands import Choice from redbot.core.bot import Red from redbot.core.commands.converter import parse_relativedelta, parse_timedelta -from redbot.core.utils.chat_formatting import (box, error, humanize_list, - humanize_timedelta, warning) +from redbot.core.utils.chat_formatting import box, error, humanize_list, humanize_timedelta, warning from aurora.importers.aurora import ImportAuroraView from aurora.importers.galacticbot import ImportGalacticBotView @@ -29,19 +28,10 @@ from aurora.menus.guild import Guild from aurora.menus.immune import Immune from aurora.menus.overrides import Overrides from aurora.utilities.config import config, register_config -from aurora.utilities.database import (connect, create_guild_table, fetch_case, - mysql_log) -from aurora.utilities.factory import (addrole_embed, case_factory, - changes_factory, evidenceformat_factory, - guild_embed, immune_embed, - message_factory, overrides_embed) +from aurora.utilities.database import connect, create_guild_table, fetch_case, mysql_log +from aurora.utilities.factory import addrole_embed, case_factory, changes_factory, evidenceformat_factory, guild_embed, immune_embed, message_factory, overrides_embed from aurora.utilities.logger import logger -from aurora.utilities.utils import (check_moddable, check_permissions, - convert_timedelta_to_str, - fetch_channel_dict, fetch_user_dict, - generate_dict, get_footer_image, log, - send_evidenceformat, - timedelta_from_relativedelta) +from aurora.utilities.utils import check_moddable, check_permissions, convert_timedelta_to_str, dump, dumps, fetch_channel_dict, fetch_user_dict, generate_dict, get_footer_image, log, send_evidenceformat, timedelta_from_relativedelta class Aurora(commands.Cog): @@ -1078,7 +1068,7 @@ class Aurora(commands.Cog): ) with open(filename, "w", encoding="utf-8") as f: - json.dump(cases, f, indent=2) + dump(cases, f, indent=2) await interaction.followup.send( file=discord.File( @@ -1337,7 +1327,7 @@ class Aurora(commands.Cog): cursor.execute( resolve_query, ( - json.dumps(changes), + dumps(changes), interaction.user.id, reason, case_dict["moderation_id"], @@ -1416,7 +1406,7 @@ class Aurora(commands.Cog): ) with open(filename, "w", encoding="utf-8") as f: - json.dump(case_dict, f, indent=2) + dump(case_dict, f, indent=2) if export.value == "codeblock": content = f"Case #{case:,} exported.\n" + warning( @@ -1437,7 +1427,7 @@ class Aurora(commands.Cog): os.remove(filename) return await interaction.response.send_message( - content=box(json.dumps(case_dict, indent=2), 'json'), + content=box(dumps(case_dict, indent=2), 'json'), ephemeral=ephemeral, ) return @@ -1586,7 +1576,7 @@ class Aurora(commands.Cog): cursor.execute( update_query, ( - json.dumps(changes), + dumps(changes), reason, convert_timedelta_to_str(parsed_time), end_timestamp, @@ -1595,7 +1585,7 @@ class Aurora(commands.Cog): ) else: update_query = f"UPDATE `moderation_{interaction.guild.id}` SET changes = ?, reason = ? WHERE moderation_id = ?" - cursor.execute(update_query, (json.dumps(changes), reason, case)) + cursor.execute(update_query, (dumps(changes), reason, case)) database.commit() new_case = await fetch_case(case, interaction.guild.id) diff --git a/aurora/models.py b/aurora/models.py index 391312d..6244ebf 100644 --- a/aurora/models.py +++ b/aurora/models.py @@ -68,15 +68,3 @@ class Moderation(BaseModel): return cls(**case) return None - -class JSONEncoder(json.JSONEncoder): - def default(self, o): - if isinstance(o, datetime): - return int(o.timestamp()) - if isinstance(o, timedelta): - return str(o) - if isinstance(o, Moderation): - return o.model_dump() - if isinstance(o, None): - return "NULL" - return super().default(o) diff --git a/aurora/utilities/encoder.py b/aurora/utilities/encoder.py new file mode 100644 index 0000000..ba69ef2 --- /dev/null +++ b/aurora/utilities/encoder.py @@ -0,0 +1,15 @@ +import json +from datetime import datetime, timedelta + +from aurora.models import Moderation + + +class JSONEncoder(json.JSONEncoder): + def default(self, o): + if isinstance(o, datetime): + return int(o.timestamp()) + if isinstance(o, timedelta): + return str(o) + if isinstance(o, Moderation): + return o.model_dump() + return super().default(o) diff --git a/aurora/utilities/utils.py b/aurora/utilities/utils.py index 1ff21fa..8a31063 100644 --- a/aurora/utilities/utils.py +++ b/aurora/utilities/utils.py @@ -296,3 +296,13 @@ def get_footer_image(coginstance: commands.Cog) -> File: """Returns the footer image for the embeds.""" image_path = data_manager.bundled_data_path(coginstance) / "arrow.png" return File(image_path, filename="arrow.png", description="arrow") + +def dumps(obj: any, indent: int = None) -> str: + """Returns a JSON string from an object.""" + from aurora.utilities.encoder import JSONEncoder + return json.dumps(obj, indent=indent, cls=JSONEncoder) + +def dump(obj: any, indent: int = None) -> str: + """Returns a JSON string from an object.""" + from aurora.utilities.encoder import JSONEncoder + return json.dump(obj, indent=indent, cls=JSONEncoder)