mirror of
https://github.com/lllin000/PaperForge.git
synced 2026-07-22 06:50:53 +00:00
140 lines
4.4 KiB
Python
140 lines
4.4 KiB
Python
"""Sync command — unified sync through SyncService."""
|
|
|
|
import argparse
|
|
import logging
|
|
|
|
from paperforge import __version__
|
|
from paperforge.config import migrate_paperforge_json
|
|
from paperforge.core.result import PFResult
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def run(args: argparse.Namespace) -> int:
|
|
vault = getattr(args, "vault_path", None)
|
|
if vault is None:
|
|
from paperforge.config import resolve_vault
|
|
|
|
vault = resolve_vault(cli_vault=getattr(args, "vault", None))
|
|
|
|
verbose = getattr(args, "verbose", False)
|
|
migrated = migrate_paperforge_json(vault)
|
|
if migrated:
|
|
logger.info("Migrated paperforge.json to vault_config canonical format")
|
|
if verbose:
|
|
print("[INFO] paperforge.json migrated to canonical format (backup: paperforge.json.bak)")
|
|
|
|
dry_run = getattr(args, "dry_run", False)
|
|
selection_only = getattr(args, "selection", False)
|
|
index_only = getattr(args, "index", False)
|
|
json_output = getattr(args, "json", False)
|
|
prune_flag = getattr(args, "prune", False)
|
|
prune_force = getattr(args, "prune_force", False)
|
|
|
|
if dry_run:
|
|
if json_output:
|
|
result = PFResult(
|
|
ok=True,
|
|
command="sync",
|
|
version=__version__,
|
|
data={"dry_run": True, "selection": not index_only, "index": not selection_only},
|
|
)
|
|
print(result.to_json())
|
|
return 0
|
|
print("[DRY-RUN] Would run sync operations")
|
|
if not selection_only and not index_only:
|
|
print(" - selection-sync")
|
|
print(" - index-refresh")
|
|
else:
|
|
if selection_only:
|
|
print(" - selection-sync")
|
|
if index_only:
|
|
print(" - index-refresh")
|
|
return 0
|
|
|
|
from paperforge.services.sync_service import SyncService
|
|
|
|
svc = SyncService(vault)
|
|
result = svc.run(
|
|
verbose=verbose,
|
|
json_output=json_output,
|
|
selection_only=selection_only,
|
|
index_only=index_only,
|
|
prune=prune_flag,
|
|
prune_force=prune_force,
|
|
)
|
|
|
|
_write_orphan_state(vault, result)
|
|
|
|
if json_output:
|
|
print(result.to_json())
|
|
if result.ok and not dry_run and not index_only and not selection_only:
|
|
try:
|
|
from paperforge.memory.builder import build_from_index
|
|
|
|
build_from_index(vault)
|
|
except Exception:
|
|
pass
|
|
try:
|
|
import subprocess
|
|
import sys
|
|
|
|
subprocess.Popen(
|
|
[sys.executable, "-m", "paperforge", "embed", "build", "--resume"],
|
|
cwd=str(vault),
|
|
stdout=subprocess.DEVNULL,
|
|
stderr=subprocess.DEVNULL,
|
|
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP if sys.platform == "win32" else 0,
|
|
)
|
|
except Exception:
|
|
pass
|
|
return 0
|
|
|
|
if not result.ok:
|
|
return 1
|
|
|
|
try:
|
|
from paperforge.memory.builder import build_from_index
|
|
|
|
counts = build_from_index(vault)
|
|
tag = " (fast)" if counts.get("hash_match") else ""
|
|
print(f"memory: {counts.get('papers_indexed', 0)} papers{tag}")
|
|
except Exception as e:
|
|
print(f"memory: deferred ({e})")
|
|
|
|
try:
|
|
import subprocess
|
|
import sys
|
|
|
|
subprocess.Popen(
|
|
[sys.executable, "-m", "paperforge", "embed", "build", "--resume"],
|
|
cwd=str(vault),
|
|
stdout=subprocess.DEVNULL,
|
|
stderr=subprocess.DEVNULL,
|
|
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP if sys.platform == "win32" else 0,
|
|
)
|
|
except Exception:
|
|
pass
|
|
|
|
return 0
|
|
|
|
|
|
def _write_orphan_state(vault, result: PFResult) -> None:
|
|
from paperforge.config import paperforge_paths
|
|
preview = (result.data or {}).get("prune", {}) if result.data else {}
|
|
items = preview.get("preview", []) if isinstance(preview, dict) else []
|
|
orphan_path = paperforge_paths(vault)["index"].parent / "sync-orphan-state.json"
|
|
if not items:
|
|
try:
|
|
orphan_path.unlink(missing_ok=True)
|
|
except Exception:
|
|
pass
|
|
return
|
|
|
|
import json as _json
|
|
|
|
orphan_path.parent.mkdir(parents=True, exist_ok=True)
|
|
try:
|
|
orphan_path.write_text(_json.dumps({"orphans": items, "count": len(items)}, indent=2), encoding="utf-8")
|
|
except Exception:
|
|
pass
|