From 4c2ac3ab5674bd46075641d3ad40f88b8181e75f Mon Sep 17 00:00:00 2001 From: Beast Date: Sun, 14 Jun 2026 13:29:25 +0800 Subject: [PATCH] feat: Chinese news sources, AI summary, todo extraction --- scripts/extract_all_todos.py | 68 ++++++++++++++++++++++++++++++++++++ scripts/fetch_news.py | 10 +++--- scripts/push_todos.py | 17 +++++++++ 3 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 scripts/extract_all_todos.py create mode 100644 scripts/push_todos.py diff --git a/scripts/extract_all_todos.py b/scripts/extract_all_todos.py new file mode 100644 index 0000000..c41fd36 --- /dev/null +++ b/scripts/extract_all_todos.py @@ -0,0 +1,68 @@ +"""Extract ALL todos from ALL existing inspiration digests and push to todo API.""" +import os, re, requests + +DIGEST_DIR = os.path.expanduser("~/inspiration-collector/ai-insights") +TODO_API = "http://127.0.0.1:9001/api/todos" + + +def get_all_digests(): + """Recursively find all digest files.""" + result = [] + for root, dirs, files in os.walk(DIGEST_DIR): + for f in files: + if f.endswith("_digest.md") and not f.endswith(".bak.md"): + result.append(os.path.join(root, f)) + result.sort() + return result + + +def extract_todos(filepath): + with open(filepath) as f: + content = f.read() + todos = [] + in_todo_section = False + for line in content.split("\n"): + # Markdown checkbox: - [ ] something + m = re.match(r"\s*[-*]\s*\[\s*[ ]\s*\]\s*(.+)", line) + if m: + todos.append(m.group(1).strip()) + continue + # Numbered todos under "待办事项" section + m2 = re.match(r"\s*\d+\.\s*\*{0,2}(.+?)\*{0,2}\s*$", line) + if m2 and in_todo_section: + text = m2.group(1).strip() + if text and len(text) > 5: + todos.append(text) + # Track if we're in the todo section + if "待办" in line or "TODO" in line: + in_todo_section = True + elif line.strip() == "" and in_todo_section: + in_todo_section = False + return todos + + +def push_todos(todos): + try: + resp = requests.get(TODO_API, timeout=5) + existing = [t["text"] for t in resp.json().get("todos", [])] + except: + existing = [] + count = 0 + for text in todos: + if text not in existing: + requests.post(TODO_API, json={"text": text, "source": "inspiration"}, timeout=5) + count += 1 + return count + + +if __name__ == "__main__": + digests = get_all_digests() + print(f"Found {len(digests)} digest files") + total = 0 + for fp in digests: + todos = extract_todos(fp) + if todos: + pushed = push_todos(todos) + total += pushed + print(f" {os.path.basename(fp)}: {len(todos)} found, {pushed} new") + print(f"\nTotal: {total} new todos pushed") diff --git a/scripts/fetch_news.py b/scripts/fetch_news.py index e093b99..f25dbbc 100644 --- a/scripts/fetch_news.py +++ b/scripts/fetch_news.py @@ -7,16 +7,18 @@ from datetime import datetime, timezone, timedelta OUTPUT = "/var/www/nav/data/news.json" tz = timezone(timedelta(hours=8)) -# RSS feeds - balanced selection of world news sources +# RSS feeds - balanced selection of world news sources (Chinese weighted) FEEDS = [ {"name": "BBC World", "url": "http://feeds.bbci.co.uk/news/world/rss.xml", "lang": "en"}, + {"name": "\u65b0\u6d6a\u65b0\u95fb", "url": "https://rss.sina.com.cn/news/china.xml", "lang": "zh"}, + {"name": "\u6d8c\u62a5", "url": "https://www.ybai.com/wp-json/wp/v2/posts?per_page=10", "lang": "zh"}, {"name": "BBC \u4e2d\u6587", "url": "https://www.bbc.com/zhongwen/simp/index.xml", "lang": "zh"}, - {"name": "Reuters", "url": "https://www.reutersagency.com/feed/", "lang": "en"}, {"name": "HN", "url": "https://hnrss.org/frontpage?count=10", "lang": "en"}, + {"name": "Reuters", "url": "https://www.reutersagency.com/feed/", "lang": "en"}, ] -MAX_PER_FEED = 8 -MAX_TOTAL = 30 +MAX_PER_FEED = 10 +MAX_TOTAL = 40 def fetch_news(): diff --git a/scripts/push_todos.py b/scripts/push_todos.py new file mode 100644 index 0000000..56d2961 --- /dev/null +++ b/scripts/push_todos.py @@ -0,0 +1,17 @@ +"""Push 4 key todos from the existing library to todo API.""" +import requests + +todos = [ + "为心理黑箱绘制决策流程图,复盘日线震荡却做多的那一单", + "为服务器AI设置即时调用接口,支持命令行快捷提问", + "修复Dashboard的初始金额和策略编号显示错误", + "为倒计时建立仪式感:在Memos创建告别笔记标签", +] + +for text in todos: + r = requests.post("http://127.0.0.1:9001/api/todos", + json={"text": text, "source": "inspiration"}, timeout=5) + print(f" {r.status_code}: {text[:40]}") + +r = requests.get("http://127.0.0.1:9001/api/todos", timeout=5) +print(f"\nTotal todos: {len(r.json()['todos'])}")