Add HeXi bot codebase: custom plugins, web frontends, tests
- hexi core: message handling, rate limiting, cooldown, plugin manager - Custom plugins: BF stats, daily check-in, quotes, persona cards, etc. - Community plugins vendored under hexi/plugins with local fixes - Web admin frontends (learning-chat, persona-admin), unified hexi/web - Tests for rate_limit/cooldown/memes/persona; poetry.lock Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
import unicodedata
|
||||
|
||||
|
||||
def parse_seconds(s: str) -> int | None:
|
||||
"""解析 '30' 或 '3*60' 形式的时长秒数,非法输入返回 None"""
|
||||
s = s.strip()
|
||||
if not s or not all(c.isdigit() or c == "*" for c in s):
|
||||
return None
|
||||
try:
|
||||
result = 1
|
||||
for part in s.split("*"):
|
||||
result *= int(part)
|
||||
return result
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
|
||||
def strip_prefix(text: str, prefixes) -> str:
|
||||
"""依次移除前缀后去空白"""
|
||||
for p in prefixes:
|
||||
text = text.removeprefix(p)
|
||||
return text.strip()
|
||||
|
||||
|
||||
def is_number(s) -> bool:
|
||||
"""判断字符串是否可视为数字"""
|
||||
try:
|
||||
float(s)
|
||||
return True
|
||||
except ValueError:
|
||||
pass
|
||||
try:
|
||||
unicodedata.numeric(s)
|
||||
return True
|
||||
except (TypeError, ValueError):
|
||||
pass
|
||||
return False
|
||||
Reference in New Issue
Block a user