fix: handle PEP 668 env in /update; harden reminders and CSV import; add ptb job-queue extra

This commit is contained in:
Xiaolan Bot
2026-08-24 20:35:48 +08:00
parent 2c9d538f55
commit fcdafcd4b2
2 changed files with 19 additions and 13 deletions
+15 -9
View File
@@ -418,8 +418,8 @@ async def check_and_send_reminders(context: CallbackContext):
message += " 将会自动续费。"
keyboard = None
elif renewal_type == 'manual' and sub['reminder_days'] > 0:
reminder_date = due_date - datetime.timedelta(days=sub['reminder_days'])
elif renewal_type == 'manual' and int(sub['reminder_days'] or 0) > 0:
reminder_date = due_date - datetime.timedelta(days=int(sub['reminder_days']))
if reminder_date == today:
days_left = (due_date - today).days
days_text = f"<b>{days_left}天后</b>" if days_left > 0 else "<b>今天</b>"
@@ -440,7 +440,7 @@ async def check_and_send_reminders(context: CallbackContext):
logger.info(f"Reminder sent for sub_id {sub['id']}")
except Exception as e:
logger.error(f"Failed to process reminder for sub_id {sub.get('id', 'N/A')}: {e}")
logger.error(f"Failed to process reminder for sub_id {sub['id']}: {e}")
# --- 命令处理器 ---
async def start(update: Update, context: CallbackContext):
user_id = update.effective_user.id
@@ -746,7 +746,7 @@ async def import_upload_received(update: Update, context: CallbackContext):
renewal_base = str(row['renewal_base']).lower().strip()
if renewal_base not in valid_renewal_bases:
raise ValueError(f"无效续订起算方式: {renewal_base}")
notes = str(row['notes']).strip() if pd.notna(row['notes']) else None
notes = str(row['notes']).strip() if ('notes' in df.columns and pd.notna(row['notes'])) else None
if notes and len(notes) > MAX_NOTES_LEN:
raise ValueError(f"备注过长(>{MAX_NOTES_LEN}")
name = str(row['name']).strip()
@@ -1804,11 +1804,14 @@ async def update_bot(update: Update, context: CallbackContext):
await update.message.reply_text(f"更新失败(reset):\n<code>{escape_html(err)}</code>", parse_mode='HTML')
return
pip_proc = await asyncio.to_thread(
_run_cmd,
[sys.executable, "-m", "pip", "install", "-r", "requirements.txt"],
repo_dir
)
pip_cmd = [sys.executable, "-m", "pip", "install", "-r", "requirements.txt"]
pip_proc = await asyncio.to_thread(_run_cmd, pip_cmd, repo_dir)
if pip_proc.returncode != 0:
pip_output = (pip_proc.stderr or "") + (pip_proc.stdout or "")
# Debian/Ubuntu 的系统托管 PythonPEP 668)会拒绝直接安装,需加 --break-system-packages
if "externally-managed-environment" in pip_output:
await update.message.reply_text("检测到系统托管的 Python 环境(PEP 668),改用 --break-system-packages 重试…")
pip_proc = await asyncio.to_thread(_run_cmd, pip_cmd + ["--break-system-packages"], repo_dir)
if pip_proc.returncode != 0:
err = (pip_proc.stderr or pip_proc.stdout or "未知错误").strip()
await update.message.reply_text(f"依赖安装失败:\n<code>{escape_html(err[-1800:])}</code>", parse_mode='HTML')
@@ -1870,6 +1873,9 @@ def main():
time=datetime.time(hour=9, minute=0, tzinfo=datetime.timezone(datetime.timedelta(hours=8))),
name='daily_reminders'
)
# 启动后稍作等待补跑一次,避免重启导致当天的提醒被跳过(函数内部按 last_reminded_date 去重)
app.job_queue.run_once(check_and_send_reminders, when=datetime.timedelta(seconds=15),
name='startup_reminder_catchup')
logger.info("Daily reminder job scheduled.")
application.post_init = post_init
+1 -1
View File
@@ -1,4 +1,4 @@
python-telegram-bot>=20.0
python-telegram-bot[job-queue]>=20.0
pandas
matplotlib
python-dateutil