get total playtime from player

This commit is contained in:
Corban-Lee Jones 2024-12-11 22:55:39 +00:00
parent b2847ebe95
commit 1ff4f4e831

View File

@ -4,6 +4,7 @@ Database schemas.
import logging import logging
from datetime import datetime, timedelta from datetime import datetime, timedelta
from pytz import timezone
import httpx import httpx
from tortoise import fields from tortoise import fields
@ -61,13 +62,15 @@ class PlayerSession(Model):
on_delete=fields.CASCADE on_delete=fields.CASCADE
) )
connected_at = fields.DatetimeField() connected_at = fields.DatetimeField()
disconnected_at = fields.DatetimeField(null=False) disconnected_at = fields.DatetimeField(null=True)
connected_coords = fields.ForeignKeyField( connected_coords = fields.ForeignKeyField(
model_name="models.Coordinates", model_name="models.Coordinates",
related_name="connected_coords",
on_delete=fields.CASCADE on_delete=fields.CASCADE
) )
disconnected_coords = fields.ForeignKeyField( disconnected_coords = fields.ForeignKeyField(
model_name="models.Coordinates", model_name="models.Coordinates",
related_name="disconnected_coords",
on_delete=fields.CASCADE, on_delete=fields.CASCADE,
null=True null=True
) )
@ -93,10 +96,18 @@ class Player(Model):
table = "players" table = "players"
async def get_playtime(self) -> timedelta: async def get_playtime(self) -> timedelta:
playtime = await PlayerSession.filter(player=self).exclude(disconnected_at=None).annotate( sessions = await PlayerSession.filter(player=self)
total_playtime=Sum(F("disconnected_at") - F("connected_at")) total_playtime = timedelta()
).values() now = datetime.now()
return timedelta(seconds=playtime[0]["total_playtime"].total_seconds() if playtime else timedelta()) 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]: async def get_deaths(self) -> list[PlayerDeath]:
return await PlayerDeath.filter(player=self) return await PlayerDeath.filter(player=self)
@ -139,7 +150,8 @@ class Player(Model):
log.debug("creating session for player: %s", self.username) log.debug("creating session for player: %s", self.username)
existing_session = await self.get_latest_session(ignore_closed_sessions=True) existing_session = await self.get_latest_session(ignore_closed_sessions=True)
if existing_session: 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) coordinates = await Coordinates.create(x=coord_x, y=coord_y, z=coord_z)
return await PlayerSession.create( return await PlayerSession.create(
@ -213,7 +225,8 @@ class Player(Model):
raise ValueError("You must fetch the steam_profile_summary before creating an embed.") raise ValueError("You must fetch the steam_profile_summary before creating an embed.")
death_count = len(await self.get_deaths()) 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( embed = Embed(
title="Player", title="Player",