fix: 7 bugs — parse_mode, /removeplayer, SNo>300, fd leak, warmup sleep, warmup range, dupe print
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 6s
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 6s
- cancel_sub: add parse_mode=MARKDOWN_V2 so users don't see literal backslashes
- /removeplayer: add CommandHandler that was advertised in /start but missing from handlers
- parse_standings: raise SNo limit 300→5000 to support large open tournaments
- call_bbp_with_checklist: close mkstemp fd to fix resource leak
- _warmup_cache_sync: make time.sleep(1.0) conditional on HTTP fetch, skip for cache hits
- _warmup_cache_sync: derive start_tnr from max(max_tnr_seen, max cached tnr) instead of hardcoded 1445000
- main: remove duplicate print('Client bot started') after blocking run_polling()
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
77c8a87e16
commit
dd0dd5643d
4 changed files with 36 additions and 15 deletions
|
|
@ -321,9 +321,9 @@ async def add_player(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)
|
||||
if had_fide:
|
||||
await update.message.reply_text('❎ Подписка отменена\.')
|
||||
await update.message.reply_text('❎ Подписка отменена\.', parse_mode=ParseMode.MARKDOWN_V2)
|
||||
else:
|
||||
await update.message.reply_text('Нет активного процесса подписки\.')
|
||||
await update.message.reply_text('Нет активного процесса подписки\.', parse_mode=ParseMode.MARKDOWN_V2)
|
||||
|
||||
|
||||
def _player_card(p: dict, loc: dict) -> tuple[str, InlineKeyboardMarkup]:
|
||||
|
|
@ -424,6 +424,16 @@ def _extract_fide_id(text: str) -> int | None:
|
|||
return None
|
||||
|
||||
|
||||
async def remove_player(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
loc = _get_locale((update.effective_user.language_code or ''))
|
||||
await update.message.reply_text(
|
||||
loc['no_players'] if not tracker.get_user_subs(update.effective_user.id)
|
||||
else ('Нажми 🗑 *Удалить* рядом с нужным игроком:\n/myplayers'
|
||||
if (update.effective_user.language_code or '').startswith('ru')
|
||||
else 'Tap 🗑 *Remove* next to the player:\n/myplayers'),
|
||||
parse_mode=ParseMode.MARKDOWN_V2)
|
||||
|
||||
|
||||
async def _lookup_and_confirm(update: Update, context, fide_id: int):
|
||||
user = update.effective_user
|
||||
lang_code = user.language_code or ''
|
||||
|
|
@ -730,6 +740,7 @@ def main():
|
|||
app.add_handler(CommandHandler('addplayer', add_player))
|
||||
app.add_handler(CommandHandler('cancel', cancel_sub))
|
||||
app.add_handler(CommandHandler('myplayers', my_players))
|
||||
app.add_handler(CommandHandler('removeplayer', remove_player))
|
||||
app.add_handler(CallbackQueryHandler(remove_player_callback, pattern=r'^remove:\d+$'))
|
||||
app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_url))
|
||||
|
||||
|
|
@ -742,8 +753,6 @@ def main():
|
|||
app.job_queue.run_repeating(
|
||||
tracker.warmup_cache, interval=21600, first=10)
|
||||
|
||||
print('Client bot started', file=sys.stderr)
|
||||
|
||||
print('Client bot started', file=sys.stderr)
|
||||
app.run_polling()
|
||||
|
||||
|
|
|
|||
|
|
@ -753,17 +753,28 @@ async def warmup_cache(context):
|
|||
|
||||
|
||||
def _warmup_cache_sync():
|
||||
"""Scan the 1.4M cluster at step 1, caching ALL valid TNRs with players.
|
||||
One-time cost ~40 min, then all searches are instant SQL queries.
|
||||
"""Scan ~12 000 TNRs from current max downwards, caching valid ones.
|
||||
Starts from max(max_tnr_seen, max cached tnr, 1445000) so it stays current.
|
||||
Saves progress to tnr_state so it resumes after restart."""
|
||||
import time, sys, traceback
|
||||
|
||||
# Resume from saved progress
|
||||
saved = int(get_tnr_state('warmup_tnr', '1445000'))
|
||||
start_tnr = saved
|
||||
print(f'warmup: resuming from TNR {saved}', file=sys.stderr)
|
||||
# Resume from saved progress, or start from current max_tnr if fresh run.
|
||||
# Default fallback kept so warmup doesn't probe 0 on a brand-new install.
|
||||
saved_raw = get_tnr_state('warmup_tnr', '')
|
||||
if saved_raw and saved_raw != 'done':
|
||||
start_tnr = int(saved_raw)
|
||||
else:
|
||||
conn = _get_conn()
|
||||
row = conn.execute('SELECT MAX(tnr) FROM tnr_cache').fetchone()
|
||||
conn.close()
|
||||
max_cached = row[0] if row and row[0] else 0
|
||||
saved_state = int(get_tnr_state('max_tnr_seen', '1445000'))
|
||||
start_tnr = max(max_cached, saved_state, 1445000)
|
||||
end_tnr = max(1, start_tnr - 12000)
|
||||
print(f'warmup: resuming from TNR {start_tnr} down to {end_tnr}', file=sys.stderr)
|
||||
|
||||
for tnr in range(start_tnr, 1433999, -1):
|
||||
for tnr in range(start_tnr, end_tnr, -1):
|
||||
already_cached = _get_cached_tnr(tnr) is not None
|
||||
try:
|
||||
_fetch_and_parse_art0(tnr)
|
||||
except Exception as e:
|
||||
|
|
@ -776,8 +787,8 @@ def _warmup_cache_sync():
|
|||
set_tnr_state('warmup_tnr', str(tnr))
|
||||
if tnr % 500 == 0:
|
||||
print(f'warmup: progress TNR {tnr} (started at {start_tnr})', file=sys.stderr)
|
||||
# Rate-limit: ~1 req/sec to stay within chess-results.com daily limit.
|
||||
# Cached TNRs return instantly (no HTTP), so this only applies to misses.
|
||||
# Rate-limit: only for HTTP fetches; cached hits return instantly.
|
||||
if not already_cached:
|
||||
time.sleep(1.0)
|
||||
|
||||
# Mark warmup as complete — next run will see this and skip
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@ def call_bbp_with_checklist(
|
|||
|
||||
# Also create temp file for checklist
|
||||
checklist_fd, checklist_path = tempfile.mkstemp(suffix='.txt')
|
||||
os.close(checklist_fd)
|
||||
|
||||
try:
|
||||
result = subprocess.run(
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ def parse_standings(html: str) -> List[Dict]:
|
|||
continue
|
||||
|
||||
sno = int(texts[0])
|
||||
if sno < 1 or sno > 300:
|
||||
if sno < 1 or sno > 5000:
|
||||
continue
|
||||
|
||||
# Find name: look for player name (Latin or Cyrillic)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue