import multer from 'multer' import fs from 'fs/promises' import path from 'path' import * as pdfjsLib from 'pdfjs-dist' // PDF.js Worker konfigurieren pdfjsLib.GlobalWorkerOptions.workerSrc = 'pdfjs-dist/build/pdf.worker.min.js' // Handle both dev and production paths const getDataPath = (filename) => { const cwd = process.cwd() // In production (.output/server), working dir is .output if (cwd.endsWith('.output')) { return path.join(cwd, '../server/data', filename) } // In development, working dir is project root return path.join(cwd, 'server/data', filename) } // Multer-Konfiguration für PDF-Uploads const storage = multer.diskStorage({ destination: (req, file, cb) => { cb(null, 'public/documents/') }, filename: (req, file, cb) => { cb(null, 'satzung.pdf') } }) const upload = multer({ storage, fileFilter: (req, file, cb) => { if (file.mimetype === 'application/pdf') { cb(null, true) } else { cb(new Error('Nur PDF-Dateien sind erlaubt'), false) } }, limits: { fileSize: 10 * 1024 * 1024 // 10MB Limit } }) export default defineEventHandler(async (event) => { if (event.method !== 'POST') { throw createError({ statusCode: 405, statusMessage: 'Method Not Allowed' }) } try { // Multer-Middleware für File-Upload await new Promise((resolve, reject) => { upload.single('pdf')(event.node.req, event.node.res, (err) => { if (err) reject(err) else resolve() }) }) const file = event.node.req.file if (!file) { throw createError({ statusCode: 400, statusMessage: 'Keine PDF-Datei hochgeladen' }) } // PDF-Text extrahieren mit PDF.js const pdfBuffer = await fs.readFile(file.path) const pdfData = await pdfjsLib.getDocument({ data: pdfBuffer }).promise let fullText = '' // Alle Seiten durchgehen for (let pageNum = 1; pageNum <= pdfData.numPages; pageNum++) { const page = await pdfData.getPage(pageNum) const textContent = await page.getTextContent() const pageText = textContent.items.map(item => item.str).join(' ') fullText += pageText + '\n' } // Text in HTML-Format konvertieren const htmlContent = convertTextToHtml(fullText) // Config aktualisieren const configPath = getDataPath('config.json') const configData = JSON.parse(await fs.readFile(configPath, 'utf-8')) configData.seiten.satzung = { pdfUrl: '/documents/satzung.pdf', content: htmlContent } await fs.writeFile(configPath, JSON.stringify(configData, null, 2)) return { success: true, message: 'Satzung erfolgreich hochgeladen und verarbeitet', pdfUrl: '/documents/satzung.pdf' } } catch (error) { console.error('PDF Upload Error:', error) throw createError({ statusCode: 500, statusMessage: error.message || 'Fehler beim Verarbeiten der PDF-Datei' }) } }) // PDF-Text zu HTML konvertieren function convertTextToHtml(text) { // Text bereinigen und strukturieren let html = text .replace(/\r\n/g, '\n') // Windows-Zeilenumbrüche normalisieren .replace(/\r/g, '\n') // Mac-Zeilenumbrüche normalisieren .replace(/\n\s*\n/g, '\n\n') // Mehrfache Zeilenumbrüche reduzieren .trim() // Überschriften erkennen und formatieren html = html.replace(/^(Vereinssatzung|Satzung)$/gm, '

$1

') html = html.replace(/^(§\s*\d+[^§\n]*)$/gm, '

$1

') // Absätze erstellen html = html.split('\n\n').map(paragraph => { paragraph = paragraph.trim() if (!paragraph) return '' // Überschriften nicht als Paragraphen behandeln if (paragraph.match(/^/) || paragraph.match(/^§\s*\d+/)) { return paragraph } // Listen erkennen if (paragraph.includes('•') || paragraph.includes('-') || paragraph.match(/^\d+\./)) { const listItems = paragraph.split(/\n/).map(item => { item = item.trim() if (item.match(/^[•\-]\s/) || item.match(/^\d+\.\s/)) { return `
  • ${item.replace(/^[•\-]\s/, '').replace(/^\d+\.\s/, '')}
  • ` } return `
  • ${item}
  • ` }).join('') return `` } // Normale Absätze return `

    ${paragraph.replace(/\n/g, '
    ')}

    ` }).join('\n') // Mehrfache Zeilenumbrüche entfernen html = html.replace(/\n{3,}/g, '\n\n') return html }