Files
eink-push/push_client.py
YANG JIANKUAN 85b5113ba4 feat: E1002 新增公网图片服务(恒定 URL 现渲染)+底部改为 BTC 时K
- server.py:三条恒定 URL 并行——/e1002.png 内存现渲染 PNG(主力)、
  /e1002.html 现代网页、/e1002-web.png 网页经无头 Chrome 截图后固化六色;
  天气/橘喵/BTC 按 WEATHER_TTL/MAO_TTL/BTC_TTL 走内存缓存,过期才实拉、
  失败沿用旧值;用量不读本机文件,改由 POST /push/usage(_gpt) 推送暂存
- push_client.py:本机把 Claude 用量快照推送到服务(X-Push-Token 鉴权)
- btc_api.py:OKX/Coinbase/Huobi 免费接口逐源兜底,时K 近 72 小时,涨绿跌红
- data.py 拆出 weather_fetch/mao_fetch/btc_fetch 与 usage_from_raw,
  统一按 TZ_NAME 时区;宽版只用点阵字体整数倍字号 12/24/36/48
- probe_server.py:验证平台对同一 URL 是否周期重抓(结论:Image 控件
  不重抓,HTML 控件重抓)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-10 18:55:47 +08:00

56 lines
2.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
推送端(本机运行)—— 把本机的用量原始快照 POST 到 server.py服务端暂存、渲染时现算 pace。
推什么:
- Claude~/.claude/usage-snapshot.json 原文statusline 生产,含 five_hour / seven_day / seven_day_fable / updated_at→ POST /push/usage
- ChatGPT暂无本机数据源将来有了按 data.GPT_WINDOWS 的键five_hour / seven_day / seven_day_codex各含 utilization + resets_at
组一个 dict → POST /push/usage_gpt。目前不推服务端用 mock 并标「示例数据」。
鉴权:请求头 X-Push-Token = PUSH_TOKEN。网络直连不走代理连接类异常重试 2 次。
调度:与喵喵设备推送同节律,由 launchd 每 5 分钟跑一次 `main.py --target push`(或加进 run.sh
"""
import json
import time
import urllib.error
import urllib.request
import config
import usage_local
RETRY_TIMES, RETRY_DELAY, TIMEOUT = 2, 2, 10
def _post_json(url, payload):
body = json.dumps(payload, ensure_ascii=False).encode("utf-8")
req = urllib.request.Request(url, data=body, method="POST", headers={
"Content-Type": "application/json; charset=utf-8",
"X-Push-Token": config.PUSH_TOKEN,
"User-Agent": "eink-push/push_client",
})
last = None
for i in range(RETRY_TIMES + 1):
try:
with urllib.request.urlopen(req, timeout=TIMEOUT) as resp:
return json.loads(resp.read().decode("utf-8"))
except urllib.error.HTTPError as e: # 4xx/5xx 不重试,直接报出服务端的说明
raise RuntimeError(f"HTTP {e.code}: {e.read().decode('utf-8', 'replace')[:200]}") from e
except urllib.error.URLError as e: # 连接类:重试
last = e
if i < RETRY_TIMES:
time.sleep(RETRY_DELAY)
raise RuntimeError(f"连接失败:{last}")
def push_usage():
if not config.PUSH_URL or not config.PUSH_TOKEN:
raise SystemExit("[推送] 需在 .env 配置 PUSH_URL 与 PUSH_TOKEN")
raw = usage_local.get_usage() # 缺文件直接抛错——没有快照就没什么可推
resp = _post_json(config.PUSH_URL.rstrip("/") + "/push/usage", raw)
print(f"[推送] Claude 用量快照已推送到 {config.PUSH_URL}{resp}")
return resp
if __name__ == "__main__":
push_usage()