Files
ResourceLoader/electron/pdf-import.js
Zaine Qayyum 9e075ec941 Testing
2026-08-19 09:56:06 +01:00

91 lines
2.5 KiB
JavaScript

const fs = require("fs");
const path = require("path");
const { PDFDocument } = require("pdf-lib");
function clean(value) {
if (value == null) return "";
return String(value).replace(/\0/g, "").replace(/\s+/g, " ").trim();
}
function titleFromFilename(filePath) {
return path
.basename(filePath, path.extname(filePath))
.replace(/[_]+/g, " ")
.replace(/\s+/g, " ")
.trim();
}
function parseKeywords(value) {
if (!value) return [];
const list = Array.isArray(value) ? value : String(value).split(/[,;]+/);
return [...new Set(list.map(clean).filter(Boolean))];
}
function uniqueDest(dir, originalName) {
const ext = path.extname(originalName) || ".pdf";
const stem =
path
.basename(originalName, ext)
.replace(/[<>:"/\\|?*]+/g, "-")
.slice(0, 80) || "document";
let dest = path.join(dir, `${stem}${ext}`);
let n = 2;
while (fs.existsSync(dest)) {
dest = path.join(dir, `${stem}-${n}${ext}`);
n += 1;
}
return dest;
}
async function extractMetadata(filePath) {
const bytes = fs.readFileSync(filePath);
const pdf = await PDFDocument.load(bytes, {
ignoreEncryption: true,
updateMetadata: false,
});
return {
title: clean(pdf.getTitle()) || titleFromFilename(filePath),
author: clean(pdf.getAuthor()),
totalPages: pdf.getPageCount(),
notes: clean(pdf.getSubject()),
tags: parseKeywords(pdf.getKeywords()),
};
}
async function importPdfFiles(filePaths, destDir, existingNames) {
fs.mkdirSync(destDir, { recursive: true });
const known = new Set((existingNames || []).map((name) => name.toLowerCase()));
const imported = [];
const skipped = [];
const errors = [];
for (const filePath of filePaths) {
const sourceName = path.basename(filePath);
if (!filePath.toLowerCase().endsWith(".pdf")) {
skipped.push({ file: sourceName, reason: "not a PDF" });
continue;
}
if (known.has(sourceName.toLowerCase())) {
skipped.push({ file: sourceName, reason: "already in catalog" });
continue;
}
try {
const meta = await extractMetadata(filePath);
const dest = uniqueDest(destDir, sourceName);
fs.copyFileSync(filePath, dest);
known.add(sourceName.toLowerCase());
imported.push({
...meta,
pdfPath: dest,
sourceName,
});
} catch (err) {
errors.push({ file: sourceName, message: err.message });
}
}
return { imported, skipped, errors };
}
module.exports = { importPdfFiles };