fix: implement symlink resolution for more reliable source deletion in destruct mode
All checks were successful
Docker Build / build (push) Successful in 13s
All checks were successful
Docker Build / build (push) Successful in 13s
This commit is contained in:
parent
8876469c43
commit
e99d21fac7
1 changed files with 61 additions and 31 deletions
|
|
@ -117,6 +117,21 @@ def translate_ta_path(ta_path):
|
||||||
|
|
||||||
return p
|
return p
|
||||||
|
|
||||||
|
def translate_host_path(host_path):
|
||||||
|
"""
|
||||||
|
Translates a path from the Host filesystem (e.g. /mnt/user/tubearchives/bp/...)
|
||||||
|
to the container's /app/source mount.
|
||||||
|
"""
|
||||||
|
if not host_path: return None
|
||||||
|
host_path_str = str(host_path)
|
||||||
|
host_prefix = "/mnt/user/tubearchives/bp"
|
||||||
|
|
||||||
|
if host_path_str.startswith(host_prefix):
|
||||||
|
rel = host_path_str[len(host_prefix):].lstrip("/")
|
||||||
|
return SOURCE_DIR / rel
|
||||||
|
|
||||||
|
return Path(host_path)
|
||||||
|
|
||||||
def tlog(msg):
|
def tlog(msg):
|
||||||
"""Logs a message to the transcode log buffer."""
|
"""Logs a message to the transcode log buffer."""
|
||||||
print(f"[TRANSCODE] {msg}", flush=True)
|
print(f"[TRANSCODE] {msg}", flush=True)
|
||||||
|
|
@ -1183,42 +1198,57 @@ def api_recovery_delete_batch():
|
||||||
p = Path(path)
|
p = Path(path)
|
||||||
if destruct:
|
if destruct:
|
||||||
source_deleted = False
|
source_deleted = False
|
||||||
# Try to find video_id from DB first (most reliable for library files)
|
source_path = None
|
||||||
vid_id = None
|
|
||||||
with get_db() as conn:
|
|
||||||
row = conn.execute("SELECT video_id FROM videos WHERE symlink = ?", (path,)).fetchone()
|
|
||||||
if row:
|
|
||||||
vid_id = row['video_id']
|
|
||||||
|
|
||||||
# Fallback: Extraction from filename
|
# --- Method A: Symlink Resolution (Highest reliability for library files) ---
|
||||||
if not vid_id:
|
if os.path.islink(p):
|
||||||
vid_id = extract_id_from_filename(p.name)
|
try:
|
||||||
|
target_raw = os.readlink(p)
|
||||||
|
log(f" [DESTRUCT] Symlink target: {target_raw}")
|
||||||
|
source_path = translate_host_path(target_raw)
|
||||||
|
log(f" [DESTRUCT] Translated source: {source_path}")
|
||||||
|
except Exception as eread:
|
||||||
|
log(f" [DESTRUCT] Warning: Could not read symlink {p}: {eread}")
|
||||||
|
|
||||||
if vid_id:
|
# --- Method B: Database/TA Metadata Fallback ---
|
||||||
meta = video_map.get(vid_id)
|
if not source_path or not source_path.exists():
|
||||||
if meta:
|
# Try to find video_id from DB
|
||||||
raw_ta_path = meta.get('filesystem_path')
|
vid_id = None
|
||||||
if raw_ta_path:
|
with get_db() as conn:
|
||||||
# Translate internal TA path to our /app/source mount
|
row = conn.execute("SELECT video_id FROM videos WHERE symlink = ?", (path,)).fetchone()
|
||||||
source_path = translate_ta_path(raw_ta_path)
|
if row:
|
||||||
|
vid_id = row['video_id']
|
||||||
log(f" [DESTRUCT] Attempting lookup for ID {vid_id}")
|
|
||||||
log(f" [DESTRUCT] TA Path: {raw_ta_path}")
|
if not vid_id:
|
||||||
log(f" [DESTRUCT] Local Path: {source_path}")
|
vid_id = extract_id_from_filename(p.name)
|
||||||
|
|
||||||
if source_path and source_path.exists():
|
if vid_id:
|
||||||
try:
|
meta = video_map.get(vid_id)
|
||||||
source_path.unlink()
|
if meta:
|
||||||
log(f"☢️ [DESTRUCT] Deleted source: {source_path}")
|
raw_ta_path = meta.get('filesystem_path')
|
||||||
source_deleted = True
|
if raw_ta_path:
|
||||||
except Exception as se:
|
source_path = translate_ta_path(raw_ta_path)
|
||||||
log(f"❌ [DESTRUCT] Failed to delete source {source_path}: {se}")
|
log(f" [DESTRUCT] API Fallback Path: {source_path}")
|
||||||
raise Exception(f"Source deletion failed: {se}")
|
|
||||||
else:
|
# --- Execution: Delete the identified source ---
|
||||||
log(f" [DESTRUCT] Local file NOT FOUND at: {source_path}")
|
if source_path and source_path.exists():
|
||||||
|
try:
|
||||||
|
source_path.unlink()
|
||||||
|
log(f"☢️ [DESTRUCT] Deleted source: {source_path}")
|
||||||
|
source_deleted = True
|
||||||
|
except Exception as se:
|
||||||
|
log(f"❌ [DESTRUCT] Failed to delete source {source_path}: {se}")
|
||||||
|
raise Exception(f"Source deletion failed: {se}")
|
||||||
|
else:
|
||||||
|
log(f"⚠️ [DESTRUCT] Source file NOT FOUND (Tried symlink resolution and API lookup)")
|
||||||
|
|
||||||
if not source_deleted:
|
if not source_deleted:
|
||||||
log(f"⚠️ [DESTRUCT] Source file not found for: {path} (ID: {vid_id or 'unknown'})")
|
# Log IDs to help debug if it still fails
|
||||||
|
vid_id_debug = "?"
|
||||||
|
with get_db() as conn:
|
||||||
|
row = conn.execute("SELECT video_id FROM videos WHERE symlink = ?", (path,)).fetchone()
|
||||||
|
if row: vid_id_debug = row['video_id']
|
||||||
|
log(f"⚠️ [DESTRUCT] Source file not found for: {path} (ID: {vid_id_debug})")
|
||||||
|
|
||||||
# 2. Delete Target (Use lexists so we can delete broken symlinks!)
|
# 2. Delete Target (Use lexists so we can delete broken symlinks!)
|
||||||
if os.path.lexists(p):
|
if os.path.lexists(p):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue