0.12.0-3 Plugin Integration
This commit is contained in:
@@ -4059,10 +4059,25 @@ class HistoryService {
|
||||
}
|
||||
}
|
||||
|
||||
const hasTrackedOutputSource = (sources = []) => {
|
||||
const normalizedSources = Array.isArray(sources)
|
||||
? sources
|
||||
.map((source) => String(source || '').trim().toLowerCase())
|
||||
.filter(Boolean)
|
||||
: [];
|
||||
return normalizedSources.includes('output_path') || normalizedSources.includes('lineage_output_path');
|
||||
};
|
||||
|
||||
const buildList = (target) => Array.from(candidateMap.values())
|
||||
.filter((row) => row.target === target)
|
||||
.map((row) => {
|
||||
const inspection = inspectDeletionPath(row.path);
|
||||
const sources = Array.from(row.sources).sort((left, right) => left.localeCompare(right));
|
||||
// Do not expose stale output file paths from DB/lineage in delete preview.
|
||||
// They cannot be deleted anyway and show up as "ghost paths" in UI/QA checks.
|
||||
if (target === 'movie' && !inspection.exists && hasTrackedOutputSource(sources)) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
target,
|
||||
path: row.path,
|
||||
@@ -4070,9 +4085,10 @@ class HistoryService {
|
||||
isDirectory: Boolean(inspection.isDirectory),
|
||||
isFile: Boolean(inspection.isFile),
|
||||
jobIds: Array.from(row.jobIds).sort((left, right) => left - right),
|
||||
sources: Array.from(row.sources).sort((left, right) => left.localeCompare(right))
|
||||
sources
|
||||
};
|
||||
})
|
||||
.filter(Boolean)
|
||||
.sort((left, right) => String(left.path || '').localeCompare(String(right.path || ''), 'de'));
|
||||
|
||||
return {
|
||||
@@ -4289,6 +4305,8 @@ class HistoryService {
|
||||
raw: { attempted: false, deleted: false, filesDeleted: 0, dirsRemoved: 0, reason: null },
|
||||
movie: { attempted: false, deleted: false, filesDeleted: 0, dirsRemoved: 0, reason: null }
|
||||
};
|
||||
let movieDeletedPathForTracking = null;
|
||||
let movieCandidatePathForTracking = null;
|
||||
|
||||
if (target === 'raw' || target === 'both') {
|
||||
summary.raw.attempted = true;
|
||||
@@ -4328,7 +4346,59 @@ class HistoryService {
|
||||
error.statusCode = 400;
|
||||
throw error;
|
||||
} else if (!fs.existsSync(effectiveOutputPath)) {
|
||||
summary.movie.reason = 'Movie-Datei/Pfad existiert nicht.';
|
||||
const movieRoot = normalizeComparablePath(effectiveMovieDir);
|
||||
const trackedFolders = await this.getJobOutputFolders(jobId);
|
||||
const trackedExistingPaths = Array.from(new Set(
|
||||
trackedFolders
|
||||
.map((row) => normalizeComparablePath(row?.output_path))
|
||||
.filter(Boolean)
|
||||
.filter((candidatePath) => isPathInside(effectiveMovieDir, candidatePath))
|
||||
.filter((candidatePath) => candidatePath !== movieRoot)
|
||||
.filter((candidatePath) => fs.existsSync(candidatePath))
|
||||
));
|
||||
|
||||
if (trackedExistingPaths.length === 1) {
|
||||
const trackedPath = trackedExistingPaths[0];
|
||||
const stat = fs.lstatSync(trackedPath);
|
||||
if (stat.isDirectory()) {
|
||||
const keepRoot = trackedPath === movieRoot;
|
||||
const result = deleteFilesRecursively(trackedPath, keepRoot);
|
||||
summary.movie.deleted = true;
|
||||
summary.movie.filesDeleted = result.filesDeleted;
|
||||
summary.movie.dirsRemoved = result.dirsRemoved;
|
||||
movieDeletedPathForTracking = trackedPath;
|
||||
movieCandidatePathForTracking = trackedPath;
|
||||
summary.movie.reason = null;
|
||||
} else {
|
||||
const parentDir = normalizeComparablePath(path.dirname(trackedPath));
|
||||
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;
|
||||
movieDeletedPathForTracking = parentDir;
|
||||
movieCandidatePathForTracking = trackedPath;
|
||||
} else {
|
||||
fs.unlinkSync(trackedPath);
|
||||
summary.movie.deleted = true;
|
||||
summary.movie.filesDeleted = 1;
|
||||
summary.movie.dirsRemoved = 0;
|
||||
movieDeletedPathForTracking = trackedPath;
|
||||
movieCandidatePathForTracking = trackedPath;
|
||||
}
|
||||
summary.movie.reason = null;
|
||||
}
|
||||
} else if (trackedExistingPaths.length > 1) {
|
||||
summary.movie.reason = 'Mehrere bekannte Output-Ordner gefunden. Bitte gezielt über die Ordnerauswahl löschen.';
|
||||
} else {
|
||||
summary.movie.reason = 'Movie-Datei/Pfad existiert nicht.';
|
||||
}
|
||||
} else {
|
||||
const outputPath = normalizeComparablePath(effectiveOutputPath);
|
||||
const movieRoot = normalizeComparablePath(effectiveMovieDir);
|
||||
@@ -4339,6 +4409,8 @@ class HistoryService {
|
||||
summary.movie.deleted = true;
|
||||
summary.movie.filesDeleted = result.filesDeleted;
|
||||
summary.movie.dirsRemoved = result.dirsRemoved;
|
||||
movieDeletedPathForTracking = outputPath;
|
||||
movieCandidatePathForTracking = outputPath;
|
||||
} else {
|
||||
const parentDir = normalizeComparablePath(path.dirname(outputPath));
|
||||
const canDeleteParentDir = parentDir
|
||||
@@ -4352,19 +4424,29 @@ class HistoryService {
|
||||
summary.movie.deleted = true;
|
||||
summary.movie.filesDeleted = result.filesDeleted;
|
||||
summary.movie.dirsRemoved = result.dirsRemoved;
|
||||
movieDeletedPathForTracking = parentDir;
|
||||
movieCandidatePathForTracking = outputPath;
|
||||
} else {
|
||||
fs.unlinkSync(outputPath);
|
||||
summary.movie.deleted = true;
|
||||
summary.movie.filesDeleted = 1;
|
||||
summary.movie.dirsRemoved = 0;
|
||||
movieDeletedPathForTracking = outputPath;
|
||||
movieCandidatePathForTracking = outputPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove deleted movie paths from output folders tracking
|
||||
if (summary.movie?.deleted && effectiveOutputPath) {
|
||||
await this.removeJobOutputFolder(jobId, effectiveOutputPath);
|
||||
if (summary.movie?.deleted) {
|
||||
const trackingCleanupPaths = Array.from(new Set([
|
||||
movieCandidatePathForTracking,
|
||||
movieDeletedPathForTracking
|
||||
].filter(Boolean)));
|
||||
for (const candidatePath of trackingCleanupPaths) {
|
||||
await this.removeJobOutputFolder(jobId, candidatePath);
|
||||
}
|
||||
}
|
||||
|
||||
await this.appendLog(
|
||||
|
||||
Reference in New Issue
Block a user