Commit graph

58 commits

Author SHA1 Message Date
vrubelroman
619c00aa06 stop infinite retry loop on rejected Lichess tokens
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 12s
A gamer's periodic check would get permanently stuck if their stored token
was revoked/expired: our stats API collapsed both "Lichess rejected the
token" (401/403, permanent) and genuine transient errors into the same 502
response, so the bot treated an invalid token exactly like a network blip —
retrying the same window forever at a capped 300s backoff, never advancing
the checkpoint (observed in prod: Dor1zz stuck for 100+ consecutive errors
over 8+ hours, admin alerts firing every 25 failures).

Preserve the distinction that already existed one layer down (lichess_client.py
already tells 401/403 apart from other failures) instead of collapsing it in
stats_service.py: add PuzzleOfPeriodResponse.auth_failed, have main.py return
401 specifically for that case, and have the bot raise a distinct
InvalidTokenError instead of returning None. On InvalidTokenError, the bot now
clears the token for that pair, notifies the user to reconnect via /addtoken,
and continues tracking games normally instead of stalling forever.
2026-07-05 07:37:14 +00:00
vrubelroman
8080921141 fix periodic-check request queue throughput bottleneck
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 12s
The bot's request_queue.py 4s FIFO gate wasn't protecting against Lichess's
rate limiter — that's already handled downstream in LichessWebServices/
rate_limiter.py (0.2s, shared across all callers of our stats service). The
bot-side gate only paced calls to our own local service, and since it awaited
each request to full completion before dequeuing the next, real dispatch gaps
were max(4s, previous request's duration) — with 454 tracked gamer/user pairs,
any burst (e.g. after a restart) piled into the queue and took 10-20+ minutes
to drain.

Replace it with a paced-dispatch + bounded-concurrency design: a hard 2s floor
between dispatches (still never lets 2+ requests through in that window),
decoupled from completion time, with up to 10 requests actually in flight at
once via a semaphore. Doesn't touch the real Lichess-facing rate limit at all.

Also add deterministic per-(user,gamer) checkpoint jitter: previously every
pair sharing the same period_minutes re-locked onto the same wall-clock phase
on every restart (backlog collapse snaps period_end_approx to `now` for
everyone overdue at once), recreating the pileup each time. Jitter is stable
across restarts (crc32-based, not Python's salted hash()) and capped well
under the 2h stale-backlog threshold. Small startup stagger added too, purely
cosmetic smoothing on top of the jitter fix.
2026-07-04 20:30:49 +00:00
vrubelroman
ad6daf2918 suppress periodic notifications for stale collapsed backlogs
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 16s
The backlog-collapse fix (previous commit) correctly stops the checkpoint
from falling further behind, but it was still sending the full per-game
notification for whatever it caught up on — meaning a gamer whose checkpoint
had drifted weeks behind now dumps a multi-week, game-by-game report on the
user in one message. That's not a "periodic update" anymore, just spam.

When the collapsed window exceeds 2 hours, catch the checkpoint up silently
(still fixes the drift) but skip sending the notification for it — only
report activity that's actually recent going forward.
2026-07-04 19:14:36 +00:00
vrubelroman
b0173950b8 fix silent addgamer drop on restart and periodic-check backlog buildup
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 13s
Persist user_data (PicklePersistence) so an in-flight /addgamer username
prompt survives a bot restart instead of being silently swallowed by
handle_username when the in-memory awaiting flag is gone.

Collapse periodic-check backlog into a single request spanning the whole
missed gap instead of replaying it one period_minutes window at a time —
with enough tracked gamers sharing one RequestQueue, per-window replay
could never catch up and the checkpoint fell further behind indefinitely.
Notification period label now reflects the actual queried span (minutes/
hours/days) instead of the configured interval, so a weeks-old catch-up
no longer gets mislabeled as "for 15 minutes".
2026-07-04 18:33:45 +00:00
vrubelroman
f154d3d7c3 align /getgamers and stats-message tables, unify stats body into one code block
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 31s
- /getgamers: column-aligned monospace table (username, ratings, period).
- Per-mode stats (rating/wins/losses/draws): column-aligned block, dropped
  the meaningless multi-game average accuracy row.
- format_stats_response/format_period_notification now wrap the whole
  message in a single markdown code block instead of alternating
  plain-text headers and separately-fenced tables.
- Rating row gets an emoji prefix to match the other three rows, so
  Telegram's monospace rendering keeps all values in the same column.
2026-07-03 13:20:50 +00:00
vrubelroman
2a7385290e fix silent onboarding drop-off in /addgamer flow
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 33s
Set awaiting_addgamer_username as soon as the menu is shown so typing a
username directly (without tapping the button) is handled instead of
being silently ignored. Also stop reporting a valid username as "not
found" when Lichess returns a non-404 error (rate limit/timeout), and
surface an error message if the addgamer menu itself fails to send.
2026-07-03 12:23:40 +00:00
vrubelroman
d479e14bf9 add per-game accuracy and outcome table to stats/notifications
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 31s
Games-of-period responses can now include a per-game breakdown
(include_games) with Lichess post-analysis accuracy, plus which side
the tracked player was on and their rating change for that game.

- lichess_client.py requests accuracy=true from Lichess; stats_service
  computes per-mode average accuracy and builds GameRow entries
  (tracked_is_white, tracked_rating_diff) for blitz/rapid/classical
- /games/{username}/period gained an include_games query param
- formatters.py renders a column-aligned monospace table per game:
  outcome circle (win/loss/draw relative to the tracked player),
  rating change, accuracy, names/ratings, result — for today/yesterday
  and periodic notifications; week keeps an aggregate accuracy line
- usernames are Markdown-escaped before formatting since messages are
  now sent with parse_mode='Markdown'
2026-07-03 09:38:51 +00:00
vrubelroman
4a783225af fix periodic activity-check algorithm silently losing player activity
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 38s
Errors from Lichess (timeouts/5xx/invalid tokens) were being disguised
as "no activity" (HTTP 200, games_count/puzzles_in_period=0), causing
the bot to silently advance its checkpoint past real, undetected
activity. Puzzle-fetch failures weren't counted as errors at all, and
the periodic task died permanently after 5 consecutive errors with no
way to recover short of a manual restart. /setperiod also unconditionally
reset the checkpoint, dropping the window between the last check and
the command.

- API now returns success=false/502 on real errors instead of masking
  them as zero activity (models.py, stats_service.py, main.py)
- Puzzle-fetch errors are now treated the same as game-fetch errors:
  retry the same window instead of reporting "no puzzles"
- Notification delivery failures no longer silently advance the
  checkpoint
- Replaced the hard 5-error kill switch with capped backoff that keeps
  retrying indefinitely, plus an admin-bot notification if a player's
  monitoring has been failing for a prolonged period (~2h+)
- /setperiod only clears the checkpoint when disabling notifications,
  preserving continuity when a period is just changed

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-02 19:29:06 +00:00
vrubelroman
63e28c279c fix by codex 2026-03-21 22:58:47 +03:00
vrubel
2ac38440da удалили сообщения That's all и Processing request... 2026-01-22 16:25:33 +03:00
vrubelroman
b3b6a54e2d пофиксил баг отправки уведомлений 2025-12-06 00:28:53 +03:00
vrubelroman
6d51cf135d после неудачных попыток добавить игрока предлагается добавить игрока 2025-12-03 13:09:40 +03:00
vrubelroman
6ed6ab866e добавлены картинки с подсказкой как добавить игрока 2025-12-03 02:33:38 +03:00
vrubelroman
f458044543 убран блок информации из /start в /help 2025-12-01 13:52:26 +03:00
vrubelroman
f08bc3a1dc bold text in /addgamer 2025-11-28 18:11:13 +03:00
vrubelroman
d04a08936c /addgamer выдает страничку игрока 2025-11-23 16:53:12 +03:00
vrubelroman
50c5e93343 версионность не в конфиге 2025-11-23 13:11:58 +03:00
vrubelroman
595c9419f4 проверка на дубликаты и ряд багов 2025-11-23 01:46:12 +03:00
vrubelroman
ab03728d00 bug fix /addtoken 2025-11-21 23:49:26 +03:00
vrubelroman
965b8775b7 add command /profile 2025-11-21 23:16:35 +03:00
vrubelroman
123749415a switch ru/en 2025-11-20 12:43:00 +03:00
vrubelroman
c16a11cf63 очередь запросов и интервал 7 сек 2025-11-20 03:23:38 +03:00
vrubelroman
4dc5539da2 bug today 2025-11-20 03:14:06 +03:00
vrubelroman
ef9aa3d3df fix bug push from timer 2025-11-20 01:22:52 +03:00
vrubelroman
278c5b9c40 add token bug fix 2025-11-19 12:02:54 +03:00
vrubelroman
1f384c12ab add audio notifications 2025-11-18 19:39:52 +03:00
vrubelroman
9cb573db7d fix notifications 2025-11-18 16:28:07 +03:00
vrubelroman
54b263f20c fix push notification 2025-11-18 14:41:13 +03:00
vrubelroman
3619eab74e bug fix notification 2025-11-18 14:03:06 +03:00
vrubelroman
0e66a05b90 delete activ status 2025-11-16 23:36:57 +03:00
vrubelroman
c39bb33282 messages when doing questions 2025-11-16 23:10:08 +03:00
vrubelroman
033a0db12f 3 sec timeout from questions /lastyear_or_1000games 2025-11-16 22:52:45 +03:00
vrubelroman
5a8c705d54 /today /yesterday ... view all stats of gamers 2025-11-16 22:49:56 +03:00
vrubelroman
d23f026b19 add versions 2025-11-16 21:36:48 +03:00
vrubelroman
a7ad36b961 bug fix /addgamer after /start 2025-11-16 21:32:33 +03:00
vrubelroman
3f5f4f14b9 add timers 1 2 3 6 12 24 hours 2025-11-16 21:01:14 +03:00
vrubelroman
13a83b9fbd add cases delgamer 2025-11-16 20:44:02 +03:00
vrubelroman
5c69859868 add /support 2025-11-16 20:23:01 +03:00
vrubelroman
d52e962022 fix /start and lastYear_or_1000games 2025-11-16 20:07:52 +03:00
vrubel
9011b3015b bug fixed text add player 2025-11-16 15:27:08 +03:00
vrubel
1d485fc100 bug fixed /addplayer 2025-11-16 13:38:25 +03:00
vrubel
3e61fa33c4 bug fixed 1000 games 2025-11-16 13:24:39 +03:00
vrubelroman
3226d4c162 add lastYear_or_1000games 2025-11-16 12:48:23 +03:00
vrubelroman
ceb62b408a add statistics 2025-11-13 13:32:46 +03:00
vrubelroman
23de80f94d admin panel 2025-11-13 01:00:48 +03:00
vrubelroman
3362bf89e2 EN language only 2025-11-12 23:20:01 +03:00
vrubelroman
ecd252cdad добавлена проверка на существование добавляемого игрока 2025-11-07 22:54:49 +03:00
vrubelroman
10211937c7 Автоматическая установка периода уведомлений при добавлении игроков
- При добавлении игрока через /addgamer автоматически устанавливается период в 60 минут
- При добавлении нового игрока через /addtoken автоматически устанавливается период в 60 минут
- Работает как при первом добавлении, так и при последующих
2025-10-31 19:12:39 +03:00
vrubel
974b5ea603 после /start /addgamer 2025-10-29 11:32:45 +03:00
vrubel
9e79b97672 поменял ключ 2025-10-29 00:59:36 +03:00