cards: 备份 9 条 Memos 卡片
This commit is contained in:
17
cards/20260612235233_今天发现的几个策略的问题:.md
Normal file
17
cards/20260612235233_今天发现的几个策略的问题:.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
title: "今天发现的几个策略的问题:"
|
||||||
|
date: 2026-06-12T23:52:33+08:00
|
||||||
|
uid: ""
|
||||||
|
source: "memos"
|
||||||
|
---
|
||||||
|
|
||||||
|
今天发现的几个策略的问题:
|
||||||
|
1.要确定一下问什么今天日线判断为震荡,但是仍下了一个做多的单子?出场入场条件是否和之前给出的结论一致?总之分析清楚这一单下单的原因。
|
||||||
|
|
||||||
|
2.dashboard 中还有几处小错误,一是交易界面总额不是 10000,策略编号不对,盈亏应当及时响应。
|
||||||
|
|
||||||
|
3.如果想指挥服务器上的 ai 在日报定时任务之外运行,应该怎么办?
|
||||||
|
|
||||||
|
4.服务器上的 api 调用属于黑箱了,要有监测和审批机制。
|
||||||
|
|
||||||
|
5.这个 api 是哪个模型,flash 还是 pro,在哪里设置?
|
||||||
12
cards/20260613011010_关于服务器端都接入哪些内容:.md
Normal file
12
cards/20260613011010_关于服务器端都接入哪些内容:.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
title: "关于服务器端都接入哪些内容:"
|
||||||
|
date: 2026-06-13T01:10:10+08:00
|
||||||
|
uid: ""
|
||||||
|
source: "memos"
|
||||||
|
---
|
||||||
|
|
||||||
|
关于服务器端都接入哪些内容:
|
||||||
|
目前 memos 已经完全接入
|
||||||
|
还想把 obsidian 也接进来,否则语料库太少
|
||||||
|
|
||||||
|
下一步,还要把交易的一些日报接近来,要全面的用 ai 帮助我进行梳理和提炼。
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
title: "和服务器上的ai对话,不能完全依靠workbuddy去传话,应该自己建立一个问答窗口。"
|
||||||
|
date: 2026-06-13T02:31:13+08:00
|
||||||
|
uid: ""
|
||||||
|
source: "memos"
|
||||||
|
---
|
||||||
|
|
||||||
|
和服务器上的ai对话,不能完全依靠workbuddy去传话,应该自己建立一个问答窗口。
|
||||||
|
|
||||||
|
经过自己的实践,确定:大模型只能问答,想执行文件操作必须依赖智能体。如果想要保持信息的安全,倒是可以部署自己的问答页面,我的确已经做了。
|
||||||
11
cards/20260613033404_不眠之夜,干了好多好多的事.md
Normal file
11
cards/20260613033404_不眠之夜,干了好多好多的事.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
title: "不眠之夜,干了好多好多的事"
|
||||||
|
date: 2026-06-13T03:34:04+08:00
|
||||||
|
uid: ""
|
||||||
|
source: "memos"
|
||||||
|
---
|
||||||
|
|
||||||
|
不眠之夜,干了好多好多的事
|
||||||
|
AI 的时代,真的让人开始进化起来了
|
||||||
|
|
||||||
|
今日心流状态超过 8 个小时
|
||||||
8
cards/20260613183248_今天晚餐去吃了李百蟹蟹黄面,西湖店。.md
Normal file
8
cards/20260613183248_今天晚餐去吃了李百蟹蟹黄面,西湖店。.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
title: "今天晚餐去吃了李百蟹蟹黄面,西湖店。"
|
||||||
|
date: 2026-06-13T18:32:48+08:00
|
||||||
|
uid: ""
|
||||||
|
source: "memos"
|
||||||
|
---
|
||||||
|
|
||||||
|
今天晚餐去吃了李百蟹蟹黄面,西湖店。
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
title: "课堂分析,灵感分析,工作记录,待办跟进。这一类的功能还要继续研究下去。尽快。"
|
||||||
|
date: 2026-06-14T12:26:49+08:00
|
||||||
|
uid: ""
|
||||||
|
source: "memos"
|
||||||
|
---
|
||||||
|
|
||||||
|
课堂分析,灵感分析,工作记录,待办跟进。这一类的功能还要继续研究下去。尽快。
|
||||||
8
cards/20260614123306_更改掉我这个平台中和_Beast_相关的内容。这不是一个好称谓.md
Normal file
8
cards/20260614123306_更改掉我这个平台中和_Beast_相关的内容。这不是一个好称谓.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
title: "更改掉我这个平台中和 Beast 相关的内容。这不是一个好称谓"
|
||||||
|
date: 2026-06-14T12:33:06+08:00
|
||||||
|
uid: ""
|
||||||
|
source: "memos"
|
||||||
|
---
|
||||||
|
|
||||||
|
更改掉我这个平台中和 Beast 相关的内容。这不是一个好称谓
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
title: "上课时使用电脑端memos做课堂记录,ai帮我整理归纳后形成文档后放在个人知识库中。这绝对是一条正确的道路,我继续完善,"
|
||||||
|
date: 2026-06-14T12:55:44+08:00
|
||||||
|
uid: ""
|
||||||
|
source: "memos"
|
||||||
|
---
|
||||||
|
|
||||||
|
上课时使用电脑端memos做课堂记录,ai帮我整理归纳后形成文档后放在个人知识库中。这绝对是一条正确的道路,我继续完善,打造闭环的个人信息流。
|
||||||
|
今天要实现:每日要闻和待办事项两个功能。
|
||||||
|
|
||||||
|
另一个思考是,先做初版,根据初版修改。而不是先空想思路。
|
||||||
|
我今天和智能体对话中,本想先讨论几轮完成思路,没想到他立即着手初版的制作。
|
||||||
|
这是对的,我的生活和工作中也要有这个认知和习惯。先做出来再说。
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
title: "我服务器上的ai对话,目前不支持markdown显示,不支持删除对话,需要修复优化。"
|
||||||
|
date: 2026-06-14T13:07:23+08:00
|
||||||
|
uid: ""
|
||||||
|
source: "memos"
|
||||||
|
---
|
||||||
|
|
||||||
|
我服务器上的ai对话,目前不支持markdown显示,不支持删除对话,需要修复优化。
|
||||||
|
|
||||||
@ -1,21 +1,21 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""
|
"""
|
||||||
sync_cards.py — Memos 卡片备份脚本
|
sync_cards.py — Memos 卡片备份脚本(基于 uid 去重)
|
||||||
|
|
||||||
每30分钟由 cron 触发,将当前用户的所有 Memos 卡片备份到 cards/ 目录,
|
每30分钟由 cron 触发,将当前用户的所有 Memos 卡片备份到 cards/ 目录,
|
||||||
并推送到 Gitea inspiration-collector 仓库。
|
并推送到 Gitea inspiration-collector 仓库。
|
||||||
|
去重方式:按 memo.uid 比对,不重复写入。
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import json
|
|
||||||
import re
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
from datetime import datetime, timezone, timedelta
|
from datetime import datetime, timezone, timedelta
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
# ── 配置 ──────────────────────────────────────────────
|
# ── 配置 ──
|
||||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
CARDS_DIR = os.path.join(BASE_DIR, "cards")
|
CARDS_DIR = os.path.join(BASE_DIR, "cards")
|
||||||
GIT_DIR = BASE_DIR
|
GIT_DIR = BASE_DIR
|
||||||
@ -25,7 +25,8 @@ MEMOS_TOKEN = os.environ.get("MEMOS_ACCESS_TOKEN", "")
|
|||||||
|
|
||||||
TZ_BEIJING = timezone(timedelta(hours=8))
|
TZ_BEIJING = timezone(timedelta(hours=8))
|
||||||
|
|
||||||
# ── Memos API 客户端 ──────────────────────────────────
|
KNOWN_TAGS = {"#功能完善", "#90后四级副职培训班", "#灵感收集器"}
|
||||||
|
|
||||||
|
|
||||||
class MemosClient:
|
class MemosClient:
|
||||||
def __init__(self, base_url, token):
|
def __init__(self, base_url, token):
|
||||||
@ -37,7 +38,6 @@ class MemosClient:
|
|||||||
})
|
})
|
||||||
|
|
||||||
def list_all_memos(self):
|
def list_all_memos(self):
|
||||||
"""Fetch ALL memos via pagination."""
|
|
||||||
all_memos = []
|
all_memos = []
|
||||||
page_token = ""
|
page_token = ""
|
||||||
while True:
|
while True:
|
||||||
@ -46,13 +46,11 @@ class MemosClient:
|
|||||||
params["pageToken"] = page_token
|
params["pageToken"] = page_token
|
||||||
resp = self.session.post(
|
resp = self.session.post(
|
||||||
f"{self.base_url}/memos.api.v1.MemoService/ListMemos",
|
f"{self.base_url}/memos.api.v1.MemoService/ListMemos",
|
||||||
json=params,
|
json=params, timeout=15
|
||||||
timeout=15
|
|
||||||
)
|
)
|
||||||
resp.raise_for_status()
|
resp.raise_for_status()
|
||||||
data = resp.json()
|
data = resp.json()
|
||||||
memos = data.get("memos", [])
|
all_memos.extend(data.get("memos", []))
|
||||||
all_memos.extend(memos)
|
|
||||||
next_token = data.get("nextPageToken", "")
|
next_token = data.get("nextPageToken", "")
|
||||||
if not next_token:
|
if not next_token:
|
||||||
break
|
break
|
||||||
@ -61,33 +59,56 @@ class MemosClient:
|
|||||||
|
|
||||||
|
|
||||||
def sanitize_filename(text):
|
def sanitize_filename(text):
|
||||||
"""清理文件名中的特殊字符"""
|
|
||||||
text = re.sub(r'[<>:"/\\|?*]', "", text)
|
text = re.sub(r'[<>:"/\\|?*]', "", text)
|
||||||
text = re.sub(r'\s+', "_", text.strip())
|
text = re.sub(r'\s+', "_", text.strip())
|
||||||
return text[:80] or "memo"
|
return text[:80] or "memo"
|
||||||
|
|
||||||
|
|
||||||
|
def extract_tags(content):
|
||||||
|
"""提取内容中的 #标签 """
|
||||||
|
return [w for w in content.split() if w.startswith("#") and w in KNOWN_TAGS]
|
||||||
|
|
||||||
|
|
||||||
|
def load_existing_uids(cards_dir):
|
||||||
|
"""扫描现有卡片文件,收集所有 uid + 文件名作为去重依据"""
|
||||||
|
uids = set()
|
||||||
|
fnames = set()
|
||||||
|
if not os.path.isdir(cards_dir):
|
||||||
|
return uids, fnames
|
||||||
|
for fname in os.listdir(cards_dir):
|
||||||
|
if not fname.endswith(".md"):
|
||||||
|
continue
|
||||||
|
fnames.add(fname)
|
||||||
|
fpath = os.path.join(cards_dir, fname)
|
||||||
|
try:
|
||||||
|
with open(fpath, "r", encoding="utf-8") as f:
|
||||||
|
head = f.read(500)
|
||||||
|
# 匹配 uid: "xxx" 或 id: xxx 或 uid: xxx(无引号)
|
||||||
|
m = re.search(r'^(?:uid|id):\s*"?([^"\n]+)"?', head, re.MULTILINE)
|
||||||
|
if m:
|
||||||
|
val = m.group(1).strip()
|
||||||
|
if val:
|
||||||
|
uids.add(val)
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
return uids, fnames
|
||||||
|
|
||||||
|
|
||||||
def memo_to_markdown(memo):
|
def memo_to_markdown(memo):
|
||||||
"""将 Memo API 返回的对象转为 Markdown 文件内容"""
|
|
||||||
uid = memo.get("uid", "")
|
uid = memo.get("uid", "")
|
||||||
content = memo.get("content", "")
|
content = memo.get("content", "")
|
||||||
create_time = memo.get("createTime", "")
|
create_time = memo.get("createTime", "")
|
||||||
|
|
||||||
# 解析时间
|
|
||||||
try:
|
try:
|
||||||
dt = datetime.fromisoformat(create_time.replace("Z", "+00:00"))
|
dt = datetime.fromisoformat(create_time.replace("Z", "+00:00"))
|
||||||
dt_bj = dt.astimezone(TZ_BEIJING)
|
dt_bj = dt.astimezone(TZ_BEIJING)
|
||||||
date_str = dt_bj.strftime("%Y-%m-%d")
|
|
||||||
time_str = dt_bj.strftime("%Y-%m-%dT%H:%M:%S+08:00")
|
time_str = dt_bj.strftime("%Y-%m-%dT%H:%M:%S+08:00")
|
||||||
file_ts = dt_bj.strftime("%Y%m%d%H%M%S")
|
file_ts = dt_bj.strftime("%Y%m%d%H%M%S")
|
||||||
except:
|
except Exception:
|
||||||
date_str = "unknown"
|
|
||||||
time_str = create_time
|
time_str = create_time
|
||||||
file_ts = uid[:14] if uid else "unknown"
|
file_ts = uid[:14] if uid else "unknown"
|
||||||
|
|
||||||
# 提取标题(第一行)
|
|
||||||
first_line = content.strip().split("\n")[0][:60]
|
first_line = content.strip().split("\n")[0][:60]
|
||||||
|
|
||||||
filename = f"{file_ts}_{sanitize_filename(first_line)}.md"
|
filename = f"{file_ts}_{sanitize_filename(first_line)}.md"
|
||||||
filepath = os.path.join(CARDS_DIR, filename)
|
filepath = os.path.join(CARDS_DIR, filename)
|
||||||
|
|
||||||
@ -100,11 +121,10 @@ source: "memos"
|
|||||||
|
|
||||||
{content}
|
{content}
|
||||||
"""
|
"""
|
||||||
return filepath, md, date_str
|
return filepath, md
|
||||||
|
|
||||||
|
|
||||||
def git_push(directory, message):
|
def git_push(directory, message):
|
||||||
"""git add + commit + push"""
|
|
||||||
try:
|
try:
|
||||||
subprocess.run(["git", "add", "-A"], cwd=directory, check=True,
|
subprocess.run(["git", "add", "-A"], cwd=directory, check=True,
|
||||||
capture_output=True, timeout=30)
|
capture_output=True, timeout=30)
|
||||||
@ -113,7 +133,7 @@ def git_push(directory, message):
|
|||||||
cwd=directory, capture_output=True, timeout=15
|
cwd=directory, capture_output=True, timeout=15
|
||||||
)
|
)
|
||||||
if result.returncode == 0:
|
if result.returncode == 0:
|
||||||
return # 无变更
|
return
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
["git", "commit", "-m", message],
|
["git", "commit", "-m", message],
|
||||||
cwd=directory, check=True, capture_output=True, timeout=30
|
cwd=directory, check=True, capture_output=True, timeout=30
|
||||||
@ -134,34 +154,33 @@ def main():
|
|||||||
print("[ERROR] MEMOS_ACCESS_TOKEN 未设置")
|
print("[ERROR] MEMOS_ACCESS_TOKEN 未设置")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
client = MemosClient(MEMOS_URL, MEMOS_TOKEN)
|
|
||||||
|
|
||||||
print(f"[INFO] 正在拉取 Memos...")
|
|
||||||
try:
|
|
||||||
all_memos = client.list_all_memos()
|
|
||||||
except Exception as e:
|
|
||||||
print(f"[ERROR] 拉取 Memos 失败: {e}")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
print(f"[INFO] 共获取 {len(all_memos)} 条卡片")
|
|
||||||
|
|
||||||
os.makedirs(CARDS_DIR, exist_ok=True)
|
os.makedirs(CARDS_DIR, exist_ok=True)
|
||||||
|
|
||||||
existing_files = set(os.listdir(CARDS_DIR))
|
|
||||||
new_count = 0
|
|
||||||
|
|
||||||
|
# 加载已有 uid + 文件名
|
||||||
|
existing_uids, existing_fnames = load_existing_uids(CARDS_DIR)
|
||||||
|
print(f"[INFO] 已有 {len(existing_fnames)} 个文件,{len(existing_uids)} 个 uid")
|
||||||
|
|
||||||
|
client = MemosClient(MEMOS_URL, MEMOS_TOKEN)
|
||||||
|
print(f"[INFO] 正在从 Memos 拉取...")
|
||||||
|
all_memos = client.list_all_memos()
|
||||||
|
print(f"[INFO] 共获取 {len(all_memos)} 条卡片")
|
||||||
|
|
||||||
|
new_count = 0
|
||||||
for memo in all_memos:
|
for memo in all_memos:
|
||||||
filepath, md, date_str = memo_to_markdown(memo)
|
uid = memo.get("uid", "")
|
||||||
filename = os.path.basename(filepath)
|
if uid and uid in existing_uids:
|
||||||
|
continue # uid 已存在,跳过
|
||||||
# 如果文件已存在则跳过
|
filepath, md = memo_to_markdown(memo)
|
||||||
if filename in existing_files:
|
fname = os.path.basename(filepath)
|
||||||
continue
|
if fname in existing_fnames:
|
||||||
|
continue # 文件名已存在,跳过(兼容旧版无 uid 的卡片)
|
||||||
with open(filepath, "w", encoding="utf-8") as f:
|
with open(filepath, "w", encoding="utf-8") as f:
|
||||||
f.write(md)
|
f.write(md)
|
||||||
new_count += 1
|
new_count += 1
|
||||||
print(f" [+] {filename}")
|
print(f" [+] {fname}")
|
||||||
|
if uid:
|
||||||
|
existing_uids.add(uid)
|
||||||
|
existing_fnames.add(fname)
|
||||||
|
|
||||||
if new_count > 0:
|
if new_count > 0:
|
||||||
print(f"[INFO] 新增 {new_count} 条卡片,推送至 Gitea...")
|
print(f"[INFO] 新增 {new_count} 条卡片,推送至 Gitea...")
|
||||||
|
|||||||
Reference in New Issue
Block a user