🔄 卡若AI 同步 2026-03-06 13:24 | 更新:Cursor规则、水桥平台对接、运营中枢工作台 | 排除 >20MB: 11 个

This commit is contained in:
2026-03-06 13:24:00 +08:00
parent 8d392d7ba5
commit f0d0213d94
7 changed files with 211 additions and 34 deletions

View File

@@ -39,6 +39,12 @@ python3 /Users/karuo/Documents/个人/卡若AI/02_卡人/水桥_平台
- `python3 feishu_token_cli.py set-march-token <token>` → 将 3 月文档 node token 写入本地(`.feishu_month_wiki_tokens.json`),写日志时自动使用
- `python3 feishu_token_cli.py get-march-token` → 输出当前 3 月 wiki token环境变量 > 本地文件)
**Token 自动获取(无 token 时)**:写今日日志(如 `write_today_with_summary.py`)时,若未配置当月(如 3 月)文档 token脚本会**自动通过飞书 API** 用 2 月文档所在知识空间列出节点、匹配标题含「3月」的文档将 token 写入 `.feishu_month_wiki_tokens.json` 后继续写入,无需手动配置。若自动获取失败(如空间内无 3 月文档),再提示用命令行:`python3 feishu_token_cli.py set-march-token <从飞书地址栏复制的 token>`
**Token 出现问题时的处理**若出现「获取文档失败」或「token 无效」,一律用命令行处理:先 `get-access-token` 确保登录有效,再 `set-march-token <正确 token>` 写入当月文档 token写日志脚本会优先使用本地已保存的 token确保能写入飞书。
**今日日志 + 配图**`write_today_with_summary.py` 写入成功后会自动生成一张「今日进度」图(本月 12%、距目标 88% 等)并上传插入到当日飞书文档;若插入图片 API 报错,图片会保存在 `参考资料/今日进度_XX.png`,可手动拖入飞书文档。
**自动完成**
1.**静默Token刷新** → 优先使用 refresh_token 自动刷新(无需授权);也可命令行 `get-access-token`
2.**检查服务** → 自动启动后端服务

View File

