From 1ff4f4e831082c70f76cbb3aa5962d8d444d0861 Mon Sep 17 00:00:00 2001 From: Corban-Lee Jones Date: Wed, 11 Dec 2024 22:55:39 +0000 Subject: [PATCH] get total playtime from player --- utils/models.py | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/utils/models.py b/utils/models.py index abd10f6..30d29ee 100644 --- a/utils/models.py +++ b/utils/models.py @@ -4,6 +4,7 @@ Database schemas. import logging from datetime import datetime, timedelta +from pytz import timezone import httpx from tortoise import fields @@ -61,13 +62,15 @@ class PlayerSession(Model): on_delete=fields.CASCADE ) connected_at = fields.DatetimeField() - disconnected_at = fields.DatetimeField(null=False) + disconnected_at = fields.DatetimeField(null=True) connected_coords = fields.ForeignKeyField( model_name="models.Coordinates", + related_name="connected_coords", on_delete=fields.CASCADE ) disconnected_coords = fields.ForeignKeyField( model_name="models.Coordinates", + related_name="disconnected_coords", on_delete=fields.CASCADE, null=True ) @@ -93,10 +96,18 @@ class Player(Model): table = "players" async def get_playtime(self) -> timedelta: - playtime = await PlayerSession.filter(player=self).exclude(disconnected_at=None).annotate( - total_playtime=Sum(F("disconnected_at") - F("connected_at")) - ).values() - return timedelta(seconds=playtime[0]["total_playtime"].total_seconds() if playtime else timedelta()) + sessions = await PlayerSession.filter(player=self) + total_playtime = timedelta() + now = datetime.now() + utc = timezone("UTC") + + # I know this is terrible efficiency-wise, but the tortoise docs + # are so bad and the annotations don't work like Django's models. Deal with it! + for session in sessions: + disconnected_at = session.disconnected_at or now + total_playtime += disconnected_at.astimezone(utc) - session.connected_at.astimezone(utc) + + return total_playtime async def get_deaths(self) -> list[PlayerDeath]: return await PlayerDeath.filter(player=self) @@ -139,7 +150,8 @@ class Player(Model): log.debug("creating session for player: %s", self.username) existing_session = await self.get_latest_session(ignore_closed_sessions=True) if existing_session: - raise ValueError("Tried to open session while an open one exists.") + log.debug("deleting an unfinished session to open a new one") + await existing_session.delete() coordinates = await Coordinates.create(x=coord_x, y=coord_y, z=coord_z) return await PlayerSession.create( @@ -213,7 +225,8 @@ class Player(Model): raise ValueError("You must fetch the steam_profile_summary before creating an embed.") death_count = len(await self.get_deaths()) - playtime = str(await self.get_playtime()) + playtime = str(await self.get_playtime()).split(".")[0] # remove the miliseconds + log.debug("death count is: %s and playtime is: %s", death_count, playtime) embed = Embed( title="Player",