feat: E1002 宽版用量配色改三档绿/黑/红+今日实时与近7天版式重做
- 用量与 pace 配色由「红/黑」二档、黄「注意」档,改为绿(健康)/黑(正常)/红(危险)三档,新增 USAGE_OK/PACE_TOL 阈值,去掉黄色进度条 - Claude/ChatGPT 用量行标签改用 statusline 同款长标签(all 5h/fable 7d 等) - 今日实时区块改为指标名角标+数值与环比同比整组居中;近7天区块改为真实数据表(取30天趋势缓存最后7天),不画折线 - renderer.py 抽出 _cmp_at/_pace_color 钩子+新增 F36 字体供宽版复用;CLAUDE.md 同步版式与配置项说明 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
35
data.py
35
data.py
@@ -218,13 +218,14 @@ def _fmt_reset(resets_at, window):
|
||||
return dt.strftime("%H:%M") if window <= 86400 else dt.strftime("%m/%d %H:%M")
|
||||
|
||||
|
||||
# Claude 用量窗口:(快照键,行标签,窗口长度秒,scoped)。scoped=True 为「按模型限定」的额度
|
||||
# (Fable 7d,来自 /api/oauth/usage 的 limits[],由 statusline 写入快照 seven_day_fable),
|
||||
# 400x300 三色小屏版面放不下第三行,只在 800x480 宽版展示。
|
||||
# Claude 用量窗口:(快照键,短标签,长标签,窗口长度秒,scoped)。
|
||||
# 短标签 k 给 400x300 小屏(标签列只有 26px);长标签 label 给 800x480 宽版,沿用 statusline 的写法
|
||||
# (all 5h / all 7d / fable 7d,小写开头)。scoped=True 为「按模型限定」的额度(Fable 7d,来自
|
||||
# /api/oauth/usage 的 limits[],由 statusline 写入快照 seven_day_fable),小屏放不下第三行,只在宽版展示。
|
||||
USAGE_WINDOWS = (
|
||||
("five_hour", "5h", FIVE_HOUR, False),
|
||||
("seven_day", "7d", SEVEN_DAY, False),
|
||||
("seven_day_fable", "Fable 7d", SEVEN_DAY, True),
|
||||
("five_hour", "5h", "all 5h", FIVE_HOUR, False),
|
||||
("seven_day", "7d", "all 7d", SEVEN_DAY, False),
|
||||
("seven_day_fable", "Fable 7d", "fable 7d", SEVEN_DAY, True),
|
||||
)
|
||||
|
||||
|
||||
@@ -234,8 +235,8 @@ def _usage(now):
|
||||
utilization 来自 statusline 从 Claude Code stdin 落盘的权威实时值(Fable 行来自其转存的 API limits);
|
||||
time_pct(时间已流逝%) 与 pace 每次按当前时间**现算**(resets_at 为绝对时间)。
|
||||
文件缺失/损坏 → 回退占位 pct=None(renderer 显示 "--");快照里没有某窗口(如旧版 statusline 无 Fable)同样 "--"。
|
||||
结构契约(renderer 依赖):{title, warn, caution, updated?, bars:[{k, pct(0~100 或 None), time_pct?, reset?, scoped}]};
|
||||
pct ≥ warn 时该条进度条与百分比转红;pace = pct − time_pct(>0 超前↑ / <0 节余↓);
|
||||
结构契约(renderer 依赖):{title, warn, ok, pace_tol, updated?, bars:[{k, label, pct(0~100 或 None), time_pct?, reset?, scoped}]};
|
||||
pct ≥ warn 时该条进度条与百分比转红(宽版另有 pct ≤ ok 绿档);pace = pct − time_pct(>0 超前↑ / <0 节余↓,宽版按 ±pace_tol 分三色);
|
||||
reset 为重置时刻文本;updated 为快照落盘时刻 HH:MM(活跃使用时持续刷新,空闲时停在最后一次)。
|
||||
"""
|
||||
raw = {}
|
||||
@@ -245,11 +246,11 @@ def _usage(now):
|
||||
print(f"[警告] Claude 用量读取失败:{e}")
|
||||
|
||||
bars = []
|
||||
for key, label, win, scoped in USAGE_WINDOWS:
|
||||
for key, k, label, win, scoped in USAGE_WINDOWS:
|
||||
seg = raw.get(key) or {}
|
||||
util = seg.get("utilization")
|
||||
pct = int(round(float(util))) if util is not None else None
|
||||
bar = {"k": label, "pct": pct, "scoped": scoped}
|
||||
bar = {"k": k, "label": label, "pct": pct, "scoped": scoped}
|
||||
tp = _window_time_pct(seg.get("resets_at"), win, now)
|
||||
if pct is not None and tp is not None:
|
||||
bar["time_pct"] = tp
|
||||
@@ -257,7 +258,7 @@ def _usage(now):
|
||||
if rs:
|
||||
bar["reset"] = rs
|
||||
bars.append(bar)
|
||||
out = {"title": "Claude Usage", "warn": config.USAGE_WARN, "caution": config.USAGE_CAUTION, "bars": bars}
|
||||
out = {"title": "Claude Usage", "warn": config.USAGE_WARN, "ok": config.USAGE_OK, "pace_tol": config.PACE_TOL, "bars": bars}
|
||||
upd = _parse_reset_ts(raw.get("updated_at"))
|
||||
if upd:
|
||||
out["updated"] = datetime.fromtimestamp(upd).strftime("%H:%M")
|
||||
@@ -267,16 +268,16 @@ def _usage(now):
|
||||
def _usage_gpt(now):
|
||||
"""ChatGPT 用量——**目前为 mock 占位**(mock=True,renderer 在标题右侧标「示例数据」)。
|
||||
结构与 _usage 完全一致,后续接入真实数据源时只需替换本函数、保持返回结构不变。
|
||||
mock 取值刻意覆盖多种配色档:5h 42%(黑)、7d 71%(黄「注意」)、Codex 7d 55%(黑,scoped 与左侧 Fable 行对称)。"""
|
||||
mock 取值刻意覆盖宽版三档配色:5h 88%(≥warn 红)、7d 71%(黑)、Codex 7d 22%(≤ok 绿,scoped,与左侧 fable 行对称)。"""
|
||||
bars = []
|
||||
for label, pct, win, remain, scoped in (("5h", 42, FIVE_HOUR, 2 * 3600, False),
|
||||
("7d", 71, SEVEN_DAY, 3 * 86400, False),
|
||||
("Codex 7d", 55, SEVEN_DAY, 3 * 86400, True)):
|
||||
for k, label, pct, win, remain, scoped in (("5h", "all 5h", 88, FIVE_HOUR, 2 * 3600, False),
|
||||
("7d", "all 7d", 71, SEVEN_DAY, 3 * 86400, False),
|
||||
("Codex 7d", "codex 7d", 22, SEVEN_DAY, 3 * 86400, True)):
|
||||
reset_ts = now.timestamp() + remain
|
||||
bars.append({"k": label, "pct": pct, "scoped": scoped,
|
||||
bars.append({"k": k, "label": label, "pct": pct, "scoped": scoped,
|
||||
"time_pct": _window_time_pct(reset_ts, win, now),
|
||||
"reset": _fmt_reset(reset_ts, win)})
|
||||
return {"title": "ChatGPT Usage", "warn": config.USAGE_WARN, "caution": config.USAGE_CAUTION,
|
||||
return {"title": "ChatGPT Usage", "warn": config.USAGE_WARN, "ok": config.USAGE_OK, "pace_tol": config.PACE_TOL,
|
||||
"bars": bars, "mock": True}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user