check_all_subscriptions: always call update_round even for the final round.
Previously, last_round_done was never updated past the second-to-last round
(because pairings aren't calculated for the last round). This kept
quick_rd > last_round_done forever on finished tournaments, triggering a full
fetch (~22 HTTP requests) every 5 minutes — causing 26k+ daily requests to
chess-results.com against a 2000-request daily limit.
rescan_existing_tournaments: when correcting player_sno, also reset
last_results_count to 0. Stale counts from a wrong player (from the FIDE ID
parsing bug) could be higher than the real player's count, permanently
suppressing result notifications for the correct player.
DB patched directly: last_results_count reset to 0 for subs 40 (Vrubel)
and 47 (Aslanbekov) so they re-learn correct scores on next fetch.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- tracker.py _parse_art0_page: stop at first 6-10 digit number as FIDE ID;
national IDs (also 6-10 digits) no longer overwrite it. FED/rating now
scanned forward past the national ID column.
- parser.py fetch_tournament: fuzzy start-list name matching no longer
overrides starting_sno from standings column 0. Fuzzy match is kept only
for rating lookup. Exact name match still may override SNo (reliable).
- tracker.py rescan_existing_tournaments: after each art=0 re-fetch, update
player_sno in subscriptions whose FIDE ID appears at a different SNo than
stored (corrects drift caused by the old parsing bug).
Root cause: national ID of Gorshkov (SNo=26 in Odintsovo Blitz) matched
Vrubel's FIDE ID in the cache; subscription was created with wrong player_sno=26.
DB already patched directly: Vrubel→sno=39, Aslanbekov→sno=40.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- check_all_subscriptions: quick pre-check (1 req, art=4 only) before
full fetch; full fetch only when results_count or current_round changed.
Interval 60s → 300s. Saves ~10,000 req/day per active subscription.
- rescan_existing_tournaments: filter to tournaments ended within last 30
days (or no end_date). Drops from ~2000 cached TNRs to ~30-100 active
ones per run, saving ~22,000 req/day.
- warmup: sleep 1s per TNR instead of 20ms per 500 — spreads initial
full-scan over hours rather than minutes.
- parser: extract _normalize_url helper, add fetch_tournament_quick().
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- fetch_fide_player: parse rapid and blitz ratings from FIDE profile
- subscriptions: add rapid/blitz columns (auto-migration)
- /myplayers card: show rapid (📍) and blitz (⚡) ratings
- /addplayer confirmation: show rapid/blitz alongside standard rating
- find_player_in_cache: extract instant SQL-only search from scan_for_player
- /addplayer: use find_player_in_cache instead of full HTTP scan — instant response
- tournament names in /myplayers and /addplayer are now hyperlinks
- add_player_watch: ON CONFLICT DO UPDATE to reactivate deleted players
- my_players: try/except per card with plain-text fallback, error logged to stderr
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- scan_for_player: remove hardcoded TNR range (1434k-1450k), search full cache
- discover_max_tnr: start from cache MAX(tnr) instead of stuck-at-500k value
- addplayer: if no tournament found, add fide_only watch instead of asking for URL
- rescan_new_tournaments: deactivate fide_only entry when real tournament found
- /myplayers: card layout grouped by player, removal by FIDE ID
- /removeplayer: now accepts FIDE ID, removes all subscriptions for that player
- fix MarkdownV2 escaping: dates (hyphens), <> in messages, title='None'
- check_all_subscriptions: skip fide_only entries; interval 5min → 1min
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- _build_table_rows: filter to ±5 boards around player
- Normalize names (strip commas) for matching FIDE vs pairings format
- Highlight subscribed player with ✅ emoji
- Reduce name column width to compensate for emoji
- Add tournament name to pairing header
- Manual URL flow: look up subscription to highlight player
- Fix MarkdownV2 escaping for em-dash