This commit is contained in:
seb
2026-09-22 07:25:16 +02:00
parent 4ed6260e91
commit cca131d83a
148 changed files with 5343 additions and 3466 deletions

View File

@@ -28,6 +28,40 @@ async function renderPdfPageToPng(pdfBuffer) {
* @param {Object} [options]
* @returns {Promise<{thumbavif: Buffer|null, thumbx: number|null, thumby: number|null}>}
*/
function escapeXml(str) {
return str.replace(/[&<>'"]/g, (c) => {
switch (c) {
case '&': return '&amp;';
case '<': return '&lt;';
case '>': return '&gt;';
case "'": return '&apos;';
case '"': return '&quot;';
default: return c;
}
});
}
function renderTextToSvg(text, width = 400, height = 560) {
const lines = text.split(/\r?\n/).slice(0, 32);
const paddingX = 24;
const paddingTop = 32;
const lineHeight = 16;
const textElements = lines
.map((line, idx) => {
const y = paddingTop + idx * lineHeight;
const truncated = line.length > 50 ? line.slice(0, 47) + '...' : line;
return `<text x="${paddingX}" y="${y}" font-family="monospace" font-size="11" fill="#334155">${escapeXml(truncated)}</text>`;
})
.join('\n');
return Buffer.from(`<svg width="${width}" height="${height}" xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" fill="#ffffff" stroke="#e2e8f0" stroke-width="2"/>
${textElements}
</svg>`, 'utf8');
}
export default async function generateDocumentThumb(content, mimetype, options = {}) {
if (!Buffer.isBuffer(content) || content.length === 0) {
return { thumbavif: null, thumbx: null, thumby: null };
@@ -45,6 +79,19 @@ export default async function generateDocumentThumb(content, mimetype, options =
}
} else if (type.startsWith('image/')) {
imageBuffer = content;
} else if (
type === 'text/plain' ||
type === 'text/csv' ||
type.startsWith('text/') ||
options.filename?.toLowerCase().endsWith('.txt') ||
options.filename?.toLowerCase().endsWith('.csv')
) {
try {
imageBuffer = renderTextToSvg(content.toString('utf8'));
} catch (err) {
console.warn('generateDocumentThumb: Text render failed:', err.message);
return { thumbavif: null, thumbx: null, thumby: null };
}
} else {
return { thumbavif: null, thumbx: null, thumby: null };
}