Remove empty release dirs after finalize move

05_Finalize_Move loeschte nur die Original-Videodatei, nicht das
Release-Verzeichnis. Zurueck blieben leere Ordner mit .nfo-Resten unter
/tdarr/complete/, die GET /media/handoff/diagnostics als target_directories
auflistet und dadurch wie haengende Jobs aussehen (6 Leichen gefunden).

cleanupSourceDir loescht das Verzeichnis nur wenn:
- es unter SourceRoot liegt und nicht SourceRoot selbst ist
- find erfolgreich war (fail safe bei Fehler)
- keine Mediendatei mehr darin liegt (Season-Pack-Schutz)

6 neue Tests im bestehenden Node-VM-Harness, 22/22 gruen.
This commit is contained in:
Trulla 2026-09-16 11:45:33 +02:00
parent d32600aaa2
commit 650417d42b
2 changed files with 216 additions and 1 deletions

View file

@ -4,8 +4,10 @@
* behandelt Untertitel (Text-Subs als .srt-Sidecar, Bild-Subs Disposition neutralisieren).
* SICHERHEITS-FIX 17.07.2026: atomare Sidecar-Erzeugung, 0-Byte-Pruefung,
* nur erfolgreich extrahierte Textspuren entfernen, Remux-Verifikation.
* CLEANUP-FIX 16.09.2026: leeres Release-Verzeichnis unter SourceRoot
* entfernen (nur wenn keine Mediendatei mehr drin liegt).
* @author Sascha + Trulla
* @revision 2
* @revision 3
* @output OK
* @output Fehler
*/
@ -58,6 +60,7 @@ function Script(SourceRoot, DestRoot)
if (origPath !== destAbs) {
Flow.Execute({ command: '/bin/rm', argumentList: ['-f', origPath] });
Logger.ILog('Deleted original: ' + origPath);
cleanupSourceDir(origPath);
}
// =======================================================================
@ -87,6 +90,52 @@ function Script(SourceRoot, DestRoot)
return 1;
// -- Helfer --------------------------------------------------------------
/**
* Loescht das Release-Verzeichnis des Originals, wenn darin keine
* Mediendatei mehr liegt. Ohne das bleiben nach jedem Import leere
* Ordner mit .nfo/.sfv-Resten unter /tdarr/complete/ liegen, die den
* Handoff-Diagnostics-Endpoint als "target_directories" verschmutzen
* und faelschlich wie haengende Jobs aussehen.
* Sicherheit: nur unter SourceRoot, nur wenn keine Mediendatei mehr da.
*/
function cleanupSourceDir(originalFile) {
var dir = originalFile.substring(0, originalFile.lastIndexOf('/'));
if (!dir || dir.indexOf(SourceRoot) !== 0 || dir === SourceRoot ||
dir === SourceRoot.replace(/\/$/, '')) {
Logger.ILog('Cleanup: "' + dir + '" nicht unter ' + SourceRoot + ' - uebersprungen');
return;
}
var mediaExts = ['mkv', 'mp4', 'avi', 'ts', 'm2ts', 'mov', 'wmv', 'mpg', 'mpeg', 'm4v', 'iso'];
var findArgs = [dir, '-type', 'f', '('];
mediaExts.forEach(function (ext, i) {
if (i > 0) findArgs.push('-o');
findArgs.push('-iname', '*.' + ext);
});
findArgs.push(')');
var found = Flow.Execute({ command: '/usr/bin/find', argumentList: findArgs });
if (!found || found.exitCode !== 0) {
Logger.WLog('Cleanup: find fehlgeschlagen - Verzeichnis bleibt: ' + dir);
return;
}
var remaining = ('' + (found.standardOutput || '')).trim();
if (remaining.length > 0) {
Logger.ILog('Cleanup: Mediendateien noch vorhanden - Verzeichnis bleibt: ' + dir);
return;
}
var del = Flow.Execute({ command: '/bin/rm', argumentList: ['-rf', dir] });
if (del && del.exitCode === 0) {
Logger.ILog('Cleanup: Release-Verzeichnis entfernt: ' + dir);
} else {
Logger.WLog('Cleanup: rm fehlgeschlagen (exit=' + (del ? del.exitCode : '?') + '): ' + dir);
}
}
function handleSubtitles(file) {
var ffprobe = Flow.GetToolPath('ffprobe') || Variables['ffprobe'] || 'ffprobe';
var ffmpeg = Flow.GetToolPath('ffmpeg') || Variables['ffmpeg'] || 'ffmpeg';