(stats): New xp display format.

This commit is contained in:
2023-10-09 16:50:35 +03:00
parent 50a1a9c8a1
commit d674dc4c8e
3 changed files with 77 additions and 10 deletions

Submodule src/gui updated: 24e94d10e2...f2760218ef

View File

@@ -6,11 +6,28 @@ import discord
from meta import LionBot
from gui.cards import StatsCard
from gui.base import CardMode
from tracking.text.data import TextTrackerData
from .. import babel
from ..data import StatsData
_p = babel._p
def format_time(seconds):
return "{:02}:{:02}".format(
int(seconds // 3600),
int(seconds % 3600 // 60)
)
def format_xp(messages, xp):
return f"{messages} ({xp} XP)"
async def get_stats_card(bot: LionBot, userid: int, guildid: int, mode: CardMode):
t = bot.translator.t
data: StatsData = bot.get_cog('StatsCog').data
# TODO: Workouts
@@ -32,28 +49,41 @@ async def get_stats_card(bot: LionBot, userid: int, guildid: int, mode: CardMode
)
# Extract the study times for each period
if mode in (CardMode.STUDY, CardMode.VOICE):
if mode in (CardMode.STUDY, CardMode.VOICE, CardMode.ANKI):
model = data.VoiceSessionStats
refkey = (guildid or None, userid)
ref_since = model.study_times_since
ref_between = model.study_times_between
period_activity = await ref_since(*refkey, *period_timestamps)
period_strings = [format_time(activity) for activity in reversed(period_activity)]
month_activity = period_activity[1]
month_string = t(_p(
'gui:stats|mode:voice|month',
"{hours} hours"
)).format(hours=int(month_activity // 3600))
elif mode is CardMode.TEXT:
msgmodel = TextTrackerData.TextSessions
if guildid:
model = data.MemberExp
msg_since = msgmodel.member_messages_since
refkey = (guildid, userid)
else:
model = data.UserExp
msg_since = msgmodel.member_messages_between
refkey = (userid,)
ref_since = model.xp_since
ref_between = model.xp_between
else:
# TODO ANKI
model = data.VoiceSessionStats
refkey = (guildid, userid)
ref_since = model.study_times_since
ref_between = model.study_times_between
study_times = await ref_since(*refkey, *period_timestamps)
xp_period_activity = await ref_since(*refkey, *period_timestamps)
msg_period_activity = await msg_since(*refkey, *period_timestamps)
period_strings = [
format_xp(msgs, xp)
for msgs, xp in zip(reversed(msg_period_activity), reversed(xp_period_activity))
]
month_string = f"{xp_period_activity[1]} XP"
else:
raise ValueError(f"Mode {mode} not supported")
# Get leaderboard position
# TODO: Efficiency
@@ -89,7 +119,8 @@ async def get_stats_card(bot: LionBot, userid: int, guildid: int, mode: CardMode
card = StatsCard(
(position, 0),
list(reversed(study_times)),
period_strings,
month_string,
100,
streaks,
skin={'mode': mode}

View File

@@ -288,6 +288,42 @@ class TextTrackerData(Registry):
tuple(chain((userid, guildid), points))
)
return [r['messages'] or 0 for r in await cursor.fetchall()]
@classmethod
@log_wrap(action='user_messages_since')
async def user_messages_since(cls, userid: int, *points):
"""
Compute messages written between the given points.
"""
query = sql.SQL(
"""
SELECT
(
SELECT
SUM(messages)
FROM text_sessions s
WHERE
s.userid = %s
AND s.start_time >= t._start
) AS messages
FROM
(VALUES {})
AS
t (_start)
ORDER BY t._start
"""
).format(
sql.SQL(', ').join(
sql.SQL("({})").format(sql.Placeholder()) for _ in points
)
)
async with cls._connector.connection() as conn:
async with conn.cursor() as cursor:
await cursor.execute(
query,
tuple(chain((userid,), points))
)
return [r['messages'] or 0 for r in await cursor.fetchall()]
@classmethod
@log_wrap(action='msgs_leaderboard_all')