Refactor Galerie component to use image IDs for keys and update image loading logic; add new scripts for generating previews and migrating public gallery to metadata with authentication checks.
This commit is contained in:
107
scripts/generate-galerie-previews.js
Normal file
107
scripts/generate-galerie-previews.js
Normal file
@@ -0,0 +1,107 @@
|
||||
import fs from 'fs/promises'
|
||||
import path from 'path'
|
||||
import sharp from 'sharp'
|
||||
|
||||
const getDataPath = (filename) => {
|
||||
const cwd = process.cwd()
|
||||
if (cwd.endsWith('.output')) return path.join(cwd, '../server/data', filename)
|
||||
return path.join(cwd, 'server/data', filename)
|
||||
}
|
||||
|
||||
const GALERIE_DIR = getDataPath('galerie')
|
||||
const GALERIE_METADATA = getDataPath('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 original = path.join(GALERIE_DIR, 'originals', entry.filename)
|
||||
if (!(await fileExists(original))) return { ok: false, reason: 'missing original' }
|
||||
|
||||
const previewFilename = entry.previewFilename && String(entry.previewFilename).trim() !== ''
|
||||
? entry.previewFilename
|
||||
: `preview_${entry.filename}`
|
||||
|
||||
const preview = path.join(GALERIE_DIR, 'previews', previewFilename)
|
||||
|
||||
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)
|
||||
})
|
||||
Reference in New Issue
Block a user