notesctl 1.0.0__tar.gz → 1.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. {notesctl-1.0.0 → notesctl-1.0.1}/CHANGELOG.md +10 -1
  2. {notesctl-1.0.0 → notesctl-1.0.1}/PKG-INFO +1 -1
  3. {notesctl-1.0.0 → notesctl-1.0.1}/pyproject.toml +1 -1
  4. {notesctl-1.0.0 → notesctl-1.0.1}/src/notesctl/__init__.py +1 -1
  5. {notesctl-1.0.0 → notesctl-1.0.1}/src/notesctl/database/connection.py +19 -8
  6. {notesctl-1.0.0 → notesctl-1.0.1}/src/notesctl/database/queries.py +7 -2
  7. {notesctl-1.0.0 → notesctl-1.0.1}/src/notesctl/parser/note_parser.py +6 -3
  8. {notesctl-1.0.0 → notesctl-1.0.1}/uv.lock +1 -1
  9. {notesctl-1.0.0 → notesctl-1.0.1}/.github/workflows/ci.yml +0 -0
  10. {notesctl-1.0.0 → notesctl-1.0.1}/.github/workflows/publish.yml +0 -0
  11. {notesctl-1.0.0 → notesctl-1.0.1}/.gitignore +0 -0
  12. {notesctl-1.0.0 → notesctl-1.0.1}/LICENSE +0 -0
  13. {notesctl-1.0.0 → notesctl-1.0.1}/README.md +0 -0
  14. {notesctl-1.0.0 → notesctl-1.0.1}/proto/notestore.proto +0 -0
  15. {notesctl-1.0.0 → notesctl-1.0.1}/src/notesctl/cli.py +0 -0
  16. {notesctl-1.0.0 → notesctl-1.0.1}/src/notesctl/converter/__init__.py +0 -0
  17. {notesctl-1.0.0 → notesctl-1.0.1}/src/notesctl/converter/markdown.py +0 -0
  18. {notesctl-1.0.0 → notesctl-1.0.1}/src/notesctl/database/__init__.py +0 -0
  19. {notesctl-1.0.0 → notesctl-1.0.1}/src/notesctl/database/models.py +0 -0
  20. {notesctl-1.0.0 → notesctl-1.0.1}/src/notesctl/exporter.py +0 -0
  21. {notesctl-1.0.0 → notesctl-1.0.1}/src/notesctl/parser/__init__.py +0 -0
  22. {notesctl-1.0.0 → notesctl-1.0.1}/src/notesctl/parser/protobuf/__init__.py +0 -0
  23. {notesctl-1.0.0 → notesctl-1.0.1}/src/notesctl/parser/protobuf/notestore_pb2.py +0 -0
  24. {notesctl-1.0.0 → notesctl-1.0.1}/tests/__init__.py +0 -0
  25. {notesctl-1.0.0 → notesctl-1.0.1}/tests/test_connection.py +0 -0
  26. {notesctl-1.0.0 → notesctl-1.0.1}/tests/test_converter.py +0 -0
  27. {notesctl-1.0.0 → notesctl-1.0.1}/tests/test_models.py +0 -0
  28. {notesctl-1.0.0 → notesctl-1.0.1}/tests/test_parser.py +0 -0
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.0.1] - 2026-01-17
11
+
12
+ ### Fixed
13
+
14
+ - Fixed mypy strict type checking errors across database and parser modules
15
+ - Added proper type annotations for tuple parameters and return types
16
+ - Fixed type-checking imports to satisfy ruff TC rules
17
+
10
18
  ## [1.0.0] - 2026-01-17
11
19
 
12
20
  ### Added
@@ -34,5 +42,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
34
42
  - Original Notes database is never modified
35
43
  - All queries validated to be SELECT statements only
36
44
 
37
- [Unreleased]: https://github.com/jwmoss/notesctl/compare/v1.0.0...HEAD
45
+ [Unreleased]: https://github.com/jwmoss/notesctl/compare/v1.0.1...HEAD
46
+ [1.0.1]: https://github.com/jwmoss/notesctl/compare/v1.0.0...v1.0.1
38
47
  [1.0.0]: https://github.com/jwmoss/notesctl/releases/tag/v1.0.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: notesctl
3
- Version: 1.0.0
3
+ Version: 1.0.1
4
4
  Summary: Export Apple iCloud Notes to Markdown files safely
5
5
  Project-URL: Homepage, https://github.com/jwmoss/notesctl
6
6
  Project-URL: Repository, https://github.com/jwmoss/notesctl
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "notesctl"
7
- version = "1.0.0"
7
+ version = "1.0.1"
8
8
  description = "Export Apple iCloud Notes to Markdown files safely"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -1,3 +1,3 @@
1
1
  """iCloud Notes to Markdown Exporter."""
2
2
 
3
- __version__ = "1.0.0"
3
+ __version__ = "1.0.1"
@@ -1,14 +1,19 @@
1
1
  """Safe read-only database connection for Apple Notes."""
2
2
 
3
+ from __future__ import annotations
4
+
3
5
  import shutil
4
6
  import sqlite3
5
7
  import tempfile
6
- from collections.abc import Iterator
7
8
  from contextlib import contextmanager
