Add YAPF style + ignore, and format tracked Python files

This commit is contained in:
2025-12-29 18:42:02 -08:00
parent c019c00aed
commit 507946a3e4
108 changed files with 11664 additions and 6494 deletions

View File

@@ -21,7 +21,11 @@ from Store import Store
def _refresh_tag_view_if_current(
file_hash: str | None, store_name: str | None, path: str | None, config: Dict[str, Any]
file_hash: str | None,
store_name: str | None,
path: str | None,
config: Dict[str,
Any]
) -> None:
"""If the current subject matches the target, refresh tags via get-tag."""
try:
@@ -52,11 +56,17 @@ def _refresh_tag_view_if_current(
subj_paths: list[str] = []
if isinstance(subject, dict):
subj_hashes = [norm(v) for v in [subject.get("hash")] if v]
subj_paths = [norm(v) for v in [subject.get("path"), subject.get("target")] if v]
else:
subj_hashes = [norm(get_field(subject, f)) for f in ("hash",) if get_field(subject, f)]
subj_paths = [
norm(get_field(subject, f)) for f in ("path", "target") if get_field(subject, f)
norm(v) for v in [subject.get("path"), subject.get("target")] if v
]
else:
subj_hashes = [
norm(get_field(subject,
f)) for f in ("hash", ) if get_field(subject, f)
]
subj_paths = [
norm(get_field(subject,
f)) for f in ("path", "target") if get_field(subject, f)
]
is_match = False
@@ -108,11 +118,10 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
return False
# TagItem (direct) or PipeObject/dict emitted from get-tag table rows.
try:
if (
hasattr(obj, "__class__")
and obj.__class__.__name__ == "TagItem"
and hasattr(obj, "tag_name")
):
if (hasattr(obj,
"__class__") and obj.__class__.__name__ == "TagItem"
and hasattr(obj,
"tag_name")):
return True
except Exception:
pass
@@ -123,7 +132,8 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
has_piped_tag = _looks_like_tag_row(result)
has_piped_tag_list = (
isinstance(result, list) and bool(result) and _looks_like_tag_row(result[0])
isinstance(result,
list) and bool(result) and _looks_like_tag_row(result[0])
)
# Parse -query/-store overrides and collect remaining args.
@@ -135,25 +145,32 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
while i < len(args):
a = args[i]
low = str(a).lower()
if low in {"-query", "--query", "query"} and i + 1 < len(args):
if low in {"-query",
"--query",
"query"} and i + 1 < len(args):
override_query = str(args[i + 1]).strip()
i += 2
continue
if low in {"-store", "--store", "store"} and i + 1 < len(args):
if low in {"-store",
"--store",
"store"} and i + 1 < len(args):
override_store = str(args[i + 1]).strip()
i += 2
continue
rest.append(a)
i += 1
override_hash = sh.parse_single_hash_query(override_query) if override_query else None
override_hash = sh.parse_single_hash_query(
override_query
) if override_query else None
if override_query and not override_hash:
log("Invalid -query value (expected hash:<sha256>)", file=sys.stderr)
return 1
# Selection syntax (@...) is handled by the pipeline runner, not by this cmdlet.
# If @ reaches here as a literal argument, it's almost certainly user error.
if rest and str(rest[0]).startswith("@") and not (has_piped_tag or has_piped_tag_list):
if rest and str(rest[0]
).startswith("@") and not (has_piped_tag or has_piped_tag_list):
log("Selection syntax is only supported via piping. Use: @N | delete-tag")
return 1
@@ -166,16 +183,13 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
grouped_table = ""
grouped_tags = get_field(result, "tag") if result is not None else None
tags_arg = parse_tag_arguments(rest)
if (
grouped_table == "tag.selection"
and isinstance(grouped_tags, list)
and grouped_tags
and not tags_arg
):
if (grouped_table == "tag.selection" and isinstance(grouped_tags,
list) and grouped_tags
and not tags_arg):
file_hash = (
normalize_hash(override_hash)
if override_hash
else normalize_hash(get_field(result, "hash"))
if override_hash else normalize_hash(get_field(result,
"hash"))
)
store_name = override_store or get_field(result, "store")
path = get_field(result, "path") or get_field(result, "target")
@@ -200,20 +214,25 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
# If we have Files (or other objects) and args, we are deleting tags FROM those files
# Check if we are in "delete selected tags" mode (tag rows)
is_tag_item_mode = bool(items_to_process) and _looks_like_tag_row(items_to_process[0])
is_tag_item_mode = bool(items_to_process) and _looks_like_tag_row(
items_to_process[0]
)
if is_tag_item_mode:
# Collect all tags to delete from the TagItems and batch per file.
# This keeps delete-tag efficient (one backend call per file).
groups: Dict[tuple[str, str, str], list[str]] = {}
groups: Dict[tuple[str,
str,
str],
list[str]] = {}
for item in items_to_process:
tag_name = get_field(item, "tag_name")
if not tag_name:
continue
item_hash = (
normalize_hash(override_hash)
if override_hash
else normalize_hash(get_field(item, "hash"))
if override_hash else normalize_hash(get_field(item,
"hash"))
)
item_store = override_store or get_field(item, "store")
item_path = get_field(item, "path") or get_field(item, "target")
@@ -246,8 +265,8 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
tags_to_delete: list[str] = []
item_hash = (
normalize_hash(override_hash)
if override_hash
else normalize_hash(get_field(item, "hash"))
if override_hash else normalize_hash(get_field(item,
"hash"))
)
item_path = get_field(item, "path") or get_field(item, "target")
item_store = override_store or get_field(item, "store")
@@ -266,7 +285,11 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
continue
if tags_to_delete:
if _process_deletion(tags_to_delete, item_hash, item_path, item_store, config):
if _process_deletion(tags_to_delete,
item_hash,
item_path,
item_store,
config):
success_count += 1
if success_count > 0:
@@ -279,7 +302,8 @@ def _process_deletion(
file_hash: str | None,
path: str | None,
store_name: str | None,
config: Dict[str, Any],
config: Dict[str,
Any],
) -> bool:
"""Helper to execute the deletion logic for a single target."""
@@ -287,7 +311,10 @@ def _process_deletion(
return False
if not store_name:
log("Store is required (use -store or pipe a result with store)", file=sys.stderr)
log(
"Store is required (use -store or pipe a result with store)",
file=sys.stderr
)
return False
resolved_hash = normalize_hash(file_hash) if file_hash else None
@@ -315,13 +342,17 @@ def _process_deletion(
return []
# Safety: only block if this deletion would remove the final title tag
title_tags = [t for t in tags if isinstance(t, str) and t.lower().startswith("title:")]
title_tags = [
t for t in tags if isinstance(t, str) and t.lower().startswith("title:")
]
if title_tags:
existing_tags = _fetch_existing_tags()
current_titles = [
t for t in existing_tags if isinstance(t, str) and t.lower().startswith("title:")
t for t in existing_tags
if isinstance(t, str) and t.lower().startswith("title:")
]
del_title_set = {t.lower() for t in title_tags}
del_title_set = {t.lower()
for t in title_tags}
remaining_titles = [t for t in current_titles if t.lower() not in del_title_set]
if current_titles and not remaining_titles:
log(
@@ -335,7 +366,9 @@ def _process_deletion(
ok = backend.delete_tag(resolved_hash, list(tags), config=config)
if ok:
preview = resolved_hash[:12] + ("" if len(resolved_hash) > 12 else "")
debug(f"Removed {len(tags)} tag(s) from {preview} via store '{store_name}'.")
debug(
f"Removed {len(tags)} tag(s) from {preview} via store '{store_name}'."
)
_refresh_tag_view_if_current(resolved_hash, store_name, path, config)
return True
return False