fix: resilient file lookup — walk directory if exact path not found; use resume_file for sessions

This commit is contained in:
Claus Lohmar 2026-07-27 12:37:38 +00:00
parent b257ada9a8
commit 7aaa0d1553
3 changed files with 20 additions and 3 deletions

View file

@ -145,12 +145,18 @@ def list_sessions():
continue
archives = {".7z", ".zip", ".rar", ".tar.gz", ".tgz", ".tar", ".gz", ".bz2", ".xz", ".ova"}
has_source = has_disks or any(f["name"].lower().endswith(tuple(archives)) for f in session_files)
resume_file = session_files[0]["name"]
for f in session_files:
if f["name"].lower().endswith(tuple(archives)) or f["name"].lower().endswith((".vmdk", ".qcow2", ".vdi")):
resume_file = f["name"]
break
sessions.append({
"session_id": entry.name,
"files": session_files[:10],
"total_size_gb": round(total_bytes / (1024**3), 1),
"has_disks": has_disks,
"resumable": has_source,
"resume_file": resume_file,
})
except Exception:
pass

View file

@ -52,7 +52,18 @@ def extract_if_needed(filename: str) -> Path:
if not filepath.is_absolute():
filepath = STAGING_ROOT / filename
if not filepath.exists():
raise FileNotFoundError(f"Source not found: {filepath}")
# Try finding by name — walk the parent directory
parent = filepath.parent
fname = filepath.name
if parent.exists() and parent.is_dir():
found = list(parent.rglob(fname))
if found:
filepath = found[0]
logger.info("Found by name: %s", filepath)
else:
raise FileNotFoundError(f"Source not found: {filepath}")
else:
raise FileNotFoundError(f"Source not found: {filepath}")
# Detect archive type
name = filepath.name.lower()

View file

@ -91,13 +91,13 @@ async function loadSessions() {
for (var i = 0; i < sessions.length; i++) {
var s = sessions[i];
var fileNames = s.files.map(function(f) { return f.name; }).join(', ');
var firstFile = s.files[0].name;
var resumeFile = s.resume_file || s.files[0].name;
html += '<div style="display:flex;align-items:center;justify-content:space-between;padding:0.4rem 0;border-bottom:1px solid var(--pve-border);">';
html += '<div><span class="pve-code">' + s.session_id.substring(0, 8) + '</span> &mdash; ' + fileNames + ' <span class="pve-dim">(' + s.total_size_gb + ' GiB)</span>';
if (s.has_disks) html += ' <span class="pve-badge pve-badge-completed" style="font-size:0.65rem;">extracted</span>';
html += '</div>';
if (s.resumable) {
html += '<button class="pve-btn pve-btn-primary pve-btn-small" onclick="resumeSession(\'' + s.session_id + '\', \'' + firstFile.replace(/'/g, "\\'") + '\')">Resume</button>';
html += '<button class="pve-btn pve-btn-primary pve-btn-small" onclick="resumeSession(\'' + s.session_id + '\', \'' + resumeFile.replace(/'/g, "\\'") + '\')">Resume</button>';
}
html += '<button class="pve-btn pve-btn-small" onclick="cleanupSession(\'' + s.session_id + '\', this)" style="margin-left:0.3rem;color:var(--pve-red);border-color:var(--pve-red);">Clear</button>';
html += '</div>';