0.13.1-10 Misc fixes
This commit is contained in:
@@ -133,6 +133,16 @@ function parseInfoFromValue(value, fallback = null) {
|
||||
return parseJsonSafe(value, fallback);
|
||||
}
|
||||
|
||||
function isOrphanRawImportMakemkvInfo(makemkvInfo = null) {
|
||||
const info = makemkvInfo && typeof makemkvInfo === 'object' ? makemkvInfo : {};
|
||||
const source = String(
|
||||
info?.source
|
||||
|| info?.importRecovery?.source
|
||||
|| ''
|
||||
).trim().toLowerCase();
|
||||
return source === 'orphan_raw_import';
|
||||
}
|
||||
|
||||
function hasBlurayStructure(rawPath) {
|
||||
const basePath = String(rawPath || '').trim();
|
||||
if (!basePath) {
|
||||
@@ -5180,6 +5190,7 @@ class HistoryService {
|
||||
? Math.trunc(manualEpisodeCountRaw)
|
||||
: null;
|
||||
const manualEpisodes = Array.isArray(payload.episodes) ? payload.episodes : null;
|
||||
const hasExplicitManualEpisodes = Boolean(manualEpisodes && manualEpisodes.length > 0);
|
||||
const manualMetadataKind = String(payload.metadataKind || '').trim().toLowerCase() || null;
|
||||
const manualProviderId = String(payload.providerId || '').trim() || null;
|
||||
|
||||
@@ -5240,7 +5251,7 @@ class HistoryService {
|
||||
let episodeCount = manualEpisodeCount !== null
|
||||
? manualEpisodeCount
|
||||
: (Number(existingSelectedMetadata?.episodeCount || 0) || 0);
|
||||
let episodes = manualEpisodes && manualEpisodes.length > 0
|
||||
let episodes = hasExplicitManualEpisodes
|
||||
? manualEpisodes
|
||||
: (Array.isArray(existingSelectedMetadata?.episodes) ? existingSelectedMetadata.episodes : []);
|
||||
const discNumber = manualDiscNumber !== null
|
||||
@@ -5280,6 +5291,13 @@ class HistoryService {
|
||||
? `tmdb:${effectiveTmdbId}:season:${seasonNumber}`
|
||||
: `tmdb:${effectiveTmdbId}`;
|
||||
}
|
||||
let tmdbLanguage = null;
|
||||
try {
|
||||
const dvdSettings = await settingsService.getEffectiveSettingsMap('dvd');
|
||||
tmdbLanguage = String(dvdSettings?.dvd_series_language || '').trim() || null;
|
||||
} catch (_settingsError) {
|
||||
tmdbLanguage = null;
|
||||
}
|
||||
|
||||
let tmdbDetails = existingSelectedMetadata?.tmdbDetails && typeof existingSelectedMetadata.tmdbDetails === 'object'
|
||||
? { ...existingSelectedMetadata.tmdbDetails }
|
||||
@@ -5287,6 +5305,7 @@ class HistoryService {
|
||||
if (effectiveTmdbId !== null) {
|
||||
try {
|
||||
const seriesDetails = await tmdbService.getSeriesDetails(effectiveTmdbId, {
|
||||
language: tmdbLanguage,
|
||||
appendToResponse: ['credits', 'external_ids']
|
||||
});
|
||||
if (seriesDetails) {
|
||||
@@ -5325,12 +5344,16 @@ class HistoryService {
|
||||
|
||||
if (effectiveTmdbId !== null && seasonNumber !== null) {
|
||||
try {
|
||||
const seasonDetails = await tmdbService.getSeasonDetails(effectiveTmdbId, seasonNumber);
|
||||
const seasonCredits = await tmdbService.getSeasonCredits(effectiveTmdbId, seasonNumber);
|
||||
const seasonDetails = await tmdbService.getSeasonDetails(effectiveTmdbId, seasonNumber, {
|
||||
language: tmdbLanguage
|
||||
});
|
||||
const seasonCredits = await tmdbService.getSeasonCredits(effectiveTmdbId, seasonNumber, {
|
||||
language: tmdbLanguage
|
||||
});
|
||||
const seasonSummary = tmdbService.buildSeasonSummary(seasonDetails);
|
||||
if (seasonSummary) {
|
||||
const fetchedEpisodes = Array.isArray(seasonSummary.episodes) ? seasonSummary.episodes : [];
|
||||
if (fetchedEpisodes.length > 0 && (!Array.isArray(episodes) || episodes.length === 0)) {
|
||||
if (fetchedEpisodes.length > 0 && !hasExplicitManualEpisodes) {
|
||||
episodes = fetchedEpisodes;
|
||||
}
|
||||
const fetchedEpisodeCount = Number(seasonSummary.episodeCount || 0) || 0;
|
||||
@@ -6177,15 +6200,20 @@ class HistoryService {
|
||||
lineageArtifactsByJobId,
|
||||
outputFoldersByJobId
|
||||
);
|
||||
const relatedJobs = jobs.map((job) => ({
|
||||
id: Number(job.id),
|
||||
parentJobId: normalizeJobIdValue(job.parent_job_id),
|
||||
title: buildJobDisplayTitle(job),
|
||||
status: String(job.status || '').trim() || null,
|
||||
discDevice: String(job.disc_device || '').trim() || null,
|
||||
isPrimary: Number(job.id) === normalizedJobId,
|
||||
createdAt: String(job.created_at || '').trim() || null
|
||||
}));
|
||||
const relatedJobs = jobs.map((job) => {
|
||||
const mkInfo = parseJsonSafe(job?.makemkv_info_json, {});
|
||||
return {
|
||||
id: Number(job.id),
|
||||
parentJobId: normalizeJobIdValue(job.parent_job_id),
|
||||
title: buildJobDisplayTitle(job),
|
||||
status: String(job.status || '').trim() || null,
|
||||
discDevice: String(job.disc_device || '').trim() || null,
|
||||
isPrimary: Number(job.id) === normalizedJobId,
|
||||
createdAt: String(job.created_at || '').trim() || null,
|
||||
orphanRawImport: isOrphanRawImportMakemkvInfo(mkInfo)
|
||||
};
|
||||
});
|
||||
const orphanRawImportJobs = relatedJobs.filter((row) => Boolean(row?.orphanRawImport)).length;
|
||||
const existingRawCandidates = preview.pathCandidates.raw.filter((row) => row.exists).length;
|
||||
const existingMovieCandidates = preview.pathCandidates.movie.filter((row) => row.exists).length;
|
||||
|
||||
@@ -6195,8 +6223,12 @@ class HistoryService {
|
||||
relatedJobs,
|
||||
pathCandidates: preview.pathCandidates,
|
||||
protectedRoots: preview.protectedRoots,
|
||||
flags: {
|
||||
containsOrphanRawImportJob: orphanRawImportJobs > 0
|
||||
},
|
||||
counts: {
|
||||
relatedJobs: relatedJobs.length,
|
||||
orphanRawImportJobs,
|
||||
rawCandidates: preview.pathCandidates.raw.length,
|
||||
movieCandidates: preview.pathCandidates.movie.length,
|
||||
existingRawCandidates,
|
||||
@@ -6887,6 +6919,28 @@ class HistoryService {
|
||||
throw error;
|
||||
}
|
||||
|
||||
const preserveRawForImportJobs = Boolean(options?.preserveRawForImportJobs);
|
||||
const isOrphanRawImportJobRow = (row) => {
|
||||
if (!row || typeof row !== 'object') {
|
||||
return false;
|
||||
}
|
||||
const mkInfo = parseJsonSafe(row?.makemkv_info_json, {});
|
||||
return isOrphanRawImportMakemkvInfo(mkInfo);
|
||||
};
|
||||
const resolveEffectiveFileTarget = (requestedTarget, row) => {
|
||||
if (!preserveRawForImportJobs || !isOrphanRawImportJobRow(row)) {
|
||||
return requestedTarget;
|
||||
}
|
||||
const normalizedRequested = String(requestedTarget || 'none').trim().toLowerCase();
|
||||
if (normalizedRequested === 'raw') {
|
||||
return 'none';
|
||||
}
|
||||
if (normalizedRequested === 'both') {
|
||||
return 'movie';
|
||||
}
|
||||
return normalizedRequested;
|
||||
};
|
||||
|
||||
const includeRelated = Boolean(options?.includeRelated);
|
||||
if (!includeRelated) {
|
||||
const resolved = await this.getJobByIdOrReplacement(jobId);
|
||||
@@ -6903,10 +6957,11 @@ class HistoryService {
|
||||
throw error;
|
||||
}
|
||||
|
||||
const effectiveFileTarget = resolveEffectiveFileTarget(fileTarget, existing);
|
||||
let fileSummary = null;
|
||||
if (fileTarget !== 'none') {
|
||||
if (effectiveFileTarget !== 'none') {
|
||||
const preview = await this.getJobDeletePreview(normalizedJobId, { includeRelated: false });
|
||||
fileSummary = this._deletePathsFromPreview(preview, fileTarget, {
|
||||
fileSummary = this._deletePathsFromPreview(preview, effectiveFileTarget, {
|
||||
selectedMoviePaths: options?.selectedMoviePaths
|
||||
});
|
||||
}
|
||||
@@ -6968,7 +7023,8 @@ class HistoryService {
|
||||
|
||||
logger.warn('job:deleted', {
|
||||
jobId: normalizedJobId,
|
||||
fileTarget,
|
||||
fileTarget: effectiveFileTarget,
|
||||
requestedFileTarget: fileTarget,
|
||||
includeRelated: false,
|
||||
pipelineStateReset: isActivePipelineJob,
|
||||
filesDeleted: fileSummary
|
||||
@@ -6982,7 +7038,8 @@ class HistoryService {
|
||||
return {
|
||||
deleted: true,
|
||||
jobId: normalizedJobId,
|
||||
fileTarget,
|
||||
fileTarget: effectiveFileTarget,
|
||||
requestedFileTarget: fileTarget,
|
||||
includeRelated: false,
|
||||
deletedJobIds: [Number(normalizedJobId)],
|
||||
fileSummary
|
||||
@@ -6990,6 +7047,7 @@ class HistoryService {
|
||||
}
|
||||
|
||||
const resolved = await this.getJobByIdOrReplacement(jobId);
|
||||
const existing = resolved?.job || null;
|
||||
const normalizedJobId = normalizeJobIdValue(resolved?.resolvedJobId || jobId);
|
||||
const preview = await this.getJobDeletePreview(normalizedJobId, { includeRelated: true });
|
||||
const deleteJobIds = Array.isArray(preview?.relatedJobs)
|
||||
@@ -7014,9 +7072,10 @@ class HistoryService {
|
||||
throw error;
|
||||
}
|
||||
|
||||
const effectiveFileTarget = resolveEffectiveFileTarget(fileTarget, existing);
|
||||
let fileSummary = null;
|
||||
if (fileTarget !== 'none') {
|
||||
fileSummary = this._deletePathsFromPreview(preview, fileTarget, {
|
||||
if (effectiveFileTarget !== 'none') {
|
||||
fileSummary = this._deletePathsFromPreview(preview, effectiveFileTarget, {
|
||||
selectedMoviePaths: options?.selectedMoviePaths
|
||||
});
|
||||
}
|
||||
@@ -7068,7 +7127,8 @@ class HistoryService {
|
||||
|
||||
logger.warn('job:deleted', {
|
||||
jobId: normalizedJobId,
|
||||
fileTarget,
|
||||
fileTarget: effectiveFileTarget,
|
||||
requestedFileTarget: fileTarget,
|
||||
includeRelated: true,
|
||||
deletedJobIds: deleteJobIds,
|
||||
deletedJobCount: deleteJobIds.length,
|
||||
@@ -7084,7 +7144,8 @@ class HistoryService {
|
||||
return {
|
||||
deleted: true,
|
||||
jobId: normalizedJobId,
|
||||
fileTarget,
|
||||
fileTarget: effectiveFileTarget,
|
||||
requestedFileTarget: fileTarget,
|
||||
includeRelated: true,
|
||||
deletedJobIds: deleteJobIds,
|
||||
deletedJobs: preview.relatedJobs,
|
||||
|
||||
Reference in New Issue
Block a user