bearcli 1.0.0__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.
- bearcli/__init__.py +0 -0
- bearcli/actions.py +71 -0
- bearcli/cli.py +788 -0
- bearcli/db.py +260 -0
- bearcli/export.py +250 -0
- bearcli/search.py +121 -0
- bearcli-1.0.0.dist-info/METADATA +159 -0
- bearcli-1.0.0.dist-info/RECORD +11 -0
- bearcli-1.0.0.dist-info/WHEEL +4 -0
- bearcli-1.0.0.dist-info/entry_points.txt +3 -0
- bearcli-1.0.0.dist-info/licenses/LICENSE +21 -0
bearcli/__init__.py
ADDED
|
File without changes
|
bearcli/actions.py
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""Write actions via Bear's x-callback-url scheme.
|
|
2
|
+
|
|
3
|
+
The database stays strictly read-only; all mutations go through Bear's own
|
|
4
|
+
URL API (which launches the app if needed). Calls are fire-and-forget — Bear
|
|
5
|
+
gives no result back — so callers verify outcomes by re-reading the database.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import subprocess
|
|
11
|
+
import time
|
|
12
|
+
from collections.abc import Callable
|
|
13
|
+
from urllib.parse import quote, urlencode
|
|
14
|
+
|
|
15
|
+
BASE_URL = "bear://x-callback-url/"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def call_bear(action: str, foreground: bool = False, **params: str | None) -> None:
|
|
19
|
+
query = urlencode({k: v for k, v in params.items() if v is not None}, quote_via=quote)
|
|
20
|
+
# -g keeps Bear in the background instead of stealing focus.
|
|
21
|
+
cmd = ["open", f"{BASE_URL}{action}?{query}"] if foreground else ["open", "-g", f"{BASE_URL}{action}?{query}"]
|
|
22
|
+
subprocess.run(cmd, check=True)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def create_note(title: str, text: str | None = None, tags: list[str] | None = None) -> None:
|
|
26
|
+
call_bear(
|
|
27
|
+
"create",
|
|
28
|
+
title=title,
|
|
29
|
+
text=text,
|
|
30
|
+
tags=",".join(tags) if tags else None,
|
|
31
|
+
open_note="no",
|
|
32
|
+
show_window="no",
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def add_text(note_id: str, text: str, mode: str = "append") -> None:
|
|
37
|
+
call_bear("add-text", id=note_id, text=text, mode=mode, open_note="no", show_window="no")
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def add_file(note_id: str, filename: str, file_b64: str) -> None:
|
|
41
|
+
call_bear("add-file", id=note_id, filename=filename, file=file_b64, mode="append", open_note="no", show_window="no")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def rename_tag(name: str, new_name: str) -> None:
|
|
45
|
+
call_bear("rename-tag", name=name, new_name=new_name, show_window="no")
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def delete_tag(name: str) -> None:
|
|
49
|
+
call_bear("delete-tag", name=name, show_window="no")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def open_note(note_id: str, new_window: bool = False) -> None:
|
|
53
|
+
call_bear("open-note", foreground=True, id=note_id, new_window="yes" if new_window else "no")
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def trash_note(note_id: str) -> None:
|
|
57
|
+
call_bear("trash", id=note_id, show_window="no")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def archive_note(note_id: str) -> None:
|
|
61
|
+
call_bear("archive", id=note_id, show_window="no")
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def wait_for(predicate: Callable[[], bool], timeout: float = 6.0, interval: float = 0.3) -> bool:
|
|
65
|
+
"""Poll until predicate() is true; Bear applies URL actions asynchronously."""
|
|
66
|
+
deadline = time.monotonic() + timeout
|
|
67
|
+
while time.monotonic() < deadline:
|
|
68
|
+
if predicate():
|
|
69
|
+
return True
|
|
70
|
+
time.sleep(interval)
|
|
71
|
+
return predicate()
|