add basic import functionality

This commit is contained in:
Infinidoge 2025-01-01 00:51:41 -05:00
parent 347aa76de5
commit bd5706c0ce
Signed by: Infinidoge
SSH key fingerprint: SHA256:GT2StvPQMMfFHyiiFJymQxfTG/z6EWLJ6NWItf5K5sA

View file

@ -1,14 +1,23 @@
import json
import logging import logging
from typing import Literal from typing import Literal
import disnake import disnake
import re2 as re
from disnake.ext.commands import Cog, group, guild_only from disnake.ext.commands import Cog, group, guild_only
from .notifications import KeywordError
from .utils import confirm from .utils import confirm
log = logging.getLogger("nomen.settings") log = logging.getLogger("nomen.settings")
log.setLevel(logging.DEBUG) log.setLevel(logging.DEBUG)
DUSTY_DATA_LINE = re.compile(r"^(.+) notified (\d+) times$")
class InvalidImportFormat(Exception):
pass
class Settings(Cog): class Settings(Cog):
def __init__(self, bot): def __init__(self, bot):
@ -44,11 +53,57 @@ You may want to `{ctx.clean_prefix}nomen export` first"""
else: else:
await ctx.send("Cancelled.") await ctx.send("Cancelled.")
async def import_json(self, ctx, data):
try:
data = json.loads(data)
except json.JSONDecodeError as e:
raise InvalidImportFormat from e
await ctx.send("Importing JSON")
async def import_dusty(self, ctx, data):
lines = map(str.strip, data.split("\n"))
to_add = []
for line in lines:
if match := DUSTY_DATA_LINE.fullmatch(line):
to_add.append((match.group(1), int(match.group(2))))
else:
raise InvalidImportFormat
await ctx.send(f"Importing from Dusty notification list to {ctx.guild}...")
added = []
errors = []
async with ctx.typing():
notifications = self.bot.get_cog("Notifications")
for keyword, count in to_add:
try:
await notifications.add_keyword(ctx.guild.id, ctx.author.id, keyword, False, count)
added.append(keyword)
except KeywordError as e:
errors.append(e)
if not errors:
await ctx.send("Successfully imported all keywords!")
else:
await ctx.send(
f"Import successful, with some errors\n\n"
f"Sucessfully imported:\n{"\n".join(f"- {keyword}" for keyword in added)}\n"
f"Errors (check PMs):\n{"\n".join(f"- {e.msg}" for e in errors)}\n\n"
f"If you want to import erroring keywords, delete conflicting keywords and modify the list to only include the ones that failed to import, and run the command again."
)
for e in errors:
await ctx.author.send(e.dm_msg)
async def import_raw(self, data):
pass
@nomen.command(name="import") @nomen.command(name="import")
@guild_only() @guild_only()
async def _import(self, ctx): async def _import(self, ctx, *, data):
""" """
Imports a JSON of all of your user data Imports user data, either from JSON or from a simple list
""" """
schema = { schema = {
"disabled": bool, "disabled": bool,
@ -65,6 +120,18 @@ You may want to `{ctx.clean_prefix}nomen export` first"""
], ],
} }
notifications = self.bot.get_cog("Notifications")
try:
await self.import_json(ctx, data)
await ctx.send("Sorry, JSON imports and exports haven't been implemented yet.")
return
except InvalidImportFormat:
try:
await self.import_dusty(ctx, data)
except InvalidImportFormat:
await ctx.send("Invalid import format")
# @nomen.command() # @nomen.command()
# @guild_only() # @guild_only()
# async def export(self, ctx): # async def export(self, ctx):