0.12.0-16 misc fixes

This commit is contained in:
michael committed 2026-03-30 14:37:23 +00:00
1 parent 76b020d5c0
commit 5284dd2a43
30 files changed
+6955 -896

No files matched your search

+144 -7
View File
@@ -251,14 +251,120 @@ async function getEntryByRelPath(relPath) {
return row || null;
}
async function markEntryAsJob(relPath, jobId) {
async function setEntryJobAssignment(relPath, jobId) {
const normalizedRelPath = normalizeRelPath(relPath);
if (normalizedRelPath === null || normalizedRelPath === '') {
throw makeError('Ungültiger relPath für Job-Zuweisung.', 400);
}
const normalizedJobId = Number(jobId);
if (!Number.isFinite(normalizedJobId) || normalizedJobId <= 0) {
throw makeError('Ungültige jobId für Job-Zuweisung.', 400);
}
const db = await getDb();
const existing = await db.get(
`SELECT entry_type, file_size, detected_media_type, detected_format
FROM converter_scan_entries
WHERE rel_path = ?`,
[normalizedRelPath]
);
let entryType = String(existing?.entry_type || 'file').trim() || 'file';
let fileSize = existing?.file_size ?? null;
let detectedMediaType = existing?.detected_media_type ?? null;
let detectedFormat = existing?.detected_format ?? null;
const rawDir = await getRawDir();
const absPath = rawDir ? path.join(rawDir, normalizedRelPath) : null;
if (absPath && fs.existsSync(absPath)) {
try {
const stat = fs.statSync(absPath);
entryType = stat.isDirectory() ? 'directory' : 'file';
fileSize = stat.isFile() ? stat.size : null;
if (stat.isFile()) {
const fileName = path.basename(normalizedRelPath);
detectedMediaType = detectMediaType(fileName);
detectedFormat = detectFormat(fileName);
}
} catch (_err) {
// Keep existing metadata values if stat/read fails.
}
}
await db.run(
`
INSERT INTO converter_scan_entries (
rel_path,
entry_type,
file_size,
detected_media_type,
detected_format,
job_id,
last_seen_at
)
VALUES (?, ?, ?, ?, ?, ?, datetime('now'))
ON CONFLICT(rel_path) DO UPDATE SET
entry_type = excluded.entry_type,
file_size = excluded.file_size,
detected_media_type = excluded.detected_media_type,
detected_format = excluded.detected_format,
job_id = excluded.job_id,
last_seen_at = excluded.last_seen_at
`,
[
normalizedRelPath,
entryType,
fileSize,
detectedMediaType,
detectedFormat,
Math.trunc(normalizedJobId)
]
);
}
async function clearEntryJobAssignment(relPath, expectedJobId = null) {
const normalizedRelPath = normalizeRelPath(relPath);
if (normalizedRelPath === null || normalizedRelPath === '') {
throw makeError('Ungültiger relPath für Job-Entfernung.', 400);
}
const db = await getDb();
const normalizedExpected = Number(expectedJobId);
if (Number.isFinite(normalizedExpected) && normalizedExpected > 0) {
await db.run(
`UPDATE converter_scan_entries SET job_id = NULL WHERE rel_path = ? AND job_id = ?`,
[normalizedRelPath, Math.trunc(normalizedExpected)]
);
return;
}
await db.run(
`UPDATE converter_scan_entries SET job_id = NULL WHERE rel_path = ?`,
[normalizedRelPath]
);
}
async function clearAssignmentsForJob(jobId) {
const normalizedJobId = Number(jobId);
if (!Number.isFinite(normalizedJobId) || normalizedJobId <= 0) {
throw makeError('Ungültige jobId für Job-Entfernung.', 400);
}
const db = await getDb();
await db.run(
`UPDATE converter_scan_entries SET job_id = ? WHERE rel_path = ?`,
[jobId, relPath]
`UPDATE converter_scan_entries SET job_id = NULL WHERE job_id = ?`,
[Math.trunc(normalizedJobId)]
);
}
async function assignEntriesToJob(relPaths, jobId) {
const normalizedPaths = Array.isArray(relPaths) ? relPaths : [];
for (const relPath of normalizedPaths) {
await setEntryJobAssignment(relPath, jobId);
}
}
async function markEntryAsJob(relPath, jobId) {
await setEntryJobAssignment(relPath, jobId);
}
async function getRawDir() {
const settings = await settingsService.getSettingsMap();
return String(settings?.converter_raw_dir || defaultConverterRawDir || '').trim();
@@ -480,7 +586,7 @@ async function createFolder(parentRelPath, name) {
const TREE_MAX_DEPTH = 8;
function buildRawTree(rawDir, relPath, depth) {
function buildRawTree(rawDir, relPath, depth, assignments = new Map()) {
if (depth >= TREE_MAX_DEPTH) return [];
const absDir = relPath ? path.join(rawDir, relPath) : rawDir;
let dirents;
@@ -503,19 +609,23 @@ function buildRawTree(rawDir, relPath, depth) {
if (dirent.name.startsWith('.')) continue;
const childRel = relPath ? `${relPath}/${dirent.name}` : dirent.name;
if (dirent.isDirectory()) {
const children = buildRawTree(rawDir, childRel, depth + 1);
const children = buildRawTree(rawDir, childRel, depth + 1, assignments);
const size = children.reduce((s, c) => s + (c.size || 0), 0);
nodes.push({ name: dirent.name, type: 'folder', path: childRel, size, children });
} else if (dirent.isFile()) {
let size = 0;
try { size = fs.statSync(path.join(rawDir, childRel)).size; } catch (_) {}
const assignment = assignments.get(childRel) || null;
nodes.push({
name: dirent.name,
type: 'file',
path: childRel,
size,
detectedMediaType: detectMediaType(dirent.name),
detectedFormat: detectFormat(dirent.name)
detectedFormat: detectFormat(dirent.name),
jobId: assignment?.jobId || null,
jobTitle: assignment?.jobTitle || null,
jobStatus: assignment?.jobStatus || null
});
}
}
@@ -527,7 +637,30 @@ async function getTree() {
if (!rawDir || !fs.existsSync(rawDir)) {
return { rawDir: rawDir || null, tree: null };
}
const children = buildRawTree(rawDir, '', 0);
const db = await getDb();
const rows = await db.all(`
SELECT
e.rel_path,
e.job_id,
j.title AS job_title,
j.detected_title AS job_detected_title,
j.status AS job_status
FROM converter_scan_entries e
LEFT JOIN jobs j ON j.id = e.job_id
WHERE e.job_id IS NOT NULL
`);
const assignments = new Map();
for (const row of rows) {
const rel = String(row?.rel_path || '').trim();
const jobId = Number(row?.job_id);
if (!rel || !Number.isFinite(jobId) || jobId <= 0) continue;
assignments.set(rel, {
jobId: Math.trunc(jobId),
jobTitle: String(row?.job_title || row?.job_detected_title || '').trim() || null,
jobStatus: String(row?.job_status || '').trim() || null
});
}
const children = buildRawTree(rawDir, '', 0, assignments);
const size = children.reduce((s, c) => s + (c.size || 0), 0);
return {
rawDir,
@@ -541,6 +674,10 @@ module.exports = {
getEntryById,
getEntryByRelPath,
markEntryAsJob,
setEntryJobAssignment,
clearEntryJobAssignment,
clearAssignmentsForJob,
assignEntriesToJob,
getRawDir,
normalizeRelPath,
getTree,