bug fixed 1000 games

This commit is contained in:
vrubel 2025-11-16 13:24:39 +03:00
parent 3226d4c162
commit 3e61fa33c4
4 changed files with 29 additions and 22 deletions

View file

@ -640,6 +640,11 @@ class LichessBot:
year_ms = 365 * 24 * 3600 * 1000 year_ms = 365 * 24 * 3600 * 1000
since_ms = now_ms - year_ms since_ms = now_ms - year_ms
try: try:
# Inform user that the request is being processed
try:
await update.message.reply_text("⏳ Please wait a moment, processing the request…")
except Exception:
pass
data = await self.lichess_api.get_games_period(username, since_ms, now_ms, rated_only=True) data = await self.lichess_api.get_games_period(username, since_ms, now_ms, rated_only=True)
if not data: if not data:
await update.message.reply_text(t('no_data', lang)) await update.message.reply_text(t('no_data', lang))

View file

@ -11,7 +11,7 @@ class StatsFormatter:
elif rating_change < 0: elif rating_change < 0:
return f"🔴 {rating_change}" return f"🔴 {rating_change}"
else: else:
return f"0" return "0"
@staticmethod @staticmethod
def format_stats_response(data: Dict[str, Any], username: str, period: str, lang: str = 'en') -> str: def format_stats_response(data: Dict[str, Any], username: str, period: str, lang: str = 'en') -> str:
@ -185,16 +185,18 @@ class StatsFormatter:
# Title and subheader # Title and subheader
if games_count >= 1000: if games_count >= 1000:
header = f"📈 {username}: last 1000 rated games" header = f"📈 {username}: last 1000 rated games"
# Use period_start as earliest known bound (server does not expose earliest game timestamp) earliest_ts = data.get('earliest_game_ts')
if isinstance(period_start, int): if isinstance(earliest_ts, int):
earliest = datetime.fromtimestamp(period_start).strftime("%d.%m.%Y") earliest = datetime.fromtimestamp(earliest_ts).strftime("%d.%m.%Y")
header += f"\nНачало этих 1000 партий: {earliest}" header += f"\nStart of these 1000 games: {earliest}"
else: else:
header = f"📈 {username}: last year (rated), games: {games_count}" header = f"📈 {username}: last year (rated), games: {games_count}"
if isinstance(period_start, int) and isinstance(period_end, int): # Use earliest actual game date instead of naive 'year ago'
start_str = datetime.fromtimestamp(period_start).strftime("%d.%m.%Y") earliest_ts = data.get('earliest_game_ts', period_start)
if isinstance(earliest_ts, int) and isinstance(period_end, int):
start_str = datetime.fromtimestamp(earliest_ts).strftime("%d.%m.%Y")
end_str = datetime.fromtimestamp(period_end).strftime("%d.%m.%Y") end_str = datetime.fromtimestamp(period_end).strftime("%d.%m.%Y")
header += f"\nПериод: {start_str}{end_str}" header += f"\nPeriod: {start_str}{end_str}"
# Body per mode # Body per mode
lines = [] lines = []
for mode in ["bullet", "blitz", "rapid", "classical", "correspondence"]: for mode in ["bullet", "blitz", "rapid", "classical", "correspondence"]:
@ -213,20 +215,9 @@ class StatsFormatter:
rating = mode_stats.get('rating') rating = mode_stats.get('rating')
rating_str = rating if rating is not None else "" rating_str = rating if rating is not None else ""
lines.append( lines.append(
f"{emoji} {mode.title()}: {games_played} Δ {rating_change_str} R {rating_str} (+{wins} -{losses} ={draws})" f"{emoji} {mode.title()}: {games_played} Δ {rating_change_str} R {rating_str} {wins}{losses} 🤝 {draws}"
) )
# Total # Total
total = stats.get('total') or {} # Do not print 'Итого' line per new requirement
total_line = "" body = "\n".join(lines)
if total:
tg = total.get('games_played', 0)
tw = total.get('wins', 0)
tl = total.get('losses', 0)
td = total.get('draws', 0)
trc = total.get('rating_change', 0)
trc_str = StatsFormatter._format_rating_change(trc)
tr = total.get('rating')
tr_str = tr if tr is not None else ""
total_line = f"\nИтого: {tg} Δ {trc_str} R {tr_str} (+{tw} -{tl} ={td})"
body = "\n".join(lines) + total_line
return f"{header}\n{body}".rstrip() return f"{header}\n{body}".rstrip()

View file

@ -190,6 +190,7 @@ class GamesOfPeriodResponse(BaseModel):
period_start: int = Field(..., description="Начало периода (Unix timestamp)", example=1640995200) period_start: int = Field(..., description="Начало периода (Unix timestamp)", example=1640995200)
period_end: int = Field(..., description="Конец периода (Unix timestamp)", example=1641081600) period_end: int = Field(..., description="Конец периода (Unix timestamp)", example=1641081600)
games_count: int = Field(..., description="Общее количество игр", example=25) games_count: int = Field(..., description="Общее количество игр", example=25)
earliest_game_ts: Optional[int] = Field(None, description="Время самой старой найденной партии (Unix timestamp, секунды)", example=1638316800)
data: Optional[GamesOfPeriodStats] = Field(None, description="Данные статистики игр") data: Optional[GamesOfPeriodStats] = Field(None, description="Данные статистики игр")
# ============================================================================= # =============================================================================

View file

@ -606,6 +606,15 @@ class StatsService:
# Обрабатываем игры # Обрабатываем игры
games_stats = self._process_games_of_period(games, username) games_stats = self._process_games_of_period(games, username)
# Определяем время самой старой партии (в секундах)
earliest_game_ts = None
try:
if games:
earliest_game_ts = min(g.get('createdAt', 0) for g in games if isinstance(g.get('createdAt', None), int))
if earliest_game_ts:
earliest_game_ts = earliest_game_ts // 1000
except Exception:
earliest_game_ts = None
return GamesOfPeriodResponse( return GamesOfPeriodResponse(
message="Статистика игр за период", message="Статистика игр за период",
@ -613,6 +622,7 @@ class StatsService:
period_start=since_timestamp, period_start=since_timestamp,
period_end=until_timestamp, period_end=until_timestamp,
games_count=len(games), games_count=len(games),
earliest_game_ts=earliest_game_ts,
data=games_stats data=games_stats
) )