diff --git a/token_bot/history_manager/history.py b/token_bot/history_manager/history.py index 36d9a05..eaa77b0 100644 --- a/token_bot/history_manager/history.py +++ b/token_bot/history_manager/history.py @@ -49,4 +49,10 @@ class History: self._history.append(datum) return await self._process_update_triggers() + async def find_update_trigger_from_alert(self, alert: Alert) -> UpdateTrigger: + for trigger in self._update_triggers: + if trigger.alert == alert: + return trigger + raise ValueError + diff --git a/token_bot/persistant_database/alert_schema.py b/token_bot/persistant_database/alert_schema.py index a44866e..9487df1 100644 --- a/token_bot/persistant_database/alert_schema.py +++ b/token_bot/persistant_database/alert_schema.py @@ -75,7 +75,7 @@ class Alert: raise NotImplementedError else: alert_type_str = ' '.join(self.alert_type.name.split("_")) - return f"\n|\tRegion: {self.region.value.upper()}\tFlavor: {self.flavor.name.lower()}\tAlert: {alert_type_str.title()}\t|" + return f"{alert_type_str.title()}" async def _lazy_load(self, table: Table, consistent: bool = False) -> None: if consistent or not self._loaded: diff --git a/token_bot/tracker.py b/token_bot/tracker.py index 3fa4ef3..1c8230b 100644 --- a/token_bot/tracker.py +++ b/token_bot/tracker.py @@ -4,7 +4,7 @@ from typing import Type, Dict, List import aiohttp from interactions import Extension, SlashContext, component_callback, \ - ComponentContext, StringSelectMenu, Message, Embed + ComponentContext, StringSelectMenu, Message, Embed, EmbedField from interactions import Task, IntervalTrigger from interactions import slash_command, listen from interactions.api.events import Component @@ -12,7 +12,7 @@ from interactions.api.events import Startup from token_bot.controller.alerts import AlertsController from token_bot.controller.users import UsersController -from token_bot.history_manager.history_manager import HistoryManager +from token_bot.history_manager.history_manager import HistoryManager, History from token_bot.persistant_database.alert_category import AlertCategory from token_bot.persistant_database.alert_schema import Alert from token_bot.persistant_database.alert_type import AlertType @@ -25,6 +25,18 @@ from token_bot.ui.select_menus.alert_menu import HIGH_ALERT_MENU, LOW_ALERT_MENU from token_bot.ui.select_menus.flavor_menu import FLAVOR_MENU from token_bot.ui.select_menus.region_menu import REGION_MENU +#### Static Helper Functions + +async def gather_alerts_by_flavor(alerts: List[Alert]) -> Dict[Flavor, List[Alert]]: + alerts_by_flavor = {} + for alert in alerts: + if alert.flavor not in alerts_by_flavor: + alerts_by_flavor[alert.flavor] = [alert] + else: + alerts_by_flavor[alert.flavor].append(alert) + return alerts_by_flavor + + class Tracker(Extension): def __init__(self, bot): @@ -54,20 +66,19 @@ class Tracker(Extension): users_alerts[user].append(alert) for user in users_alerts: discord_user = await self.bot.fetch_user(user.user_id) - alert_message = str() - for alert in users_alerts[user]: - if alert.alert_type != AlertType.SPECIFIC_PRICE: - alert_message += f"{alert.to_human_string()}" - embed = Embed( + embeds = [Embed( title="TokenBot Tracker Alert Triggered", color=0xb10000, description=f"Hello, you requested to be sent an alert when the price of the World of Warcraft " - f"token reaches a certain value.\n\n" - f"As a reminder, you can remove an alert via /remove-alert\n" - f"or you can remove all registrations via /remove-registration\n\n" - f"The following alerts have been triggered: {alert_message}", - ) - await discord_user.send(embed=embed) + f"token reaches a certain value.\n\n" + f"As a reminder, you can remove an alert via ```/remove-alert```\n" + f"or you can remove all registrations via ```/remove-registration```\n\n" + )] + alerts_by_flavor = await gather_alerts_by_flavor(users_alerts[user]) + for flavor in alerts_by_flavor: + embeds.append(await self.render_alert_flavor(alerts_by_flavor[flavor])) + + await discord_user.send(embeds=embeds) ################################### @@ -95,8 +106,7 @@ class Tracker(Extension): "Please note: \n" "* You can only be registered with one region at a time \n" "* Changing your region will remove all previous alerts you have signed up for \n" - "* You can remove all alerts and registration using /remove-registration") - await self._users.add(ctx.user.id) + "* You can remove all alerts and registration using ```/remove-registration```") await ctx.send(text, components=REGION_MENU, ephemeral=True) @slash_command() @@ -149,10 +159,16 @@ class Tracker(Extension): @slash_command() async def list_alerts(self, ctx: SlashContext): alerts = await self._users.list_alerts(ctx.user.id) - alerts_str = str() - for alert in alerts: - alerts_str += f"{alert.to_human_string()}\n" - await ctx.send(str(alerts), ephemeral=True) + alerts_str = f"You have {len(alerts)} out of 25 maximum alerts registered" + embeds = [Embed( + title="List of TokenBot Tracker Alerts", + color=0x0000b1, + description=alerts_str + )] + alerts_by_flavor = await gather_alerts_by_flavor(alerts) + for flavor in alerts_by_flavor: + embeds.append(await self.render_alert_flavor(alerts_by_flavor[flavor])) + await ctx.send(embeds=embeds, ephemeral=True) ################################### # Callbacks Commands # @@ -264,3 +280,25 @@ class Tracker(Extension): components=low_menu, ephemeral=True) return await self._alert_select_menu_handler(ctx, low_menu, low_message) + + async def render_alert_flavor(self, alerts: List[Alert]) -> Embed: + region = alerts[0].region + flavor = alerts[0].flavor + fields: List[EmbedField] = [] + for alert in alerts: + history = await self._history_manager.get_history(alert.flavor, alert.region) + trigger = await history.find_update_trigger_from_alert(alert) + if trigger.last_trigger is not None: + alert_str = (f"Last Alerting Price Value: {format(trigger.last_trigger[1], ",")}\n" + f"Last Alerting Time: {trigger.last_trigger[0].strftime('%Y-%m-%d %H:%M:%S UTC')}\n") + else: + alert_str = "You should only be seeing this if the bot has not finished importing history at startup." + fields.append( + EmbedField( + name=f"{alert.to_human_string()} Alert", value=alert_str, inline=False)) + embed = Embed( + title=f"Alerts for {region.name} {flavor.name.lower().title()}", + color=0xb10000, + fields=fields + ) + return embed