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
|
|
@ -291,8 +291,7 @@ async def add_player(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
|
|
||||||
async def cancel_sub(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
async def cancel_sub(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
had_fide = context.user_data.pop('awaiting_fide_id', None)
|
had_fide = context.user_data.pop('awaiting_fide_id', None)
|
||||||
had_pending = context.user_data.pop('pending_fide', None)
|
if had_fide:
|
||||||
if had_fide or had_pending:
|
|
||||||
await update.message.reply_text('❎ Подписка отменена\.')
|
await update.message.reply_text('❎ Подписка отменена\.')
|
||||||
else:
|
else:
|
||||||
await update.message.reply_text('Нет активного процесса подписки\.')
|
await update.message.reply_text('Нет активного процесса подписки\.')
|
||||||
|
|
@ -300,20 +299,42 @@ async def cancel_sub(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
|
|
||||||
async def my_players(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
async def my_players(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
user = update.effective_user
|
user = update.effective_user
|
||||||
subs = tracker.get_user_subs(user.id)
|
players = tracker.get_user_subs(user.id)
|
||||||
if not subs:
|
if not players:
|
||||||
await update.message.reply_text('У вас нет активных подписок\.\n'
|
await update.message.reply_text('У вас нет активных подписок\.\n'
|
||||||
'/addplayer — добавить игрока')
|
'/addplayer — добавить игрока',
|
||||||
|
parse_mode=ParseMode.MARKDOWN_V2)
|
||||||
return
|
return
|
||||||
lines = ['*Ваши подписки:*']
|
|
||||||
for s in subs:
|
sep = '━' * 22
|
||||||
safe_name = _md_escape(s['player_name'])
|
lines = [f'*Ваши игроки \\({len(players)}\\):*']
|
||||||
safe_tour = _md_escape(s['tournament_name'] or '—')
|
for p in players:
|
||||||
last_pts_str = _md_escape(f'{s["last_points"]:.1f}')
|
safe_name = _md_escape(p['player_name'])
|
||||||
lines.append(
|
fed = p['fed'] or ''
|
||||||
f' {s["id"]}\\. {safe_name} \({s["rating"]}, {s["fed"]}\) '
|
rating = p['rating'] or '—'
|
||||||
f'— {safe_tour} — {last_pts_str} очк\\.')
|
fide_id = p['fide_id']
|
||||||
lines.append('\n/removeplayer <номер> — удалить подписку')
|
|
||||||
|
lines.append(sep)
|
||||||
|
lines.append(f'👤 *{safe_name}*')
|
||||||
|
lines.append(f'🏳 {_md_escape(fed)} · {rating}')
|
||||||
|
|
||||||
|
tours = p['tournaments']
|
||||||
|
waiting = all(t['name'] is None for t in tours)
|
||||||
|
if waiting:
|
||||||
|
lines.append('⏳ _Ожидаю турнир_')
|
||||||
|
else:
|
||||||
|
for t in tours:
|
||||||
|
if t['name'] is None:
|
||||||
|
continue
|
||||||
|
safe_tour = _md_escape(t['name'])
|
||||||
|
pts = _md_escape(f'{t["points"]:.1f}')
|
||||||
|
rd = t['round_done']
|
||||||
|
lines.append(f'📌 {safe_tour}')
|
||||||
|
lines.append(f' {pts} очк\\., тур {rd}')
|
||||||
|
|
||||||
|
lines.append(f'🗑 /removeplayer {fide_id}')
|
||||||
|
|
||||||
|
lines.append(sep)
|
||||||
await update.message.reply_text('\n'.join(lines),
|
await update.message.reply_text('\n'.join(lines),
|
||||||
parse_mode=ParseMode.MARKDOWN_V2)
|
parse_mode=ParseMode.MARKDOWN_V2)
|
||||||
|
|
||||||
|
|
@ -323,16 +344,18 @@ async def remove_player(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
parts = update.message.text.strip().split()
|
parts = update.message.text.strip().split()
|
||||||
if len(parts) < 2 or not parts[1].isdigit():
|
if len(parts) < 2 or not parts[1].isdigit():
|
||||||
await update.message.reply_text(
|
await update.message.reply_text(
|
||||||
'Использование: `/removeplayer <номер>`\n'
|
'Использование: `/removeplayer FIDE_ID`\n'
|
||||||
'/myplayers — посмотреть список с номерами',
|
'/myplayers — посмотреть список',
|
||||||
parse_mode=ParseMode.MARKDOWN_V2)
|
parse_mode=ParseMode.MARKDOWN_V2)
|
||||||
return
|
return
|
||||||
sub_id = int(parts[1])
|
fide_id = int(parts[1])
|
||||||
ok = tracker.remove_subscription(sub_id, user.id)
|
ok = tracker.remove_player_subscriptions(fide_id, user.id)
|
||||||
if ok:
|
if ok:
|
||||||
await update.message.reply_text('✅ Подписка удалена\.')
|
await update.message.reply_text('✅ Игрок удалён из подписок\.',
|
||||||
|
parse_mode=ParseMode.MARKDOWN_V2)
|
||||||
else:
|
else:
|
||||||
await update.message.reply_text('Подписка не найдена\. /myplayers — список')
|
await update.message.reply_text('Игрок не найден\. /myplayers — список',
|
||||||
|
parse_mode=ParseMode.MARKDOWN_V2)
|
||||||
|
|
||||||
|
|
||||||
def _extract_fide_id(text: str) -> int | None:
|
def _extract_fide_id(text: str) -> int | None:
|
||||||
|
|
@ -362,10 +385,12 @@ async def _lookup_and_confirm(update: Update, context, fide_id: int):
|
||||||
return
|
return
|
||||||
|
|
||||||
safe_name = _md_escape(player['name'])
|
safe_name = _md_escape(player['name'])
|
||||||
title_str = f', {player["title"]}' if player.get('title') else ''
|
title = player.get('title') or ''
|
||||||
|
title_str = f', {_md_escape(title)}' if title and title != 'None' else ''
|
||||||
|
fed = player.get('fed') or ''
|
||||||
await update.message.reply_text(
|
await update.message.reply_text(
|
||||||
f'✅ *{safe_name}*{title_str}\n'
|
f'✅ *{safe_name}*{title_str}\n'
|
||||||
f'{"🇫 " if player["fed"] else ""}{player["fed"]} \\| Рейтинг: {player["rating"]}\n\n'
|
f'{"🇫 " if fed else ""}{_md_escape(fed)} \\| Рейтинг: {player["rating"]}\n\n'
|
||||||
'🔍 Ищу турниры на chess\\-results\\.com\\.\\.',
|
'🔍 Ищу турниры на chess\\-results\\.com\\.\\.',
|
||||||
parse_mode=ParseMode.MARKDOWN_V2)
|
parse_mode=ParseMode.MARKDOWN_V2)
|
||||||
|
|
||||||
|
|
@ -385,7 +410,7 @@ async def _lookup_and_confirm(update: Update, context, fide_id: int):
|
||||||
0, 0.0, lang_code, t['start_date'], t['end_date'])
|
0, 0.0, lang_code, t['start_date'], t['end_date'])
|
||||||
dates = ''
|
dates = ''
|
||||||
if t['start_date'] and t['end_date']:
|
if t['start_date'] and t['end_date']:
|
||||||
dates = f' \({t["start_date"]} — {t["end_date"]}\)'
|
dates = f' \\({_md_escape(t["start_date"])} — {_md_escape(t["end_date"])}\\)'
|
||||||
safe_tour = _md_escape(t['name'])
|
safe_tour = _md_escape(t['name'])
|
||||||
lines.append(f' • {safe_tour}{dates}')
|
lines.append(f' • {safe_tour}{dates}')
|
||||||
lines.append('\nЯ буду присылать результаты и жеребьёвку\.\n'
|
lines.append('\nЯ буду присылать результаты и жеребьёвку\.\n'
|
||||||
|
|
@ -393,16 +418,14 @@ async def _lookup_and_confirm(update: Update, context, fide_id: int):
|
||||||
await update.message.reply_text('\n'.join(lines),
|
await update.message.reply_text('\n'.join(lines),
|
||||||
parse_mode=ParseMode.MARKDOWN_V2)
|
parse_mode=ParseMode.MARKDOWN_V2)
|
||||||
else:
|
else:
|
||||||
# No tournaments found — fallback to manual URL
|
# No active tournament found — watch for future ones
|
||||||
context.user_data['pending_fide'] = {
|
tracker.add_player_watch(user.id, player, lang_code)
|
||||||
'player': player,
|
safe_name = _md_escape(player['name'])
|
||||||
'lang': lang_code,
|
|
||||||
}
|
|
||||||
await update.message.reply_text(
|
await update.message.reply_text(
|
||||||
'❌ Турниров не найдено автоматически\\.\n\n'
|
f'👁 *{safe_name}* поставлен на отслеживание\.\n\n'
|
||||||
'Отправь ссылку на турнир chess\\-results\\.com, '
|
'Активного турнира сейчас не найдено\\. '
|
||||||
'где играет этот игрок\\.\n'
|
'Как только игрок появится в новом турнире — сразу подпишу и пришлю жеребьёвку\\.\n\n'
|
||||||
'/cancel — отмена',
|
'/myplayers \\- список подписок',
|
||||||
parse_mode=ParseMode.MARKDOWN_V2)
|
parse_mode=ParseMode.MARKDOWN_V2)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -479,50 +502,6 @@ def _apply_round_results(tournament, games, rd):
|
||||||
tournament['current_round'] = rd
|
tournament['current_round'] = rd
|
||||||
|
|
||||||
|
|
||||||
async def _subscribe_to_tournament(update: Update, context, url: str, pending: dict):
|
|
||||||
user = update.effective_user
|
|
||||||
player = pending['player']
|
|
||||||
lang_code = pending['lang']
|
|
||||||
|
|
||||||
msg = await update.message.reply_text('⏳ Проверяю турнир\.\.\.',
|
|
||||||
parse_mode=ParseMode.MARKDOWN_V2)
|
|
||||||
|
|
||||||
try:
|
|
||||||
tournament = fetch_tournament(url)
|
|
||||||
except Exception as e:
|
|
||||||
await msg.edit_text(f'❌ Ошибка загрузки турнира: {_md_escape(str(e))}',
|
|
||||||
parse_mode=ParseMode.MARKDOWN_V2)
|
|
||||||
context.user_data['pending_fide'] = pending
|
|
||||||
return
|
|
||||||
|
|
||||||
p = tracker.find_player(tournament, player['name'])
|
|
||||||
if p is None:
|
|
||||||
safe_name = _md_escape(player['name'])
|
|
||||||
await msg.edit_text(
|
|
||||||
f'❌ *{safe_name}* не найден в этом турнире\\.\n'
|
|
||||||
'Отправь другой URL или /cancel',
|
|
||||||
parse_mode=ParseMode.MARKDOWN_V2)
|
|
||||||
context.user_data['pending_fide'] = pending
|
|
||||||
return
|
|
||||||
|
|
||||||
p_sno = p.get('starting_sno', 0)
|
|
||||||
results_count = len(p.get('results', []))
|
|
||||||
points = p.get('points', 0.0)
|
|
||||||
tracker.add_subscription(
|
|
||||||
user.id, player, url,
|
|
||||||
tournament.get('name', ''),
|
|
||||||
p_sno, results_count, points, lang_code)
|
|
||||||
|
|
||||||
safe_name = _md_escape(player['name'])
|
|
||||||
safe_tour = _md_escape(tournament.get('name', ''))
|
|
||||||
await msg.edit_text(
|
|
||||||
f'✅ *{safe_name}* найден в турнире\\.\n'
|
|
||||||
f'📅 *{safe_tour}*\n'
|
|
||||||
f'Ст\\.№ {p_sno}, {_md_escape(f"{points:.1f}")} очк\\. — отслеживаю\!\n\n'
|
|
||||||
'Я буду присылать результаты игрока и жеребьёвку следующих туров\.\n'
|
|
||||||
'/myplayers — список подписок',
|
|
||||||
parse_mode=ParseMode.MARKDOWN_V2)
|
|
||||||
|
|
||||||
|
|
||||||
async def handle_url(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
async def handle_url(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
user = update.effective_user
|
user = update.effective_user
|
||||||
|
|
@ -530,8 +509,6 @@ async def handle_url(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
record_user(user.id, user.username or '', user.first_name or '',
|
record_user(user.id, user.username or '', user.first_name or '',
|
||||||
user.last_name or '')
|
user.last_name or '')
|
||||||
|
|
||||||
# State machine: waiting for FIDE ID → tournament URL → regular pairings
|
|
||||||
|
|
||||||
# Step 1: user just called /addplayer — waiting for FIDE ID
|
# Step 1: user just called /addplayer — waiting for FIDE ID
|
||||||
if context.user_data.pop('awaiting_fide_id', None):
|
if context.user_data.pop('awaiting_fide_id', None):
|
||||||
fide_id = _extract_fide_id(text)
|
fide_id = _extract_fide_id(text)
|
||||||
|
|
@ -546,24 +523,7 @@ async def handle_url(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
await _lookup_and_confirm(update, context, fide_id)
|
await _lookup_and_confirm(update, context, fide_id)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Step 2: player confirmed — waiting for tournament URL
|
# Step 2: regular pairings request
|
||||||
pending = context.user_data.get('pending_fide')
|
|
||||||
if pending:
|
|
||||||
match = URL_PATTERN.search(text)
|
|
||||||
if not match:
|
|
||||||
await update.message.reply_text(
|
|
||||||
'Не нашёл ссылку на chess\\-results\\.com в сообщении\\.\n\n'
|
|
||||||
'Пришли ссылку вида:\n'
|
|
||||||
'`https://chess\\-results\\.com/tnr1393124\\.aspx?lan=11`\n\n'
|
|
||||||
'/cancel — отмена',
|
|
||||||
parse_mode=ParseMode.MARKDOWN_V2)
|
|
||||||
return
|
|
||||||
url = match.group(0)
|
|
||||||
context.user_data.pop('pending_fide', None)
|
|
||||||
await _subscribe_to_tournament(update, context, url, pending)
|
|
||||||
return
|
|
||||||
|
|
||||||
# Step 3: regular pairings request
|
|
||||||
match = URL_PATTERN.search(text)
|
match = URL_PATTERN.search(text)
|
||||||
if not match:
|
if not match:
|
||||||
await update.message.reply_text(
|
await update.message.reply_text(
|
||||||
|
|
@ -718,7 +678,7 @@ def main():
|
||||||
app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_url))
|
app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_url))
|
||||||
|
|
||||||
app.job_queue.run_repeating(
|
app.job_queue.run_repeating(
|
||||||
tracker.check_all_subscriptions, interval=300, first=10)
|
tracker.check_all_subscriptions, interval=60, first=10)
|
||||||
app.job_queue.run_repeating(
|
app.job_queue.run_repeating(
|
||||||
tracker.rescan_new_tournaments, interval=3600, first=60)
|
tracker.rescan_new_tournaments, interval=3600, first=60)
|
||||||
app.job_queue.run_repeating(
|
app.job_queue.run_repeating(
|
||||||
|
|
|
||||||
|
|
@ -148,6 +148,25 @@ def fetch_fide_player(fide_id: int) -> dict:
|
||||||
|
|
||||||
# ═══ Subscription CRUD ═══
|
# ═══ 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,
|
def add_subscription(user_id: int, player: dict, tournament_url: str,
|
||||||
tournament_name: str, player_sno: int,
|
tournament_name: str, player_sno: int,
|
||||||
last_results_count: int, last_points: float,
|
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:
|
def get_user_subs(user_id: int) -> list:
|
||||||
|
"""Return subscriptions grouped by player (fide_id)."""
|
||||||
conn = _get_conn()
|
conn = _get_conn()
|
||||||
rows = conn.execute(
|
rows = conn.execute(
|
||||||
'SELECT id, player_name, rating, fed, tournament_name, '
|
'SELECT fide_id, player_name, rating, fed, tournament_name, '
|
||||||
'last_points, last_round_done, active FROM subscriptions '
|
'last_points, last_round_done, tournament_url FROM subscriptions '
|
||||||
'WHERE user_id = ? AND active = 1 ORDER BY id',
|
'WHERE user_id = ? AND active = 1 ORDER BY fide_id, id',
|
||||||
(user_id,)).fetchall()
|
(user_id,)).fetchall()
|
||||||
conn.close()
|
conn.close()
|
||||||
return [{'id': r[0], 'player_name': r[1], 'rating': r[2], 'fed': r[3],
|
|
||||||
'tournament_name': r[4], 'last_points': r[5],
|
players: dict = {}
|
||||||
'last_round_done': r[6], 'active': r[7]} for r in rows]
|
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:
|
def get_active_subs() -> list:
|
||||||
|
|
@ -205,6 +241,18 @@ def remove_subscription(sub_id: int, user_id: int) -> bool:
|
||||||
return deleted
|
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):
|
def update_result(sub_id: int, results_count: int, points: float):
|
||||||
conn = _get_conn()
|
conn = _get_conn()
|
||||||
conn.execute(
|
conn.execute(
|
||||||
|
|
@ -508,6 +556,13 @@ def discover_max_tnr() -> int:
|
||||||
saved = get_tnr_state('max_tnr_seen', str(DEFAULT_MAX_TNR))
|
saved = get_tnr_state('max_tnr_seen', str(DEFAULT_MAX_TNR))
|
||||||
tnr = int(saved)
|
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]:
|
for step in [10000, 1000, 100, 50, 20, 10, 5, 1]:
|
||||||
while True:
|
while True:
|
||||||
parsed = _fetch_and_parse_art0(tnr + step)
|
parsed = _fetch_and_parse_art0(tnr + step)
|
||||||
|
|
@ -535,14 +590,14 @@ def scan_for_player(fide_id: int, max_tnr: int = None,
|
||||||
results = []
|
results = []
|
||||||
seen_tnrs = set()
|
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()
|
conn = _get_conn()
|
||||||
pattern = f'%"{fide_id}"%'
|
pattern = f'%"{fide_id}"%'
|
||||||
rows = conn.execute(
|
rows = conn.execute(
|
||||||
'SELECT tnr, name, start_date, end_date, players_json FROM tnr_cache '
|
'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',
|
'ORDER BY tnr DESC',
|
||||||
(1434000, 1450000, pattern)).fetchall()
|
(pattern,)).fetchall()
|
||||||
conn.close()
|
conn.close()
|
||||||
for row in rows:
|
for row in rows:
|
||||||
tnr, tname, tstart, tend, players_json = row
|
tnr, tname, tstart, tend, players_json = row
|
||||||
|
|
@ -769,6 +824,8 @@ async def check_all_subscriptions(context):
|
||||||
|
|
||||||
today_str = date.today().isoformat()
|
today_str = date.today().isoformat()
|
||||||
for sub in subs:
|
for sub in subs:
|
||||||
|
if sub['tournament_url'] == 'fide_only':
|
||||||
|
continue
|
||||||
try:
|
try:
|
||||||
tournament = fetch_tournament(sub['tournament_url'])
|
tournament = fetch_tournament(sub['tournament_url'])
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|
@ -846,6 +903,14 @@ async def rescan_new_tournaments(context):
|
||||||
add_subscription(
|
add_subscription(
|
||||||
user_id, player, t['url'], t['name'], t['sno'],
|
user_id, player, t['url'], t['name'], t['sno'],
|
||||||
0, 0.0, lang, t['start_date'], t['end_date'])
|
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:
|
try:
|
||||||
safe_name = _md_escape_tracker(t['player_name'])
|
safe_name = _md_escape_tracker(t['player_name'])
|
||||||
safe_tour = _md_escape_tracker(t['name'])
|
safe_tour = _md_escape_tracker(t['name'])
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue