supernote 0.3.0__tar.gz → 0.4.0__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.
- supernote-0.4.0/PKG-INFO +205 -0
- supernote-0.4.0/README.md +175 -0
- {supernote-0.3.0 → supernote-0.4.0}/pyproject.toml +21 -7
- supernote-0.4.0/supernote/__init__.py +26 -0
- supernote-0.3.0/supernote/cmds/cloud_login_tool.py → supernote-0.4.0/supernote/cli/client.py +36 -33
- supernote-0.4.0/supernote/cli/main.py +41 -0
- supernote-0.3.0/supernote/cmds/supernote_tool.py → supernote-0.4.0/supernote/cli/notebook.py +30 -65
- supernote-0.4.0/supernote/cli/server.py +109 -0
- supernote-0.4.0/supernote/client/__init__.py +15 -0
- {supernote-0.3.0/supernote/cloud → supernote-0.4.0/supernote/client}/api_model.py +3 -3
- {supernote-0.3.0/supernote/cloud → supernote-0.4.0/supernote/client}/auth.py +3 -3
- {supernote-0.3.0/supernote/cloud → supernote-0.4.0/supernote/client}/client.py +1 -1
- {supernote-0.3.0/supernote/cloud → supernote-0.4.0/supernote/client}/cloud_client.py +27 -3
- supernote-0.4.0/supernote/notebook/__init__.py +67 -0
- {supernote-0.3.0/supernote → supernote-0.4.0/supernote/notebook}/converter.py +8 -9
- {supernote-0.3.0/supernote → supernote-0.4.0/supernote/notebook}/decoder.py +4 -4
- {supernote-0.3.0/supernote → supernote-0.4.0/supernote/notebook}/manipulator.py +1 -4
- {supernote-0.3.0/supernote → supernote-0.4.0/supernote/notebook}/parser.py +2 -3
- supernote-0.4.0/supernote/py.typed +0 -0
- supernote-0.4.0/supernote/server/__init__.py +12 -0
- supernote-0.4.0/supernote/server/app.py +129 -0
- supernote-0.4.0/supernote/server/config.py +16 -0
- supernote-0.4.0/supernote/server/models/__init__.py +1 -0
- supernote-0.4.0/supernote/server/models/auth.py +139 -0
- supernote-0.4.0/supernote/server/models/base.py +30 -0
- supernote-0.4.0/supernote/server/models/file.py +350 -0
- supernote-0.4.0/supernote/server/routes/auth.py +155 -0
- supernote-0.4.0/supernote/server/routes/decorators.py +13 -0
- supernote-0.4.0/supernote/server/routes/file.py +410 -0
- supernote-0.4.0/supernote/server/routes/system.py +33 -0
- supernote-0.4.0/supernote/server/services/__init__.py +3 -0
- supernote-0.4.0/supernote/server/services/file.py +369 -0
- supernote-0.4.0/supernote/server/services/storage.py +350 -0
- supernote-0.4.0/supernote/server/services/user.py +230 -0
- supernote-0.4.0/supernote.egg-info/PKG-INFO +205 -0
- supernote-0.4.0/supernote.egg-info/SOURCES.txt +47 -0
- supernote-0.4.0/supernote.egg-info/entry_points.txt +3 -0
- {supernote-0.3.0 → supernote-0.4.0}/supernote.egg-info/requires.txt +12 -0
- supernote-0.3.0/PKG-INFO +0 -36
- supernote-0.3.0/README.md +0 -15
- supernote-0.3.0/supernote/__init__.py +0 -15
- supernote-0.3.0/supernote.egg-info/PKG-INFO +0 -36
- supernote-0.3.0/supernote.egg-info/SOURCES.txt +0 -28
- supernote-0.3.0/supernote.egg-info/entry_points.txt +0 -2
- supernote-0.3.0/tests/test_init.py +0 -6
- {supernote-0.3.0 → supernote-0.4.0}/LICENSE +0 -0
- {supernote-0.3.0 → supernote-0.4.0}/setup.cfg +0 -0
- {supernote-0.3.0/supernote/cmds → supernote-0.4.0/supernote/cli}/__init__.py +0 -0
- {supernote-0.3.0/supernote/cloud → supernote-0.4.0/supernote/client}/exceptions.py +0 -0
- {supernote-0.3.0/supernote/cloud → supernote-0.4.0/supernote/client}/login_client.py +6 -6
- {supernote-0.3.0/supernote → supernote-0.4.0/supernote/notebook}/color.py +0 -0
- {supernote-0.3.0/supernote → supernote-0.4.0/supernote/notebook}/exceptions.py +0 -0
- {supernote-0.3.0/supernote → supernote-0.4.0/supernote/notebook}/fileformat.py +0 -0
- {supernote-0.3.0/supernote → supernote-0.4.0/supernote/notebook}/utils.py +0 -0
- {supernote-0.3.0 → supernote-0.4.0}/supernote.egg-info/dependency_links.txt +0 -0
- {supernote-0.3.0 → supernote-0.4.0}/supernote.egg-info/top_level.txt +0 -0
supernote-0.4.0/PKG-INFO
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: supernote
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: All-in-one toolkit for Supernote devices: parse notebooks, self-host services, access services
|
|
5
|
+
Author-email: jya <jya@wizmy.net>, Allen Porter <allen.porter@gmail.com>
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: Source, https://github.com/allenporter/supernote
|
|
8
|
+
Requires-Python: >=3.13
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: colour>=0.1.5
|
|
12
|
+
Requires-Dist: numpy>=1.19.0
|
|
13
|
+
Requires-Dist: Pillow>=7.2.0
|
|
14
|
+
Requires-Dist: potracer>=0.0.1
|
|
15
|
+
Requires-Dist: pypng>=0.0.20
|
|
16
|
+
Requires-Dist: reportlab>=3.6.1
|
|
17
|
+
Requires-Dist: svgwrite>=1.4
|
|
18
|
+
Provides-Extra: client
|
|
19
|
+
Requires-Dist: aiohttp; extra == "client"
|
|
20
|
+
Requires-Dist: requests; extra == "client"
|
|
21
|
+
Requires-Dist: tqdm; extra == "client"
|
|
22
|
+
Provides-Extra: server
|
|
23
|
+
Requires-Dist: aiohttp>=3.13.2; extra == "server"
|
|
24
|
+
Requires-Dist: mashumaro>=3.17; extra == "server"
|
|
25
|
+
Requires-Dist: pyyaml>=6.0; extra == "server"
|
|
26
|
+
Requires-Dist: PyJWT>=2.10.1; extra == "server"
|
|
27
|
+
Provides-Extra: all
|
|
28
|
+
Requires-Dist: supernote[client,server]; extra == "all"
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
# supernote
|
|
32
|
+
|
|
33
|
+
All-in-one toolkit for Supernote devices: parse notebooks, self host, and access services.
|
|
34
|
+
|
|
35
|
+
This content is shared between the [documentation](https://allenporter.github.io/supernote-lite/) and github repository at [github.com/allenporter/supernote-lite](https://github.com/allenporter/supernote-lite).
|
|
36
|
+
|
|
37
|
+
## Features
|
|
38
|
+
|
|
39
|
+
- **Notebook Parsing**: Convert `.note` files to PDF, PNG, SVG, or text
|
|
40
|
+
- **Private Server**: Self-hosted Supernote Private Cloud implementation
|
|
41
|
+
- **Client**: Interact with Supernote service API
|
|
42
|
+
|
|
43
|
+
## Installation
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
|
|
47
|
+
# Install specific components
|
|
48
|
+
pip install supernote # Notebook parsing only
|
|
49
|
+
pip install supernote[server] # + Private server
|
|
50
|
+
pip install supernote[client] # + Client
|
|
51
|
+
|
|
52
|
+
# Full installation (recommended for server users)
|
|
53
|
+
pip install supernote[all]
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Local Development
|
|
57
|
+
|
|
58
|
+
Install in a virtual environment:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
uv venv --python=3.14
|
|
62
|
+
source .venv/bin/activate
|
|
63
|
+
uv pip install -r requirements_dev.txt
|
|
64
|
+
uv pip install -e ".[all]"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Quick Start
|
|
68
|
+
|
|
69
|
+
### Parse a Notebook
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from supernote.notebook import parse_notebook
|
|
73
|
+
|
|
74
|
+
notebook = parse_notebook("mynote.note")
|
|
75
|
+
notebook.to_pdf("output.pdf")
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The notebook parser is a fork and slightly lighter dependency version of [supernote-tool](https://github.com/jya-dev/supernote-tool) that drops svg dependencies not found in some containers. Generally, you should probably prefer to use that original library unless there is a specific reason you're also having a similar dependency
|
|
79
|
+
limitation. All credit goes to the original authors of [supernote-tool](https://github.com/jya-dev/supernote-tool) for providing an amazing low level utility.
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
### Run Private Server
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# Configure users (you will be prompted for a password)
|
|
86
|
+
supernote-server user add alice
|
|
87
|
+
|
|
88
|
+
# Start server
|
|
89
|
+
supernote-server serve
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Run with Docker
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
# Build image
|
|
96
|
+
docker build -t supernote-server .
|
|
97
|
+
|
|
98
|
+
# Create user
|
|
99
|
+
mkdir config
|
|
100
|
+
docker run --rm -it -v $(pwd)/config:/config supernote-server supernote-server user add alice
|
|
101
|
+
|
|
102
|
+
# Run server
|
|
103
|
+
docker run -d -p 8080:8080 \
|
|
104
|
+
-v $(pwd)/config:/config \
|
|
105
|
+
-v $(pwd)/storage:/data \
|
|
106
|
+
supernote-server
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
See [Server Documentation](supernote/server/README.md) for details.
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
### Access Supernote Services
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
|
|
116
|
+
from supernote.client import SupernoteClient
|
|
117
|
+
|
|
118
|
+
async with SupernoteClient.from_credentials(email, password) as client:
|
|
119
|
+
files = await client.list_files()
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
## CLI Usage
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
# Notebook operations
|
|
127
|
+
supernote convert input.note output.pdf
|
|
128
|
+
supernote analyze input.note
|
|
129
|
+
|
|
130
|
+
# Server operations
|
|
131
|
+
supernote-server serve
|
|
132
|
+
supernote-server user add alice
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
# Client operations
|
|
136
|
+
supernote client login
|
|
137
|
+
supernote client ls
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Development
|
|
141
|
+
|
|
142
|
+
This package is designed for:
|
|
143
|
+
1. **Server operators** - Self-hosting Supernote Private Cloud
|
|
144
|
+
2. **Developers** - Integrating Supernote into applications
|
|
145
|
+
3. **Reference** - Understanding Supernote protocols
|
|
146
|
+
|
|
147
|
+
See [ARCHITECTURE.md](supernote/server/ARCHITECTURE.md) for protocol details.
|
|
148
|
+
|
|
149
|
+
### Setup
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
uv venv --python=3.14
|
|
153
|
+
source .venv/bin/activate
|
|
154
|
+
uv pip install -r requirements_dev.txt
|
|
155
|
+
uv pip install -e ".[all]"
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Credits
|
|
159
|
+
|
|
160
|
+
The `supernote` library is a fork and slightly lighter dependency version of [supernote-tool](https://github.com/jya-dev/supernote-tool) that drops svg dependencies not found in some containers. Generally, you should probably prefer to use that library unless there is a specific reason you're also having a similar dependency limitation.
|
|
161
|
+
|
|
162
|
+
## Acknowledgments
|
|
163
|
+
|
|
164
|
+
This project is in support of the amazing [Ratta Supernote](https://supernote.com/) product and community. This project aims to be a complementary, unofficial offering that is compatible with the [Private Cloud feature](https://support.supernote.com/Whats-New/setting-up-your-own-supernote-private-cloud-beta), helping to support their open ecosystem, helping to reduce load on their servers etc (e.g. for AI
|
|
165
|
+
powered personal assistant integrations that need to process notebooks, etc)
|
|
166
|
+
|
|
167
|
+
### Comparison with Official Private Cloud
|
|
168
|
+
|
|
169
|
+
Ratta offers an [official Private Cloud solution](https://support.supernote.com/Whats-New/setting-up-your-own-supernote-private-cloud-beta) based on Docker. You
|
|
170
|
+
should generally prefer that solution, unless you are interested in lower level
|
|
171
|
+
integrations and are comfortable managing your own security, SSL, etc.
|
|
172
|
+
|
|
173
|
+
Here is how this project compares:
|
|
174
|
+
|
|
175
|
+
| Feature | Official Private Cloud | Supernote-Lite (This Project) |
|
|
176
|
+
|---------|------------------------|-------------------------------|
|
|
177
|
+
| **Type** | Official Product | Community Project |
|
|
178
|
+
| **Technology** | Docker Container (Java/Spring) | Python Package |
|
|
179
|
+
| **Source** | Closed Source | Open Source |
|
|
180
|
+
| **Focus** | Stability & End-Users | Hackability & Developers |
|
|
181
|
+
| **Requirements** | Docker Environment | Python 3.10+ |
|
|
182
|
+
| **Extensibility** | Low (Black Box) | High (Modular Codebase) |
|
|
183
|
+
| **Security/SSL** | Documented Guides Included | DIY (Bring Your Own Proxy) |
|
|
184
|
+
|
|
185
|
+
**Use the Official Private Cloud if:**
|
|
186
|
+
- You want a supported, "set-and-forget" solution.
|
|
187
|
+
- You prefer using Docker containers.
|
|
188
|
+
|
|
189
|
+
**Use Supernote-Lite if:**
|
|
190
|
+
- You want to understand how the protocol works.
|
|
191
|
+
- You want to run on low-power hardware without Docker overhead.
|
|
192
|
+
- You want to integrate Supernote sync into your own Python applications.
|
|
193
|
+
- You want to customize the server behavior.
|
|
194
|
+
|
|
195
|
+
### Community Projects
|
|
196
|
+
|
|
197
|
+
- [github.com/jya-dev/supernote-tool](https://github.com/jya-dev/supernote-tool) - Unofficial python tool for Ratta Supernote for parsing notebook files, which this projects notebook module is based on.
|
|
198
|
+
- [github.com/philips/supernote-typescript](https://github.com/philips/supernote-typescript) - Supernote file-format support in typescript
|
|
199
|
+
- [github.com/julianprester/sncloud](https://github.com/julianprester/sncloud) - Supernote Cloud API for Python
|
|
200
|
+
- [github.com/fharper/awesome-supernote](https://github.com/fharper/awesome-supernote) - A curated list of Supernote resources
|
|
201
|
+
- [github.com/philips/supernote-obsidian-plugin](https://github.com/philips/supernote-obsidian-plugin) - Obsidian plugin for Supernote
|
|
202
|
+
- [github.com/jbchouinard/supernote-sync](https://github.com/jbchouinard/supernote-sync) - Tool to automatically backup files from the Supernote using local WiFi using the Supernote Browse & Access feature
|
|
203
|
+
- [github.com/theburningbush/snbackup](https://github.com/theburningbush/snbackup) - CLI tool for wireless Supernote backups using the Browse & Access feature
|
|
204
|
+
- [github.com/dsummersl/sn2md](https://github.com/dsummersl/sn2md) - Supernote to text/image converter (sn2md)
|
|
205
|
+
- [github.com/calebc42/eink-template-gen](https://github.com/calebc42/eink-template-gen) - Generates pixel-perfect page templates for e-ink devices.
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# supernote
|
|
2
|
+
|
|
3
|
+
All-in-one toolkit for Supernote devices: parse notebooks, self host, and access services.
|
|
4
|
+
|
|
5
|
+
This content is shared between the [documentation](https://allenporter.github.io/supernote-lite/) and github repository at [github.com/allenporter/supernote-lite](https://github.com/allenporter/supernote-lite).
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Notebook Parsing**: Convert `.note` files to PDF, PNG, SVG, or text
|
|
10
|
+
- **Private Server**: Self-hosted Supernote Private Cloud implementation
|
|
11
|
+
- **Client**: Interact with Supernote service API
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
|
|
17
|
+
# Install specific components
|
|
18
|
+
pip install supernote # Notebook parsing only
|
|
19
|
+
pip install supernote[server] # + Private server
|
|
20
|
+
pip install supernote[client] # + Client
|
|
21
|
+
|
|
22
|
+
# Full installation (recommended for server users)
|
|
23
|
+
pip install supernote[all]
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Local Development
|
|
27
|
+
|
|
28
|
+
Install in a virtual environment:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
uv venv --python=3.14
|
|
32
|
+
source .venv/bin/activate
|
|
33
|
+
uv pip install -r requirements_dev.txt
|
|
34
|
+
uv pip install -e ".[all]"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Quick Start
|
|
38
|
+
|
|
39
|
+
### Parse a Notebook
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
from supernote.notebook import parse_notebook
|
|
43
|
+
|
|
44
|
+
notebook = parse_notebook("mynote.note")
|
|
45
|
+
notebook.to_pdf("output.pdf")
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The notebook parser is a fork and slightly lighter dependency version of [supernote-tool](https://github.com/jya-dev/supernote-tool) that drops svg dependencies not found in some containers. Generally, you should probably prefer to use that original library unless there is a specific reason you're also having a similar dependency
|
|
49
|
+
limitation. All credit goes to the original authors of [supernote-tool](https://github.com/jya-dev/supernote-tool) for providing an amazing low level utility.
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
### Run Private Server
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Configure users (you will be prompted for a password)
|
|
56
|
+
supernote-server user add alice
|
|
57
|
+
|
|
58
|
+
# Start server
|
|
59
|
+
supernote-server serve
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Run with Docker
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# Build image
|
|
66
|
+
docker build -t supernote-server .
|
|
67
|
+
|
|
68
|
+
# Create user
|
|
69
|
+
mkdir config
|
|
70
|
+
docker run --rm -it -v $(pwd)/config:/config supernote-server supernote-server user add alice
|
|
71
|
+
|
|
72
|
+
# Run server
|
|
73
|
+
docker run -d -p 8080:8080 \
|
|
74
|
+
-v $(pwd)/config:/config \
|
|
75
|
+
-v $(pwd)/storage:/data \
|
|
76
|
+
supernote-server
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
See [Server Documentation](supernote/server/README.md) for details.
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
### Access Supernote Services
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
|
|
86
|
+
from supernote.client import SupernoteClient
|
|
87
|
+
|
|
88
|
+
async with SupernoteClient.from_credentials(email, password) as client:
|
|
89
|
+
files = await client.list_files()
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
## CLI Usage
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# Notebook operations
|
|
97
|
+
supernote convert input.note output.pdf
|
|
98
|
+
supernote analyze input.note
|
|
99
|
+
|
|
100
|
+
# Server operations
|
|
101
|
+
supernote-server serve
|
|
102
|
+
supernote-server user add alice
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
# Client operations
|
|
106
|
+
supernote client login
|
|
107
|
+
supernote client ls
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Development
|
|
111
|
+
|
|
112
|
+
This package is designed for:
|
|
113
|
+
1. **Server operators** - Self-hosting Supernote Private Cloud
|
|
114
|
+
2. **Developers** - Integrating Supernote into applications
|
|
115
|
+
3. **Reference** - Understanding Supernote protocols
|
|
116
|
+
|
|
117
|
+
See [ARCHITECTURE.md](supernote/server/ARCHITECTURE.md) for protocol details.
|
|
118
|
+
|
|
119
|
+
### Setup
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
uv venv --python=3.14
|
|
123
|
+
source .venv/bin/activate
|
|
124
|
+
uv pip install -r requirements_dev.txt
|
|
125
|
+
uv pip install -e ".[all]"
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Credits
|
|
129
|
+
|
|
130
|
+
The `supernote` library is a fork and slightly lighter dependency version of [supernote-tool](https://github.com/jya-dev/supernote-tool) that drops svg dependencies not found in some containers. Generally, you should probably prefer to use that library unless there is a specific reason you're also having a similar dependency limitation.
|
|
131
|
+
|
|
132
|
+
## Acknowledgments
|
|
133
|
+
|
|
134
|
+
This project is in support of the amazing [Ratta Supernote](https://supernote.com/) product and community. This project aims to be a complementary, unofficial offering that is compatible with the [Private Cloud feature](https://support.supernote.com/Whats-New/setting-up-your-own-supernote-private-cloud-beta), helping to support their open ecosystem, helping to reduce load on their servers etc (e.g. for AI
|
|
135
|
+
powered personal assistant integrations that need to process notebooks, etc)
|
|
136
|
+
|
|
137
|
+
### Comparison with Official Private Cloud
|
|
138
|
+
|
|
139
|
+
Ratta offers an [official Private Cloud solution](https://support.supernote.com/Whats-New/setting-up-your-own-supernote-private-cloud-beta) based on Docker. You
|
|
140
|
+
should generally prefer that solution, unless you are interested in lower level
|
|
141
|
+
integrations and are comfortable managing your own security, SSL, etc.
|
|
142
|
+
|
|
143
|
+
Here is how this project compares:
|
|
144
|
+
|
|
145
|
+
| Feature | Official Private Cloud | Supernote-Lite (This Project) |
|
|
146
|
+
|---------|------------------------|-------------------------------|
|
|
147
|
+
| **Type** | Official Product | Community Project |
|
|
148
|
+
| **Technology** | Docker Container (Java/Spring) | Python Package |
|
|
149
|
+
| **Source** | Closed Source | Open Source |
|
|
150
|
+
| **Focus** | Stability & End-Users | Hackability & Developers |
|
|
151
|
+
| **Requirements** | Docker Environment | Python 3.10+ |
|
|
152
|
+
| **Extensibility** | Low (Black Box) | High (Modular Codebase) |
|
|
153
|
+
| **Security/SSL** | Documented Guides Included | DIY (Bring Your Own Proxy) |
|
|
154
|
+
|
|
155
|
+
**Use the Official Private Cloud if:**
|
|
156
|
+
- You want a supported, "set-and-forget" solution.
|
|
157
|
+
- You prefer using Docker containers.
|
|
158
|
+
|
|
159
|
+
**Use Supernote-Lite if:**
|
|
160
|
+
- You want to understand how the protocol works.
|
|
161
|
+
- You want to run on low-power hardware without Docker overhead.
|
|
162
|
+
- You want to integrate Supernote sync into your own Python applications.
|
|
163
|
+
- You want to customize the server behavior.
|
|
164
|
+
|
|
165
|
+
### Community Projects
|
|
166
|
+
|
|
167
|
+
- [github.com/jya-dev/supernote-tool](https://github.com/jya-dev/supernote-tool) - Unofficial python tool for Ratta Supernote for parsing notebook files, which this projects notebook module is based on.
|
|
168
|
+
- [github.com/philips/supernote-typescript](https://github.com/philips/supernote-typescript) - Supernote file-format support in typescript
|
|
169
|
+
- [github.com/julianprester/sncloud](https://github.com/julianprester/sncloud) - Supernote Cloud API for Python
|
|
170
|
+
- [github.com/fharper/awesome-supernote](https://github.com/fharper/awesome-supernote) - A curated list of Supernote resources
|
|
171
|
+
- [github.com/philips/supernote-obsidian-plugin](https://github.com/philips/supernote-obsidian-plugin) - Obsidian plugin for Supernote
|
|
172
|
+
- [github.com/jbchouinard/supernote-sync](https://github.com/jbchouinard/supernote-sync) - Tool to automatically backup files from the Supernote using local WiFi using the Supernote Browse & Access feature
|
|
173
|
+
- [github.com/theburningbush/snbackup](https://github.com/theburningbush/snbackup) - CLI tool for wireless Supernote backups using the Browse & Access feature
|
|
174
|
+
- [github.com/dsummersl/sn2md](https://github.com/dsummersl/sn2md) - Supernote to text/image converter (sn2md)
|
|
175
|
+
- [github.com/calebc42/eink-template-gen](https://github.com/calebc42/eink-template-gen) - Generates pixel-perfect page templates for e-ink devices.
|
|
@@ -4,10 +4,10 @@ requires = ["setuptools>=77.0"]
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "supernote"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.4.0"
|
|
8
8
|
license = "Apache-2.0"
|
|
9
9
|
license-files = ["LICENSE"]
|
|
10
|
-
description = "
|
|
10
|
+
description = "All-in-one toolkit for Supernote devices: parse notebooks, self-host services, access services"
|
|
11
11
|
readme = "README.md"
|
|
12
12
|
authors = [
|
|
13
13
|
{ name = "jya", email = "jya@wizmy.net" },
|
|
@@ -16,7 +16,7 @@ authors = [
|
|
|
16
16
|
requires-python = ">=3.13"
|
|
17
17
|
classifiers = []
|
|
18
18
|
dependencies = [
|
|
19
|
-
#
|
|
19
|
+
# Core notebook dependencies (always installed)
|
|
20
20
|
"colour>=0.1.5",
|
|
21
21
|
"numpy>=1.19.0",
|
|
22
22
|
"Pillow>=7.2.0",
|
|
@@ -24,11 +24,21 @@ dependencies = [
|
|
|
24
24
|
"pypng>=0.0.20",
|
|
25
25
|
"reportlab>=3.6.1",
|
|
26
26
|
"svgwrite>=1.4",
|
|
27
|
+
]
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
[project.optional-dependencies]
|
|
30
|
+
client = [
|
|
31
|
+
"aiohttp",
|
|
32
|
+
"requests",
|
|
33
|
+
"tqdm",
|
|
34
|
+
]
|
|
35
|
+
server = [
|
|
29
36
|
"aiohttp>=3.13.2",
|
|
30
37
|
"mashumaro>=3.17",
|
|
38
|
+
"pyyaml>=6.0",
|
|
39
|
+
"PyJWT>=2.10.1",
|
|
31
40
|
]
|
|
41
|
+
all = ["supernote[client,server]"]
|
|
32
42
|
|
|
33
43
|
[project.urls]
|
|
34
44
|
Source = "https://github.com/allenporter/supernote"
|
|
@@ -37,16 +47,20 @@ Source = "https://github.com/allenporter/supernote"
|
|
|
37
47
|
include = ["supernote*"]
|
|
38
48
|
|
|
39
49
|
[project.entry-points."console_scripts"]
|
|
40
|
-
supernote
|
|
50
|
+
supernote = "supernote.cli.main:main"
|
|
51
|
+
supernote-server = "supernote.cli.server:main"
|
|
41
52
|
|
|
42
53
|
[tool.mypy]
|
|
43
54
|
exclude = [
|
|
44
55
|
"venv/",
|
|
45
|
-
"
|
|
56
|
+
"data",
|
|
57
|
+
# TODO: Fix mypy errors and then remove this
|
|
58
|
+
"supernote/notebook/",
|
|
59
|
+
"supernote/cli/",
|
|
46
60
|
]
|
|
47
61
|
platform = "linux"
|
|
48
62
|
show_error_codes = true
|
|
49
|
-
follow_imports = "
|
|
63
|
+
follow_imports = "silent"
|
|
50
64
|
local_partial_types = true
|
|
51
65
|
strict_equality = true
|
|
52
66
|
no_implicit_optional = true
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""
|
|
2
|
+
.. include:: ../README.md
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
# Core notebook parsing (always available)
|
|
6
|
+
from . import notebook
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"notebook",
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
# Optional: Client library
|
|
13
|
+
try:
|
|
14
|
+
from . import client # noqa: F401
|
|
15
|
+
|
|
16
|
+
__all__.extend(["client"])
|
|
17
|
+
except ImportError:
|
|
18
|
+
pass
|
|
19
|
+
|
|
20
|
+
# Optional: Server
|
|
21
|
+
try:
|
|
22
|
+
from . import server # noqa: F401
|
|
23
|
+
|
|
24
|
+
__all__.extend(["server"])
|
|
25
|
+
except ImportError:
|
|
26
|
+
pass
|
supernote-0.3.0/supernote/cmds/cloud_login_tool.py → supernote-0.4.0/supernote/cli/client.py
RENAMED
|
@@ -1,19 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
"""Cloud login debugging tool for Supernote Cloud."""
|
|
1
|
+
"""Client CLI commands."""
|
|
3
2
|
|
|
4
3
|
import asyncio
|
|
5
4
|
import logging
|
|
6
|
-
import sys
|
|
7
5
|
import os
|
|
6
|
+
import sys
|
|
8
7
|
|
|
9
8
|
import aiohttp
|
|
10
9
|
|
|
11
|
-
from supernote.
|
|
12
|
-
from supernote.
|
|
13
|
-
from supernote.
|
|
14
|
-
from supernote.
|
|
15
|
-
from supernote.
|
|
16
|
-
|
|
10
|
+
from supernote.client.auth import FileCacheAuth
|
|
11
|
+
from supernote.client.client import Client
|
|
12
|
+
from supernote.client.cloud_client import SupernoteClient
|
|
13
|
+
from supernote.client.exceptions import SupernoteException
|
|
14
|
+
from supernote.client.login_client import LoginClient
|
|
17
15
|
|
|
18
16
|
_LOGGER = logging.getLogger(__name__)
|
|
19
17
|
|
|
@@ -72,11 +70,7 @@ async def async_cloud_login(email: str, password: str, verbose: bool = False) ->
|
|
|
72
70
|
access_token = await login_client.login(email, password)
|
|
73
71
|
except SupernoteException as err:
|
|
74
72
|
# Check if it's an SMS verification requirement
|
|
75
|
-
|
|
76
|
-
# we need to make sure we import it.
|
|
77
|
-
# For now, let's assume if the message contains "verification code" it is one.
|
|
78
|
-
# But better to use the type.
|
|
79
|
-
from supernote.cloud.exceptions import SmsVerificationRequired
|
|
73
|
+
from supernote.client.exceptions import SmsVerificationRequired
|
|
80
74
|
|
|
81
75
|
if isinstance(err, SmsVerificationRequired):
|
|
82
76
|
print()
|
|
@@ -120,9 +114,8 @@ async def async_cloud_login(email: str, password: str, verbose: bool = False) ->
|
|
|
120
114
|
|
|
121
115
|
# Step 2: Test basic functionality
|
|
122
116
|
print("Step 3: Testing basic functionality...")
|
|
123
|
-
# auth = ConstantAuth(access_token) # No longer needed as we use FileCacheAuth
|
|
124
117
|
authenticated_client = Client(session, auth=auth)
|
|
125
|
-
cloud_client =
|
|
118
|
+
cloud_client = SupernoteClient(authenticated_client)
|
|
126
119
|
|
|
127
120
|
# Test 1: Query user
|
|
128
121
|
print(" Test 1: Querying user information...")
|
|
@@ -185,33 +178,25 @@ async def async_cloud_login(email: str, password: str, verbose: bool = False) ->
|
|
|
185
178
|
|
|
186
179
|
|
|
187
180
|
def subcommand_cloud_login(args) -> None:
|
|
188
|
-
"""Handler for cloud-login subcommand.
|
|
189
|
-
|
|
190
|
-
Args:
|
|
191
|
-
args: Parsed command line arguments
|
|
192
|
-
"""
|
|
181
|
+
"""Handler for cloud-login subcommand."""
|
|
193
182
|
asyncio.run(async_cloud_login(args.email, args.password, args.verbose))
|
|
194
183
|
|
|
195
184
|
|
|
196
185
|
async def async_cloud_ls(verbose: bool = False) -> None:
|
|
197
|
-
"""List files in Supernote Cloud using cached credentials.
|
|
198
|
-
|
|
199
|
-
Args:
|
|
200
|
-
verbose: Enable verbose logging
|
|
201
|
-
"""
|
|
186
|
+
"""List files in Supernote Cloud using cached credentials."""
|
|
202
187
|
setup_logging(verbose)
|
|
203
188
|
|
|
204
189
|
cache_path = os.path.expanduser("~/.cache/supernote.pkl")
|
|
205
190
|
if not os.path.exists(cache_path):
|
|
206
191
|
print(f"Error: No cached credentials found at {cache_path}")
|
|
207
|
-
print("Please run 'supernote
|
|
192
|
+
print("Please run 'supernote cloud login' first.")
|
|
208
193
|
sys.exit(1)
|
|
209
194
|
|
|
210
195
|
async with aiohttp.ClientSession() as session:
|
|
211
196
|
try:
|
|
212
197
|
auth = FileCacheAuth(cache_path)
|
|
213
198
|
client = Client(session, auth=auth)
|
|
214
|
-
cloud_client =
|
|
199
|
+
cloud_client = SupernoteClient(client)
|
|
215
200
|
|
|
216
201
|
print("Listing files in root directory...")
|
|
217
202
|
file_list_response = await cloud_client.file_list()
|
|
@@ -239,9 +224,27 @@ async def async_cloud_ls(verbose: bool = False) -> None:
|
|
|
239
224
|
|
|
240
225
|
|
|
241
226
|
def subcommand_cloud_ls(args) -> None:
|
|
242
|
-
"""Handler for cloud-ls subcommand.
|
|
243
|
-
|
|
244
|
-
Args:
|
|
245
|
-
args: Parsed command line arguments
|
|
246
|
-
"""
|
|
227
|
+
"""Handler for cloud-ls subcommand."""
|
|
247
228
|
asyncio.run(async_cloud_ls(args.verbose))
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def add_parser(subparsers):
|
|
232
|
+
# 'cloud-login' subcommand
|
|
233
|
+
parser_cloud_login = subparsers.add_parser(
|
|
234
|
+
"cloud-login", help="debug Supernote Cloud login flow"
|
|
235
|
+
)
|
|
236
|
+
parser_cloud_login.add_argument("email", type=str, help="user email/account")
|
|
237
|
+
parser_cloud_login.add_argument("password", type=str, help="user password")
|
|
238
|
+
parser_cloud_login.add_argument(
|
|
239
|
+
"-v", "--verbose", action="store_true", help="Enable verbose logging"
|
|
240
|
+
)
|
|
241
|
+
parser_cloud_login.set_defaults(func=subcommand_cloud_login)
|
|
242
|
+
|
|
243
|
+
# Cloud ls command
|
|
244
|
+
cloud_ls_parser = subparsers.add_parser(
|
|
245
|
+
"cloud-ls", help="List files in Supernote Cloud"
|
|
246
|
+
)
|
|
247
|
+
cloud_ls_parser.add_argument(
|
|
248
|
+
"-v", "--verbose", action="store_true", help="Enable verbose logging"
|
|
249
|
+
)
|
|
250
|
+
cloud_ls_parser.set_defaults(func=subcommand_cloud_ls)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""Main CLI entry point."""
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
from . import client, notebook, server
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def main():
|
|
10
|
+
parser = argparse.ArgumentParser(
|
|
11
|
+
prog="supernote",
|
|
12
|
+
description="Supernote toolkit for parsing, self hosting, and service access",
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
subparsers = parser.add_subparsers(dest="command", help="Command to run")
|
|
16
|
+
|
|
17
|
+
# Notebook commands
|
|
18
|
+
notebook.add_parser(subparsers)
|
|
19
|
+
|
|
20
|
+
# Client commands
|
|
21
|
+
client.add_parser(subparsers)
|
|
22
|
+
|
|
23
|
+
# Server commands
|
|
24
|
+
server.add_parser(subparsers)
|
|
25
|
+
|
|
26
|
+
args = parser.parse_args()
|
|
27
|
+
|
|
28
|
+
if args.command is None:
|
|
29
|
+
parser.print_help()
|
|
30
|
+
sys.exit(1)
|
|
31
|
+
|
|
32
|
+
# Dispatch to appropriate handler
|
|
33
|
+
if hasattr(args, "func"):
|
|
34
|
+
args.func(args)
|
|
35
|
+
else:
|
|
36
|
+
parser.print_help()
|
|
37
|
+
sys.exit(1)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
if __name__ == "__main__":
|
|
41
|
+
main()
|