supernote 0.13.6__py3-none-any.whl

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 (138) hide show
  1. supernote/__init__.py +28 -0
  2. supernote/alembic/__init__.py +0 -0
  3. supernote/alembic/env.py +121 -0
  4. supernote/alembic/script.py.mako +28 -0
  5. supernote/alembic/versions/0543a383957b_initial_schema.py +312 -0
  6. supernote/alembic.ini +149 -0
  7. supernote/cli/__init__.py +1 -0
  8. supernote/cli/admin.py +178 -0
  9. supernote/cli/client.py +434 -0
  10. supernote/cli/main.py +61 -0
  11. supernote/cli/notebook.py +313 -0
  12. supernote/cli/server.py +89 -0
  13. supernote/client/__init__.py +28 -0
  14. supernote/client/admin.py +76 -0
  15. supernote/client/api.py +135 -0
  16. supernote/client/api_model.py +231 -0
  17. supernote/client/auth.py +84 -0
  18. supernote/client/client.py +365 -0
  19. supernote/client/device.py +361 -0
  20. supernote/client/exceptions.py +33 -0
  21. supernote/client/extended.py +20 -0
  22. supernote/client/hashing.py +50 -0
  23. supernote/client/login_client.py +154 -0
  24. supernote/client/schedule.py +149 -0
  25. supernote/client/summary.py +156 -0
  26. supernote/client/web.py +213 -0
  27. supernote/models/__init__.py +14 -0
  28. supernote/models/auth.py +380 -0
  29. supernote/models/base.py +266 -0
  30. supernote/models/equipment.py +276 -0
  31. supernote/models/extended.py +124 -0
  32. supernote/models/file_common.py +95 -0
  33. supernote/models/file_device.py +571 -0
  34. supernote/models/file_web.py +602 -0
  35. supernote/models/schedule.py +663 -0
  36. supernote/models/summary.py +830 -0
  37. supernote/models/system.py +431 -0
  38. supernote/models/user.py +638 -0
  39. supernote/notebook/__init__.py +67 -0
  40. supernote/notebook/color.py +93 -0
  41. supernote/notebook/converter.py +560 -0
  42. supernote/notebook/decoder.py +398 -0
  43. supernote/notebook/exceptions.py +43 -0
  44. supernote/notebook/fileformat.py +463 -0
  45. supernote/notebook/manipulator.py +420 -0
  46. supernote/notebook/parser.py +737 -0
  47. supernote/notebook/utils.py +49 -0
  48. supernote/py.typed +0 -0
  49. supernote/server/__init__.py +12 -0
  50. supernote/server/app.py +428 -0
  51. supernote/server/config.py +265 -0
  52. supernote/server/constants.py +26 -0
  53. supernote/server/db/__init__.py +9 -0
  54. supernote/server/db/base.py +8 -0
  55. supernote/server/db/migrations.py +44 -0
  56. supernote/server/db/models/__init__.py +23 -0
  57. supernote/server/db/models/device.py +17 -0
  58. supernote/server/db/models/file.py +107 -0
  59. supernote/server/db/models/kv.py +17 -0
  60. supernote/server/db/models/login_record.py +22 -0
  61. supernote/server/db/models/note_processing.py +100 -0
  62. supernote/server/db/models/schedule.py +83 -0
  63. supernote/server/db/models/summary.py +122 -0
  64. supernote/server/db/models/user.py +30 -0
  65. supernote/server/db/session.py +88 -0
  66. supernote/server/events.py +63 -0
  67. supernote/server/exceptions.py +153 -0
  68. supernote/server/mcp/__init__.py +1 -0
  69. supernote/server/mcp/models.py +109 -0
  70. supernote/server/mcp/server.py +176 -0
  71. supernote/server/resources/__init__.py +0 -0
  72. supernote/server/resources/prompts/__init__.py +0 -0
  73. supernote/server/resources/prompts/ocr/common/context.md +19 -0
  74. supernote/server/resources/prompts/ocr/common/legend.md +11 -0
  75. supernote/server/resources/prompts/ocr/daily/prompt.md +12 -0
  76. supernote/server/resources/prompts/ocr/default/system.md +14 -0
  77. supernote/server/resources/prompts/ocr/monthly/prompt.md +22 -0
  78. supernote/server/resources/prompts/ocr/weekly/prompt.md +16 -0
  79. supernote/server/resources/prompts/summary/common/instruction.md +8 -0
  80. supernote/server/resources/prompts/summary/daily/prompt.md +6 -0
  81. supernote/server/resources/prompts/summary/default/prompt.md +4 -0
  82. supernote/server/resources/prompts/summary/monthly/prompt.md +6 -0
  83. supernote/server/resources/prompts/summary/weekly/prompt.md +6 -0
  84. supernote/server/routes/admin.py +109 -0
  85. supernote/server/routes/auth.py +337 -0
  86. supernote/server/routes/decorators.py +13 -0
  87. supernote/server/routes/extended.py +139 -0
  88. supernote/server/routes/file_device.py +593 -0
  89. supernote/server/routes/file_web.py +597 -0
  90. supernote/server/routes/oss.py +317 -0
  91. supernote/server/routes/schedule.py +223 -0
  92. supernote/server/routes/summary.py +390 -0
  93. supernote/server/routes/system.py +57 -0
  94. supernote/server/services/__init__.py +15 -0
  95. supernote/server/services/blob.py +214 -0
  96. supernote/server/services/coordination.py +171 -0
  97. supernote/server/services/file.py +970 -0
  98. supernote/server/services/gemini.py +66 -0
  99. supernote/server/services/integrity.py +112 -0
  100. supernote/server/services/processor.py +331 -0
  101. supernote/server/services/processor_modules/__init__.py +145 -0
  102. supernote/server/services/processor_modules/gemini_embedding.py +112 -0
  103. supernote/server/services/processor_modules/gemini_ocr.py +149 -0
  104. supernote/server/services/processor_modules/page_hashing.py +220 -0
  105. supernote/server/services/processor_modules/png_conversion.py +107 -0
  106. supernote/server/services/processor_modules/summary.py +302 -0
  107. supernote/server/services/prompt_loader.py +133 -0
  108. supernote/server/services/schedule.py +161 -0
  109. supernote/server/services/search.py +250 -0
  110. supernote/server/services/summary.py +419 -0
  111. supernote/server/services/user.py +480 -0
  112. supernote/server/services/vfs.py +476 -0
  113. supernote/server/static/favicon.ico +0 -0
  114. supernote/server/static/index.html +186 -0
  115. supernote/server/static/js/api/client.js +463 -0
  116. supernote/server/static/js/components/FileCard.js +55 -0
  117. supernote/server/static/js/components/FileViewer.js +137 -0
  118. supernote/server/static/js/components/LoginCard.js +64 -0
  119. supernote/server/static/js/components/MoveModal.js +74 -0
  120. supernote/server/static/js/components/RenameModal.js +39 -0
  121. supernote/server/static/js/components/SummaryPanel.js +101 -0
  122. supernote/server/static/js/components/SystemPanel.js +158 -0
  123. supernote/server/static/js/composables/useFileSystem.js +116 -0
  124. supernote/server/static/js/main.js +241 -0
  125. supernote/server/static/style.css +14 -0
  126. supernote/server/utils/hashing.py +18 -0
  127. supernote/server/utils/note_content.py +76 -0
  128. supernote/server/utils/paths.py +58 -0
  129. supernote/server/utils/rate_limit.py +52 -0
  130. supernote/server/utils/tasks.py +71 -0
  131. supernote/server/utils/unique_id.py +48 -0
  132. supernote/server/utils/url_signer.py +218 -0
  133. supernote-0.13.6.dist-info/METADATA +183 -0
  134. supernote-0.13.6.dist-info/RECORD +138 -0
  135. supernote-0.13.6.dist-info/WHEEL +5 -0
  136. supernote-0.13.6.dist-info/entry_points.txt +3 -0
  137. supernote-0.13.6.dist-info/licenses/LICENSE +201 -0
  138. supernote-0.13.6.dist-info/top_level.txt +1 -0