8
9
  from pathlib import Path
10
+ from typing import TYPE_CHECKING, Any
9
11
 
10
12
  from rich.console import Console
11
13
 
14
+ if TYPE_CHECKING:
15
+ from collections.abc import Iterator
16
+
12
17
  console = Console()
13
18
 
14
19
  # Default location of the Apple Notes database
@@ -100,7 +105,7 @@ class SafeNotesDatabase:
100
105
  raise RuntimeError("Database not connected. Call connect() first.")
101
106
  return self._connection
102
107
 
103
- def execute(self, query: str, params: tuple = ()) -> sqlite3.Cursor:
108
+ def execute(self, query: str, params: tuple[Any, ...] = ()) -> sqlite3.Cursor:
104
109
  """
105
110
  Execute a SELECT query safely.
106
111
 
@@ -121,20 +126,26 @@ class SafeNotesDatabase:
121
126
 
122
127
  return self.connection.execute(query, params)
123
128
 
124
- def fetchall(self, query: str, params: tuple = ()) -> list[sqlite3.Row]:
129
+ def fetchall(self, query: str, params: tuple[Any, ...] = ()) -> list[sqlite3.Row]:
125
130
  """Execute a query and fetch all results."""
126
- return self.execute(query, params).fetchall()
131
+ return list(self.execute(query, params).fetchall())
127
132
 
128
- def fetchone(self, query: str, params: tuple = ()) -> sqlite3.Row | None:
133
+ def fetchone(self, query: str, params: tuple[Any, ...] = ()) -> sqlite3.Row | None:
129
134
  """Execute a query and fetch one result."""
130
- return self.execute(query, params).fetchone()
135
+ result: sqlite3.Row | None = self.execute(query, params).fetchone()
136
+ return result
131
137
 
132
- def __enter__(self) -> "SafeNotesDatabase":
138
+ def __enter__(self) -> SafeNotesDatabase:
133
139
  """Context manager entry."""
134
140
  self.connect()
135
141
  return self
136
142
 
137
- def __exit__(self, exc_type, exc_val, exc_tb) -> None:
143
+ def __exit__(
144
+ self,
145
+ exc_type: type[BaseException] | None,
146
+ exc_val: BaseException | None,
147
+ exc_tb: Any,
148
+ ) -> None:
138
149
  """Context manager exit."""
139
150
  self.close()
140
151
 
@@ -1,11 +1,16 @@
1
1
  """SQL queries for reading Apple Notes data (SELECT only)."""
2
2
 
3
+ from __future__ import annotations
4
+
3
5
  from datetime import UTC, datetime
4
6
  from pathlib import Path
7
+ from typing import TYPE_CHECKING, Any
5
8
 
6
- from .connection import SafeNotesDatabase
7
9
  from .models import Attachment, Folder, Note
8
10
 
11
+ if TYPE_CHECKING:
12
+ from .connection import SafeNotesDatabase
13
+
9
14
  # Apple's Core Data timestamp epoch (2001-01-01 00:00:00 UTC)
10
15
  APPLE_EPOCH = datetime(2001, 1, 1, tzinfo=UTC)
11
16
 
@@ -114,7 +119,7 @@ class NotesQueries:
114
119
  WHERE n.ZTITLE1 IS NOT NULL
115
120
  """
116
121
 
117
- params: list = []
122
+ params: list[Any] = []
118
123
 
119
124
  if folder_id is not None:
120
125
  query += " AND n.ZFOLDER = ?"
@@ -1,10 +1,13 @@
1
1
  """Parser for Apple Notes gzip-compressed protobuf content."""
2
2
 
3
+ from __future__ import annotations
4
+
3
5
  import gzip
4
6
  from dataclasses import dataclass, field
5
7
  from enum import IntEnum
8
+ from typing import Any
6
9
 
7
- from .protobuf.notestore_pb2 import NoteStoreProto
10
+ from .protobuf.notestore_pb2 import NoteStoreProto # type: ignore[attr-defined]
8
11
 
9
12
 
10
13
  class StyleType(IntEnum):
@@ -69,7 +72,7 @@ class ParsedNote:
69
72
  class NoteParser:
70
73
  """Parser for Apple Notes protobuf content."""
71
74
 
72
- def __init__(self):
75
+ def __init__(self) -> None:
73
76
  """Initialize the parser."""
74
77
  self._numbered_list_counters: dict[int, int] = {}
75
78
 
@@ -104,7 +107,7 @@ class NoteParser:
104
107
 
105
108
  return self._parse_proto(proto, title)
106
109
 
107
- def _parse_proto(self, proto: NoteStoreProto, title: str) -> ParsedNote:
110
+ def _parse_proto(self, proto: Any, title: str) -> ParsedNote:
108
111
  """Parse the protobuf message into structured content."""
109
112
  note = ParsedNote(title=title)
110
113
 
@@ -361,7 +361,7 @@ wheels = [
361
361
 
362
362
  [[package]]
363
363
  name = "notesctl"
364
- version = "0.1.0"
364
+ version = "1.0.1"
365
365
  source = { editable = "." }
366
366
  dependencies = [
367
367
  { name = "pillow" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes