This commit is contained in:
2026-03-04 14:48:56 +00:00
parent 31d3e36597
commit 3b293bb743
11 changed files with 1116 additions and 310 deletions

View File

@@ -210,6 +210,8 @@ function enrichJobRow(job) {
const omdbInfo = parseJsonSafe(job.omdb_json, null);
const encodePlan = parseJsonSafe(job.encode_plan_json, null);
const mediaType = inferMediaType(job, makemkvInfo, mediainfoInfo, encodePlan);
const backupSuccess = String(makemkvInfo?.status || '').trim().toUpperCase() === 'SUCCESS';
const encodeSuccess = String(handbrakeInfo?.status || '').trim().toUpperCase() === 'SUCCESS';
return {
...job,
@@ -219,6 +221,8 @@ function enrichJobRow(job) {
omdbInfo,
encodePlan,
mediaType,
backupSuccess,
encodeSuccess,
rawStatus,
outputStatus,
movieDirStatus
@@ -959,17 +963,34 @@ class HistoryService {
} else if (!fs.existsSync(job.output_path)) {
summary.movie.reason = 'Movie-Datei/Pfad existiert nicht.';
} else {
const stat = fs.lstatSync(job.output_path);
const outputPath = normalizeComparablePath(job.output_path);
const movieRoot = normalizeComparablePath(settings.movie_dir);
const stat = fs.lstatSync(outputPath);
if (stat.isDirectory()) {
const result = deleteFilesRecursively(job.output_path, true);
const keepRoot = outputPath === movieRoot;
const result = deleteFilesRecursively(outputPath, keepRoot ? true : false);
summary.movie.deleted = true;
summary.movie.filesDeleted = result.filesDeleted;
summary.movie.dirsRemoved = result.dirsRemoved;
} else {
fs.unlinkSync(job.output_path);
summary.movie.deleted = true;
summary.movie.filesDeleted = 1;
summary.movie.dirsRemoved = 0;
const parentDir = normalizeComparablePath(path.dirname(outputPath));
const canDeleteParentDir = parentDir
&& parentDir !== movieRoot
&& isPathInside(movieRoot, parentDir)
&& fs.existsSync(parentDir)
&& fs.lstatSync(parentDir).isDirectory();
if (canDeleteParentDir) {
const result = deleteFilesRecursively(parentDir, false);
summary.movie.deleted = true;
summary.movie.filesDeleted = result.filesDeleted;
summary.movie.dirsRemoved = result.dirsRemoved;
} else {
fs.unlinkSync(outputPath);
summary.movie.deleted = true;
summary.movie.filesDeleted = 1;
summary.movie.dirsRemoved = 0;
}
}
}
}

View File

@@ -4894,8 +4894,31 @@ class PipelineService extends EventEmitter {
throw error;
}
const settings = await settingsService.getSettingsMap();
const restartDeleteIncompleteOutput = settings?.handbrake_restart_delete_incomplete_output !== undefined
? Boolean(settings.handbrake_restart_delete_incomplete_output)
: true;
const handBrakeInfo = this.safeParseJson(job.handbrake_info_json);
const encodePreviouslySuccessful = String(handBrakeInfo?.status || '').trim().toUpperCase() === 'SUCCESS';
const previousOutputPath = String(job.output_path || '').trim() || null;
if (previousOutputPath && restartDeleteIncompleteOutput && !encodePreviouslySuccessful) {
try {
const deleteResult = await historyService.deleteJobFiles(jobId, 'movie');
await historyService.appendLog(
jobId,
'USER_ACTION',
`Encode-Neustart: unvollständigen Output vor Start entfernt (movie files=${deleteResult?.summary?.movie?.filesDeleted ?? 0}, dirs=${deleteResult?.summary?.movie?.dirsRemoved ?? 0}).`
);
} catch (error) {
logger.warn('restartEncodeWithLastSettings:delete-incomplete-output-failed', {
jobId,
outputPath: previousOutputPath,
error: errorToMeta(error)
});
}
}
await historyService.updateJob(jobId, {
status: 'READY_TO_ENCODE',
last_state: 'READY_TO_ENCODE',
@@ -4908,7 +4931,7 @@ class PipelineService extends EventEmitter {
jobId,
'USER_ACTION',
previousOutputPath
? `Encode-Neustart angefordert. Letzte bestätigte Auswahl wird verwendet. Vorheriger Output-Pfad: ${previousOutputPath}`
? `Encode-Neustart angefordert. Letzte bestätigte Auswahl wird verwendet. Vorheriger Output-Pfad: ${previousOutputPath}. autoDeleteIncomplete=${restartDeleteIncompleteOutput ? 'on' : 'off'}`
: 'Encode-Neustart angefordert. Letzte bestätigte Auswahl wird verwendet.'
);