@@ -0,0 +1,276 @@
1
+ """Equipment related API data models mirroring OpenAPI Spec.
2
+
3
+ The following endpoints are supported:
4
+ - /api/terminal/user/activateEquipment
5
+ - /api/terminal/user/bindEquipment
6
+ - /api/terminal/equipment/unlink
7
+ - /api/equipment/bind/status
8
+ - /api/equipment/query/by/equipmentno
9
+ - /api/equipment/manual/deleteApi
10
+ - /api/equipment/query/by/{userId}
11
+ """
12
+
13
+ from dataclasses import dataclass, field
14
+
15
+ from mashumaro import field_options
16
+ from mashumaro.config import BaseConfig
17
+ from mashumaro.mixins.json import DataClassJSONMixin
18
+
19
+ from .base import BaseResponse, BooleanEnum
20
+
21
+
22
+ @dataclass
23
+ class ActivateEquipmentDTO(DataClassJSONMixin):
24
+ """Request to activate equipment.
25
+
26
+ Used by:
27
+ /api/terminal/user/activateEquipment (POST)
28
+ """
29
+
30
+ equipment_no: str = field(metadata=field_options(alias="equipmentNo"))
31
+ """Device serial number."""
32
+
33
+ class Config(BaseConfig):
34
+ serialize_by_alias = True
35
+
36
+
37
+ @dataclass
38
+ class BindEquipmentDTO(DataClassJSONMixin):
39
+ """Request to bind equipment.
40
+
41
+ Used by:
42
+ /api/terminal/user/bindEquipment (POST)
43
+ """
44
+
45
+ equipment_no: str = field(metadata=field_options(alias="equipmentNo"))
46
+ """Device serial number."""
47
+
48
+ account: str
49
+ """User account."""
50
+
51
+ name: str
52
+ """Device name."""
53
+
54
+ total_capacity: str = field(metadata=field_options(alias="totalCapacity"))
55
+ """Total device capacity."""
56
+
57
+ flag: str | None = None
58
+ """Identifier (Fixed value: 1)."""
59
+
60
+ label: list[str] = field(default_factory=list)
61
+ """Labels."""
62
+
63
+ class Config(BaseConfig):
64
+ serialize_by_alias = True
65
+
66
+
67
+ @dataclass
68
+ class UnbindEquipmentDTO(DataClassJSONMixin):
69
+ """Request to unbind equipment.
70
+
71
+ Used by:
72
+ /api/terminal/equipment/unlink (POST)
73
+ """
74
+
75
+ equipment_no: str = field(metadata=field_options(alias="equipmentNo"))
76
+ """Device serial number."""
77
+
78
+ class Config(BaseConfig):
79
+ serialize_by_alias = True
80
+
81
+
82
+ @dataclass
83
+ class QueryEquipmentDTO(DataClassJSONMixin):
84
+ """Request to query equipment list.
85
+
86
+ Used by:
87
+ /api/equipment/query/user/equipment/deleteApi (POST)
88
+ """
89
+
90
+ page_no: str = field(metadata=field_options(alias="pageNo"))
91
+ """Page number."""
92
+
93
+ page_size: str = field(metadata=field_options(alias="pageSize"))
94
+ """Page size."""
95
+
96
+ equipment_number: str | None = field(
97
+ metadata=field_options(alias="equipmentNumber"), default=None
98
+ )
99
+ """Equipment number."""
100
+
101
+ firmware_version: str | None = field(
102
+ metadata=field_options(alias="firmwareVersion"), default=None
103
+ )
104
+ """Firmware version."""
105
+
106
+ country_code: str | None = field(
107
+ metadata=field_options(alias="countryCode"), default=None
108
+ )
109
+ """Country code."""
110
+
111
+ telephone: str | None = field(default=None)
112
+ """Telephone."""
113
+
114
+ email: str | None = field(default=None)
115
+ """Email."""
116
+
117
+ class Config(BaseConfig):
118
+ serialize_by_alias = True
119
+
120
+
121
+ @dataclass
122
+ class UserEquipmentDTO(DataClassJSONMixin):
123
+ """Request to query user equipment.
124
+
125
+ Used by:
126
+ /api/equipment/query/by/equipmentno (POST)
127
+ """
128
+
129
+ equipment_no: str = field(metadata=field_options(alias="equipmentNo"))
130
+ """Device serial number."""
131
+
132
+ class Config(BaseConfig):
133
+ serialize_by_alias = True
134
+
135
+
136
+ @dataclass
137
+ class EquipmentManualDTO(DataClassJSONMixin):
138
+ """Request for equipment manual.
139
+
140
+ Used by:
141
+ /api/equipment/manual/deleteApi (POST)
142
+ """
143
+
144
+ equipment_no: str = field(metadata=field_options(alias="equipmentNo"))
145
+ """Device serial number."""
146
+
147
+ language: str
148
+ """Language (JP, CN, HK, EN)."""
149
+
150
+ logic_version: str = field(metadata=field_options(alias="logicVersion"))
151
+ """Logic version number."""
152
+
153
+ class Config(BaseConfig):
154
+ serialize_by_alias = True
155
+
156
+
157
+ @dataclass(kw_only=True)
158
+ class BindStatusVO(BaseResponse):
159
+ """Response for bind status.
160
+
161
+ Used by:
162
+ /api/equipment/bind/status (POST)
163
+ """
164
+
165
+ bind_status: bool | None = field(
166
+ metadata=field_options(alias="bindStatus"), default=None
167
+ )
168
+ """Bind status (true: bound, false: unbound)."""
169
+
170
+
171
+ @dataclass(kw_only=True)
172
+ class EquipmentManualVO(BaseResponse):
173
+ """Response for equipment manual.
174
+
175
+ Used by:
176
+ /api/equipment/manual/deleteApi (POST)
177
+ """
178
+
179
+ equipment_no: str | None = field(
180
+ metadata=field_options(alias="equipmentNo"), default=None
181
+ )
182
+ url: str | None = None
183
+ md5: str | None = None
184
+ file_name: str | None = field(
185
+ metadata=field_options(alias="fileName"), default=None
186
+ )
187
+ version: str | None = None
188
+
189
+
190
+ @dataclass
191
+ class EquipmentVO(DataClassJSONMixin):
192
+ """Equipment details object."""
193
+
194
+ equipment_number: str | None = field(
195
+ metadata=field_options(alias="equipmentNumber"), default=None
196
+ )
197
+ firmware_version: str | None = field(
198
+ metadata=field_options(alias="firmwareVersion"), default=None
199
+ )
200
+ update_status: str | None = field(
201
+ metadata=field_options(alias="updateStatus"), default=None
202
+ )
203
+ remark: str | None = None
204
+
205
+ class Config(BaseConfig):
206
+ serialize_by_alias = True
207
+
208
+
209
+ @dataclass(kw_only=True)
210
+ class UserEquipmentVO(BaseResponse):
211
+ """User equipment details response.
212
+
213
+ Used by:
214
+ /api/equipment/query/by/equipmentno (POST)
215
+ """
216
+
217
+ equipment_number: str | None = field(
218
+ metadata=field_options(alias="equipmentNumber"), default=None
219
+ )
220
+ user_id: int | None = field(metadata=field_options(alias="userId"), default=None)
221
+ name: str | None = None
222
+ status: str | None = None
223
+
224
+
225
+ @dataclass(kw_only=True)
226
+ class UserEquipmentListVO(BaseResponse):
227
+ """List of user equipment.
228
+
229
+ Used by:
230
+ /api/equipment/query/by/{userId} (GET)
231
+ """
232
+
233
+ equipment_vo_list: list[UserEquipmentVO] = field(
234
+ metadata=field_options(alias="equipmentVOList"), default_factory=list
235
+ )
236
+
237
+
238
+ @dataclass
239
+ class QueryEquipmentVO(DataClassJSONMixin):
240
+ """Detailed equipment query response object."""
241
+
242
+ user_id: str | None = field(metadata=field_options(alias="userId"), default=None)
243
+ equipment_number: str | None = field(
244
+ metadata=field_options(alias="equipmentNumber"), default=None
245
+ )
246
+ name: str | None = None
247
+ firmware_version: str | None = field(
248
+ metadata=field_options(alias="firmwareVersion"), default=None
249
+ )
250
+ create_time: int | None = field(
251
+ metadata=field_options(alias="createTime"), default=None
252
+ )
253
+ activate_time: int | None = field(
254
+ metadata=field_options(alias="activateTime"), default=None
255
+ )
256
+ country_code: str | None = field(
257
+ metadata=field_options(alias="countryCode"), default=None
258
+ )
259
+ telephone: str | None = None
260
+ email: str | None = None
261
+ status: BooleanEnum | None = None
262
+ """Device status (e.g., Y: Active, N: Inactive)."""
263
+
264
+ update_status: str | None = field(
265
+ metadata=field_options(alias="updateStatus"), default=None
266
+ )
267
+ """Firmware update status."""
268
+
269
+ remark: str | None = None
270
+ """Remark or note."""
271
+ file_server: str | None = field(
272
+ metadata=field_options(alias="fileServer"), default=None
273
+ )
274
+
275
+ class Config(BaseConfig):
276
+ serialize_by_alias = True
@@ -0,0 +1,124 @@
1
+ """Module for server-specific extension models.
2
+
3
+ These are for APIs that are not part of the standard API offering, specific
4
+ to our new server.
5
+ """
6
+
7
+ from dataclasses import dataclass, field
8
+
9
+ from mashumaro import field_options
10
+ from mashumaro.config import BaseConfig
11
+ from mashumaro.mixins.json import DataClassJSONMixin
12
+
13
+ from supernote.models.base import BaseResponse, ProcessingStatus
14
+ from supernote.models.summary import SummaryItem
15
+
16
+
17
+ @dataclass
18
+ class WebSummaryListRequestDTO(DataClassJSONMixin):
19
+ """Request DTO for listing summaries by file ID (Web Extension)."""
20
+
21
+ file_id: int = field(metadata=field_options(alias="fileId"))
22
+ """The ID of the file to list summaries for."""
23
+
24
+ class Config(BaseConfig):
25
+ serialize_by_alias = True
26
+
27
+
28
+ @dataclass
29
+ class WebSummaryListVO(BaseResponse):
30
+ """Response VO for listing summaries (Web Extension).
31
+
32
+ Used by: POST /api/extended/file/summary/list
33
+ """
34
+
35
+ summary_do_list: list[SummaryItem] = field(
36
+ metadata=field_options(alias="summaryDOList"), default_factory=list
37
+ )
38
+ """List of summary items found for the file."""
39
+
40
+ total_records: int = field(metadata=field_options(alias="totalRecords"), default=0)
41
+ """Total count of summaries returned."""
42
+
43
+ class Config(BaseConfig):
44
+ serialize_by_alias = True
45
+
46
+
47
+ @dataclass
48
+ class SystemTaskVO(DataClassJSONMixin):
49
+ """VO for a system processing task.
50
+
51
+ Used by: GET /api/extended/system/tasks
52
+ """
53
+
54
+ id: int
55
+ """The unique ID of the system task."""
56
+
57
+ file_id: int = field(metadata=field_options(alias="fileId"))
58
+ """The ID of the file associated with this task."""
59
+
60
+ task_type: str = field(metadata=field_options(alias="taskType"))
61
+ """The type of task (e.g. 'OCR', 'SUMMARY')."""
62
+
63
+ key: str
64
+ """The specific key for the task (e.g. 'page_1', 'global')."""
65
+
66
+ status: ProcessingStatus
67
+ """The current status (PENDING, PROCESSING, COMPLETED, FAILED)."""
68
+
69
+ retry_count: int = field(metadata=field_options(alias="retryCount"))
70
+ """Number of times the task has been retried."""
71
+
72
+ update_time: int = field(metadata=field_options(alias="updateTime"))
73
+ """Timestamp of the last update (ms)."""
74
+
75
+ last_error: str | None = field(
76
+ metadata=field_options(alias="lastError"), default=None
77
+ )
78
+ """Error message from the last failure, if any."""
79
+
80
+ class Config(BaseConfig):
81
+ serialize_by_alias = True
82
+
83
+
84
+ @dataclass
85
+ class SystemTaskListVO(BaseResponse):
86
+ """Response VO for listing system tasks.
87
+
88
+ Used by: GET /api/extended/system/tasks
89
+ """
90
+
91
+ tasks: list[SystemTaskVO] = field(default_factory=list)
92
+ """List of recent system tasks."""
93
+
94
+ class Config(BaseConfig):
95
+ serialize_by_alias = True
96
+
97
+
98
+ @dataclass
99
+ class FileProcessingStatusDTO(DataClassJSONMixin):
100
+ """Request model for querying processing status of files.
101
+
102
+ Used by:
103
+ /api/extended/file/processing/status (POST)
104
+ """
105
+
106
+ file_ids: list[int] = field(metadata=field_options(alias="fileIds"))
107
+
108
+ class Config(BaseConfig):
109
+ serialize_by_alias = True
110
+
111
+
112
+ @dataclass
113
+ class FileProcessingStatusVO(BaseResponse):
114
+ """Response model for file processing status.
115
+
116
+ Used by:
117
+ /api/extended/file/processing/status (POST)
118
+ """
119
+
120
+ # Map of file_id -> status summary
121
+ # status: PENDING, PROCESSING, COMPLETED, FAILED
122
+ status_map: dict[str, ProcessingStatus] = field(
123
+ metadata=field_options(alias="statusMap"), default_factory=dict
124
+ )
@@ -0,0 +1,95 @@
1
+ from dataclasses import dataclass, field
2
+
3
+ from mashumaro import field_options
4
+ from mashumaro.config import BaseConfig
5
+ from mashumaro.mixins.json import DataClassJSONMixin
6
+
7
+ from .base import BaseEnum, BaseResponse
8
+
9
+
10
+ class FileSortOrder(str, BaseEnum):
11
+ """Sort order for file listing."""
12
+
13
+ FILENAME = "filename"
14
+ TIME = "time"
15
+ SIZE = "size"
16
+
17
+
18
+ class FileSortSequence(str, BaseEnum):
19
+ """Sort sequence for file listing."""
20
+
21
+ ASC = "asc"
22
+ DESC = "desc"
23
+
24
+
25
+ class DownloadType(str, BaseEnum):
26
+ """Download type."""
27
+
28
+ DOWNLOAD = "0"
29
+ SHARE = "1"
30
+
31
+
32
+ class UploadType(str, BaseEnum):
33
+ """Upload type."""
34
+
35
+ APP = "1"
36
+ CLOUD = "2"
37
+
38
+
39
+ @dataclass
40
+ class EntriesVO(DataClassJSONMixin):
41
+ """Object representing a file entry (Device)."""
42
+
43
+ id: str
44
+ name: str
45
+ tag: str = ""
46
+ path_display: str = field(metadata=field_options(alias="path_display"), default="")
47
+ content_hash: str | None = field(
48
+ metadata=field_options(alias="content_hash"), default=None
49
+ )
50
+ is_downloadable: bool = field(
51
+ metadata=field_options(alias="is_downloadable"), default=True
52
+ )
53
+ size: int = 0
54
+ last_update_time: int = field(
55
+ metadata=field_options(alias="lastUpdateTime"), default=0
56
+ )
57
+ parent_path: str = field(metadata=field_options(alias="parent_path"), default="")
58
+
59
+ class Config(BaseConfig):
60
+ serialize_by_alias = True
61
+
62
+
63
+ @dataclass
64
+ class FileUploadApplyLocalVO(BaseResponse):
65
+ """Response model containing upload credentials/URLs.
66
+
67
+ This is used by the following POST endpoint:
68
+ /api/file/upload/apply
69
+ /api/file/terminal/upload/apply
70
+ """
71
+
72
+ equipment_no: str | None = field(
73
+ metadata=field_options(alias="equipmentNo"), default=None
74
+ )
75
+ bucket_name: str | None = field(
76
+ metadata=field_options(alias="bucketName"), default=None
77
+ )
78
+ """In private clouds, typically 'supernote'."""
79
+
80
+ inner_name: str | None = field(
81
+ metadata=field_options(alias="innerName"), default=None
82
+ )
83
+ """Obfuscated storage key. Formula: {UUID}-{tail}.{ext} where tail is SN last 3 digits."""
84
+
85
+ x_amz_date: str | None = field(
86
+ metadata=field_options(alias="xAmzDate"), default=None
87
+ )
88
+ authorization: str | None = None
89
+ """The signature for the upload request which should be passed in the x-access-token header."""
90
+ full_upload_url: str | None = field(
91
+ metadata=field_options(alias="fullUploadUrl"), default=None
92
+ )
93
+ part_upload_url: str | None = field(
94
+ metadata=field_options(alias="partUploadUrl"), default=None
95
+ )