Bug fixes
Based on the first day of dogfooding for myself
This commit is contained in:
parent
5db4e76de8
commit
a067953467
@ -14,6 +14,7 @@ class UsersController:
|
|||||||
self._pdb: pdb.Database = pdb.Database(session)
|
self._pdb: pdb.Database = pdb.Database(session)
|
||||||
self.table: aiodynamo.client.Table = self._pdb.client.table(os.getenv('USERS_TABLE'))
|
self.table: aiodynamo.client.Table = self._pdb.client.table(os.getenv('USERS_TABLE'))
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _user_to_obj(user: int | User) -> User:
|
def _user_to_obj(user: int | User) -> User:
|
||||||
if isinstance(user, int):
|
if isinstance(user, int):
|
||||||
|
@ -9,6 +9,7 @@ from token_bot.token_database.region import Region
|
|||||||
from token_bot.token_database import database as tdb
|
from token_bot.token_database import database as tdb
|
||||||
|
|
||||||
class HistoryManager:
|
class HistoryManager:
|
||||||
|
HIGH_FIDELITY_PERIOD = '72h'
|
||||||
def __init__(self, token_db: tdb.Database):
|
def __init__(self, token_db: tdb.Database):
|
||||||
self._history : Dict[Flavor, Dict[Region, History]] = {}
|
self._history : Dict[Flavor, Dict[Region, History]] = {}
|
||||||
self._tdb : tdb.Database = token_db
|
self._tdb : tdb.Database = token_db
|
||||||
@ -21,15 +22,19 @@ class HistoryManager:
|
|||||||
async def _retrieve_data(self, flavor: Flavor, region: Region) -> List[Tuple[datetime.datetime, int]]:
|
async def _retrieve_data(self, flavor: Flavor, region: Region) -> List[Tuple[datetime.datetime, int]]:
|
||||||
high_fidelity_time = datetime.datetime.now(tz=datetime.UTC) - datetime.timedelta(hours=72)
|
high_fidelity_time = datetime.datetime.now(tz=datetime.UTC) - datetime.timedelta(hours=72)
|
||||||
all_history = await self._tdb.history(flavor, region)
|
all_history = await self._tdb.history(flavor, region)
|
||||||
high_fidelity_history = await self._tdb.history(flavor, region, '72h')
|
high_fidelity_history = await self._tdb.history(flavor, region, self.HIGH_FIDELITY_PERIOD)
|
||||||
final_response = []
|
final_response = []
|
||||||
|
|
||||||
|
def _convert_to_datetime(data: Tuple[str, int]):
|
||||||
|
return datetime.datetime.fromisoformat(data[0]), data[1]
|
||||||
|
|
||||||
for data_point in all_history:
|
for data_point in all_history:
|
||||||
datum = (datetime.datetime.fromisoformat(data_point[0]), data_point[1])
|
datetime_tuple = _convert_to_datetime(data_point)
|
||||||
if datum[0] < high_fidelity_time:
|
if datetime_tuple[0] < high_fidelity_time:
|
||||||
final_response.append(datum)
|
final_response.append(datetime_tuple)
|
||||||
for data_point in high_fidelity_history:
|
|
||||||
datum = (datetime.datetime.fromisoformat(data_point[0]), data_point[1])
|
final_response.extend(_convert_to_datetime(data_point) for data_point in high_fidelity_history)
|
||||||
final_response.append(datum)
|
|
||||||
return final_response
|
return final_response
|
||||||
|
|
||||||
|
|
||||||
@ -37,7 +42,7 @@ class HistoryManager:
|
|||||||
for flavor in Flavor:
|
for flavor in Flavor:
|
||||||
for r in Region:
|
for r in Region:
|
||||||
region = Region(r)
|
region = Region(r)
|
||||||
history = History(flavor, Region(region))
|
history = History(flavor, region)
|
||||||
history_response = await self._retrieve_data(flavor, region)
|
history_response = await self._retrieve_data(flavor, region)
|
||||||
for item in history_response:
|
for item in history_response:
|
||||||
await history.add_price(item)
|
await history.add_price(item)
|
||||||
|
@ -4,6 +4,7 @@ from aiodynamo.client import Table
|
|||||||
from aiodynamo.errors import ItemNotFound
|
from aiodynamo.errors import ItemNotFound
|
||||||
from aiodynamo.expressions import F
|
from aiodynamo.expressions import F
|
||||||
|
|
||||||
|
from token_bot.persistant_database import AlertType
|
||||||
from token_bot.token_database.flavor import Flavor
|
from token_bot.token_database.flavor import Flavor
|
||||||
from token_bot.token_database.region import Region
|
from token_bot.token_database.region import Region
|
||||||
import token_bot.persistant_database as pdb
|
import token_bot.persistant_database as pdb
|
||||||
@ -70,10 +71,10 @@ class Alert:
|
|||||||
return self.alert_type == other.alert_type and self.flavor == other.flavor and self.price == other.price
|
return self.alert_type == other.alert_type and self.flavor == other.flavor and self.price == other.price
|
||||||
|
|
||||||
def to_human_string(self):
|
def to_human_string(self):
|
||||||
if self.alert_type.SPECIFIC_PRICE:
|
if self.alert_type == AlertType.SPECIFIC_PRICE:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
else:
|
else:
|
||||||
return f"\n|Region: {self.region.value.upper()}\tFlavor: {self.flavor.value.upper()}\tAlert: {self.alert_type.name.lower()}|"
|
return f"\n|\tRegion: {self.region.value.upper()}\tFlavor: {self.flavor.name.lower()}\tAlert: {self.alert_type.name.lower()}\t|"
|
||||||
|
|
||||||
async def _lazy_load(self, table: Table, consistent: bool = False) -> None:
|
async def _lazy_load(self, table: Table, consistent: bool = False) -> None:
|
||||||
if consistent or not self._loaded:
|
if consistent or not self._loaded:
|
||||||
@ -91,7 +92,7 @@ class Alert:
|
|||||||
)
|
)
|
||||||
|
|
||||||
async def put(self, table: Table) -> None:
|
async def put(self, table: Table) -> None:
|
||||||
user_ids = [user.user_id for user in self._users]
|
user_ids = [str(user.user_id) for user in self._users]
|
||||||
await table.put_item(
|
await table.put_item(
|
||||||
item={
|
item={
|
||||||
self.primary_key_name: self.primary_key,
|
self.primary_key_name: self.primary_key,
|
||||||
@ -108,8 +109,7 @@ class Alert:
|
|||||||
)
|
)
|
||||||
except ItemNotFound:
|
except ItemNotFound:
|
||||||
return False
|
return False
|
||||||
if 'Item' in response:
|
self._users = [pdb.User(int(user_id)) for user_id in response['users']]
|
||||||
self._users = [pdb.User(int(user_id)) for user_id in response['Item']['users']['NS']]
|
|
||||||
self._loaded = True
|
self._loaded = True
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -18,21 +18,24 @@ class User:
|
|||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return self.user_id == other.user_id
|
return self.user_id == other.user_id
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
return hash(self.user_id)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_item(cls, primary_key: int, region: Region, subscribed_alerts: List[str]) -> 'User':
|
def from_item(cls, primary_key: int, region: Region, subscribed_alerts: List[str]) -> 'User':
|
||||||
alerts = [pdb.Alert.from_str(alert_str) for alert_str in subscribed_alerts]
|
alerts = [pdb.Alert.from_str(alert_str) for alert_str in subscribed_alerts]
|
||||||
return cls(primary_key, region, alerts)
|
return cls(primary_key, region, alerts)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def primary_key(self) -> int:
|
def primary_key(self) -> str:
|
||||||
return self.user_id
|
return str(self.user_id)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def primary_key_name(self) -> str:
|
def primary_key_name(self) -> str:
|
||||||
return 'user_id'
|
return 'user_id'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def key(self) -> Dict[str, int]:
|
def key(self) -> Dict[str, str]:
|
||||||
return {
|
return {
|
||||||
self.primary_key_name: self.primary_key
|
self.primary_key_name: self.primary_key
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
from typing import Dict, List, LiteralString
|
from typing import Dict, List
|
||||||
|
|
||||||
from token_bot.token_database.endpoints import Endpoints
|
|
||||||
from token_bot.token_database.flavor import Flavor
|
from token_bot.token_database.flavor import Flavor
|
||||||
from token_bot.token_database.exceptions import *
|
from token_bot.token_database.exceptions import *
|
||||||
import aiohttp
|
import aiohttp
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
|
|
||||||
|
|
||||||
class Endpoints(str, Enum):
|
|
||||||
RETAIL_CURRENT = '/v2/current/retail.json'
|
|
||||||
CLASSIC_CURRENT = '/v2/current/classic.json'
|
|
||||||
RETAIL_HISTORY_ALL = '/v2/relative/retail/us/all.json'
|
|
@ -61,13 +61,14 @@ class Tracker(Extension):
|
|||||||
else:
|
else:
|
||||||
users_alerts[user].append(alert)
|
users_alerts[user].append(alert)
|
||||||
for user in users_alerts:
|
for user in users_alerts:
|
||||||
discord_user = self.bot.get_user(user.user_id)
|
discord_user = await self.bot.fetch_user(user.user_id)
|
||||||
alert_message = str()
|
alert_message = str()
|
||||||
for alert in users_alerts[user]:
|
for alert in users_alerts[user]:
|
||||||
|
if alert.alert_type != AlertType.SPECIFIC_PRICE:
|
||||||
alert_message += f"{alert.to_human_string()}"
|
alert_message += f"{alert.to_human_string()}"
|
||||||
await discord_user.send(f"Hello, you requested to be sent an alert when the price of the World of Warcraft "
|
await discord_user.send(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"token reaches a certain value.\n\n"
|
||||||
f"As a reminder, you can always remove an alert via /remove-alert\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"or you can remove all registrations via /remove-registration\n\n"
|
||||||
f"The following alerts have been triggered: {alert_message}")
|
f"The following alerts have been triggered: {alert_message}")
|
||||||
|
|
||||||
@ -96,7 +97,8 @@ class Tracker(Extension):
|
|||||||
text = ("## Select a region to register with \n\n"
|
text = ("## Select a region to register with \n\n"
|
||||||
"Please note: \n"
|
"Please note: \n"
|
||||||
"* You can only be registered with one region at a time \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")
|
"* 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)
|
await self._users.add(ctx.user.id)
|
||||||
await ctx.send(text, components=REGION_MENU, ephemeral=True)
|
await ctx.send(text, components=REGION_MENU, ephemeral=True)
|
||||||
|
|
||||||
@ -105,11 +107,6 @@ class Tracker(Extension):
|
|||||||
await self._users.delete(ctx.user.id)
|
await self._users.delete(ctx.user.id)
|
||||||
await ctx.send("All alert subscriptions and user registration deleted", ephemeral=True)
|
await ctx.send("All alert subscriptions and user registration deleted", ephemeral=True)
|
||||||
|
|
||||||
@slash_command()
|
|
||||||
async def delete(self, ctx: SlashContext):
|
|
||||||
await self._users.delete(ctx.user.id)
|
|
||||||
await ctx.send("Deletion Successful", ephemeral=True)
|
|
||||||
|
|
||||||
@slash_command()
|
@slash_command()
|
||||||
async def exists(self, ctx: SlashContext):
|
async def exists(self, ctx: SlashContext):
|
||||||
await ctx.send(str(await self._users.exists(ctx.user.id)), ephemeral=True)
|
await ctx.send(str(await self._users.exists(ctx.user.id)), ephemeral=True)
|
||||||
@ -150,7 +147,7 @@ class Tracker(Extension):
|
|||||||
|
|
||||||
@slash_command()
|
@slash_command()
|
||||||
async def remove_alert(self, ctx: SlashContext):
|
async def remove_alert(self, ctx: SlashContext):
|
||||||
pass
|
await ctx.send("This is not implemented yet, use /remove-registration for the time being", ephemeral=True)
|
||||||
|
|
||||||
@slash_command()
|
@slash_command()
|
||||||
async def list_alerts(self, ctx: SlashContext):
|
async def list_alerts(self, ctx: SlashContext):
|
||||||
|
Loading…
Reference in New Issue
Block a user