perf(update): pin default remote URL and offload blocking update/currency ops
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
TELEGRAM_TOKEN=""
|
||||
EXCHANGE_API_KEY=""
|
||||
UPDATE_OWNER_ID=""
|
||||
AUTO_UPDATE_REMOTE="gitllc"
|
||||
AUTO_UPDATE_REMOTE="https://git.llc/zimk/SubMind.git"
|
||||
AUTO_UPDATE_BRANCH="main"
|
||||
|
||||
@@ -56,13 +56,16 @@ cp .env.example .env
|
||||
```env
|
||||
TELEGRAM_TOKEN="<YOUR_TELEGRAM_BOT_TOKEN>"
|
||||
EXCHANGE_API_KEY="<YOUR_EXCHANGE_API_KEY>"
|
||||
UPDATE_OWNER_ID="5355641202"
|
||||
AUTO_UPDATE_REMOTE="https://git.llc/zimk/SubMind.git"
|
||||
AUTO_UPDATE_BRANCH="main"
|
||||
```
|
||||
|
||||
说明:
|
||||
- `TELEGRAM_TOKEN` 必填。
|
||||
- `EXCHANGE_API_KEY` 可选(不填时不做在线汇率转换)。
|
||||
- `UPDATE_OWNER_ID` 可选(建议配置为你的 Telegram 用户 ID,仅该用户可执行 `/update`)。
|
||||
- `AUTO_UPDATE_REMOTE` 可选(默认 `gitllc`)。
|
||||
- `AUTO_UPDATE_REMOTE` 可选(默认 `https://git.llc/zimk/SubMind.git`)。
|
||||
- `AUTO_UPDATE_BRANCH` 可选(默认 `main`)。
|
||||
|
||||
### 4) 运行
|
||||
|
||||
45
SubMind.py
45
SubMind.py
@@ -46,8 +46,8 @@ DB_FILE = 'submind.db'
|
||||
|
||||
# 自动更新配置
|
||||
UPDATE_OWNER_ID = os.getenv('UPDATE_OWNER_ID') # 仅允许此用户执行 /update
|
||||
AUTO_UPDATE_REMOTE = os.getenv('AUTO_UPDATE_REMOTE', '').strip()
|
||||
AUTO_UPDATE_BRANCH = os.getenv('AUTO_UPDATE_BRANCH', 'main')
|
||||
AUTO_UPDATE_REMOTE = os.getenv('AUTO_UPDATE_REMOTE', 'https://git.llc/zimk/SubMind.git').strip()
|
||||
AUTO_UPDATE_BRANCH = os.getenv('AUTO_UPDATE_BRANCH', 'main').strip() or 'main'
|
||||
|
||||
# --- 对话处理器状态 ---
|
||||
(ADD_NAME, ADD_COST, ADD_CURRENCY, ADD_CATEGORY, ADD_NEXT_DUE,
|
||||
@@ -848,7 +848,7 @@ async def add_next_due_received(update: Update, context: CallbackContext):
|
||||
|
||||
parsed_date = parse_date(update.message.text)
|
||||
if not parsed_date:
|
||||
await update.message.reply_text("无法识别的日期格式,请使用类似 '2025\\-10\\-01' 或 '10月1日' 的格式。")
|
||||
await update.message.reply_text("无法识别的日期格式,请使用类似 '2025-10-01' 或 '10月1日' 的格式。")
|
||||
return ADD_NEXT_DUE
|
||||
sub_data['next_due'] = parsed_date
|
||||
keyboard = [
|
||||
@@ -1022,7 +1022,7 @@ async def show_subscription_view(update: Update, context: CallbackContext, sub_i
|
||||
sub['reminders_enabled'], sub['notes'])
|
||||
freq_text = format_frequency(sub['frequency_unit'], sub['frequency_value'])
|
||||
main_currency = get_user_main_currency(user_id)
|
||||
converted_cost = convert_currency(cost, currency, main_currency)
|
||||
converted_cost = await asyncio.to_thread(convert_currency, cost, currency, main_currency)
|
||||
safe_name, safe_category, safe_freq = escape_html(name), escape_html(category), escape_html(freq_text)
|
||||
cost_str, converted_cost_str = escape_html(f"{cost:.2f}"), escape_html(f"{converted_cost:.2f}")
|
||||
renewal_text = "手动续费" if renewal_type == 'manual' else "自动续费"
|
||||
@@ -1400,7 +1400,7 @@ async def edit_new_value_received(update: Update, context: CallbackContext):
|
||||
parsed = parse_date(str(new_value))
|
||||
if not parsed:
|
||||
if message_to_reply:
|
||||
await message_to_reply.reply_text("无法识别的日期格式,请使用类似 '2025\\-10\\-01' 或 '10月1日' 的格式。")
|
||||
await message_to_reply.reply_text("无法识别的日期格式,请使用类似 '2025-10-01' 或 '10月1日' 的格式。")
|
||||
validation_failed = True
|
||||
else:
|
||||
new_value = parsed
|
||||
@@ -1666,6 +1666,10 @@ def _resolve_update_target(repo_dir: str):
|
||||
return remotes[0], branch
|
||||
|
||||
|
||||
def _run_cmd(cmd, cwd):
|
||||
return subprocess.run(cmd, cwd=cwd, capture_output=True, text=True)
|
||||
|
||||
|
||||
async def update_bot(update: Update, context: CallbackContext):
|
||||
user_id = update.effective_user.id
|
||||
if not _can_run_update(user_id):
|
||||
@@ -1683,43 +1687,40 @@ async def update_bot(update: Update, context: CallbackContext):
|
||||
return
|
||||
|
||||
fetch_cmd = ["git", "fetch", remote_name, branch_name]
|
||||
fetch_proc = subprocess.run(fetch_cmd, cwd=repo_dir, capture_output=True, text=True)
|
||||
fetch_proc = await asyncio.to_thread(_run_cmd, fetch_cmd, repo_dir)
|
||||
if fetch_proc.returncode != 0:
|
||||
err = (fetch_proc.stderr or fetch_proc.stdout or "未知错误").strip()
|
||||
await update.message.reply_text(f"更新失败(fetch):\n<code>{escape_html(err)}</code>", parse_mode='HTML')
|
||||
return
|
||||
|
||||
local_rev = subprocess.run(
|
||||
["git", "rev-parse", "HEAD"], cwd=repo_dir, capture_output=True, text=True
|
||||
)
|
||||
remote_rev = subprocess.run(
|
||||
["git", "rev-parse", f"{remote_name}/{branch_name}"],
|
||||
cwd=repo_dir, capture_output=True, text=True
|
||||
)
|
||||
local_rev = await asyncio.to_thread(_run_cmd, ["git", "rev-parse", "HEAD"], repo_dir)
|
||||
fetched_rev = await asyncio.to_thread(_run_cmd, ["git", "rev-parse", "FETCH_HEAD"], repo_dir)
|
||||
|
||||
if local_rev.returncode != 0 or remote_rev.returncode != 0:
|
||||
if local_rev.returncode != 0 or fetched_rev.returncode != 0:
|
||||
await update.message.reply_text("更新失败:无法读取当前版本。")
|
||||
return
|
||||
|
||||
local_hash = local_rev.stdout.strip()
|
||||
remote_hash = remote_rev.stdout.strip()
|
||||
fetched_hash = fetched_rev.stdout.strip()
|
||||
|
||||
if local_hash == remote_hash:
|
||||
if local_hash == fetched_hash:
|
||||
await update.message.reply_text("当前已是最新版本,无需更新。")
|
||||
return
|
||||
|
||||
reset_proc = subprocess.run(
|
||||
["git", "reset", "--hard", f"{remote_name}/{branch_name}"],
|
||||
cwd=repo_dir, capture_output=True, text=True
|
||||
reset_proc = await asyncio.to_thread(
|
||||
_run_cmd,
|
||||
["git", "reset", "--hard", "FETCH_HEAD"],
|
||||
repo_dir
|
||||
)
|
||||
if reset_proc.returncode != 0:
|
||||
err = (reset_proc.stderr or reset_proc.stdout or "未知错误").strip()
|
||||
await update.message.reply_text(f"更新失败(reset):\n<code>{escape_html(err)}</code>", parse_mode='HTML')
|
||||
return
|
||||
|
||||
pip_proc = subprocess.run(
|
||||
pip_proc = await asyncio.to_thread(
|
||||
_run_cmd,
|
||||
[sys.executable, "-m", "pip", "install", "-r", "requirements.txt"],
|
||||
cwd=repo_dir, capture_output=True, text=True
|
||||
repo_dir
|
||||
)
|
||||
if pip_proc.returncode != 0:
|
||||
err = (pip_proc.stderr or pip_proc.stdout or "未知错误").strip()
|
||||
@@ -1727,7 +1728,7 @@ async def update_bot(update: Update, context: CallbackContext):
|
||||
return
|
||||
|
||||
await update.message.reply_text(
|
||||
f"更新完成({escape_html(remote_name)}/{escape_html(branch_name)}),正在重启机器人…",
|
||||
f"更新完成({escape_html(remote_name)} {escape_html(branch_name)}),正在重启机器人…",
|
||||
parse_mode='HTML'
|
||||
)
|
||||
os.execv(sys.executable, [sys.executable] + sys.argv)
|
||||
|
||||
Reference in New Issue
Block a user