import fs from 'fs/promises' import path from 'path' import sharp from 'sharp' const getDataRoot = () => { const cwd = process.cwd() return cwd.endsWith('.output') ? `${cwd}/../server/data` : `${cwd}/server/data` } const DATA_ROOT = getDataRoot() const GALERIE_DIR = `${DATA_ROOT}/galerie` const GALERIE_METADATA = `${DATA_ROOT}/galerie-metadata.json` async function readJsonArray(file) { try { const data = await fs.readFile(file, 'utf-8') const parsed = JSON.parse(data) return Array.isArray(parsed) ? parsed : [] } catch (e) { if (e.code === 'ENOENT') return [] throw e } } async function writeJson(file, obj) { await fs.writeFile(file, JSON.stringify(obj, null, 2), 'utf-8') } async function ensureDirs() { await fs.mkdir(path.join(GALERIE_DIR, 'originals'), { recursive: true }) await fs.mkdir(path.join(GALERIE_DIR, 'previews'), { recursive: true }) } async function fileExists(p) { try { await fs.access(p) return true } catch { return false } } async function generatePreviewForEntry(entry, size) { const safeOriginal = path.basename(String(entry.filename || '')) const original = `${GALERIE_DIR}/originals/${safeOriginal}` if (!(await fileExists(original))) return { ok: false, reason: 'missing original' } const previewFilename = entry.previewFilename && String(entry.previewFilename).trim() !== '' ? entry.previewFilename : `preview_${entry.filename}` const safePreview = path.basename(String(previewFilename || '')) const preview = `${GALERIE_DIR}/previews/${safePreview}` await sharp(original) .rotate() .resize(size, size, { fit: 'cover', withoutEnlargement: true }) .jpeg({ quality: 82, mozjpeg: true }) .toFile(preview) return { ok: true, previewFilename } } async function main() { const size = Number(process.env.GALERIE_PREVIEW_SIZE || 300) await ensureDirs() const entries = await readJsonArray(GALERIE_METADATA) if (entries.length === 0) { console.log('Keine Galerie-Metadaten gefunden.') return } let changed = 0 let generated = 0 let skipped = 0 for (const entry of entries) { if (!entry || !entry.filename) { skipped++ continue } const res = await generatePreviewForEntry(entry, size) if (!res.ok) { skipped++ continue } generated++ if (entry.previewFilename !== res.previewFilename) { entry.previewFilename = res.previewFilename changed++ } } if (changed > 0) await writeJson(GALERIE_METADATA, entries) console.log(`Previews erzeugt: ${generated}, übersprungen: ${skipped}, metadata-updates: ${changed}`) } main().catch(e => { console.error(e) process.exit(1) })