mirror of
https://github.com/towishy/Owen-Graphite.git
synced 2026-07-22 04:40:30 +00:00
125 lines
4.1 KiB
Python
125 lines
4.1 KiB
Python
#!/usr/bin/env python3
|
|
"""Bundle and sync Owen Graphite v3 into an Obsidian theme folder.
|
|
|
|
Re-bundles src/ via bundle_v3.py, promotes the bundle to theme.css, and
|
|
copies the release assets into <vault>/.obsidian/themes/Owen Graphite.
|
|
|
|
Reload Obsidian (Ctrl+R) after sync.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import importlib.util
|
|
import shutil
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
THEME_FOLDER_NAME = "Owen Graphite"
|
|
RELEASE_ASSETS = [
|
|
"theme.css",
|
|
"manifest.json",
|
|
"README.md",
|
|
"CHANGELOG.md",
|
|
"LICENSE",
|
|
"screenshots/light.png",
|
|
"screenshots/dark.png",
|
|
"screenshots/readme/workspace-chrome-connected-glass.svg",
|
|
"screenshots/readme/top-tabs-liquid-glass.svg",
|
|
"screenshots/readme/workspace-writing-surface.jpg",
|
|
"screenshots/readme/style-settings-report-options.jpg",
|
|
"screenshots/readme/pdf-customer-delivery-feature.png",
|
|
"screenshots/readme/owen-editor-toolbar-settings.jpg",
|
|
"screenshots/readme/file-explorer-type-badges.svg",
|
|
"screenshots/readme/sponsor-coffee.svg",
|
|
]
|
|
DEFAULT_VAULTS = [
|
|
Path(r"H:\Owen-WIKI"),
|
|
Path(r"H:\Obsidian"),
|
|
Path(r"D:\JAELE\Obsidian"),
|
|
Path.home() / "Work" / "Obsidian",
|
|
Path.home() / "work" / "Obsidian",
|
|
]
|
|
|
|
|
|
def load_module(name: str, path: Path):
|
|
spec = importlib.util.spec_from_file_location(name, path)
|
|
if spec is None or spec.loader is None:
|
|
raise RuntimeError(f"unable to load {path.relative_to(ROOT)}")
|
|
module = importlib.util.module_from_spec(spec)
|
|
sys.modules[spec.name] = module
|
|
spec.loader.exec_module(module)
|
|
return module
|
|
|
|
|
|
def candidate_targets() -> list[Path]:
|
|
return [vault / ".obsidian" / "themes" / THEME_FOLDER_NAME for vault in DEFAULT_VAULTS]
|
|
|
|
|
|
def find_target(explicit: Path | None) -> Path:
|
|
if explicit:
|
|
return explicit
|
|
existing = [path for path in candidate_targets() if path.exists()]
|
|
if existing:
|
|
return existing[0]
|
|
candidates = "\n".join(f"- {path}" for path in candidate_targets())
|
|
raise SystemExit(
|
|
"ERROR: no Obsidian target theme folder found. Pass --target explicitly.\n"
|
|
f"Checked:\n{candidates}"
|
|
)
|
|
|
|
|
|
def bundle_and_promote() -> None:
|
|
bundle = load_module("bundle_v3", ROOT / "dev" / "scripts" / "bundle_v3.py")
|
|
result = bundle.main()
|
|
if result:
|
|
raise RuntimeError("bundle_v3.py failed")
|
|
src = ROOT / "dist" / "theme-v3.css"
|
|
dst = ROOT / "theme.css"
|
|
shutil.copy2(src, dst)
|
|
print(f"OK: promoted {src.relative_to(ROOT)} -> theme.css")
|
|
|
|
|
|
def copy_assets(target: Path, dry_run: bool) -> None:
|
|
for rel in RELEASE_ASSETS:
|
|
source = ROOT / rel
|
|
if not source.is_file() or source.stat().st_size == 0:
|
|
raise FileNotFoundError(f"missing release asset: {rel}")
|
|
destination = target / rel
|
|
print(f"{'DRY-RUN' if dry_run else 'COPY'}: {rel} -> {destination}")
|
|
if dry_run:
|
|
continue
|
|
destination.parent.mkdir(parents=True, exist_ok=True)
|
|
shutil.copy2(source, destination)
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("--target", type=Path, help="Obsidian theme folder to sync, e.g. H:\\Obsidian\\.obsidian\\themes\\Owen Graphite")
|
|
parser.add_argument("--dry-run", action="store_true", help="Show copy operations without writing files.")
|
|
parser.add_argument("--skip-bundle", action="store_true", help="Reuse existing theme.css; skip bundle + promote.")
|
|
parser.add_argument("--list-targets", action="store_true", help="Print known target candidates and exit.")
|
|
args = parser.parse_args()
|
|
|
|
if args.list_targets:
|
|
for path in candidate_targets():
|
|
marker = "exists" if path.exists() else "missing"
|
|
print(f"{marker}: {path}")
|
|
return 0
|
|
|
|
target = find_target(args.target)
|
|
print(f"Target: {target}")
|
|
|
|
if not args.skip_bundle:
|
|
bundle_and_promote()
|
|
|
|
copy_assets(target, args.dry_run)
|
|
if not args.dry_run:
|
|
print(f"OK: synced Owen Graphite to {target}")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|