Add YAPF style + ignore, and format tracked Python files
This commit is contained in:
@@ -22,7 +22,7 @@ fetch_hydrus_metadata = sh.fetch_hydrus_metadata
|
||||
should_show_help = sh.should_show_help
|
||||
get_field = sh.get_field
|
||||
from API.folder import API_folder_store
|
||||
from config import get_local_storage_path
|
||||
from SYS.config import get_local_storage_path
|
||||
from result_table import ResultTable
|
||||
from Store import Store
|
||||
|
||||
@@ -55,11 +55,15 @@ def _run(result: Any, _args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
while i < len(args_list):
|
||||
a = args_list[i]
|
||||
low = str(a).lower()
|
||||
if low in {"-query", "--query", "query"} and i + 1 < len(args_list):
|
||||
if low in {"-query",
|
||||
"--query",
|
||||
"query"} and i + 1 < len(args_list):
|
||||
override_query = str(args_list[i + 1]).strip()
|
||||
i += 2
|
||||
continue
|
||||
if low in {"-store", "--store", "store"} and i + 1 < len(args_list):
|
||||
if low in {"-store",
|
||||
"--store",
|
||||
"store"} and i + 1 < len(args_list):
|
||||
override_store = str(args_list[i + 1]).strip()
|
||||
i += 2
|
||||
continue
|
||||
@@ -93,15 +97,13 @@ def _run(result: Any, _args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
def _add_relationship(entry: Dict[str, Any]) -> None:
|
||||
"""Add relationship if not already present by hash or path."""
|
||||
for existing in found_relationships:
|
||||
if (
|
||||
entry.get("hash")
|
||||
and str(existing.get("hash", "")).lower() == str(entry["hash"]).lower()
|
||||
):
|
||||
if (entry.get("hash")
|
||||
and str(existing.get("hash",
|
||||
"")).lower() == str(entry["hash"]).lower()):
|
||||
return
|
||||
if (
|
||||
entry.get("path")
|
||||
and str(existing.get("path", "")).lower() == str(entry["path"]).lower()
|
||||
):
|
||||
if (entry.get("path")
|
||||
and str(existing.get("path",
|
||||
"")).lower() == str(entry["path"]).lower()):
|
||||
return
|
||||
found_relationships.append(entry)
|
||||
|
||||
@@ -112,14 +114,15 @@ def _run(result: Any, _args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
|
||||
hash_hex = (
|
||||
normalize_hash(override_hash)
|
||||
if override_hash
|
||||
else normalize_hash(get_hash_for_operation(None, result))
|
||||
if override_hash else normalize_hash(get_hash_for_operation(None,
|
||||
result))
|
||||
)
|
||||
|
||||
if not source_title or source_title == "Unknown":
|
||||
source_title = (
|
||||
get_field(result, "title")
|
||||
or get_field(result, "name")
|
||||
get_field(result,
|
||||
"title") or get_field(result,
|
||||
"name")
|
||||
or (hash_hex[:16] + "..." if hash_hex else "Unknown")
|
||||
)
|
||||
|
||||
@@ -133,11 +136,10 @@ def _run(result: Any, _args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
# Folder store relationships
|
||||
# IMPORTANT: only treat the Folder backend as a local DB store.
|
||||
# Other backends may expose a location() method but are not SQLite folder stores.
|
||||
if (
|
||||
type(backend).__name__ == "Folder"
|
||||
and hasattr(backend, "location")
|
||||
and callable(getattr(backend, "location"))
|
||||
):
|
||||
if (type(backend).__name__ == "Folder" and hasattr(backend,
|
||||
"location")
|
||||
and callable(getattr(backend,
|
||||
"location"))):
|
||||
storage_path = Path(str(backend.location()))
|
||||
with API_folder_store(storage_path) as db:
|
||||
local_db_checked = True
|
||||
@@ -167,7 +169,8 @@ def _run(result: Any, _args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
continue
|
||||
|
||||
entry_type = (
|
||||
"king" if str(rel_type).lower() == "alt" else str(rel_type)
|
||||
"king" if str(rel_type).lower() == "alt" else
|
||||
str(rel_type)
|
||||
)
|
||||
if entry_type == "king":
|
||||
king_hashes.append(related_hash)
|
||||
@@ -176,7 +179,9 @@ def _run(result: Any, _args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
try:
|
||||
rel_tags = db.get_tags(related_hash)
|
||||
for t in rel_tags:
|
||||
if isinstance(t, str) and t.lower().startswith("title:"):
|
||||
if isinstance(
|
||||
t,
|
||||
str) and t.lower().startswith("title:"):
|
||||
related_title = t[6:].strip()
|
||||
break
|
||||
except Exception:
|
||||
@@ -208,13 +213,16 @@ def _run(result: Any, _args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
try:
|
||||
child_tags = db.get_tags(child_hash)
|
||||
for t in child_tags:
|
||||
if isinstance(t, str) and t.lower().startswith("title:"):
|
||||
if isinstance(t,
|
||||
str) and t.lower().startswith("title:"):
|
||||
child_title = t[6:].strip()
|
||||
break
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
entry_type = "alt" if rel_type == "alt" else (rel_type or "related")
|
||||
entry_type = "alt" if rel_type == "alt" else (
|
||||
rel_type or "related"
|
||||
)
|
||||
_add_relationship(
|
||||
{
|
||||
"hash": child_hash,
|
||||
@@ -234,20 +242,25 @@ def _run(result: Any, _args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
for sib in siblings or []:
|
||||
sib_hash = normalize_hash(str(sib.get("hash") or ""))
|
||||
sib_type = str(sib.get("type") or "").strip().lower()
|
||||
if not sib_hash or sib_hash in {hash_hex, king_hash}:
|
||||
if not sib_hash or sib_hash in {hash_hex,
|
||||
king_hash}:
|
||||
continue
|
||||
|
||||
sib_title = sib_hash[:16] + "..."
|
||||
try:
|
||||
sib_tags = db.get_tags(sib_hash)
|
||||
for t in sib_tags:
|
||||
if isinstance(t, str) and t.lower().startswith("title:"):
|
||||
if isinstance(
|
||||
t,
|
||||
str) and t.lower().startswith("title:"):
|
||||
sib_title = t[6:].strip()
|
||||
break
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
entry_type = "alt" if sib_type == "alt" else (sib_type or "related")
|
||||
entry_type = "alt" if sib_type == "alt" else (
|
||||
sib_type or "related"
|
||||
)
|
||||
_add_relationship(
|
||||
{
|
||||
"hash": sib_hash,
|
||||
@@ -268,8 +281,8 @@ def _run(result: Any, _args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
|
||||
hash_hex = (
|
||||
normalize_hash(override_hash)
|
||||
if override_hash
|
||||
else normalize_hash(get_hash_for_operation(None, result))
|
||||
if override_hash else normalize_hash(get_hash_for_operation(None,
|
||||
result))
|
||||
)
|
||||
|
||||
if hash_hex and not local_db_checked:
|
||||
@@ -284,12 +297,16 @@ def _run(result: Any, _args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
store = Store(config)
|
||||
backend_obj = store[str(store_name)]
|
||||
candidate = getattr(backend_obj, "_client", None)
|
||||
if candidate is not None and hasattr(candidate, "get_file_relationships"):
|
||||
if candidate is not None and hasattr(candidate,
|
||||
"get_file_relationships"):
|
||||
client = candidate
|
||||
except Exception:
|
||||
client = None
|
||||
if client is None:
|
||||
log(f"Hydrus client unavailable for store '{store_name}'", file=sys.stderr)
|
||||
log(
|
||||
f"Hydrus client unavailable for store '{store_name}'",
|
||||
file=sys.stderr
|
||||
)
|
||||
return 1
|
||||
else:
|
||||
client = hydrus_wrapper.get_client(config)
|
||||
@@ -312,12 +329,13 @@ def _run(result: Any, _args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
tag_result = backend_obj.get_tag(h)
|
||||
tags = (
|
||||
tag_result[0]
|
||||
if isinstance(tag_result, tuple) and tag_result
|
||||
else tag_result
|
||||
if isinstance(tag_result,
|
||||
tuple) and tag_result else tag_result
|
||||
)
|
||||
if isinstance(tags, list):
|
||||
for t in tags:
|
||||
if isinstance(t, str) and t.lower().startswith("title:"):
|
||||
if isinstance(t,
|
||||
str) and t.lower().startswith("title:"):
|
||||
val = t.split(":", 1)[1].strip()
|
||||
if val:
|
||||
return val
|
||||
@@ -349,7 +367,10 @@ def _run(result: Any, _args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
for group in storage.values():
|
||||
if isinstance(group, list):
|
||||
tag_candidates.extend(
|
||||
[str(x) for x in group if isinstance(x, str)]
|
||||
[
|
||||
str(x) for x in group
|
||||
if isinstance(x, str)
|
||||
]
|
||||
)
|
||||
display = svc_data.get("display_tags")
|
||||
if isinstance(display, list):
|
||||
@@ -358,7 +379,9 @@ def _run(result: Any, _args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
)
|
||||
flat = meta.get("tags_flat")
|
||||
if isinstance(flat, list):
|
||||
tag_candidates.extend([str(x) for x in flat if isinstance(x, str)])
|
||||
tag_candidates.extend(
|
||||
[str(x) for x in flat if isinstance(x, str)]
|
||||
)
|
||||
|
||||
for t in tag_candidates:
|
||||
if isinstance(t, str) and t.lower().startswith("title:"):
|
||||
@@ -373,7 +396,8 @@ def _run(result: Any, _args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
if client:
|
||||
rel = client.get_file_relationships(hash_hex)
|
||||
if rel:
|
||||
file_rels = rel.get("file_relationships", {})
|
||||
file_rels = rel.get("file_relationships",
|
||||
{})
|
||||
this_file_rels = file_rels.get(hash_hex)
|
||||
|
||||
if this_file_rels:
|
||||
@@ -392,26 +416,28 @@ def _run(result: Any, _args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
key = str(rel_type_id)
|
||||
|
||||
# Handle metadata keys explicitly.
|
||||
if key in {"is_king", "king_is_on_file_domain", "king_is_local"}:
|
||||
if key in {"is_king",
|
||||
"king_is_on_file_domain",
|
||||
"king_is_local"}:
|
||||
continue
|
||||
|
||||
# Some Hydrus responses provide a direct king hash under the 'king' key.
|
||||
if key == "king":
|
||||
king_hash = (
|
||||
normalize_hash(rel_value)
|
||||
if isinstance(rel_value, str)
|
||||
else None
|
||||
if isinstance(rel_value,
|
||||
str) else None
|
||||
)
|
||||
if king_hash and king_hash != hash_hex:
|
||||
if not any(
|
||||
str(r.get("hash", "")).lower() == king_hash
|
||||
for r in found_relationships
|
||||
):
|
||||
if not any(str(r.get("hash",
|
||||
"")).lower() == king_hash
|
||||
for r in found_relationships):
|
||||
found_relationships.append(
|
||||
{
|
||||
"hash": king_hash,
|
||||
"type": "king",
|
||||
"title": _resolve_related_title(king_hash),
|
||||
"title":
|
||||
_resolve_related_title(king_hash),
|
||||
"path": None,
|
||||
"store": store_label,
|
||||
}
|
||||
@@ -425,39 +451,47 @@ def _run(result: Any, _args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
for rel_hash in rel_value:
|
||||
rel_hash_norm = (
|
||||
normalize_hash(rel_hash)
|
||||
if isinstance(rel_hash, str)
|
||||
else None
|
||||
if isinstance(rel_hash,
|
||||
str) else None
|
||||
)
|
||||
if not rel_hash_norm or rel_hash_norm == hash_hex:
|
||||
continue
|
||||
if not any(
|
||||
str(r.get("hash", "")).lower() == rel_hash_norm
|
||||
for r in found_relationships
|
||||
):
|
||||
if not any(str(r.get("hash",
|
||||
"")).lower() == rel_hash_norm
|
||||
for r in found_relationships):
|
||||
found_relationships.append(
|
||||
{
|
||||
"hash": rel_hash_norm,
|
||||
"type": rel_name,
|
||||
"title": _resolve_related_title(rel_hash_norm),
|
||||
"path": None,
|
||||
"store": store_label,
|
||||
"hash":
|
||||
rel_hash_norm,
|
||||
"type":
|
||||
rel_name,
|
||||
"title":
|
||||
_resolve_related_title(rel_hash_norm),
|
||||
"path":
|
||||
None,
|
||||
"store":
|
||||
store_label,
|
||||
}
|
||||
)
|
||||
# Defensive: sometimes the API may return a single hash string.
|
||||
elif isinstance(rel_value, str):
|
||||
rel_hash_norm = normalize_hash(rel_value)
|
||||
if rel_hash_norm and rel_hash_norm != hash_hex:
|
||||
if not any(
|
||||
str(r.get("hash", "")).lower() == rel_hash_norm
|
||||
for r in found_relationships
|
||||
):
|
||||
if not any(str(r.get("hash",
|
||||
"")).lower() == rel_hash_norm
|
||||
for r in found_relationships):
|
||||
found_relationships.append(
|
||||
{
|
||||
"hash": rel_hash_norm,
|
||||
"type": rel_name,
|
||||
"title": _resolve_related_title(rel_hash_norm),
|
||||
"path": None,
|
||||
"store": store_label,
|
||||
"hash":
|
||||
rel_hash_norm,
|
||||
"type":
|
||||
rel_name,
|
||||
"title":
|
||||
_resolve_related_title(rel_hash_norm),
|
||||
"path":
|
||||
None,
|
||||
"store":
|
||||
store_label,
|
||||
}
|
||||
)
|
||||
except Exception as exc:
|
||||
@@ -471,13 +505,18 @@ def _run(result: Any, _args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
from rich_display import stdout_console
|
||||
|
||||
title = source_title or (hash_hex[:16] + "..." if hash_hex else "Item")
|
||||
stdout_console().print(Panel(f"{title} has no relationships", title="Relationships"))
|
||||
stdout_console().print(
|
||||
Panel(f"{title} has no relationships",
|
||||
title="Relationships")
|
||||
)
|
||||
except Exception:
|
||||
log("No relationships found.")
|
||||
return 0
|
||||
|
||||
# Display results
|
||||
table = ResultTable(f"Relationships: {source_title}").init_command("get-relationship", [])
|
||||
table = ResultTable(f"Relationships: {source_title}"
|
||||
).init_command("get-relationship",
|
||||
[])
|
||||
|
||||
# Sort by type then title
|
||||
# Custom sort order: King first, then Derivative, then others
|
||||
@@ -487,7 +526,9 @@ def _run(result: Any, _args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
return 0
|
||||
elif t == "derivative":
|
||||
return 1
|
||||
elif t in {"alternative", "alternate", "alt"}:
|
||||
elif t in {"alternative",
|
||||
"alternate",
|
||||
"alt"}:
|
||||
return 2
|
||||
elif t == "duplicate":
|
||||
return 3
|
||||
@@ -520,7 +561,11 @@ def _run(result: Any, _args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
|
||||
# Set selection args
|
||||
table.set_row_selection_args(
|
||||
i, ["-store", str(item["store"]), "-query", f"hash:{item['hash']}"]
|
||||
i,
|
||||
["-store",
|
||||
str(item["store"]),
|
||||
"-query",
|
||||
f"hash:{item['hash']}"]
|
||||
)
|
||||
|
||||
ctx.set_last_result_table(table, pipeline_results)
|
||||
|
||||
Reference in New Issue
Block a user