This commit is contained in:
2026-01-22 03:12:16 -08:00
parent ba23c0606f
commit ca467a3453
8 changed files with 26 additions and 4900 deletions

View File

@@ -25,7 +25,6 @@ from pathlib import Path
from typing import Any, Dict, List, Optional, Sequence, Tuple
from SYS import pipeline as ctx
from API.folder import read_sidecar, write_sidecar
from . import _shared as sh
normalize_hash = sh.normalize_hash
@@ -525,157 +524,6 @@ def _apply_result_updates_from_tags(result: Any, tag_list: List[str]) -> None:
pass
def _handle_title_rename(old_path: Path, tags_list: List[str]) -> Optional[Path]:
"""If a title: tag is present, rename the file and its .tag sidecar to match.
Returns the new path if renamed, otherwise returns None.
"""
# Extract title from tags
new_title = None
for tag in tags_list:
if isinstance(tag, str) and tag.lower().startswith("title:"):
new_title = tag.split(":", 1)[1].strip()
break
if not new_title or not old_path.exists():
return None
try:
# Build new filename with same extension
old_name = old_path.name
old_suffix = old_path.suffix
# Create new filename: title + extension
new_name = f"{new_title}{old_suffix}"
new_path = old_path.parent / new_name
# Don't rename if already the same name
if new_path == old_path:
return None
# Rename the main file
if new_path.exists():
log(f"Warning: Target filename already exists: {new_name}", file=sys.stderr)
return None
old_path.rename(new_path)
log(f"Renamed file: {old_name}{new_name}", file=sys.stderr)
# Rename the .tag sidecar if it exists
old_tags_path = old_path.parent / (old_name + ".tag")
if old_tags_path.exists():
new_tags_path = old_path.parent / (new_name + ".tag")
if new_tags_path.exists():
log(
f"Warning: Target sidecar already exists: {new_tags_path.name}",
file=sys.stderr
)
else:
old_tags_path.rename(new_tags_path)
log(
f"Renamed sidecar: {old_tags_path.name}{new_tags_path.name}",
file=sys.stderr
)
return new_path
except Exception as exc:
log(f"Warning: Failed to rename file: {exc}", file=sys.stderr)
return None
def _read_sidecar_fallback(p: Path) -> tuple[Optional[str], List[str], List[str]]:
"""Fallback sidecar reader if metadata module unavailable.
Format:
- Lines with "hash:" prefix: file hash
- Lines with "url:" or "url:" prefix: url
- Lines with "relationship:" prefix: ignored (internal relationships)
- Lines with "key:", "namespace:value" format: treated as namespace tags
- Plain lines without colons: freeform tags
Excluded namespaces (treated as metadata, not tags): hash, url, url, relationship
"""
try:
raw = p.read_text(encoding="utf-8", errors="ignore")
except OSError:
return None, [], []
t: List[str] = []
u: List[str] = []
h: Optional[str] = None
# Namespaces to exclude from tags
excluded_namespaces = {"hash",
"url",
"url",
"relationship"}
for line in raw.splitlines():
s = line.strip()
if not s:
continue
low = s.lower()
# Check if this is a hash line
if low.startswith("hash:"):
h = s.split(":", 1)[1].strip() if ":" in s else h
# Check if this is a URL line
elif low.startswith("url:") or low.startswith("url:"):
val = s.split(":", 1)[1].strip() if ":" in s else ""
if val:
u.append(val)
# Check if this is an excluded namespace
elif ":" in s:
namespace = s.split(":", 1)[0].strip().lower()
if namespace not in excluded_namespaces:
# Include as namespace tag (e.g., "title: The Freemasons")
t.append(s)
else:
# Plain text without colon = freeform tag
t.append(s)
return h, t, u
def _write_sidecar(
p: Path,
media: Path,
tag_list: List[str],
url: List[str],
hash_in_sidecar: Optional[str]
) -> Path:
"""Write tags to sidecar file and handle title-based renaming.
Returns the new media path if renamed, otherwise returns the original media path.
"""
success = write_sidecar(media, tag_list, url, hash_in_sidecar)
if success:
_apply_result_updates_from_tags(None, tag_list)
# Check if we should rename the file based on title tag
new_media = _handle_title_rename(media, tag_list)
if new_media:
return new_media
return media
# Fallback writer
ordered = [s for s in tag_list if s and s.strip()]
lines = []
if hash_in_sidecar:
lines.append(f"hash:{hash_in_sidecar}")
lines.extend(ordered)
for u in url:
lines.append(f"url:{u}")
try:
p.write_text("\n".join(lines) + "\n", encoding="utf-8")
# Check if we should rename the file based on title tag
new_media = _handle_title_rename(media, tag_list)
if new_media:
return new_media
return media
except OSError as exc:
log(f"Failed to write sidecar: {exc}", file=sys.stderr)
return media
def _emit_tag_payload(
source: str,
tags_list: List[str],
@@ -1497,17 +1345,7 @@ def _run(result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
str) and file_path and not file_path.lower().startswith(
("http://",
"https://"))):
try:
media_path = Path(str(file_path))
if media_path.exists():
tags_from_sidecar = read_sidecar(media_path)
if isinstance(tags_from_sidecar, list):
identifier_tags = [
str(t) for t in tags_from_sidecar
if isinstance(t, (str, bytes))
]
except Exception:
pass
pass
title_from_tags = _extract_tag_value(identifier_tags, "title")
artist_from_tags = _extract_tag_value(identifier_tags, "artist")