51 lines
1.6 KiB
Python
51 lines
1.6 KiB
Python
#!/usr/bin/env python3
|
|
"""Example: replace children of a named bookmark folder from a small JSON list.
|
|
|
|
This is not a sync engine. It finds one folder by title, deletes its children,
|
|
and creates the supplied bookmarks. See AGENTS.md.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
sys.path.insert(0, str(ROOT / "tools"))
|
|
from client import call # noqa: E402
|
|
|
|
|
|
def find_folder(title: str) -> dict:
|
|
hits = call("bookmarks.search", [{"title": title}])
|
|
folders = [n for n in hits if not n.get("url")]
|
|
if not folders:
|
|
raise SystemExit(f"folder not found: {title}")
|
|
if len(folders) > 1:
|
|
raise SystemExit(f"multiple folders titled {title!r}; pass a unique name")
|
|
return folders[0]
|
|
|
|
|
|
def main() -> int:
|
|
if len(sys.argv) != 3:
|
|
print("usage: replace_named_folder.py FOLDER_TITLE items.json", file=sys.stderr)
|
|
return 2
|
|
title = sys.argv[1]
|
|
items = json.loads(Path(sys.argv[2]).read_text(encoding="utf-8"))
|
|
folder = find_folder(title)
|
|
for child in call("bookmarks.getChildren", [folder["id"]]):
|
|
if child.get("url"):
|
|
call("bookmarks.remove", [child["id"]])
|
|
else:
|
|
call("bookmarks.removeTree", [child["id"]])
|
|
for item in items:
|
|
call(
|
|
"bookmarks.create",
|
|
[{"parentId": folder["id"], "title": item["title"], "url": item["url"]}],
|
|
)
|
|
print(f"replaced {len(items)} bookmarks in {title!r} ({folder['id']})")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|