final dev

This commit is contained in:
2026-03-11 13:17:34 +00:00
parent c23fbb53b7
commit e70c50ae87

View File

@@ -3423,12 +3423,31 @@ class PipelineService extends EventEmitter {
return null; return null;
} }
const folderName = path.basename(stored); const folderName = path.basename(stored);
const candidates = [stored]; const currentBaseDir = path.dirname(stored);
const allBaseDirs = [rawBaseDir, ...extraBaseDirs].filter(Boolean); const allBaseDirs = [currentBaseDir, rawBaseDir, ...extraBaseDirs].filter(Boolean);
for (const baseDir of allBaseDirs) { const uniqueBaseDirs = Array.from(new Set(allBaseDirs.map((item) => String(item).trim()).filter(Boolean)));
const byFolder = path.join(baseDir, folderName); const variantFolderNames = Array.from(
if (!candidates.includes(byFolder)) { new Set(
candidates.push(byFolder); [
folderName,
applyRawFolderStateToName(folderName, RAW_FOLDER_STATES.RIP_COMPLETE),
applyRawFolderStateToName(folderName, RAW_FOLDER_STATES.INCOMPLETE),
applyRawFolderStateToName(folderName, RAW_FOLDER_STATES.COMPLETE)
].map((item) => String(item || '').trim()).filter(Boolean)
)
);
const candidates = [];
const pushCandidate = (candidatePath) => {
const normalized = String(candidatePath || '').trim();
if (!normalized || candidates.includes(normalized)) {
return;
}
candidates.push(normalized);
};
pushCandidate(stored);
for (const baseDir of uniqueBaseDirs) {
for (const variantFolderName of variantFolderNames) {
pushCandidate(path.join(baseDir, variantFolderName));
} }
} }
for (const candidate of candidates) { for (const candidate of candidates) {
@@ -6602,6 +6621,15 @@ class PipelineService extends EventEmitter {
this.startEncodingFromPrepared(jobId).catch((error) => { this.startEncodingFromPrepared(jobId).catch((error) => {
logger.error('startPreparedJob:encode-background-failed', { jobId, error: errorToMeta(error) }); logger.error('startPreparedJob:encode-background-failed', { jobId, error: errorToMeta(error) });
if (error?.jobAlreadyFailed) {
return;
}
this.failJob(jobId, 'ENCODING', error).catch((failError) => {
logger.error('startPreparedJob:encode-background-failJob-failed', {
jobId,
error: errorToMeta(failError)
});
});
}); });
return { started: true, stage: 'ENCODING' }; return { started: true, stage: 'ENCODING' };
@@ -7823,17 +7851,59 @@ class PipelineService extends EventEmitter {
rawPath: job.raw_path rawPath: job.raw_path
}); });
const settings = await settingsService.getEffectiveSettingsMap(mediaProfile); const settings = await settingsService.getEffectiveSettingsMap(mediaProfile);
const rawBaseDir = String(settings.raw_dir || '').trim();
const rawExtraDirs = [
settings.raw_dir_bluray,
settings.raw_dir_dvd,
settings.raw_dir_other
].map((item) => String(item || '').trim()).filter(Boolean);
const resolvedRawPath = job.raw_path
? this.resolveCurrentRawPath(rawBaseDir, job.raw_path, rawExtraDirs)
: null;
const activeRawPath = resolvedRawPath || String(job.raw_path || '').trim() || null;
if (activeRawPath && normalizeComparablePath(activeRawPath) !== normalizeComparablePath(job.raw_path)) {
await historyService.updateJob(jobId, { raw_path: activeRawPath });
await historyService.appendLog(
jobId,
'SYSTEM',
`RAW-Pfad für Encode-Start aktualisiert: ${job.raw_path} -> ${activeRawPath}`
);
}
const movieDir = settings.movie_dir; const movieDir = settings.movie_dir;
ensureDir(movieDir); ensureDir(movieDir);
const mode = encodePlan?.mode || this.snapshot.context?.mode || 'rip'; const mode = encodePlan?.mode || this.snapshot.context?.mode || 'rip';
let inputPath = job.encode_input_path || encodePlan?.encodeInputPath || this.snapshot.context?.inputPath || null; let inputPath = job.encode_input_path || encodePlan?.encodeInputPath || this.snapshot.context?.inputPath || null;
let playlistDecision = null;
if (!inputPath && job.raw_path) { const resolveInputFromRaw = (rawPathCandidate) => {
const playlistDecision = this.resolvePlaylistDecisionForJob(jobId, job); if (!rawPathCandidate) {
inputPath = findPreferredRawInput(job.raw_path, { return null;
}
if (hasBluRayBackupStructure(rawPathCandidate)) {
return rawPathCandidate;
}
if (!playlistDecision) {
playlistDecision = this.resolvePlaylistDecisionForJob(jobId, job);
}
return findPreferredRawInput(rawPathCandidate, {
playlistAnalysis: playlistDecision.playlistAnalysis, playlistAnalysis: playlistDecision.playlistAnalysis,
selectedPlaylistId: playlistDecision.selectedPlaylist selectedPlaylistId: playlistDecision.selectedPlaylist
})?.path || null; })?.path || null;
};
if (inputPath && !fs.existsSync(inputPath)) {
const recoveredInputPath = resolveInputFromRaw(activeRawPath);
if (recoveredInputPath && fs.existsSync(recoveredInputPath)) {
await historyService.appendLog(
jobId,
'SYSTEM',
`Encode-Input wurde auf aktuellen RAW-Pfad korrigiert: ${inputPath} -> ${recoveredInputPath}`
);
inputPath = recoveredInputPath;
}
}
if (!inputPath) {
inputPath = resolveInputFromRaw(activeRawPath);
} }
if (!inputPath) { if (!inputPath) {
@@ -7878,7 +7948,8 @@ class PipelineService extends EventEmitter {
status: 'ENCODING', status: 'ENCODING',
last_state: 'ENCODING', last_state: 'ENCODING',
output_path: incompleteOutputPath, output_path: incompleteOutputPath,
encode_input_path: inputPath encode_input_path: inputPath,
...(activeRawPath ? { raw_path: activeRawPath } : {})
}); });
await historyService.appendLog( await historyService.appendLog(
@@ -7904,7 +7975,7 @@ class PipelineService extends EventEmitter {
jobId, jobId,
jobTitle: job.title || job.detected_title || null, jobTitle: job.title || job.detected_title || null,
inputPath, inputPath,
rawPath: job.raw_path || null, rawPath: activeRawPath,
mediaProfile mediaProfile
}; };
const preScriptIds = normalizeScriptIdList(encodePlan?.preEncodeScriptIds || []); const preScriptIds = normalizeScriptIdList(encodePlan?.preEncodeScriptIds || []);
@@ -8115,7 +8186,7 @@ class PipelineService extends EventEmitter {
jobTitle: job.title || job.detected_title || null, jobTitle: job.title || job.detected_title || null,
inputPath, inputPath,
outputPath: finalizedOutputPath, outputPath: finalizedOutputPath,
rawPath: job.raw_path || null rawPath: activeRawPath
}, encodeScriptProgressTracker); }, encodeScriptProgressTracker);
} catch (error) { } catch (error) {
logger.warn('encode:post-script:summary-failed', { logger.warn('encode:post-script:summary-failed', {
@@ -8135,9 +8206,9 @@ class PipelineService extends EventEmitter {
`Post-Encode Skripte abgeschlossen: ${postEncodeScriptsSummary.succeeded} erfolgreich, ${postEncodeScriptsSummary.failed} fehlgeschlagen, ${postEncodeScriptsSummary.skipped} übersprungen.${postEncodeScriptsSummary.aborted ? ' Kette wurde abgebrochen.' : ''}` `Post-Encode Skripte abgeschlossen: ${postEncodeScriptsSummary.succeeded} erfolgreich, ${postEncodeScriptsSummary.failed} fehlgeschlagen, ${postEncodeScriptsSummary.skipped} übersprungen.${postEncodeScriptsSummary.aborted ? ' Kette wurde abgebrochen.' : ''}`
); );
} }
let finalizedRawPath = job.raw_path || null; let finalizedRawPath = activeRawPath || null;
if (job.raw_path) { if (activeRawPath) {
const currentRawPath = String(job.raw_path || '').trim(); const currentRawPath = String(activeRawPath || '').trim();
const completedRawPath = buildCompletedRawPath(currentRawPath); const completedRawPath = buildCompletedRawPath(currentRawPath);
if (completedRawPath && completedRawPath !== currentRawPath) { if (completedRawPath && completedRawPath !== currentRawPath) {
if (fs.existsSync(completedRawPath)) { if (fs.existsSync(completedRawPath)) {
@@ -8245,6 +8316,7 @@ class PipelineService extends EventEmitter {
} }
logger.error('encode:start-from-prepared:failed', { jobId, mode, error: errorToMeta(error) }); logger.error('encode:start-from-prepared:failed', { jobId, mode, error: errorToMeta(error) });
await this.failJob(jobId, 'ENCODING', error); await this.failJob(jobId, 'ENCODING', error);
error.jobAlreadyFailed = true;
throw error; throw error;
} }
} }