fix: player tracking subscription flow and /myplayers display
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 4s
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 4s
- 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>
This commit is contained in:
parent
282c651821
commit
293c1d90c8
2 changed files with 131 additions and 106 deletions
|
|
@ -148,6 +148,25 @@ def fetch_fide_player(fide_id: int) -> dict:
|
|||
|
||||
# ═══ Subscription CRUD ═══
|
||||
|
||||
def add_player_watch(user_id: int, player: dict, lang: str):
|
||||
"""Subscribe to a player with no active tournament yet.
|
||||
|
||||
rescan_new_tournaments will auto-upgrade this to a real subscription
|
||||
when a tournament appears.
|
||||
"""
|
||||
conn = _get_conn()
|
||||
conn.execute('''
|
||||
INSERT OR IGNORE INTO subscriptions
|
||||
(user_id, fide_id, player_name, rating, fed, lang, tournament_url,
|
||||
tournament_name, player_sno, last_results_count, last_points,
|
||||
last_round_done, active)
|
||||
VALUES (?, ?, ?, ?, ?, ?, 'fide_only', '', 0, 0, 0.0, 0, 1)
|
||||
''', (user_id, player['fide_id'], player['name'], player.get('rating', 0),
|
||||
player.get('fed', ''), lang))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
|
||||
def add_subscription(user_id: int, player: dict, tournament_url: str,
|
||||
tournament_name: str, player_sno: int,
|
||||
last_results_count: int, last_points: float,
|
||||
|
|
@ -167,16 +186,33 @@ def add_subscription(user_id: int, player: dict, tournament_url: str,
|
|||
|
||||
|
||||
def get_user_subs(user_id: int) -> list:
|
||||
"""Return subscriptions grouped by player (fide_id)."""
|
||||
conn = _get_conn()
|
||||
rows = conn.execute(
|
||||
'SELECT id, player_name, rating, fed, tournament_name, '
|
||||
'last_points, last_round_done, active FROM subscriptions '
|
||||
'WHERE user_id = ? AND active = 1 ORDER BY id',
|
||||
'SELECT fide_id, player_name, rating, fed, tournament_name, '
|
||||
'last_points, last_round_done, tournament_url FROM subscriptions '
|
||||
'WHERE user_id = ? AND active = 1 ORDER BY fide_id, id',
|
||||
(user_id,)).fetchall()
|
||||
conn.close()
|
||||
return [{'id': r[0], 'player_name': r[1], 'rating': r[2], 'fed': r[3],
|
||||
'tournament_name': r[4], 'last_points': r[5],
|
||||
'last_round_done': r[6], 'active': r[7]} for r in rows]
|
||||
|
||||
players: dict = {}
|
||||
for r in rows:
|
||||
fide_id, pname, rating, fed, tname, pts, rd, url = r
|
||||
if fide_id not in players:
|
||||
players[fide_id] = {
|
||||
'fide_id': fide_id, 'player_name': pname,
|
||||
'rating': rating, 'fed': fed or '',
|
||||
'tournaments': [],
|
||||
}
|
||||
if url == 'fide_only':
|
||||
players[fide_id]['tournaments'].append({
|
||||
'name': None, 'points': pts, 'round_done': rd,
|
||||
})
|
||||
else:
|
||||
players[fide_id]['tournaments'].append({
|
||||
'name': tname or url, 'points': pts, 'round_done': rd,
|
||||
})
|
||||
return list(players.values())
|
||||
|
||||
|
||||
def get_active_subs() -> list:
|
||||
|
|
@ -205,6 +241,18 @@ def remove_subscription(sub_id: int, user_id: int) -> bool:
|
|||
return deleted
|
||||
|
||||
|
||||
def remove_player_subscriptions(fide_id: int, user_id: int) -> bool:
|
||||
"""Deactivate all subscriptions for a player (by FIDE ID)."""
|
||||
conn = _get_conn()
|
||||
cur = conn.execute(
|
||||
'UPDATE subscriptions SET active = 0 WHERE fide_id = ? AND user_id = ?',
|
||||
(fide_id, user_id))
|
||||
conn.commit()
|
||||
deleted = cur.rowcount > 0
|
||||
conn.close()
|
||||
return deleted
|
||||
|
||||
|
||||
def update_result(sub_id: int, results_count: int, points: float):
|
||||
conn = _get_conn()
|
||||
conn.execute(
|
||||
|
|
@ -508,6 +556,13 @@ def discover_max_tnr() -> int:
|
|||
saved = get_tnr_state('max_tnr_seen', str(DEFAULT_MAX_TNR))
|
||||
tnr = int(saved)
|
||||
|
||||
# Use max cached TNR as a better starting point (avoids stuck-at-500K problem)
|
||||
conn = _get_conn()
|
||||
row = conn.execute('SELECT MAX(tnr) FROM tnr_cache').fetchone()
|
||||
conn.close()
|
||||
if row and row[0]:
|
||||
tnr = max(tnr, row[0])
|
||||
|
||||
for step in [10000, 1000, 100, 50, 20, 10, 5, 1]:
|
||||
while True:
|
||||
parsed = _fetch_and_parse_art0(tnr + step)
|
||||
|
|
@ -535,14 +590,14 @@ def scan_for_player(fide_id: int, max_tnr: int = None,
|
|||
results = []
|
||||
seen_tnrs = set()
|
||||
|
||||
# Phase 1: check tnr_cache via SQL (single query, instant). Return if found.
|
||||
# Phase 1: check full tnr_cache via SQL (single query, instant). Return if found.
|
||||
conn = _get_conn()
|
||||
pattern = f'%"{fide_id}"%'
|
||||
rows = conn.execute(
|
||||
'SELECT tnr, name, start_date, end_date, players_json FROM tnr_cache '
|
||||
'WHERE tnr >= ? AND tnr <= ? AND players_json LIKE ? '
|
||||
'WHERE players_json LIKE ? '
|
||||
'ORDER BY tnr DESC',
|
||||
(1434000, 1450000, pattern)).fetchall()
|
||||
(pattern,)).fetchall()
|
||||
conn.close()
|
||||
for row in rows:
|
||||
tnr, tname, tstart, tend, players_json = row
|
||||
|
|
@ -769,6 +824,8 @@ async def check_all_subscriptions(context):
|
|||
|
||||
today_str = date.today().isoformat()
|
||||
for sub in subs:
|
||||
if sub['tournament_url'] == 'fide_only':
|
||||
continue
|
||||
try:
|
||||
tournament = fetch_tournament(sub['tournament_url'])
|
||||
except Exception:
|
||||
|
|
@ -846,6 +903,14 @@ async def rescan_new_tournaments(context):
|
|||
add_subscription(
|
||||
user_id, player, t['url'], t['name'], t['sno'],
|
||||
0, 0.0, lang, t['start_date'], t['end_date'])
|
||||
# Deactivate the fide_only watch entry now that we have a real tournament
|
||||
conn = _get_conn()
|
||||
conn.execute(
|
||||
"UPDATE subscriptions SET active = 0 "
|
||||
"WHERE user_id = ? AND fide_id = ? AND tournament_url = 'fide_only'",
|
||||
(user_id, fide_id))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
try:
|
||||
safe_name = _md_escape_tracker(t['player_name'])
|
||||
safe_tour = _md_escape_tracker(t['name'])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue