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.
Files changed (56) hide show
  1. supernote-0.4.0/PKG-INFO +205 -0
  2. supernote-0.4.0/README.md +175 -0
  3. {supernote-0.3.0 → supernote-0.4.0}/pyproject.toml +21 -7
  4. supernote-0.4.0/supernote/__init__.py +26 -0
  5. supernote-0.3.0/supernote/cmds/cloud_login_tool.py → supernote-0.4.0/supernote/cli/client.py +36 -33
  6. supernote-0.4.0/supernote/cli/main.py +41 -0
  7. supernote-0.3.0/supernote/cmds/supernote_tool.py → supernote-0.4.0/supernote/cli/notebook.py +30 -65
  8. supernote-0.4.0/supernote/cli/server.py +109 -0
  9. supernote-0.4.0/supernote/client/__init__.py +15 -0
  10. {supernote-0.3.0/supernote/cloud → supernote-0.4.0/supernote/client}/api_model.py +3 -3
  11. {supernote-0.3.0/supernote/cloud → supernote-0.4.0/supernote/client}/auth.py +3 -3
  12. {supernote-0.3.0/supernote/cloud → supernote-0.4.0/supernote/client}/client.py +1 -1
  13. {supernote-0.3.0/supernote/cloud → supernote-0.4.0/supernote/client}/cloud_client.py +27 -3
  14. supernote-0.4.0/supernote/notebook/__init__.py +67 -0
  15. {supernote-0.3.0/supernote → supernote-0.4.0/supernote/notebook}/converter.py +8 -9
  16. {supernote-0.3.0/supernote → supernote-0.4.0/supernote/notebook}/decoder.py +4 -4
  17. {supernote-0.3.0/supernote → supernote-0.4.0/supernote/notebook}/manipulator.py +1 -4
  18. {supernote-0.3.0/supernote → supernote-0.4.0/supernote/notebook}/parser.py +2 -3
  19. supernote-0.4.0/supernote/py.typed +0 -0
  20. supernote-0.4.0/supernote/server/__init__.py +12 -0
  21. supernote-0.4.0/supernote/server/app.py +129 -0
  22. supernote-0.4.0/supernote/server/config.py +16 -0
  23. supernote-0.4.0/supernote/server/models/__init__.py +1 -0
  24. supernote-0.4.0/supernote/server/models/auth.py +139 -0
  25. supernote-0.4.0/supernote/server/models/base.py +30 -0
  26. supernote-0.4.0/supernote/server/models/file.py +350 -0
  27. supernote-0.4.0/supernote/server/routes/auth.py +155 -0
  28. supernote-0.4.0/supernote/server/routes/decorators.py +13 -0
  29. supernote-0.4.0/supernote/server/routes/file.py +410 -0
  30. supernote-0.4.0/supernote/server/routes/system.py +33 -0
  31. supernote-0.4.0/supernote/server/services/__init__.py +3 -0
  32. supernote-0.4.0/supernote/server/services/file.py +369 -0
  33. supernote-0.4.0/supernote/server/services/storage.py +350 -0
  34. supernote-0.4.0/supernote/server/services/user.py +230 -0
  35. supernote-0.4.0/supernote.egg-info/PKG-INFO +205 -0
  36. supernote-0.4.0/supernote.egg-info/SOURCES.txt +47 -0
  37. supernote-0.4.0/supernote.egg-info/entry_points.txt +3 -0
  38. {supernote-0.3.0 → supernote-0.4.0}/supernote.egg-info/requires.txt +12 -0
  39. supernote-0.3.0/PKG-INFO +0 -36
  40. supernote-0.3.0/README.md +0 -15
  41. supernote-0.3.0/supernote/__init__.py +0 -15
  42. supernote-0.3.0/supernote.egg-info/PKG-INFO +0 -36
  43. supernote-0.3.0/supernote.egg-info/SOURCES.txt +0 -28
  44. supernote-0.3.0/supernote.egg-info/entry_points.txt +0 -2
  45. supernote-0.3.0/tests/test_init.py +0 -6
  46. {supernote-0.3.0 → supernote-0.4.0}/LICENSE +0 -0
  47. {supernote-0.3.0 → supernote-0.4.0}/setup.cfg +0 -0
  48. {supernote-0.3.0/supernote/cmds → supernote-0.4.0/supernote/cli}/__init__.py +0 -0
  49. {supernote-0.3.0/supernote/cloud → supernote-0.4.0/supernote/client}/exceptions.py +0 -0
  50. {supernote-0.3.0/supernote/cloud → supernote-0.4.0/supernote/client}/login_client.py +6 -6
  51. {supernote-0.3.0/supernote → supernote-0.4.0/supernote/notebook}/color.py +0 -0
  52. {supernote-0.3.0/supernote → supernote-0.4.0/supernote/notebook}/exceptions.py +0 -0
  53. {supernote-0.3.0/supernote → supernote-0.4.0/supernote/notebook}/fileformat.py +0 -0
  54. {supernote-0.3.0/supernote → supernote-0.4.0/supernote/notebook}/utils.py +0 -0
  55. {supernote-0.3.0 → supernote-0.4.0}/supernote.egg-info/dependency_links.txt +0 -0
  56. {supernote-0.3.0 → supernote-0.4.0}/supernote.egg-info/top_level.txt +0 -0
@@ -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.3.0"
7
+ version = "0.4.0"
8
8
  license = "Apache-2.0"
9
9
  license-files = ["LICENSE"]
10
- description = "Unofficial python library for parsing Supernote notebooks"
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
- # Notebook dependencies
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
- # Cloud dependencies
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-tool = "supernote.cmds.supernote_tool:main"
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
- "supernote/cmds/",
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 = "normal"
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
@@ -1,19 +1,17 @@
1
- #!/usr/bin/env python3
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.cloud.client import Client
12
- from supernote.cloud.login_client import LoginClient
13
- from supernote.cloud.auth import FileCacheAuth
14
- from supernote.cloud.cloud_client import SupernoteCloudClient
15
- from supernote.cloud.exceptions import SupernoteException
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
- # We do this by checking the exception type, but since we just added it
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 = SupernoteCloudClient(authenticated_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-tool cloud-login' first.")
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 = SupernoteCloudClient(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()