2019-11-11 09:34:05 +00:00
|
|
|
|
import re
|
|
|
|
|
# noinspection PyUnresolvedReferences
|
|
|
|
|
from royalnet.commands import *
|
2020-09-16 00:37:31 +00:00
|
|
|
|
import royalnet.utils as ru
|
2019-11-11 09:34:05 +00:00
|
|
|
|
from ..tables import DndCharacter
|
2020-02-22 01:16:54 +00:00
|
|
|
|
from ..types import DndProficiencyType
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DndnewCommand(Command):
|
|
|
|
|
name: str = "dndnew"
|
|
|
|
|
|
|
|
|
|
description: str = "Create a new DnD character."
|
|
|
|
|
|
|
|
|
|
aliases = ["dn", "dndn", "new", "dnew"]
|
|
|
|
|
|
|
|
|
|
syntax = "{name}\n{character_sheet}"
|
|
|
|
|
|
2020-09-16 00:37:31 +00:00
|
|
|
|
@staticmethod
|
|
|
|
|
def _search_value(name: str, string: str):
|
2019-12-10 12:26:27 +00:00
|
|
|
|
return re.search(r"\s*" + name + r"\s*([0-9.]+)\s*", string, re.IGNORECASE)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
|
|
def _parse(self, character_sheet: str) -> dict:
|
2019-12-04 00:47:00 +00:00
|
|
|
|
columns = list(self.alchemy.get(DndCharacter).__table__.columns)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
column_names = [column.name for column in columns if (not column.primary_key and
|
|
|
|
|
not column.foreign_keys and
|
|
|
|
|
column.name != "name")]
|
|
|
|
|
arguments = {}
|
|
|
|
|
for column_name in column_names:
|
|
|
|
|
match = self._search_value(column_name, character_sheet)
|
|
|
|
|
if match:
|
|
|
|
|
if column_name.endswith("_proficiency"):
|
|
|
|
|
arguments[column_name] = DndProficiencyType(float(match.group(1)))
|
|
|
|
|
else:
|
|
|
|
|
arguments[column_name] = match.group(1)
|
|
|
|
|
return arguments
|
|
|
|
|
|
|
|
|
|
def _syntax(self) -> str:
|
2019-12-04 00:47:00 +00:00
|
|
|
|
columns = list(self.alchemy.get(DndCharacter).__table__.columns)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
column_names = [column.name for column in columns if (not column.primary_key and
|
|
|
|
|
not column.foreign_keys and
|
|
|
|
|
column.name != "name")]
|
|
|
|
|
message = "ℹ️ How to create a new character:\n[p]/dndnew YOUR_CHARACTER_NAME\n"
|
|
|
|
|
for column_name in column_names:
|
|
|
|
|
message += f"{column_name} _\n"
|
|
|
|
|
message += "[/p]"
|
|
|
|
|
return message
|
|
|
|
|
|
|
|
|
|
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
|
|
|
|
character_sheet = args.joined()
|
|
|
|
|
|
|
|
|
|
if character_sheet == "":
|
|
|
|
|
await data.reply(self._syntax())
|
|
|
|
|
return
|
|
|
|
|
|
2020-09-16 00:37:31 +00:00
|
|
|
|
async with data.session_acm() as session:
|
|
|
|
|
creator = await data.find_author(session=session, required=True)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
2020-09-16 00:37:31 +00:00
|
|
|
|
name, rest = character_sheet.split("\n", 1)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
2020-09-16 00:37:31 +00:00
|
|
|
|
character = self.alchemy.get(DndCharacter)(name=name, creator=creator, **self._parse(rest))
|
|
|
|
|
session.add(character)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
2020-09-16 00:37:31 +00:00
|
|
|
|
try:
|
|
|
|
|
await ru.asyncify(session.commit)
|
|
|
|
|
except Exception as err:
|
|
|
|
|
# THIS IS INTENDED
|
|
|
|
|
if err.__class__.__name__ == "IntegrityError":
|
|
|
|
|
param_name = re.search(r'in column "(\S+)"', err.args[0]).group(1)
|
|
|
|
|
raise CommandError(f"Mandatory parameter '{param_name}' is missing.")
|
|
|
|
|
raise
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
2020-09-16 00:37:31 +00:00
|
|
|
|
await data.reply(f"✅ Character [b]{character.name}[/b] (ID: {character.character_id}) created!")
|