Générateur de portfolios PDF Figures Libres (app Nuxt autonome)
App Nuxt 3 + Nuxt UI qui lit les projets du CMS Grav et compose des portfolios A3 paysage exportés en PDF (gabarit book_v3) : composeur WYSIWYG, templates cover/toc/projet/grille/page libre, pipeline Playwright + Ghostscript, gel du contenu à la génération, partage public opt-in. Dépôt autonome : Dockerfile (base Playwright + Ghostscript + ffmpeg + rsync) inclus. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
28
server/api/media/[...path].get.ts
Normal file
28
server/api/media/[...path].get.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
// Sert les médias du contenu Grav (et des snapshots figés).
|
||||
// - `?w=480` : image redimensionnée (voir server/lib/media.ts).
|
||||
// - `?poster=1` : première frame d'une vidéo.
|
||||
// - `?frozen=<portfolioId>` : résout d'abord dans le snapshot figé (§7.3).
|
||||
import { join } from 'node:path'
|
||||
import { useContentSource } from '../../lib/content-source'
|
||||
import { serveMedia, splitMediaPath } from '../../lib/media'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const { projectId, filename } = splitMediaPath(getRouterParam(event, 'path') ?? '')
|
||||
|
||||
const query = getQuery(event)
|
||||
const width = Number(query.w) || 0
|
||||
const wantPoster = Boolean(query.poster)
|
||||
const frozenId = typeof query.frozen === 'string' ? query.frozen : ''
|
||||
|
||||
const config = useRuntimeConfig(event)
|
||||
const source = useContentSource()
|
||||
|
||||
// Racines de résolution : snapshot figé d'abord, contenu live ensuite
|
||||
const roots: string[] = []
|
||||
if (frozenId && /^[\w-]+$/.test(frozenId)) {
|
||||
roots.push(join(config.dataDir, 'frozen', frozenId))
|
||||
}
|
||||
roots.push(source.rootDir)
|
||||
|
||||
return serveMedia(event, { roots, projectId, filename, width, wantPoster, dataDir: config.dataDir })
|
||||
})
|
||||
Reference in New Issue
Block a user