diff --git a/requirements.txt b/requirements.txt index 286df3da..e3dc74a8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,3 +17,4 @@ werkzeug>=0.15.4 flask>=1.0.3 markdown2>=2.3.8 mcstatus>=2.2.1 +sortedcontainers>=2.1.0 diff --git a/royalnet/commands/royalgames/__init__.py b/royalnet/commands/royalgames/__init__.py index 3cf4cabb..5566826f 100644 --- a/royalnet/commands/royalgames/__init__.py +++ b/royalnet/commands/royalgames/__init__.py @@ -20,6 +20,7 @@ from .skip import SkipCommand from .smecds import SmecdsCommand from .summon import SummonCommand from .videochannel import VideochannelCommand +from .dnditem import DnditemCommand __all__ = [ "CiaoruoziCommand", @@ -38,5 +39,6 @@ __all__ = [ "SkipCommand", "SmecdsCommand", "SummonCommand", - "VideochannelCommand" + "VideochannelCommand", + "DnditemCommand" ] diff --git a/royalnet/commands/royalgames/dnditem.py b/royalnet/commands/royalgames/dnditem.py new file mode 100644 index 00000000..df19f4a4 --- /dev/null +++ b/royalnet/commands/royalgames/dnditem.py @@ -0,0 +1,72 @@ +import typing +import aiohttp +import sortedcontainers +from ..command import Command +from ..commandargs import CommandArgs +from ..commanddata import CommandData +from ..commandinterface import CommandInterface + + +class DnditemCommand(Command): + name: str = "dnditem" + + description: str = "Ottieni informazioni su un oggetto di D&D5e." + + syntax = "(nomeoggetto)" + + _dnddata: sortedcontainers.SortedKeyList = None + + def __init__(self, interface: CommandInterface): + super().__init__(interface) + interface.loop.create_task(self._fetch_dnddata()) + + async def _fetch_dnddata(self): + async with aiohttp.ClientSession() as session: + async with session.get("https://scaleway.steffo.eu/dnd/items.json") as response: + j = await response.json() + self._dnddata = sortedcontainers.SortedKeyList(j["item"], key=lambda i: i["name"].lower()) + + def _parse_entry(self, entry): + if isinstance(entry, str): + return entry + elif isinstance(entry, dict): + string = "" + if entry["type"] == "entries": + string += f'[b]{entry.get("name", "")}[/b]\n' + for subentry in entry["entries"]: + string += self._parse_entry(subentry) + elif entry["type"] == "table": + string += "[i][table hidden][/i]" + # for label in entry["colLabels"]: + # string += f"| {label} " + # string += "|" + # for row in entry["rows"]: + # for column in row: + # string += f"| {self._parse_entry(column)} " + # string += "|\n" + elif entry["type"] == "cell": + return self._parse_entry(entry["entry"]) + else: + string += "[i][unknown type][/i]" + else: + return "[/i][unknown data][/i]" + return string + + async def run(self, args: CommandArgs, data: CommandData) -> None: + if self._dnddata is None: + await data.reply("⚠️ Il database degli oggetti di D&D non è ancora stato scaricato.") + return + search = args.joined().lower() + result = self._dnddata[self._dnddata.bisect_key_left(search)] + string = f'[b]{result["name"]}[/b]\n' \ + f'[i]{result["source"]}, page {result["page"]}[/i]\n' \ + f'\n' \ + f'Type: [b]{result.get("type", "None")}[/b]\n' \ + f'Value: [b]{result.get("value", "Priceless")}[/b]\n' \ + f'Weight: [b]{result.get("weight", "0")} lb[/b]\n' \ + f'Rarity: [b]{result["rarity"] if result["rarity"] != "None" else "Mundane"}[/b]\n' \ + f'\n' + for entry in result.get("entries", []): + string += self._parse_entry(entry) + string += "\n\n" + await data.reply(string) diff --git a/royalnet/commands/royalgames/reminder.py b/royalnet/commands/royalgames/reminder.py index bb7cda3f..e79c3e94 100644 --- a/royalnet/commands/royalgames/reminder.py +++ b/royalnet/commands/royalgames/reminder.py @@ -34,9 +34,9 @@ class ReminderCommand(Command): .all() ) for reminder in reminders: - interface.loop.create_task(self.remind(reminder)) + interface.loop.create_task(self._remind(reminder)) - async def remind(self, reminder): + async def _remind(self, reminder): await sleep_until(reminder.datetime) if self.interface.name == "telegram": chat_id: int = pickle.loads(reminder.interface_data) @@ -74,6 +74,6 @@ class ReminderCommand(Command): interface_data=interface_data, datetime=date, message=reminder_text) - self.interface.loop.create_task(self.remind(reminder)) + self.interface.loop.create_task(self._remind(reminder)) self.interface.session.add(reminder) await asyncify(self.interface.session.commit) diff --git a/royalnet/royalgames.py b/royalnet/royalgames.py index 7d679b1c..400e23a2 100644 --- a/royalnet/royalgames.py +++ b/royalnet/royalgames.py @@ -33,7 +33,8 @@ commands = [ SkipCommand, SmecdsCommand, SummonCommand, - VideochannelCommand + VideochannelCommand, + DnditemCommand ] # noinspection PyUnreachableCode diff --git a/royalnet/utils/__init__.py b/royalnet/utils/__init__.py index 7455eacc..6f77b0ae 100644 --- a/royalnet/utils/__init__.py +++ b/royalnet/utils/__init__.py @@ -6,8 +6,8 @@ from .safeformat import safeformat from .classdictjanitor import cdj from .sleepuntil import sleep_until from .networkhandler import NetworkHandler -from .formatters import andformat, plusformat, fileformat, ytdldateformat, numberemojiformat +from .formatters import andformat, plusformat, fileformat, ytdldateformat, numberemojiformat, splitstring __all__ = ["asyncify", "safeformat", "cdj", "sleep_until", "plusformat", "NetworkHandler", "andformat", "plusformat", "fileformat", "ytdldateformat", "numberemojiformat", - "telegram_escape", "discord_escape"] + "telegram_escape", "discord_escape", "splitstring"] diff --git a/royalnet/utils/formatters.py b/royalnet/utils/formatters.py index 1e4f92ee..90695fc3 100644 --- a/royalnet/utils/formatters.py +++ b/royalnet/utils/formatters.py @@ -70,3 +70,11 @@ def numberemojiformat(l: typing.List[str]) -> str: except IndexError: result += f"{extra_emoji} {element}\n" return result + + +def splitstring(s: str, max: int) -> typing.List[str]: + l = [] + while s: + l.append(s[:max]) + s = s[max:] + return l diff --git a/setup.py b/setup.py index c394d1d4..48402a00 100644 --- a/setup.py +++ b/setup.py @@ -28,7 +28,8 @@ setuptools.setup( "werkzeug>=0.15.4", "flask>=1.0.3", "markdown2>=2.3.8", - "mcstatus>=2.2.1"], + "mcstatus>=2.2.1", + "sortedcontainers>=2.1.0"], python_requires=">=3.7", classifiers=[ "Development Status :: 3 - Alpha",