refactor(ui): unify message formatting to HTML and clean imports

This commit is contained in:
Xiaolan Bot
2026-02-25 16:10:37 +08:00
parent c7ebb00145
commit 0904acad4e

View File

@@ -22,8 +22,6 @@ from telegram.ext import (
CallbackContext, CallbackQueryHandler, ConversationHandler CallbackContext, CallbackQueryHandler, ConversationHandler
) )
from telegram.error import TelegramError from telegram.error import TelegramError
from telegram.helpers import escape_markdown # Fallback just in case
import html
def escape_html(text, version=None): def escape_html(text, version=None):
if text is None: if text is None:
return '' return ''
@@ -427,19 +425,19 @@ async def start(update: Update, context: CallbackContext):
async def help_command(update: Update, context: CallbackContext): async def help_command(update: Update, context: CallbackContext):
help_text = fr""" help_text = f"""
*{escape_html(PROJECT_NAME)} 命令列表* <b>{escape_html(PROJECT_NAME)} 命令列表</b>
*🌟 核心功能* <b>🌟 核心功能</b>
/add\_sub \- 引导您添加一个新的订阅 /add_sub - 引导您添加一个新的订阅
/list\_subs \- 列出您的所有订阅 /list_subs - 列出您的所有订阅
/list\_categories \- 按分类浏览您的订阅 /list_categories - 按分类浏览您的订阅
*📊 数据管理* <b>📊 数据管理</b>
/stats \- 查看按类别分类的订阅统计 /stats - 查看按类别分类的订阅统计
/import \- 通过上传 CSV 文件批量导入订阅 /import - 通过上传 CSV 文件批量导入订阅
/export \- 将您的所有订阅导出为 CSV 文件 /export - 将您的所有订阅导出为 CSV 文件
*⚙️ 个性化设置* <b>⚙️ 个性化设置</b>
/set\_currency \`<code>\` \- 设置您的主要货币 /set_currency &lt;代码&gt; - 设置您的主要货币
/cancel \- 在任何流程中取消当前操作 /cancel - 在任何流程中取消当前操作
""" """
await update.message.reply_text(help_text, parse_mode='HTML') await update.message.reply_text(help_text, parse_mode='HTML')
@@ -836,7 +834,7 @@ async def add_category_received(update: Update, context: CallbackContext):
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("INSERT OR IGNORE INTO categories (user_id, name) VALUES (?, ?)", (user_id, category_name)) cursor.execute("INSERT OR IGNORE INTO categories (user_id, name) VALUES (?, ?)", (user_id, category_name))
conn.commit() conn.commit()
await update.message.reply_text("第五步:请输入 *下一次付款日期*(例如 2025\\-10\\-01 或 10月1日", await update.message.reply_text("第五步:请输入 <b>下一次付款日期</b>(例如 2025-10-01 或 10月1日",
parse_mode='HTML') parse_mode='HTML')
return ADD_NEXT_DUE return ADD_NEXT_DUE
@@ -877,7 +875,7 @@ async def add_freq_unit_received(update: Update, context: CallbackContext):
await query.edit_message_text("错误:无效的周期单位,请重试。") await query.edit_message_text("错误:无效的周期单位,请重试。")
return ConversationHandler.END return ConversationHandler.END
sub_data['unit'] = unit sub_data['unit'] = unit
await query.edit_message_text("第七步:请输入周期的<b>数量</b>例如每3个月输入 3", parse_mode='Markdown') await query.edit_message_text("第七步:请输入周期的<b>数量</b>例如每3个月输入 3", parse_mode='HTML')
return ADD_FREQ_VALUE return ADD_FREQ_VALUE
@@ -1029,14 +1027,14 @@ async def show_subscription_view(update: Update, context: CallbackContext, sub_i
cost_str, converted_cost_str = escape_html(f"{cost:.2f}"), escape_html(f"{converted_cost:.2f}") cost_str, converted_cost_str = escape_html(f"{cost:.2f}"), escape_html(f"{converted_cost:.2f}")
renewal_text = "手动续费" if renewal_type == 'manual' else "自动续费" renewal_text = "手动续费" if renewal_type == 'manual' else "自动续费"
reminder_status = "开启" if reminders_enabled else "关闭" reminder_status = "开启" if reminders_enabled else "关闭"
text = (f"*订阅详情: {safe_name}*\n\n" text = (f"<b>订阅详情: {safe_name}</b>\n\n"
f"\\- *费用*: `{cost_str} {currency.upper()}` \\(\\~`{converted_cost_str} {main_currency.upper()}`\\)\n" f"- <b>费用</b>: <code>{cost_str} {currency.upper()}</code> (~<code>{converted_cost_str} {main_currency.upper()}</code>)\n"
f"\\- *类别*: `{safe_category}`\n" f"- <b>类别</b>: <code>{safe_category}</code>\n"
f"\\- *下次付款*: `{next_due}` \\(周期: {safe_freq}\\)\n" f"- <b>下次付款</b>: <code>{next_due}</code> (周期: {safe_freq})\n"
f"\\- *续费方式*: `{renewal_text}`\n" f"- <b>续费方式</b>: <code>{renewal_text}</code>\n"
f"\\- *提醒状态*: `{reminder_status}`") f"- <b>提醒状态</b>: <code>{reminder_status}</code>")
if notes: if notes:
text += f"\n\\- *备注*: {escape_html(notes)}" text += f"\n- <b>备注</b>: {escape_html(notes)}"
keyboard_buttons = [ keyboard_buttons = [
[InlineKeyboardButton("✏️ 编辑", callback_data=f'edit_{sub_id}'), [InlineKeyboardButton("✏️ 编辑", callback_data=f'edit_{sub_id}'),
InlineKeyboardButton("🗑️ 删除", callback_data=f'delete_{sub_id}')], InlineKeyboardButton("🗑️ 删除", callback_data=f'delete_{sub_id}')],
@@ -1173,7 +1171,7 @@ async def button_callback_handler(update: Update, context: CallbackContext):
await query.answer("续费失败:无法计算新的到期日期。", show_alert=True) await query.answer("续费失败:无法计算新的到期日期。", show_alert=True)
else: else:
await query.answer("续费失败:此订阅可能已被删除或无权限。", show_alert=True) await query.answer("续费失败:此订阅可能已被删除或无权限。", show_alert=True)
await query.edit_message_text(text=query.message.text + "\n\n*(错误:此订阅不存在或无权限)*", await query.edit_message_text(text=query.message.text + "\n\n<b>(错误:此订阅不存在或无权限)</b>",
parse_mode='HTML', reply_markup=None) parse_mode='HTML', reply_markup=None)
elif action == 'delete': elif action == 'delete':
@@ -1481,7 +1479,7 @@ async def _display_reminder_settings(query: CallbackQuery, context: CallbackCont
safe_name = escape_html(sub['name']) safe_name = escape_html(sub['name'])
current_status = f"<b>🔔 提醒设置: {safe_name}</b>\n\n" current_status = f"<b>🔔 提醒设置: {safe_name}</b>\n\n"
if sub['renewal_type'] == 'manual': if sub['renewal_type'] == 'manual':
current_status += f"当前提前提醒: *{sub['reminder_days']}*\n" current_status += f"当前提前提醒: <b>{sub['reminder_days']}</b>\n"
keyboard.append([InlineKeyboardButton("⚙️ 更改提前天数", callback_data='remindaction_ask_days')]) keyboard.append([InlineKeyboardButton("⚙️ 更改提前天数", callback_data='remindaction_ask_days')])
keyboard.append([InlineKeyboardButton("« 返回详情", callback_data=f'view_{sub_id}')]) keyboard.append([InlineKeyboardButton("« 返回详情", callback_data=f'view_{sub_id}')])
await query.edit_message_text(current_status, reply_markup=InlineKeyboardMarkup(keyboard), parse_mode='HTML') await query.edit_message_text(current_status, reply_markup=InlineKeyboardMarkup(keyboard), parse_mode='HTML')