This commit is contained in:
2026-02-02 19:49:07 -08:00
parent 8d22ec5a81
commit 1e0000ae19
13 changed files with 297 additions and 988 deletions

View File

@@ -56,7 +56,7 @@ _LYRIC_VISIBLE_PROP = "user-data/medeia-lyric-visible"
# Optional overrides set by the playlist controller (.pipe/.mpv) so the lyric
# helper can resolve notes even when the local file path cannot be mapped back
# to a store via the store DB (common for Folder stores).
# to a store via the store DB.
_ITEM_STORE_PROP = "user-data/medeia-item-store"
_ITEM_HASH_PROP = "user-data/medeia-item-hash"
@@ -804,11 +804,7 @@ def _resolve_store_backend_for_target(
except Exception:
return None, None
# Prefer the inferred Folder store (fast), but still validate via get_file().
preferred = _infer_store_for_target(target=target, config=config)
if preferred and preferred in backend_names:
backend_names.remove(preferred)
backend_names.insert(0, preferred)
for name in backend_names:
try:
@@ -842,80 +838,9 @@ def _resolve_store_backend_for_target(
return name, backend
# Fallback for Folder stores:
# If the mpv target is inside a configured Folder store root and the filename
# is hash-named, accept the inferred store even if the store DB doesn't map
# hash->path (e.g. DB missing entry, external copy, etc.).
try:
inferred = _infer_store_for_target(target=target, config=config)
if inferred and inferred in backend_names:
backend = reg[inferred]
if type(backend).__name__ == "Folder":
p = Path(target)
stem = str(p.stem or "").strip().lower()
if stem and stem == str(file_hash or "").strip().lower():
return inferred, backend
except Exception:
pass
return None, None
def _infer_store_for_target(*, target: str, config: dict) -> Optional[str]:
"""Infer store name from the current mpv target (local path under a folder root).
Note: URLs/streams are intentionally not mapped to stores for lyrics.
"""
if isinstance(target, str) and _is_stream_target(target):
return None
try:
from Store import Store as StoreRegistry
reg = StoreRegistry(config, suppress_debug=True)
backends = [(name, reg[name]) for name in reg.list_backends()]
except Exception:
backends = []
# Local file path: choose the deepest Folder root that contains it.
try:
p = Path(target)
if not p.exists() or not p.is_file():
return None
p_str = str(p.resolve()).lower()
except Exception:
return None
best: Optional[str] = None
best_len = -1
for name, backend in backends:
if type(backend).__name__ != "Folder":
continue
root = None
try:
root = (
getattr(backend,
"_location",
None) or getattr(backend,
"location", lambda: None)()
)
except Exception:
root = None
if not root:
continue
try:
root_path = Path(str(root)).expanduser().resolve()
root_str = str(root_path).lower().rstrip("\\/")
except Exception:
continue
if p_str.startswith(root_str) and len(root_str) > best_len:
best = name
best_len = len(root_str)
return best
def _infer_hash_for_target(target: str) -> Optional[str]:
"""Infer SHA256 hash from Hydrus URL query, hash-named local files, or by hashing local file content."""
h = _extract_hash_from_target(target)