fix: Streamline transcode replacement with per-item live progress and safe history logging
This commit is contained in:
@@ -8027,7 +8027,7 @@ Return ONLY a valid JSON object with an array named "results":
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Batch Replace Action
|
// Batch Replace Action with Live Per-Item Progress
|
||||||
const btnBatchReplaceTranscodes = document.getElementById('btn-batch-replace-transcodes');
|
const btnBatchReplaceTranscodes = document.getElementById('btn-batch-replace-transcodes');
|
||||||
if (btnBatchReplaceTranscodes) {
|
if (btnBatchReplaceTranscodes) {
|
||||||
btnBatchReplaceTranscodes.addEventListener('click', async () => {
|
btnBatchReplaceTranscodes.addEventListener('click', async () => {
|
||||||
@@ -8043,35 +8043,64 @@ Return ONLY a valid JSON object with an array named "results":
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
const deleteCache = document.getElementById('transcode-opt-delete-cache')?.checked;
|
||||||
btnBatchReplaceTranscodes.disabled = true;
|
const triggerRescan = document.getElementById('transcode-opt-trigger-rescan')?.checked;
|
||||||
btnBatchReplaceTranscodes.textContent = `Replacing ${selectedItems.length}...`;
|
|
||||||
|
|
||||||
const deleteCache = document.getElementById('transcode-opt-delete-cache')?.checked;
|
let successCount = 0;
|
||||||
const triggerRescan = document.getElementById('transcode-opt-trigger-rescan')?.checked;
|
let totalSavedBytes = 0;
|
||||||
|
btnBatchReplaceTranscodes.disabled = true;
|
||||||
|
|
||||||
const res = await fetch('/api/stash/transcodes/batch-replace', {
|
for (let i = 0; i < selectedItems.length; i++) {
|
||||||
method: 'POST',
|
const item = selectedItems[i];
|
||||||
headers: { 'Content-Type': 'application/json' },
|
btnBatchReplaceTranscodes.textContent = `Replacing ${i + 1} / ${selectedItems.length}...`;
|
||||||
body: JSON.stringify({
|
|
||||||
items: selectedItems,
|
const row = document.getElementById(`transcode-row-${item.oshash}`);
|
||||||
delete_transcode: deleteCache,
|
const replaceBtn = row?.querySelector('.btn-transcode-replace-single');
|
||||||
trigger_rescan: triggerRescan
|
if (replaceBtn) {
|
||||||
})
|
replaceBtn.disabled = true;
|
||||||
});
|
replaceBtn.textContent = '⏳ Copying...';
|
||||||
const data = await res.json();
|
}
|
||||||
if (data.success) {
|
|
||||||
showToast(`✓ Batch replaced ${data.replaced_count} files (Saved ${(data.total_saved_bytes/(1024*1024)).toFixed(1)} MB)!`, 'success');
|
try {
|
||||||
await scanStashTranscodes();
|
const res = await fetch('/api/stash/transcodes/replace', {
|
||||||
} else {
|
method: 'POST',
|
||||||
showToast(`Batch error: ${data.error}`, 'error');
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({
|
||||||
|
orig_local_path: item.orig_local_path,
|
||||||
|
transcode_path: item.transcode_path,
|
||||||
|
delete_transcode: deleteCache,
|
||||||
|
trigger_rescan: (i === selectedItems.length - 1) ? triggerRescan : false
|
||||||
|
})
|
||||||
|
});
|
||||||
|
const data = await res.json();
|
||||||
|
if (data.success) {
|
||||||
|
successCount++;
|
||||||
|
totalSavedBytes += (data.saved_bytes || 0);
|
||||||
|
if (row) {
|
||||||
|
row.style.opacity = '0.4';
|
||||||
|
row.style.background = 'rgba(16, 185, 129, 0.1)';
|
||||||
|
if (replaceBtn) replaceBtn.textContent = '✅ Replaced';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (replaceBtn) {
|
||||||
|
replaceBtn.disabled = false;
|
||||||
|
replaceBtn.textContent = '❌ Failed';
|
||||||
|
replaceBtn.title = data.error || 'Failed';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
if (replaceBtn) {
|
||||||
|
replaceBtn.disabled = false;
|
||||||
|
replaceBtn.textContent = '❌ Error';
|
||||||
|
replaceBtn.title = err.message;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
|
||||||
showToast(`Batch execution error: ${err.message}`, 'error');
|
|
||||||
} finally {
|
|
||||||
btnBatchReplaceTranscodes.disabled = false;
|
|
||||||
btnBatchReplaceTranscodes.textContent = `⚡ Batch Replace Selected (${selectedTranscodeHashes.size})`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const savedMb = (totalSavedBytes / (1024 * 1024)).toFixed(1);
|
||||||
|
showToast(`✓ Batch completed: Replaced ${successCount} / ${selectedItems.length} files (Saved ${savedMb} MB)!`, 'success');
|
||||||
|
btnBatchReplaceTranscodes.disabled = false;
|
||||||
|
btnBatchReplaceTranscodes.textContent = `⚡ Batch Replace Selected (${selectedTranscodeHashes.size})`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2889,14 +2889,18 @@ class RobustProxyHandler(http.server.SimpleHTTPRequestHandler):
|
|||||||
saved_bytes = orig_size - transcode_size
|
saved_bytes = orig_size - transcode_size
|
||||||
|
|
||||||
# Step 5: Record to Relocation History audit log
|
# Step 5: Record to Relocation History audit log
|
||||||
record_relocation_history(
|
try:
|
||||||
source_path=transcode_path,
|
record_relocation_history(
|
||||||
target_path=orig_local_path,
|
source_type="stash_transcode",
|
||||||
performer_name="Transcode Optimization",
|
item_key=orig_local_path,
|
||||||
status="completed",
|
item_name=os.path.basename(orig_local_path),
|
||||||
size_bytes=transcode_size,
|
source_path=transcode_path,
|
||||||
action_type="transcode_replace"
|
target_path=orig_local_path,
|
||||||
)
|
performer="Transcode Optimization",
|
||||||
|
file_size=transcode_size
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Warning: History record error: {e}")
|
||||||
|
|
||||||
# Step 6: Trigger Stash metadata scan on parent folder if requested
|
# Step 6: Trigger Stash metadata scan on parent folder if requested
|
||||||
if trigger_rescan:
|
if trigger_rescan:
|
||||||
@@ -2967,6 +2971,19 @@ class RobustProxyHandler(http.server.SimpleHTTPRequestHandler):
|
|||||||
saved = orig_size - transcode_size
|
saved = orig_size - transcode_size
|
||||||
total_saved_bytes += saved
|
total_saved_bytes += saved
|
||||||
rescanned_dirs.add(os.path.dirname(orig_local_path))
|
rescanned_dirs.add(os.path.dirname(orig_local_path))
|
||||||
|
|
||||||
|
try:
|
||||||
|
record_relocation_history(
|
||||||
|
source_type="stash_transcode",
|
||||||
|
item_key=orig_local_path,
|
||||||
|
item_name=os.path.basename(orig_local_path),
|
||||||
|
source_path=transcode_path,
|
||||||
|
target_path=orig_local_path,
|
||||||
|
performer="Transcode Optimization",
|
||||||
|
file_size=transcode_size
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
errors.append({"path": orig_local_path, "error": str(e)})
|
errors.append({"path": orig_local_path, "error": str(e)})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user