169 lines
7.0 KiB
Python
169 lines
7.0 KiB
Python
|
|
"""Delete file relationships."""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from typing import Any, Dict, Optional, Sequence
|
||
|
|
import json
|
||
|
|
from pathlib import Path
|
||
|
|
import sys
|
||
|
|
|
||
|
|
from helper.logger import log
|
||
|
|
|
||
|
|
import pipeline as ctx
|
||
|
|
from ._shared import Cmdlet, CmdletArg, parse_cmdlet_args, normalize_result_input
|
||
|
|
from helper.local_library import LocalLibrarySearchOptimizer
|
||
|
|
from config import get_local_storage_path
|
||
|
|
|
||
|
|
|
||
|
|
def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
|
||
|
|
"""Delete relationships from files.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
result: Input result(s) from previous cmdlet
|
||
|
|
args: Command arguments
|
||
|
|
config: CLI configuration
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
Exit code (0 = success)
|
||
|
|
"""
|
||
|
|
try:
|
||
|
|
# Parse arguments
|
||
|
|
parsed_args = parse_cmdlet_args(args, CMDLET)
|
||
|
|
delete_all_flag = parsed_args.get("all", False)
|
||
|
|
rel_type_filter = parsed_args.get("type")
|
||
|
|
|
||
|
|
# Get storage path
|
||
|
|
local_storage_path = get_local_storage_path(config)
|
||
|
|
if not local_storage_path:
|
||
|
|
log("Local storage path not configured", file=sys.stderr)
|
||
|
|
return 1
|
||
|
|
|
||
|
|
# Normalize input
|
||
|
|
results = normalize_result_input(result)
|
||
|
|
|
||
|
|
if not results:
|
||
|
|
log("No results to process", file=sys.stderr)
|
||
|
|
return 1
|
||
|
|
|
||
|
|
deleted_count = 0
|
||
|
|
|
||
|
|
for single_result in results:
|
||
|
|
try:
|
||
|
|
# Get file path from result
|
||
|
|
file_path_from_result = None
|
||
|
|
|
||
|
|
if isinstance(single_result, dict):
|
||
|
|
file_path_from_result = (
|
||
|
|
single_result.get("file_path") or
|
||
|
|
single_result.get("path") or
|
||
|
|
single_result.get("target")
|
||
|
|
)
|
||
|
|
else:
|
||
|
|
file_path_from_result = (
|
||
|
|
getattr(single_result, "file_path", None) or
|
||
|
|
getattr(single_result, "path", None) or
|
||
|
|
getattr(single_result, "target", None) or
|
||
|
|
str(single_result)
|
||
|
|
)
|
||
|
|
|
||
|
|
if not file_path_from_result:
|
||
|
|
log("Could not extract file path from result", file=sys.stderr)
|
||
|
|
return 1
|
||
|
|
|
||
|
|
file_path_obj = Path(str(file_path_from_result))
|
||
|
|
|
||
|
|
if not file_path_obj.exists():
|
||
|
|
log(f"File not found: {file_path_obj}", file=sys.stderr)
|
||
|
|
return 1
|
||
|
|
|
||
|
|
with LocalLibrarySearchOptimizer(local_storage_path) as db:
|
||
|
|
file_id = db.db.get_file_id(file_path_obj)
|
||
|
|
|
||
|
|
if not file_id:
|
||
|
|
log(f"File not in database: {file_path_obj.name}", file=sys.stderr)
|
||
|
|
continue
|
||
|
|
|
||
|
|
# Get current relationships
|
||
|
|
cursor = db.db.connection.cursor()
|
||
|
|
cursor.execute("""
|
||
|
|
SELECT relationships FROM metadata WHERE file_id = ?
|
||
|
|
""", (file_id,))
|
||
|
|
|
||
|
|
row = cursor.fetchone()
|
||
|
|
if not row:
|
||
|
|
log(f"No relationships found for: {file_path_obj.name}", file=sys.stderr)
|
||
|
|
continue
|
||
|
|
|
||
|
|
relationships_str = row[0]
|
||
|
|
if not relationships_str:
|
||
|
|
log(f"No relationships found for: {file_path_obj.name}", file=sys.stderr)
|
||
|
|
continue
|
||
|
|
|
||
|
|
try:
|
||
|
|
relationships = json.loads(relationships_str)
|
||
|
|
except json.JSONDecodeError:
|
||
|
|
log(f"Invalid relationship data for: {file_path_obj.name}", file=sys.stderr)
|
||
|
|
continue
|
||
|
|
|
||
|
|
if not isinstance(relationships, dict):
|
||
|
|
relationships = {}
|
||
|
|
|
||
|
|
# Determine what to delete
|
||
|
|
if delete_all_flag:
|
||
|
|
# Delete all relationships
|
||
|
|
deleted_types = list(relationships.keys())
|
||
|
|
relationships = {}
|
||
|
|
log(f"Deleted all relationships ({len(deleted_types)} types) from: {file_path_obj.name}", file=sys.stderr)
|
||
|
|
elif rel_type_filter:
|
||
|
|
# Delete specific type
|
||
|
|
if rel_type_filter in relationships:
|
||
|
|
deleted_count_for_type = len(relationships[rel_type_filter])
|
||
|
|
del relationships[rel_type_filter]
|
||
|
|
log(f"Deleted {deleted_count_for_type} {rel_type_filter} relationship(s) from: {file_path_obj.name}", file=sys.stderr)
|
||
|
|
else:
|
||
|
|
log(f"No {rel_type_filter} relationships found for: {file_path_obj.name}", file=sys.stderr)
|
||
|
|
continue
|
||
|
|
else:
|
||
|
|
log("Specify --all to delete all relationships or -type <type> to delete specific type", file=sys.stderr)
|
||
|
|
return 1
|
||
|
|
|
||
|
|
# Save updated relationships
|
||
|
|
cursor.execute("""
|
||
|
|
INSERT INTO metadata (file_id, relationships)
|
||
|
|
VALUES (?, ?)
|
||
|
|
ON CONFLICT(file_id) DO UPDATE SET
|
||
|
|
relationships = excluded.relationships,
|
||
|
|
time_modified = CURRENT_TIMESTAMP
|
||
|
|
""", (file_id, json.dumps(relationships) if relationships else None))
|
||
|
|
|
||
|
|
db.db.connection.commit()
|
||
|
|
deleted_count += 1
|
||
|
|
|
||
|
|
except Exception as exc:
|
||
|
|
log(f"Error deleting relationship: {exc}", file=sys.stderr)
|
||
|
|
return 1
|
||
|
|
|
||
|
|
log(f"Successfully deleted relationships from {deleted_count} file(s)", file=sys.stderr)
|
||
|
|
return 0
|
||
|
|
|
||
|
|
except Exception as exc:
|
||
|
|
log(f"Error in delete-relationship: {exc}", file=sys.stderr)
|
||
|
|
return 1
|
||
|
|
|
||
|
|
|
||
|
|
CMDLET = Cmdlet(
|
||
|
|
name="delete-relationship",
|
||
|
|
summary="Remove relationships from files.",
|
||
|
|
usage="@1 | delete-relationship --all OR delete-relationship -path <file> --all OR @1-3 | delete-relationship -type alt",
|
||
|
|
args=[
|
||
|
|
CmdletArg("path", type="string", description="Specify the local file path (if not piping a result)."),
|
||
|
|
CmdletArg("all", type="flag", description="Delete all relationships for the file(s)."),
|
||
|
|
CmdletArg("type", type="string", description="Delete specific relationship type ('alt', 'king', 'related'). Default: delete all types."),
|
||
|
|
],
|
||
|
|
details=[
|
||
|
|
"- Delete all relationships: pipe files | delete-relationship --all",
|
||
|
|
"- Delete specific type: pipe files | delete-relationship -type alt",
|
||
|
|
"- Delete all from file: delete-relationship -path <file> --all",
|
||
|
|
],
|
||
|
|
)
|