vibego 0.2.31__py3-none-any.whl → 0.2.32__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- master.py +40 -2
- {vibego-0.2.31.dist-info → vibego-0.2.32.dist-info}/METADATA +1 -1
- {vibego-0.2.31.dist-info → vibego-0.2.32.dist-info}/RECORD +7 -7
- vibego_cli/__init__.py +1 -1
- {vibego-0.2.31.dist-info → vibego-0.2.32.dist-info}/WHEEL +0 -0
- {vibego-0.2.31.dist-info → vibego-0.2.32.dist-info}/entry_points.txt +0 -0
- {vibego-0.2.31.dist-info → vibego-0.2.32.dist-info}/top_level.txt +0 -0
master.py
CHANGED
|
@@ -21,6 +21,7 @@ import stat
|
|
|
21
21
|
import textwrap
|
|
22
22
|
import re
|
|
23
23
|
import threading
|
|
24
|
+
import unicodedata
|
|
24
25
|
from datetime import datetime, timezone
|
|
25
26
|
from zoneinfo import ZoneInfo
|
|
26
27
|
from dataclasses import dataclass, field
|
|
@@ -128,6 +129,43 @@ SWITCHABLE_MODELS: Tuple[Tuple[str, str], ...] = (
|
|
|
128
129
|
("claudecode", "⚙️ ClaudeCode"),
|
|
129
130
|
)
|
|
130
131
|
|
|
132
|
+
# Telegram 在不同客户端可能插入零宽字符或额外空白,提前归一化按钮文本。
|
|
133
|
+
ZERO_WIDTH_CHARACTERS: Tuple[str, ...] = ("\u200b", "\u200c", "\u200d", "\ufeff")
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def _normalize_button_text(text: str) -> str:
|
|
137
|
+
"""归一化项目按钮文本,剔除零宽字符并统一大小写。"""
|
|
138
|
+
|
|
139
|
+
filtered = "".join(ch for ch in text if ch not in ZERO_WIDTH_CHARACTERS)
|
|
140
|
+
compacted = re.sub(r"\s+", " ", filtered).strip()
|
|
141
|
+
return unicodedata.normalize("NFKC", compacted).casefold()
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
MASTER_MENU_BUTTON_CANONICAL_NORMALIZED = _normalize_button_text(MASTER_MENU_BUTTON_TEXT)
|
|
145
|
+
MASTER_MENU_BUTTON_ALLOWED_NORMALIZED = {
|
|
146
|
+
_normalize_button_text(value) for value in MASTER_MENU_BUTTON_ALLOWED_TEXTS
|
|
147
|
+
}
|
|
148
|
+
MASTER_MENU_BUTTON_KEYWORDS: Tuple[str, ...] = ("项目列表", "project", "projects")
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def _is_projects_menu_trigger(text: Optional[str]) -> bool:
|
|
152
|
+
"""判断消息文本是否可触发项目列表展示。"""
|
|
153
|
+
|
|
154
|
+
if not text:
|
|
155
|
+
return False
|
|
156
|
+
normalized = _normalize_button_text(text)
|
|
157
|
+
if not normalized:
|
|
158
|
+
return False
|
|
159
|
+
if normalized in MASTER_MENU_BUTTON_ALLOWED_NORMALIZED:
|
|
160
|
+
return True
|
|
161
|
+
return any(keyword in normalized for keyword in MASTER_MENU_BUTTON_KEYWORDS)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def _text_equals_master_button(text: str) -> bool:
|
|
165
|
+
"""判断文本是否等同于当前主按钮文案(允许空白差异)。"""
|
|
166
|
+
|
|
167
|
+
return _normalize_button_text(text) == MASTER_MENU_BUTTON_CANONICAL_NORMALIZED
|
|
168
|
+
|
|
131
169
|
|
|
132
170
|
def _build_master_main_keyboard() -> ReplyKeyboardMarkup:
|
|
133
171
|
"""构造 Master Bot 主键盘,提供项目列表与管理入口。"""
|
|
@@ -2535,7 +2573,7 @@ async def on_project_wizard_skip(callback: CallbackQuery) -> None:
|
|
|
2535
2573
|
)
|
|
2536
2574
|
|
|
2537
2575
|
|
|
2538
|
-
@router.message(F.text.
|
|
2576
|
+
@router.message(F.text.func(_is_projects_menu_trigger))
|
|
2539
2577
|
async def on_master_projects_button(message: Message) -> None:
|
|
2540
2578
|
"""处理常驻键盘触发的项目概览请求。"""
|
|
2541
2579
|
_log_update(message)
|
|
@@ -2545,7 +2583,7 @@ async def on_master_projects_button(message: Message) -> None:
|
|
|
2545
2583
|
return
|
|
2546
2584
|
requested_text = message.text or ""
|
|
2547
2585
|
reply_to_message_id: Optional[int] = message.message_id
|
|
2548
|
-
if requested_text
|
|
2586
|
+
if not _text_equals_master_button(requested_text):
|
|
2549
2587
|
log.info(
|
|
2550
2588
|
"收到旧版项目列表按钮,准备刷新聊天键盘",
|
|
2551
2589
|
extra={"text": requested_text, "chat_id": message.chat.id},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
bot.py,sha256=uJcmMJmj5SlpwUXSgtnIEeNiUGkBg-lG5g6kM9BobP4,272046
|
|
2
2
|
logging_setup.py,sha256=gvxHi8mUwK3IhXJrsGNTDo-DR6ngkyav1X-tvlBF_IE,4613
|
|
3
|
-
master.py,sha256=
|
|
3
|
+
master.py,sha256=ZW4A3Gh0MUKFnfZX-VJ7OCNnBzlEcOWkPKYH92OfyKA,112967
|
|
4
4
|
project_repository.py,sha256=UcthtSGOJK0cTE5bQCneo3xkomRG-kyc1N1QVqxeHIs,17577
|
|
5
5
|
scripts/__init__.py,sha256=LVrXUkvWKoc6Sb47X5G0gbIxu5aJ2ARW-qJ14vwi5vM,65
|
|
6
6
|
scripts/bump_version.sh,sha256=a4uB8V8Y5LPsoqTCdzQKsEE8HhwpBmqRaQInG52LDig,4089
|
|
@@ -426,14 +426,14 @@ tasks/constants.py,sha256=tS1kZxBIUm3JJUMHm25XI-KHNUZl5NhbbuzjzL_rF-c,299
|
|
|
426
426
|
tasks/fsm.py,sha256=rKXXLEieQQU4r2z_CZUvn1_70FXiZXBBugF40gpe_tQ,1476
|
|
427
427
|
tasks/models.py,sha256=N_qqRBo9xMSV0vbn4k6bLBXT8C_dp_oTFUxvdx16ZQM,2459
|
|
428
428
|
tasks/service.py,sha256=w_S_aWiVqRXzXEpimLDsuCCCX2lB5uDkff9aKThBw9c,41916
|
|
429
|
-
vibego_cli/__init__.py,sha256=
|
|
429
|
+
vibego_cli/__init__.py,sha256=yIxuD2p_Dd2qwaOZwbuf-21aP6wKVdMFcPi5wJfYlos,311
|
|
430
430
|
vibego_cli/__main__.py,sha256=qqTrYmRRLe4361fMzbI3-CqpZ7AhTofIHmfp4ykrrBY,158
|
|
431
431
|
vibego_cli/config.py,sha256=VxkPJMq01tA3h3cOkH-z_tiP7pMgfSGGicRvUnCWkhI,3054
|
|
432
432
|
vibego_cli/deps.py,sha256=1nRXI7Dd-S1hYE8DligzK5fIluQWETRUj4_OKL0DikQ,1419
|
|
433
433
|
vibego_cli/main.py,sha256=X__NXwZnIDIFbdKSTbNyZgZHKcPlN0DQz9sqTI1aQ9E,12158
|
|
434
434
|
vibego_cli/data/worker_requirements.txt,sha256=QSt30DSSSHtfucTFPpc7twk9kLS5rVLNTcvDiagxrZg,62
|
|
435
|
-
vibego-0.2.
|
|
436
|
-
vibego-0.2.
|
|
437
|
-
vibego-0.2.
|
|
438
|
-
vibego-0.2.
|
|
439
|
-
vibego-0.2.
|
|
435
|
+
vibego-0.2.32.dist-info/METADATA,sha256=Dm8z912xz2fEhlZLca0kzY-tsZEzWqinWmsEB2ycaGQ,10475
|
|
436
|
+
vibego-0.2.32.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
437
|
+
vibego-0.2.32.dist-info/entry_points.txt,sha256=Lsy_zm-dlyxt8-9DL9blBReIwU2k22c8-kifr46ND1M,48
|
|
438
|
+
vibego-0.2.32.dist-info/top_level.txt,sha256=R56CT3nW5H5v3ce0l3QDN4-C4qxTrNWzRTwrxnkDX4U,69
|
|
439
|
+
vibego-0.2.32.dist-info/RECORD,,
|
vibego_cli/__init__.py
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|