getnotes-cli 0.1.0__tar.gz → 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {getnotes_cli-0.1.0 → getnotes_cli-0.1.1}/CHANGELOG.md +7 -0
- getnotes_cli-0.1.0/README.md → getnotes_cli-0.1.1/PKG-INFO +36 -0
- getnotes_cli-0.1.0/PKG-INFO → getnotes_cli-0.1.1/README.md +19 -15
- {getnotes_cli-0.1.0 → getnotes_cli-0.1.1}/pyproject.toml +4 -2
- {getnotes_cli-0.1.0 → getnotes_cli-0.1.1}/src/getnotes_cli/cli.py +54 -0
- {getnotes_cli-0.1.0 → getnotes_cli-0.1.1}/src/getnotes_cli/config.py +6 -0
- getnotes_cli-0.1.1/src/getnotes_cli/creator.py +178 -0
- {getnotes_cli-0.1.0 → getnotes_cli-0.1.1}/.agent/workflows/release.md +0 -0
- {getnotes_cli-0.1.0 → getnotes_cli-0.1.1}/.github/workflows/publish.yml +0 -0
- {getnotes_cli-0.1.0 → getnotes_cli-0.1.1}/.gitignore +0 -0
- {getnotes_cli-0.1.0 → getnotes_cli-0.1.1}/LICENSE +0 -0
- {getnotes_cli-0.1.0 → getnotes_cli-0.1.1}/src/getnotes_cli/__init__.py +0 -0
- {getnotes_cli-0.1.0 → getnotes_cli-0.1.1}/src/getnotes_cli/auth.py +0 -0
- {getnotes_cli-0.1.0 → getnotes_cli-0.1.1}/src/getnotes_cli/cache.py +0 -0
- {getnotes_cli-0.1.0 → getnotes_cli-0.1.1}/src/getnotes_cli/cdp.py +0 -0
- {getnotes_cli-0.1.0 → getnotes_cli-0.1.1}/src/getnotes_cli/downloader.py +0 -0
- {getnotes_cli-0.1.0 → getnotes_cli-0.1.1}/src/getnotes_cli/markdown.py +0 -0
- {getnotes_cli-0.1.0 → getnotes_cli-0.1.1}/src/getnotes_cli/notebook.py +0 -0
- {getnotes_cli-0.1.0 → getnotes_cli-0.1.1}/src/getnotes_cli/notebook_downloader.py +0 -0
- {getnotes_cli-0.1.0 → getnotes_cli-0.1.1}/src/getnotes_cli/settings.py +0 -0
|
@@ -5,6 +5,13 @@
|
|
|
5
5
|
此文件的格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),
|
|
6
6
|
并且本项目遵循 [语义化版本规范 (Semantic Versioning)](https://semver.org/spec/v2.0.0.html)。
|
|
7
7
|
|
|
8
|
+
## [0.1.1] - 2026-02-27
|
|
9
|
+
|
|
10
|
+
### 新增 (Added)
|
|
11
|
+
- **创建笔记功能**:实现创建新笔记功能,支持图片上传并自动转换链接。提供 CLI 命令集成支持本地直接新建笔记。
|
|
12
|
+
- **文档完善**:新增了有关知识库 (notebooks)、笔记 (notes) 以及 Agent 工作流 (AGENT.md) 的使用说明;添加了 GitHub 评论操作文档指南。
|
|
13
|
+
- **发布配置更新**:优化与新增部分 GitHub Workflow 以支持自动化部署与评论。
|
|
14
|
+
|
|
8
15
|
## [0.1.0] - 2026-02-27
|
|
9
16
|
|
|
10
17
|
这是 `getnotes-cli` 的首次发布版本,包含以下核心功能集锦:
|
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: getnotes-cli
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Get 笔记 CLI 下载工具 — 自动登录、批量下载、Markdown 导出
|
|
5
|
+
Author: Han Zhang
|
|
6
|
+
License: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Keywords: cli,download,getnotes,markdown,得到笔记
|
|
9
|
+
Requires-Python: >=3.10
|
|
10
|
+
Requires-Dist: httpx>=0.27.0
|
|
11
|
+
Requires-Dist: requests-toolbelt>=1.0.0
|
|
12
|
+
Requires-Dist: requests>=2.0.0
|
|
13
|
+
Requires-Dist: rich>=13.0.0
|
|
14
|
+
Requires-Dist: typer>=0.9.0
|
|
15
|
+
Requires-Dist: websocket-client>=1.6.0
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
1
18
|
# getnotes-cli 🗂️
|
|
2
19
|
|
|
3
20
|
> Get笔记 CLI 下载工具 — 自动登录、批量下载、知识库管理、Markdown 导出、录音图片等附件下载
|
|
@@ -9,6 +26,7 @@
|
|
|
9
26
|
|
|
10
27
|
- 🔐 **自动登录** — 通过 Chrome DevTools Protocol 自动获取 Bearer token,无需手动抓包
|
|
11
28
|
- 📥 **批量下载** — 分页拉取全部笔记,支持指定数量
|
|
29
|
+
- 📤 **新建笔记** — 支持通过本地 Markdown 或文本文件创建笔记,并支持自动上传内嵌图片
|
|
12
30
|
- 📚 **知识库管理** — 查看、下载我的知识库与订阅知识库
|
|
13
31
|
- 📝 **Markdown 导出** — 每条笔记保存为 Markdown,包含元信息、标签、正文、引用内容
|
|
14
32
|
- 🔊 **附件下载** — 自动下载音频、图片附件,并在 Markdown 中内嵌链接
|
|
@@ -40,6 +58,19 @@ getnotes login
|
|
|
40
58
|
getnotes login --token "Bearer eyJhbGci..."
|
|
41
59
|
```
|
|
42
60
|
|
|
61
|
+
### 新建笔记
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# 从本地 Markdown 或文本文件创建得到笔记
|
|
65
|
+
getnotes create --file my_note.md
|
|
66
|
+
|
|
67
|
+
# 创建笔记并附带一张图片(图片将自动上传并追加到正文末尾)
|
|
68
|
+
getnotes create -f my_note.md --image cover.jpg
|
|
69
|
+
|
|
70
|
+
# 创建笔记并附带多张图片(多次指定 -i 或 --image 选项)
|
|
71
|
+
getnotes create -f my_note.md -i img1.png -i img2.jpg
|
|
72
|
+
```
|
|
73
|
+
|
|
43
74
|
### 下载笔记
|
|
44
75
|
|
|
45
76
|
```bash
|
|
@@ -162,6 +193,7 @@ getnotes --version
|
|
|
162
193
|
|
|
163
194
|
# 查看帮助
|
|
164
195
|
getnotes --help
|
|
196
|
+
getnotes create --help
|
|
165
197
|
getnotes download --help
|
|
166
198
|
getnotes notebook --help
|
|
167
199
|
getnotes subscribe --help
|
|
@@ -225,3 +257,7 @@ getnotes_export/
|
|
|
225
257
|
- 已下载的附件不会重复下载(自动跳过)
|
|
226
258
|
- 默认下载前 100 条用于调试,确认无误后使用 `--all` 下载全部
|
|
227
259
|
- 知识库下载按知识库名称创建子目录,统一保存在 `notebooks/` 下
|
|
260
|
+
|
|
261
|
+
## 🙏 致谢
|
|
262
|
+
|
|
263
|
+
- 部分登录逻辑及设计参考自 [notebooklm-mcp-cli](https://github.com/jacob-bd/notebooklm-mcp-cli)。
|
|
@@ -1,18 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: getnotes-cli
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Summary: 得到笔记 (GetNotes) CLI 下载工具 — 自动登录、批量下载、Markdown 导出
|
|
5
|
-
Author: Han Zhang
|
|
6
|
-
License: MIT
|
|
7
|
-
License-File: LICENSE
|
|
8
|
-
Keywords: cli,download,getnotes,markdown,得到笔记
|
|
9
|
-
Requires-Python: >=3.10
|
|
10
|
-
Requires-Dist: httpx>=0.27.0
|
|
11
|
-
Requires-Dist: rich>=13.0.0
|
|
12
|
-
Requires-Dist: typer>=0.9.0
|
|
13
|
-
Requires-Dist: websocket-client>=1.6.0
|
|
14
|
-
Description-Content-Type: text/markdown
|
|
15
|
-
|
|
16
1
|
# getnotes-cli 🗂️
|
|
17
2
|
|
|
18
3
|
> Get笔记 CLI 下载工具 — 自动登录、批量下载、知识库管理、Markdown 导出、录音图片等附件下载
|
|
@@ -24,6 +9,7 @@ Description-Content-Type: text/markdown
|
|
|
24
9
|
|
|
25
10
|
- 🔐 **自动登录** — 通过 Chrome DevTools Protocol 自动获取 Bearer token,无需手动抓包
|
|
26
11
|
- 📥 **批量下载** — 分页拉取全部笔记,支持指定数量
|
|
12
|
+
- 📤 **新建笔记** — 支持通过本地 Markdown 或文本文件创建笔记,并支持自动上传内嵌图片
|
|
27
13
|
- 📚 **知识库管理** — 查看、下载我的知识库与订阅知识库
|
|
28
14
|
- 📝 **Markdown 导出** — 每条笔记保存为 Markdown,包含元信息、标签、正文、引用内容
|
|
29
15
|
- 🔊 **附件下载** — 自动下载音频、图片附件,并在 Markdown 中内嵌链接
|
|
@@ -55,6 +41,19 @@ getnotes login
|
|
|
55
41
|
getnotes login --token "Bearer eyJhbGci..."
|
|
56
42
|
```
|
|
57
43
|
|
|
44
|
+
### 新建笔记
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# 从本地 Markdown 或文本文件创建得到笔记
|
|
48
|
+
getnotes create --file my_note.md
|
|
49
|
+
|
|
50
|
+
# 创建笔记并附带一张图片(图片将自动上传并追加到正文末尾)
|
|
51
|
+
getnotes create -f my_note.md --image cover.jpg
|
|
52
|
+
|
|
53
|
+
# 创建笔记并附带多张图片(多次指定 -i 或 --image 选项)
|
|
54
|
+
getnotes create -f my_note.md -i img1.png -i img2.jpg
|
|
55
|
+
```
|
|
56
|
+
|
|
58
57
|
### 下载笔记
|
|
59
58
|
|
|
60
59
|
```bash
|
|
@@ -177,6 +176,7 @@ getnotes --version
|
|
|
177
176
|
|
|
178
177
|
# 查看帮助
|
|
179
178
|
getnotes --help
|
|
179
|
+
getnotes create --help
|
|
180
180
|
getnotes download --help
|
|
181
181
|
getnotes notebook --help
|
|
182
182
|
getnotes subscribe --help
|
|
@@ -240,3 +240,7 @@ getnotes_export/
|
|
|
240
240
|
- 已下载的附件不会重复下载(自动跳过)
|
|
241
241
|
- 默认下载前 100 条用于调试,确认无误后使用 `--all` 下载全部
|
|
242
242
|
- 知识库下载按知识库名称创建子目录,统一保存在 `notebooks/` 下
|
|
243
|
+
|
|
244
|
+
## 🙏 致谢
|
|
245
|
+
|
|
246
|
+
- 部分登录逻辑及设计参考自 [notebooklm-mcp-cli](https://github.com/jacob-bd/notebooklm-mcp-cli)。
|
|
@@ -4,8 +4,8 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "getnotes-cli"
|
|
7
|
-
version = "0.1.
|
|
8
|
-
description = "
|
|
7
|
+
version = "0.1.1"
|
|
8
|
+
description = "Get 笔记 CLI 下载工具 — 自动登录、批量下载、Markdown 导出"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "MIT"}
|
|
11
11
|
requires-python = ">=3.10"
|
|
@@ -19,6 +19,8 @@ dependencies = [
|
|
|
19
19
|
"rich>=13.0.0",
|
|
20
20
|
"httpx>=0.27.0",
|
|
21
21
|
"websocket-client>=1.6.0",
|
|
22
|
+
"requests-toolbelt>=1.0.0",
|
|
23
|
+
"requests>=2.0.0",
|
|
22
24
|
]
|
|
23
25
|
|
|
24
26
|
[project.scripts]
|
|
@@ -58,6 +58,60 @@ def login(
|
|
|
58
58
|
raise typer.Exit(1)
|
|
59
59
|
|
|
60
60
|
|
|
61
|
+
# ========================================================================
|
|
62
|
+
# create 命令
|
|
63
|
+
# ========================================================================
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@app.command()
|
|
67
|
+
def create(
|
|
68
|
+
file: Path = typer.Option(
|
|
69
|
+
..., "--file", "-f",
|
|
70
|
+
exists=True, dir_okay=False, readable=True, resolve_path=True,
|
|
71
|
+
help="要创建为得到笔记的 Markdown 文件或文本文件",
|
|
72
|
+
),
|
|
73
|
+
images: Optional[list[Path]] = typer.Option(
|
|
74
|
+
None, "--image", "-i",
|
|
75
|
+
exists=True, dir_okay=False, readable=True, resolve_path=True,
|
|
76
|
+
help="要上传并插入的图片文件(可多次指定),将追加到文本末尾",
|
|
77
|
+
),
|
|
78
|
+
token: Optional[str] = typer.Option(
|
|
79
|
+
None, "--token", "-t",
|
|
80
|
+
help="直接传入 Bearer token(跳过缓存检查)",
|
|
81
|
+
),
|
|
82
|
+
) -> None:
|
|
83
|
+
"""📝 创建笔记 — 从本地文件与图片发布得到笔记"""
|
|
84
|
+
from getnotes_cli.auth import get_or_refresh_token, login_with_token
|
|
85
|
+
from getnotes_cli.creator import NoteCreator
|
|
86
|
+
|
|
87
|
+
# 获取 token
|
|
88
|
+
if token:
|
|
89
|
+
auth = login_with_token(token)
|
|
90
|
+
else:
|
|
91
|
+
try:
|
|
92
|
+
auth = get_or_refresh_token()
|
|
93
|
+
except RuntimeError as e:
|
|
94
|
+
console.print(f"\n[red]✗[/red] {e}")
|
|
95
|
+
console.print("[dim]请先运行 `getnotes login` 登录。[/dim]")
|
|
96
|
+
raise typer.Exit(1)
|
|
97
|
+
|
|
98
|
+
text = file.read_text(encoding="utf-8")
|
|
99
|
+
creator = NoteCreator(auth)
|
|
100
|
+
|
|
101
|
+
console.print(f"[bold]📝 正在创建笔记: {file.name}[/bold]")
|
|
102
|
+
if images:
|
|
103
|
+
console.print(f"[dim]包含 {len(images)} 张图片待上传...[/dim]")
|
|
104
|
+
|
|
105
|
+
try:
|
|
106
|
+
data = creator.create_note(text, images)
|
|
107
|
+
console.print(f"\n[green]✓[/green] 创建笔记成功!")
|
|
108
|
+
console.print(f" ID: {data.get('note_id', '')}")
|
|
109
|
+
console.print(f" 时间: {data.get('created_at', '')}")
|
|
110
|
+
except Exception as e:
|
|
111
|
+
console.print(f"\n[red]✗[/red] 创建失败: {e}")
|
|
112
|
+
raise typer.Exit(1)
|
|
113
|
+
|
|
114
|
+
|
|
61
115
|
# ========================================================================
|
|
62
116
|
# download 命令
|
|
63
117
|
# ========================================================================
|
|
@@ -12,6 +12,12 @@ NOTES_API_URL = "https://get-notes.luojilab.com/voicenotes/web/notes"
|
|
|
12
12
|
# 知识库列表 API
|
|
13
13
|
NOTEBOOKS_API_URL = "https://knowledge-api.trytalks.com/v1/web/topic/mine/list"
|
|
14
14
|
|
|
15
|
+
# 创建笔记 API
|
|
16
|
+
NOTE_CREATE_API_URL = "https://get-notes.luojilab.com/voicenotes/web/notes"
|
|
17
|
+
|
|
18
|
+
# 获取图片上传 Token API
|
|
19
|
+
IMAGE_TOKEN_API_URL = "https://get-notes.luojilab.com/voicenotes/web/token/image"
|
|
20
|
+
|
|
15
21
|
# 订阅知识库列表 API
|
|
16
22
|
SUBSCRIBE_NOTEBOOKS_API_URL = "https://knowledge-api.trytalks.com/v1/web/subscribe/topic/list"
|
|
17
23
|
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"""笔记创建模块 — 处理图片上传与笔记发布"""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
import requests
|
|
8
|
+
from requests_toolbelt.multipart.encoder import MultipartEncoder
|
|
9
|
+
|
|
10
|
+
from getnotes_cli.auth import AuthToken
|
|
11
|
+
from getnotes_cli.config import IMAGE_TOKEN_API_URL, NOTE_CREATE_API_URL
|
|
12
|
+
|
|
13
|
+
class NoteCreator:
|
|
14
|
+
"""笔记创建器,处理图片上传和笔记创建"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, token: AuthToken):
|
|
17
|
+
self.token = token
|
|
18
|
+
self.headers = token.get_headers()
|
|
19
|
+
|
|
20
|
+
def _get_image_token(self, ext: str) -> dict[str, Any]:
|
|
21
|
+
"""获取阿里云 OSS 上传凭证"""
|
|
22
|
+
payload = {"source": "web", "type": ext.lstrip(".")}
|
|
23
|
+
resp = requests.post(
|
|
24
|
+
IMAGE_TOKEN_API_URL,
|
|
25
|
+
headers=self.headers,
|
|
26
|
+
json=payload,
|
|
27
|
+
timeout=10,
|
|
28
|
+
)
|
|
29
|
+
resp.raise_for_status()
|
|
30
|
+
data = resp.json()
|
|
31
|
+
if data.get("h", {}).get("c") != 0:
|
|
32
|
+
raise RuntimeError(f"获取上传凭证失败: {data}")
|
|
33
|
+
# 返回第一条凭证
|
|
34
|
+
return data.get("c", [])[0]
|
|
35
|
+
|
|
36
|
+
def upload_image(self, image_path: Path) -> dict[str, Any]:
|
|
37
|
+
"""上传图片到阿里云 OSS,返回图片信息(包含 access_url)"""
|
|
38
|
+
if not image_path.exists():
|
|
39
|
+
raise FileNotFoundError(f"图片不存在: {image_path}")
|
|
40
|
+
|
|
41
|
+
ext = image_path.suffix.lower()
|
|
42
|
+
if ext not in (".png", ".jpg", ".jpeg", ".gif", ".webp"):
|
|
43
|
+
raise ValueError(f"不支持的图片格式: {ext}")
|
|
44
|
+
|
|
45
|
+
# 1. 获取上传凭证
|
|
46
|
+
token_info = self._get_image_token(ext)
|
|
47
|
+
|
|
48
|
+
# 2. 组装表单数据
|
|
49
|
+
# 阿里云 OSS 要求表单字段顺序:前面的参数,最后是 file
|
|
50
|
+
fields = {
|
|
51
|
+
"OSSAccessKeyId": token_info["accessid"],
|
|
52
|
+
"policy": token_info["policy"],
|
|
53
|
+
"Signature": token_info["signature"],
|
|
54
|
+
"key": token_info["object_key"],
|
|
55
|
+
"callback": token_info["callback"],
|
|
56
|
+
"success_action_status": "201",
|
|
57
|
+
"file": (image_path.name, open(image_path, "rb"), token_info.get("oss_content_type", f"image/{ext.lstrip('.')}")),
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
encoder = MultipartEncoder(fields=fields)
|
|
61
|
+
upload_headers = {
|
|
62
|
+
"Accept": "application/json, text/plain, */*",
|
|
63
|
+
"Content-Type": encoder.content_type,
|
|
64
|
+
"User-Agent": self.headers.get("User-Agent", ""),
|
|
65
|
+
"Origin": self.headers.get("Origin", ""),
|
|
66
|
+
"Referer": self.headers.get("Referer", ""),
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
# 3. 上传到 OSS
|
|
70
|
+
resp = requests.post(
|
|
71
|
+
token_info["host"],
|
|
72
|
+
headers=upload_headers,
|
|
73
|
+
data=encoder,
|
|
74
|
+
timeout=30,
|
|
75
|
+
)
|
|
76
|
+
resp.raise_for_status()
|
|
77
|
+
|
|
78
|
+
# 得到笔记的 callback 返回的是 json
|
|
79
|
+
try:
|
|
80
|
+
callback_data = resp.json()
|
|
81
|
+
if callback_data.get("h", {}).get("c") != 0:
|
|
82
|
+
raise RuntimeError(f"图片上传回调失败: {callback_data}")
|
|
83
|
+
except json.JSONDecodeError:
|
|
84
|
+
pass # 有时不会返回标准 json
|
|
85
|
+
|
|
86
|
+
return token_info
|
|
87
|
+
|
|
88
|
+
def _build_json_content(self, text: str, images: list[dict[str, Any]]) -> str:
|
|
89
|
+
"""根据文本和图片构建 ProseMirror json_content"""
|
|
90
|
+
content_nodes = []
|
|
91
|
+
|
|
92
|
+
# 文本段落
|
|
93
|
+
if text:
|
|
94
|
+
for paragraph in text.split("\\n"):
|
|
95
|
+
content_nodes.append({
|
|
96
|
+
"type": "paragraph",
|
|
97
|
+
"attrs": {"lineHeight": "100%", "textAlign": None, "class": "", "indent": 0},
|
|
98
|
+
"content": [{"type": "text", "text": paragraph}] if paragraph else []
|
|
99
|
+
})
|
|
100
|
+
else:
|
|
101
|
+
content_nodes.append({
|
|
102
|
+
"type": "paragraph",
|
|
103
|
+
"attrs": {"lineHeight": "100%", "textAlign": None, "class": "", "indent": 0},
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
# 图片节点
|
|
107
|
+
for img in images:
|
|
108
|
+
content_nodes.append({
|
|
109
|
+
"type": "image",
|
|
110
|
+
"attrs": {
|
|
111
|
+
"commentIds": None,
|
|
112
|
+
"class": "",
|
|
113
|
+
"src": img["access_url"],
|
|
114
|
+
"alt": "",
|
|
115
|
+
"title": "",
|
|
116
|
+
"width": 350,
|
|
117
|
+
"height": "auto",
|
|
118
|
+
"align": "left",
|
|
119
|
+
"href": None,
|
|
120
|
+
"target": None,
|
|
121
|
+
"data-src": None,
|
|
122
|
+
"loading": None
|
|
123
|
+
}
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
# 图片后跟一个空段落
|
|
127
|
+
content_nodes.append({
|
|
128
|
+
"type": "paragraph",
|
|
129
|
+
"attrs": {"lineHeight": "100%", "textAlign": None, "class": None, "indent": 0}
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
json_content = {
|
|
133
|
+
"type": "doc",
|
|
134
|
+
"content": content_nodes
|
|
135
|
+
}
|
|
136
|
+
return json.dumps(json_content, ensure_ascii=False)
|
|
137
|
+
|
|
138
|
+
def create_note(self, text: str, image_paths: list[Path] = None) -> dict[str, Any]:
|
|
139
|
+
"""创建笔记"""
|
|
140
|
+
image_paths = image_paths or []
|
|
141
|
+
uploaded_images = []
|
|
142
|
+
|
|
143
|
+
# 1. 上传所有图片
|
|
144
|
+
for img_path in image_paths:
|
|
145
|
+
img_info = self.upload_image(img_path)
|
|
146
|
+
uploaded_images.append(img_info)
|
|
147
|
+
|
|
148
|
+
# 2. 组装纯文本 content(末尾添加图片 markdown 语法)
|
|
149
|
+
content = text
|
|
150
|
+
if uploaded_images:
|
|
151
|
+
content += "\\n\\n" + "\\n".join([f"" for img in uploaded_images])
|
|
152
|
+
|
|
153
|
+
# 3. 组装 json_content
|
|
154
|
+
json_content_str = self._build_json_content(text, uploaded_images)
|
|
155
|
+
|
|
156
|
+
# 4. 发送创建请求
|
|
157
|
+
payload = {
|
|
158
|
+
"title": "",
|
|
159
|
+
"content": content,
|
|
160
|
+
"json_content": json_content_str,
|
|
161
|
+
"entry_type": "manual",
|
|
162
|
+
"note_type": "plain_text",
|
|
163
|
+
"source": "web",
|
|
164
|
+
"tags": []
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
resp = requests.post(
|
|
168
|
+
NOTE_CREATE_API_URL,
|
|
169
|
+
headers=self.headers,
|
|
170
|
+
json=payload,
|
|
171
|
+
timeout=10,
|
|
172
|
+
)
|
|
173
|
+
resp.raise_for_status()
|
|
174
|
+
data = resp.json()
|
|
175
|
+
if data.get("h", {}).get("c") != 0:
|
|
176
|
+
raise RuntimeError(f"创建笔记失败: {data}")
|
|
177
|
+
|
|
178
|
+
return data.get("c", {})
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|