0.12.0-18 Tests and Converter Fixes

This commit is contained in:
2026-03-31 12:51:32 +00:00
parent aea8fa6772
commit 5aa65ad4c1
24 changed files with 2281 additions and 249 deletions
+58 -6
View File
@@ -22,7 +22,7 @@ function parseJsonSafe(raw, fallback = null) {
const PROCESS_LOG_TAIL_MAX_BYTES = 1024 * 1024;
const processLogStreams = new Map();
const PROFILE_PATH_SUFFIXES = ['bluray', 'dvd', 'cd', 'audiobook', 'other'];
const PROFILE_PATH_SUFFIXES = ['bluray', 'dvd', 'cd', 'audiobook', 'converter', 'other'];
const RAW_INCOMPLETE_PREFIX = 'Incomplete_';
const RAW_RIP_COMPLETE_PREFIX = 'Rip_Complete_';
const PROCESS_LOG_FILE_PATTERN = /^job-(\d+)\.process\.log$/i;
@@ -329,7 +329,27 @@ function inferMediaType(job, makemkvInfo, mediainfoInfo, encodePlan, handbrakeIn
// Converter jobs: detected via media_type field (plan.mediaProfile = 'converter')
const rawMediaType = normalizeMediaTypeValue(job?.media_type);
const rawPlanProfile = String(plan?.mediaProfile || '').trim().toLowerCase();
if (rawPlanProfile === 'converter' || rawMediaType === 'converter') {
const converterMediaTypeHint = String(plan?.converterMediaType || '').trim().toLowerCase();
const hasConverterPathHint = (value) => {
const normalized = String(value || '')
.trim()
.replace(/\\/g, '/')
.toLowerCase();
if (!normalized) {
return false;
}
return /(^|\/)converter(\/|$)/.test(normalized);
};
if (
rawPlanProfile === 'converter'
|| rawMediaType === 'converter'
|| converterMediaTypeHint === 'video'
|| converterMediaTypeHint === 'audio'
|| converterMediaTypeHint === 'iso'
|| hasConverterPathHint(rawPath)
|| hasConverterPathHint(encodeInputPath)
|| hasConverterPathHint(plan?.inputPath)
) {
return 'converter';
}
@@ -630,12 +650,17 @@ function enrichJobRow(job, settings = null, options = {}) {
const mediainfoInfo = resolvedPaths.mediainfoInfo;
const encodePlan = resolvedPaths.encodePlan;
const mediaType = resolvedPaths.mediaType;
const normalizedJobStatus = String(job?.status || '').trim().toUpperCase();
const ripSuccessful = Number(job?.rip_successful || 0) === 1
|| String(makemkvInfo?.status || '').trim().toUpperCase() === 'SUCCESS';
const backupSuccess = ripSuccessful;
const finishedWithOutput = normalizedJobStatus === 'FINISHED'
&& (includeFsChecks ? Boolean(outputStatus?.exists) : true);
const encodeSuccess = directoryLikeOutput
? (String(job?.status || '').trim().toUpperCase() === 'FINISHED' && Boolean(outputStatus?.exists))
: String(handbrakeInfo?.status || '').trim().toUpperCase() === 'SUCCESS';
? finishedWithOutput
: (mediaType === 'converter'
? finishedWithOutput
: String(handbrakeInfo?.status || '').trim().toUpperCase() === 'SUCCESS');
return {
...job,
@@ -3067,7 +3092,33 @@ class HistoryService {
`
SELECT *
FROM jobs
WHERE status IN ('ANALYZING', 'RIPPING', 'ENCODING', 'MEDIAINFO_CHECK', 'READY_TO_ENCODE', 'CD_ANALYZING', 'CD_READY_TO_RIP', 'CD_RIPPING', 'CD_ENCODING')
WHERE status IN ('ANALYZING', 'RIPPING', 'ENCODING', 'MEDIAINFO_CHECK', 'CD_ANALYZING', 'CD_RIPPING', 'CD_ENCODING')
ORDER BY updated_at ASC, id ASC
`
),
settingsService.getSettingsMap()
]);
return rows.map((job) => ({
...enrichJobRow(job, settings),
log_count: hasProcessLogFile(job.id) ? 1 : 0
}));
}
async getQueueIdleJobs() {
const db = await getDb();
const [rows, settings] = await Promise.all([
db.all(
`
SELECT *
FROM jobs
WHERE status IN (
'METADATA_SELECTION',
'WAITING_FOR_USER_DECISION',
'READY_TO_START',
'READY_TO_ENCODE',
'CD_METADATA_SELECTION',
'CD_READY_TO_RIP'
)
ORDER BY updated_at ASC, id ASC
`
),
@@ -4041,6 +4092,7 @@ class HistoryService {
}
const artifactMoviePathSet = new Set(artifactMoviePaths);
const includeMovieParentCandidate = resolvedPaths?.mediaType !== 'converter';
for (const outputPath of explicitMoviePaths) {
addCandidate(
movieCandidates,
@@ -4050,7 +4102,7 @@ class HistoryService {
movieAllowedPaths
);
const parentDir = toNormalizedPath(path.dirname(outputPath));
if (parentDir && !movieRoots.includes(parentDir)) {
if (includeMovieParentCandidate && parentDir && !movieRoots.includes(parentDir)) {
addCandidate(
movieCandidates,
'movie',