@@ -240,6 +240,71 @@ def parse_month_from_date_str(date_str):
return None
MONTH_TOKENS_FILE = os.path.join(os.path.dirname(__file__), ".feishu_month_wiki_tokens.json")
def _try_auto_fetch_march_token(access_token):
"""无 3 月 token 时通过 API 自动获取:用 2 月文档所在 space 列出节点匹配标题含「3月」的节点并写入本地。返回 token 或 None。"""
feb_token = (CONFIG.get("MONTH_WIKI_TOKENS") or {}).get(2) or CONFIG.get("WIKI_TOKEN")
if not feb_token:
return None
headers = {"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"}
try:
r = requests.get(
"https://open.feishu.cn/open-apis/wiki/v2/spaces/get_node",
params={"token": feb_token},
headers=headers,
timeout=15,
)
j = r.json()
if j.get("code") != 0:
return None
data = j.get("data", {})
node = data.get("node", {})
space_id = node.get("space_id") or data.get("space_id")
if not space_id:
return None
# 列出空间下节点(可能需分页)
page_token = None
for _ in range(5):
params = {"page_size": 50}
if page_token:
params["page_token"] = page_token
r2 = requests.get(
f"https://open.feishu.cn/open-apis/wiki/v2/spaces/{space_id}/nodes",
params=params,
headers=headers,
timeout=15,
)
j2 = r2.json()
if j2.get("code") != 0:
break
items = j2.get("data", {}).get("items", [])
for n in items:
title = (n.get("title") or "")
if "3月" in title or "3 月" in title:
tok = n.get("node_token") or n.get("obj_token") or n.get("token")
if tok:
data = {}
if os.path.exists(MONTH_TOKENS_FILE):
try:
with open(MONTH_TOKENS_FILE, encoding="utf-8") as f:
data = json.load(f)
except Exception:
pass
data["3"] = tok
with open(MONTH_TOKENS_FILE, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
print("✅ 已通过 API 自动获取 3 月文档 token 并写入本地")
return tok
page_token = j2.get("data", {}).get("page_token")
if not page_token or not j2.get("data", {}).get("has_more"):
break
except Exception as e:
print(f"⚠️ 自动获取 3 月 token 异常: {e}")
return None
def _get_month_wiki_token(month):
"""当月 wiki token3 月优先 环境变量 > 本地 .feishu_month_wiki_tokens.json > CONFIG"""
if month == 3:
@@ -247,9 +312,8 @@ def _get_month_wiki_token(month):
if v:
return v
try:
path = os.path.join(os.path.dirname(__file__), ".feishu_month_wiki_tokens.json")
if os.path.exists(path):
with open(path, encoding="utf-8") as f:
if os.path.exists(MONTH_TOKENS_FILE):
with open(MONTH_TOKENS_FILE, encoding="utf-8") as f:
v = (json.load(f).get("3") or "").strip()
if v:
return v
@@ -311,16 +375,36 @@ def write_log(token, date_str=None, tasks=None, wiki_token=None, overwrite=False
if not date_str or not tasks:
date_str, tasks = get_today_tasks()
target_wiki_token = resolve_wiki_token_for_date(date_str, wiki_token)
month = parse_month_from_date_str(date_str)
if not target_wiki_token:
month = parse_month_from_date_str(date_str)
print(f" 未配置当月文档 token{month or '?'} 月请设置 FEISHU_MARCH_WIKI_TOKEN 或对应环境变量)")
return False
if month == 3:
print("🔄 未配置 3 月 token,尝试通过 API 自动获取...")
target_wiki_token = _try_auto_fetch_march_token(token)
if not target_wiki_token:
print(f"❌ 未配置当月文档 token{month or '?'} 月请用 feishu_token_cli.py set-march-token <token> 或设置环境变量)")
return False
# 获取文档ID
r = requests.get(f"https://open.feishu.cn/open-apis/wiki/v2/spaces/get_node?token={target_wiki_token}",
# 获取文档ID(若为 3 月且 get_node 失败,可再尝试自动获取后重试一次)
r = requests.get(f"https://open.feishu.cn/open-apis/wiki/v2/spaces/get_node?token={target_wiki_token}",
headers=headers, timeout=30)
if r.json().get('code') != 0 and month == 3:
target_wiki_token = _try_auto_fetch_march_token(token)
if target_wiki_token:
r = requests.get(f"https://open.feishu.cn/open-apis/wiki/v2/spaces/get_node?token={target_wiki_token}",
headers=headers, timeout=30)
if r.json().get('code') != 0:
print(f"❌ 获取文档失败")
# 若本地曾保存过无效 token清除以便下次可重新自动获取或手动 set
try:
if os.path.exists(MONTH_TOKENS_FILE) and month == 3:
with open(MONTH_TOKENS_FILE, encoding="utf-8") as f:
data = json.load(f)
if (data.get("3") or "").strip() == (target_wiki_token or "").strip():
data["3"] = ""
with open(MONTH_TOKENS_FILE, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
except Exception:
pass
print(f"❌ 获取文档失败(当月 token 无效或网络异常,可用 feishu_token_cli.py set-march-token 写入正确 token")
return False
node = r.json()['data']['node']
doc_id = node['obj_token']

View File

@@ -1,8 +1,10 @@
#!/usr/bin/env python3
"""
今日飞书日志:搜索全库+聊天/纪要后的最近进度总结汇总 + 每天切片20个视频 + 成交1980及全链路 + 目标百分比写清楚。
无 3 月 token 时会自动通过 API 获取;写入成功后生成一张今日进度图并上传到飞书文档。
"""
import sys
import requests
from datetime import datetime
from pathlib import Path
@@ -11,6 +13,76 @@ sys.path.insert(0, str(SCRIPT_DIR))
from auto_log import get_token_silent, write_log, open_result, resolve_wiki_token_for_date
REF_DIR = SCRIPT_DIR.parent / "参考资料"
def _generate_progress_image(date_str: str) -> Path | None:
"""生成今日进度图(本月 12% 距目标 88%),返回图片路径;无 Pillow 则返回 None。"""
try:
from PIL import Image, ImageDraw, ImageFont
except ImportError:
return None
out = REF_DIR / f"今日进度_{date_str.replace('', '').replace('', '')}.png"
REF_DIR.mkdir(parents=True, exist_ok=True)
w, h = 480, 160
img = Image.new("RGB", (w, h), color=(255, 252, 240))
draw = ImageDraw.Draw(img)
try:
font = ImageFont.truetype("/System/Library/Fonts/PingFang.ttc", 28)
font_small = ImageFont.truetype("/System/Library/Fonts/PingFang.ttc", 20)
except Exception:
font = ImageFont.load_default()
font_small = font
draw.text((20, 30), f"今日进度 · {date_str}", fill=(60, 60, 60), font=font)
draw.text((20, 75), "本月 12% / 距目标 88%", fill=(180, 80, 60), font=font)
draw.text((20, 115), "20 切片 · 1980 全链路", fill=(80, 80, 80), font=font_small)
img.save(out)
return out
def _get_doc_id(token: str, wiki_token: str) -> str | None:
"""根据 wiki node token 获取文档 obj_token。"""
r = requests.get(
"https://open.feishu.cn/open-apis/wiki/v2/spaces/get_node",
params={"token": wiki_token},
headers={"Authorization": f"Bearer {token}"},
timeout=15,
)
if r.json().get("code") != 0:
return None
return r.json().get("data", {}).get("node", {}).get("obj_token")
def _upload_and_insert_image(token: str, doc_id: str, image_path: Path, date_str: str) -> bool:
"""上传图片到文档并插入到当日标题后。"""
from write_0301_feishu_log import upload_image_to_feishu, insert_image_block
file_token = upload_image_to_feishu(token, doc_id, image_path)
if not file_token:
return False
# 获取文档 blocks找到 date_str 所在位置,在其后插入
r = requests.get(
f"https://open.feishu.cn/open-apis/docx/v1/documents/{doc_id}/blocks",
params={"document_revision_id": -1, "page_size": 500},
headers={"Authorization": f"Bearer {token}"},
timeout=15,
)
if r.json().get("code") != 0:
return False
items = r.json().get("data", {}).get("items", [])
root = [b for b in items if b.get("parent_id") == doc_id]
idx = None
for i, b in enumerate(root):
for key in ("heading4", "text"):
if key in b:
for el in b[key].get("elements", []):
if date_str in el.get("text_run", {}).get("content", ""):
idx = i
break
if idx is not None:
break
insert_at = (idx + 2) if idx is not None else 1
return insert_image_block(token, doc_id, file_token, image_path.name, insert_at)
def build_tasks_today_with_summary():
"""今日:最近进度汇总 + 每天20切片 + 1980成交及全链路 + 目标百分比"""
@@ -69,13 +141,24 @@ def main():
target_wiki_token = resolve_wiki_token_for_date(date_str)
ok = write_log(token, date_str, tasks, target_wiki_token, overwrite=True)
if ok:
target_wiki_token = resolve_wiki_token_for_date(date_str)
doc_id = _get_doc_id(token, target_wiki_token) if target_wiki_token else None
if doc_id:
img_path = _generate_progress_image(date_str)
if img_path and img_path.exists():
if _upload_and_insert_image(token, doc_id, img_path, date_str):
print("✅ 今日进度图已上传并插入飞书文档")
else:
print(f"⚠️ 图片已生成:{img_path},可手动拖入飞书文档")
else:
print("💡 未安装 Pillow 或生成失败,可手动添加配图")
open_result(target_wiki_token)
print(f"{date_str} 飞书日志已更新(含进度汇总与目标百分比)")
sys.exit(0)
print("❌ 写入失败")
ref_path = SCRIPT_DIR.parent / "参考资料" / f"{date_str}_飞书日志正文_三件事与未完成.md"
ref_path = SCRIPT_DIR.parent / "参考资料" / f"{date_str}_飞书日志_进度汇总与百分比.md"
if ref_path.exists():
print(f"💡 可复制 {ref_path} 内容到飞书当月文档手动粘贴")
print(f"💡 可复制 {ref_path} 内容到飞书 3 月文档「{date_str}」下粘贴")
sys.exit(1)