supernote 0.22.0__tar.gz → 0.23.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.22.0 → supernote-0.23.0}/PKG-INFO +1 -1
- {supernote-0.22.0 → supernote-0.23.0}/pyproject.toml +1 -1
- supernote-0.23.0/supernote/alembic/versions/68964804740d_prevent_user_id_reuse.py +74 -0
- supernote-0.23.0/supernote/server/db/migrations.py +109 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/db/models/user.py +2 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/static/index.html +1 -1
- {supernote-0.22.0 → supernote-0.23.0}/supernote.egg-info/PKG-INFO +1 -1
- {supernote-0.22.0 → supernote-0.23.0}/supernote.egg-info/SOURCES.txt +1 -0
- supernote-0.22.0/supernote/server/db/migrations.py +0 -44
- {supernote-0.22.0 → supernote-0.23.0}/LICENSE +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/README.md +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/setup.cfg +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/__init__.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/alembic/__init__.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/alembic/env.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/alembic/script.py.mako +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/alembic/versions/0543a383957b_initial_schema.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/alembic/versions/7a8291f043bc_add_links_and_sort_fields_to_schedule_task.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/alembic/versions/b8e9c0d1e2f3_backfill_summary_md5_and_timestamps.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/alembic/versions/d1e2f3a4b5c6_add_client_task_ids.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/alembic.ini +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/cli/__init__.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/cli/admin.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/cli/client.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/cli/main.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/cli/notebook.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/cli/server.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/client/__init__.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/client/admin.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/client/api.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/client/auth.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/client/client.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/client/device.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/client/exceptions.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/client/extended.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/client/hashing.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/client/login_client.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/client/schedule.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/client/socket.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/client/summary.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/client/web.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/models/__init__.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/models/auth.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/models/base.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/models/equipment.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/models/extended.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/models/file_common.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/models/file_device.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/models/file_web.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/models/schedule.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/models/socket.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/models/summary.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/models/system.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/models/user.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/notebook/__init__.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/notebook/color.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/notebook/converter.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/notebook/decoder.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/notebook/exceptions.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/notebook/fileformat.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/notebook/manipulator.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/notebook/parser.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/notebook/utils.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/py.typed +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/__init__.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/app.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/config.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/constants.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/db/__init__.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/db/base.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/db/models/__init__.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/db/models/device.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/db/models/file.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/db/models/kv.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/db/models/login_record.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/db/models/note_processing.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/db/models/schedule.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/db/models/summary.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/db/session.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/events.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/exceptions.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/mcp/__init__.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/mcp/auth.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/mcp/models.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/mcp/server.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/metrics.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/resources/__init__.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/resources/prompts/__init__.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/resources/prompts/ocr/common/context.md +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/resources/prompts/ocr/common/legend.md +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/resources/prompts/ocr/daily/prompt.md +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/resources/prompts/ocr/default/system.md +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/resources/prompts/ocr/monthly/prompt.md +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/resources/prompts/ocr/weekly/prompt.md +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/resources/prompts/summary/common/instruction.md +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/resources/prompts/summary/daily/prompt.md +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/resources/prompts/summary/default/prompt.md +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/resources/prompts/summary/monthly/prompt.md +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/resources/prompts/summary/weekly/prompt.md +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/routes/admin.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/routes/auth.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/routes/decorators.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/routes/extended.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/routes/file_device.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/routes/file_web.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/routes/oss.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/routes/schedule.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/routes/summary.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/routes/system.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/services/__init__.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/services/blob.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/services/coordination.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/services/file.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/services/gemini.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/services/ical_export.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/services/integrity.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/services/processor.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/services/processor_modules/__init__.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/services/processor_modules/gemini_embedding.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/services/processor_modules/gemini_ocr.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/services/processor_modules/page_hashing.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/services/processor_modules/png_conversion.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/services/processor_modules/summary.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/services/schedule.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/services/search.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/services/summary.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/services/user.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/services/vfs.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/socket.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/socket_auth.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/static/favicon.ico +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/static/js/api/client.js +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/static/js/api/schedule.js +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/static/js/components/DashboardView.js +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/static/js/components/FileCard.js +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/static/js/components/FileViewer.js +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/static/js/components/LoginCard.js +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/static/js/components/MoveModal.js +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/static/js/components/RenameModal.js +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/static/js/components/SearchModal.js +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/static/js/components/Sidebar.js +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/static/js/components/SummaryPanel.js +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/static/js/components/SystemPanel.js +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/static/js/components/TaskPanel.js +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/static/js/composables/useFileSystem.js +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/static/js/composables/useSchedule.js +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/static/js/main.js +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/static/style.css +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/utils/auth_utils.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/utils/gemini_content.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/utils/hashing.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/utils/note_content.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/utils/paths.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/utils/prompt_loader.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/utils/rate_limit.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/utils/tasks.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/utils/unique_id.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/server/utils/url_signer.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/testing/__init__.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote/testing/server_runner.py +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote.egg-info/dependency_links.txt +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote.egg-info/entry_points.txt +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote.egg-info/requires.txt +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/supernote.egg-info/top_level.txt +0 -0
- {supernote-0.22.0 → supernote-0.23.0}/tests/test_init.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: supernote
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.23.0
|
|
4
4
|
Summary: All-in-one toolkit for Supernote devices: parse notebooks, self-host services, access services
|
|
5
5
|
Author-email: jya <jya@wizmy.net>, Allen Porter <allen.porter@gmail.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -4,7 +4,7 @@ requires = ["setuptools>=77.0"]
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "supernote"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.23.0"
|
|
8
8
|
license = "Apache-2.0"
|
|
9
9
|
license-files = ["LICENSE"]
|
|
10
10
|
description = "All-in-one toolkit for Supernote devices: parse notebooks, self-host services, access services"
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""Prevent reuse of deleted SQLite user IDs.
|
|
2
|
+
|
|
3
|
+
Revision ID: 68964804740d
|
|
4
|
+
Revises: d1e2f3a4b5c6
|
|
5
|
+
Create Date: 2026-09-03 00:00:00.000000
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Sequence, Union
|
|
9
|
+
|
|
10
|
+
from alembic import op
|
|
11
|
+
from sqlalchemy import text
|
|
12
|
+
|
|
13
|
+
revision: str = "68964804740d"
|
|
14
|
+
down_revision: Union[str, None] = "d1e2f3a4b5c6"
|
|
15
|
+
branch_labels: Union[str, Sequence[str], None] = None
|
|
16
|
+
depends_on: Union[str, Sequence[str], None] = None
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def upgrade() -> None:
|
|
20
|
+
bind = op.get_bind()
|
|
21
|
+
if bind.dialect.name != "sqlite":
|
|
22
|
+
return
|
|
23
|
+
|
|
24
|
+
# Old deletions may have left owner rows behind. Preserve their highest user
|
|
25
|
+
# ID as part of the sequence floor so none can become visible after upgrade.
|
|
26
|
+
tables = (
|
|
27
|
+
"users",
|
|
28
|
+
"devices",
|
|
29
|
+
"login_records",
|
|
30
|
+
"f_user_file",
|
|
31
|
+
"f_capacity",
|
|
32
|
+
"f_recycle_file",
|
|
33
|
+
"f_summary",
|
|
34
|
+
"f_summary_tag",
|
|
35
|
+
"t_schedule_task",
|
|
36
|
+
"t_schedule_task_group",
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
def max_owner_id(table: str) -> int:
|
|
40
|
+
column = "id" if table == "users" else "user_id"
|
|
41
|
+
query = text(f'SELECT COALESCE(MAX({column}), 0) FROM "{table}"')
|
|
42
|
+
return int(bind.execute(query).scalar_one())
|
|
43
|
+
|
|
44
|
+
floor = max(max_owner_id(table) for table in tables)
|
|
45
|
+
|
|
46
|
+
with op.batch_alter_table(
|
|
47
|
+
"users", recreate="always", table_kwargs={"sqlite_autoincrement": True}
|
|
48
|
+
):
|
|
49
|
+
pass
|
|
50
|
+
|
|
51
|
+
current = int(
|
|
52
|
+
bind.execute(
|
|
53
|
+
text(
|
|
54
|
+
"SELECT COALESCE(MAX(seq), 0) FROM sqlite_sequence WHERE name = 'users'"
|
|
55
|
+
)
|
|
56
|
+
).scalar_one()
|
|
57
|
+
)
|
|
58
|
+
sequence = max(floor, current)
|
|
59
|
+
result = bind.execute(
|
|
60
|
+
text("UPDATE sqlite_sequence SET seq = :seq WHERE name = 'users'"),
|
|
61
|
+
{"seq": sequence},
|
|
62
|
+
)
|
|
63
|
+
if result.rowcount == 0:
|
|
64
|
+
bind.execute(
|
|
65
|
+
text("INSERT INTO sqlite_sequence(name, seq) VALUES ('users', :seq)"),
|
|
66
|
+
{"seq": sequence},
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def downgrade() -> None:
|
|
71
|
+
if op.get_bind().dialect.name != "sqlite":
|
|
72
|
+
return
|
|
73
|
+
with op.batch_alter_table("users", recreate="always"):
|
|
74
|
+
pass
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import importlib.resources
|
|
2
|
+
import logging
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
import alembic.command
|
|
6
|
+
import alembic.config
|
|
7
|
+
import sqlalchemy as sa
|
|
8
|
+
from alembic.migration import MigrationContext
|
|
9
|
+
from alembic.operations import Operations
|
|
10
|
+
from sqlalchemy.exc import OperationalError, ProgrammingError
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _heal_orphaned_v20_revision(db_url: str) -> None:
|
|
16
|
+
"""Detect and reconcile databases stamped with orphaned v0.20.0 revision c9a8b7c6d5e4.
|
|
17
|
+
|
|
18
|
+
In v0.20.0, migration c9a8b7c6d5e4 altered task_id and task_list_id to String,
|
|
19
|
+
but was superseded by d1e2f3a4b5c6 in subsequent releases. If detected, revert
|
|
20
|
+
the column types back to BigInteger and reset alembic_version to b8e9c0d1e2f3
|
|
21
|
+
so Alembic can cleanly upgrade forward to head.
|
|
22
|
+
"""
|
|
23
|
+
sync_url = db_url.replace("+aiosqlite", "").replace("+asyncpg", "")
|
|
24
|
+
engine = sa.create_engine(sync_url)
|
|
25
|
+
try:
|
|
26
|
+
with engine.connect() as conn:
|
|
27
|
+
inspector = sa.inspect(conn)
|
|
28
|
+
if "alembic_version" not in inspector.get_table_names():
|
|
29
|
+
return
|
|
30
|
+
|
|
31
|
+
current_revision = conn.execute(
|
|
32
|
+
sa.text("SELECT version_num FROM alembic_version")
|
|
33
|
+
).scalar()
|
|
34
|
+
if current_revision != "c9a8b7c6d5e4":
|
|
35
|
+
return
|
|
36
|
+
|
|
37
|
+
logger.warning(
|
|
38
|
+
"Detected orphaned v0.20.0 Alembic revision 'c9a8b7c6d5e4'. "
|
|
39
|
+
"Reconciling database schema back to 'b8e9c0d1e2f3'..."
|
|
40
|
+
)
|
|
41
|
+
migration_context = MigrationContext.configure(conn)
|
|
42
|
+
op = Operations(migration_context)
|
|
43
|
+
|
|
44
|
+
with op.batch_alter_table("t_schedule_task") as batch_op:
|
|
45
|
+
batch_op.alter_column(
|
|
46
|
+
"task_list_id", type_=sa.BigInteger(), existing_type=sa.String()
|
|
47
|
+
)
|
|
48
|
+
batch_op.alter_column(
|
|
49
|
+
"task_id", type_=sa.BigInteger(), existing_type=sa.String()
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
with op.batch_alter_table("t_schedule_task_group") as batch_op:
|
|
53
|
+
batch_op.alter_column(
|
|
54
|
+
"task_list_id", type_=sa.BigInteger(), existing_type=sa.String()
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
conn.execute(
|
|
58
|
+
sa.text(
|
|
59
|
+
"UPDATE alembic_version SET version_num = 'b8e9c0d1e2f3' WHERE version_num = 'c9a8b7c6d5e4'"
|
|
60
|
+
)
|
|
61
|
+
)
|
|
62
|
+
conn.commit()
|
|
63
|
+
logger.info(
|
|
64
|
+
"Successfully reconciled schema to 'b8e9c0d1e2f3'; proceeding with migration to head."
|
|
65
|
+
)
|
|
66
|
+
except (OperationalError, ProgrammingError) as exc:
|
|
67
|
+
logger.debug(
|
|
68
|
+
"Skipping v0.20.0 migration healing due to database check error: %s", exc
|
|
69
|
+
)
|
|
70
|
+
finally:
|
|
71
|
+
engine.dispose()
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def run_migrations(db_url: str, target_revision: str = "head") -> None:
|
|
75
|
+
"""Run pending database migrations using Alembic.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
db_url: The database connection URL to use for migrations.
|
|
79
|
+
This overrides the url in alembic.ini to ensure we target
|
|
80
|
+
the correct environment (prod, test, etc).
|
|
81
|
+
target_revision: Revision to migrate to (default: "head").
|
|
82
|
+
"""
|
|
83
|
+
# Locate alembic.ini inside the supernote package
|
|
84
|
+
traversable = importlib.resources.files("supernote") / "alembic.ini"
|
|
85
|
+
|
|
86
|
+
with importlib.resources.as_file(traversable) as ini_path:
|
|
87
|
+
if not ini_path.exists():
|
|
88
|
+
raise FileNotFoundError(f"Could not find alembic.ini at {ini_path}")
|
|
89
|
+
|
|
90
|
+
alembic_cfg = alembic.config.Config(str(ini_path))
|
|
91
|
+
|
|
92
|
+
# IMPORTANT: Override the URL with the one from the running application.
|
|
93
|
+
alembic_cfg.set_main_option("sqlalchemy.url", db_url)
|
|
94
|
+
# Don't let alembic reset our carefully configured logging
|
|
95
|
+
alembic_cfg.set_main_option("skip_logging_config", "true")
|
|
96
|
+
|
|
97
|
+
# Ensure the database directory exists because sqlite won't create it
|
|
98
|
+
if db_url.startswith("sqlite"):
|
|
99
|
+
# Extract path from sqlite+aiosqlite:///path or sqlite:///path
|
|
100
|
+
path_str = db_url.split(":///")[-1]
|
|
101
|
+
if path_str != ":memory:":
|
|
102
|
+
db_path = Path(path_str)
|
|
103
|
+
db_path.parent.mkdir(parents=True, exist_ok=True)
|
|
104
|
+
|
|
105
|
+
_heal_orphaned_v20_revision(db_url)
|
|
106
|
+
|
|
107
|
+
logger.info("Running database migrations to %s...", target_revision)
|
|
108
|
+
alembic.command.upgrade(alembic_cfg, target_revision)
|
|
109
|
+
logger.info("Database migrations complete.")
|
|
@@ -11,6 +11,8 @@ class UserDO(Base):
|
|
|
11
11
|
"""User database model."""
|
|
12
12
|
|
|
13
13
|
__tablename__ = "users"
|
|
14
|
+
# User ids should not be recycled
|
|
15
|
+
__table_args__ = {"sqlite_autoincrement": True}
|
|
14
16
|
|
|
15
17
|
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
16
18
|
email: Mapped[str] = mapped_column(String, unique=True, index=True)
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<title>Supernote Cloud - Web Viewer</title>
|
|
8
8
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
9
9
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/spark-md5/3.0.2/spark-md5.min.js"></script>
|
|
10
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-sha256/0.
|
|
10
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-sha256/1.0.0/sha256.min.js"></script>
|
|
11
11
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
|
12
12
|
<link rel="stylesheet" href="/static/style.css">
|
|
13
13
|
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: supernote
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.23.0
|
|
4
4
|
Summary: All-in-one toolkit for Supernote devices: parse notebooks, self-host services, access services
|
|
5
5
|
Author-email: jya <jya@wizmy.net>, Allen Porter <allen.porter@gmail.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -14,6 +14,7 @@ supernote/alembic/__init__.py
|
|
|
14
14
|
supernote/alembic/env.py
|
|
15
15
|
supernote/alembic/script.py.mako
|
|
16
16
|
supernote/alembic/versions/0543a383957b_initial_schema.py
|
|
17
|
+
supernote/alembic/versions/68964804740d_prevent_user_id_reuse.py
|
|
17
18
|
supernote/alembic/versions/7a8291f043bc_add_links_and_sort_fields_to_schedule_task.py
|
|
18
19
|
supernote/alembic/versions/b8e9c0d1e2f3_backfill_summary_md5_and_timestamps.py
|
|
19
20
|
supernote/alembic/versions/d1e2f3a4b5c6_add_client_task_ids.py
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import importlib.resources
|
|
2
|
-
import logging
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
|
|
5
|
-
import alembic.command
|
|
6
|
-
import alembic.config
|
|
7
|
-
|
|
8
|
-
logger = logging.getLogger(__name__)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def run_migrations(db_url: str, target_revision: str = "head") -> None:
|
|
12
|
-
"""Run pending database migrations using Alembic.
|
|
13
|
-
|
|
14
|
-
Args:
|
|
15
|
-
db_url: The database connection URL to use for migrations.
|
|
16
|
-
This overrides the url in alembic.ini to ensure we target
|
|
17
|
-
the correct environment (prod, test, etc).
|
|
18
|
-
target_revision: Revision to migrate to (default: "head").
|
|
19
|
-
"""
|
|
20
|
-
# Locate alembic.ini inside the supernote package
|
|
21
|
-
traversable = importlib.resources.files("supernote") / "alembic.ini"
|
|
22
|
-
|
|
23
|
-
with importlib.resources.as_file(traversable) as ini_path:
|
|
24
|
-
if not ini_path.exists():
|
|
25
|
-
raise FileNotFoundError(f"Could not find alembic.ini at {ini_path}")
|
|
26
|
-
|
|
27
|
-
alembic_cfg = alembic.config.Config(str(ini_path))
|
|
28
|
-
|
|
29
|
-
# IMPORTANT: Override the URL with the one from the running application.
|
|
30
|
-
alembic_cfg.set_main_option("sqlalchemy.url", db_url)
|
|
31
|
-
# Don't let alembic reset our carefully configured logging
|
|
32
|
-
alembic_cfg.set_main_option("skip_logging_config", "true")
|
|
33
|
-
|
|
34
|
-
# Ensure the database directory exists because sqlite won't create it
|
|
35
|
-
if db_url.startswith("sqlite"):
|
|
36
|
-
# Extract path from sqlite+aiosqlite:///path or sqlite:///path
|
|
37
|
-
path_str = db_url.split(":///")[-1]
|
|
38
|
-
if path_str != ":memory:":
|
|
39
|
-
db_path = Path(path_str)
|
|
40
|
-
db_path.parent.mkdir(parents=True, exist_ok=True)
|
|
41
|
-
|
|
42
|
-
logger.info("Running database migrations to %s...", target_revision)
|
|
43
|
-
alembic.command.upgrade(alembic_cfg, target_revision)
|
|
44
|
-
logger.info("Database migrations complete.")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{supernote-0.22.0 → supernote-0.23.0}/supernote/alembic/versions/0543a383957b_initial_schema.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{supernote-0.22.0 → supernote-0.23.0}/supernote/alembic/versions/d1e2f3a4b5c6_add_client_task_ids.py
RENAMED
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{supernote-0.22.0 → supernote-0.23.0}/supernote/server/resources/prompts/ocr/common/context.md
RENAMED
|
File without changes
|
{supernote-0.22.0 → supernote-0.23.0}/supernote/server/resources/prompts/ocr/common/legend.md
RENAMED
|
File without changes
|
{supernote-0.22.0 → supernote-0.23.0}/supernote/server/resources/prompts/ocr/daily/prompt.md
RENAMED
|
File without changes
|
{supernote-0.22.0 → supernote-0.23.0}/supernote/server/resources/prompts/ocr/default/system.md
RENAMED
|
File without changes
|
{supernote-0.22.0 → supernote-0.23.0}/supernote/server/resources/prompts/ocr/monthly/prompt.md
RENAMED
|
File without changes
|
{supernote-0.22.0 → supernote-0.23.0}/supernote/server/resources/prompts/ocr/weekly/prompt.md
RENAMED
|
File without changes
|
|
File without changes
|
{supernote-0.22.0 → supernote-0.23.0}/supernote/server/resources/prompts/summary/daily/prompt.md
RENAMED
|
File without changes
|
{supernote-0.22.0 → supernote-0.23.0}/supernote/server/resources/prompts/summary/default/prompt.md
RENAMED
|
File without changes
|
{supernote-0.22.0 → supernote-0.23.0}/supernote/server/resources/prompts/summary/monthly/prompt.md
RENAMED
|
File without changes
|
{supernote-0.22.0 → supernote-0.23.0}/supernote/server/resources/prompts/summary/weekly/prompt.md
RENAMED
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{supernote-0.22.0 → supernote-0.23.0}/supernote/server/services/processor_modules/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{supernote-0.22.0 → supernote-0.23.0}/supernote/server/services/processor_modules/gemini_ocr.py
RENAMED
|
File without changes
|
{supernote-0.22.0 → supernote-0.23.0}/supernote/server/services/processor_modules/page_hashing.py
RENAMED
|
File without changes
|
{supernote-0.22.0 → supernote-0.23.0}/supernote/server/services/processor_modules/png_conversion.py
RENAMED
|
File without changes
|
{supernote-0.22.0 → supernote-0.23.0}/supernote/server/services/processor_modules/summary.py
RENAMED
|
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
|
{supernote-0.22.0 → supernote-0.23.0}/supernote/server/static/js/components/DashboardView.js
RENAMED
|
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
|
{supernote-0.22.0 → supernote-0.23.0}/supernote/server/static/js/composables/useFileSystem.js
RENAMED
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|