feat(backend): Skript zur Umwandlung des Altbestands nach AVIF
Bilder, die vor der Umstellung hochgeladen wurden, liegen unverkleinert im Originalformat im Repo - damals war sharp im Container kaputt, es gab also weder Verkleinerung noch Formatwandlung. Das Skript schickt sie durch dieselbe Verarbeitung wie einen frischen Upload. node dist/scripts/convert-images-to-avif.js # nur anzeigen node dist/scripts/convert-images-to-avif.js --apply # wirklich tun Ohne --apply wird nichts geschrieben. Ablauf: Workspace auf den Repo-Stand bringen, jedes referenzierte Bild umwandeln und nach seinem Inhalt benennen (Event-Titel, Alt-Text, Zweck), die Verweise in Events, Gallery und Textbereichen nachziehen, die Vorgaenger wegraeumen und committen. Weggeraeumt wird nur, was das CMS selbst angelegt hat. Ein handgepflegtes event_karaoke.jpg bekommt zwar eine AVIF-Fassung und der Verweis zeigt darauf, das Original bleibt aber liegen und wird im Bericht genannt. saveImageBuffer aus upload.service.ts herausgeloest, damit Upload und Skript nachweislich dieselbe Verarbeitung benutzen statt zweier Kopien. replaceImageUrls ersetzt Pfade in den Textbereichen, ohne die restliche JSON-Struktur anzufassen. Durchgespielt an vier Bildern zu je ~656 KB: 2.56 MB -> 0.16 MB. Die Vorschau schreibt nichts, ein zweiter Lauf findet nichts mehr, die Highlights-Liste bleibt unversehrt und alle Bilder werden danach als image/avif ausgeliefert. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
@@ -69,6 +69,30 @@ export async function collectReferencedImageUrls(): Promise<Set<string>> {
|
||||
return urls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ersetzt Bildpfade in einem beliebigen Content-JSON anhand einer Zuordnung
|
||||
* alt -> neu. Die Struktur bleibt dabei unveraendert.
|
||||
*/
|
||||
export function replaceImageUrls(value: any, mapping: Map<string, string>): any {
|
||||
if (typeof value === 'string') {
|
||||
return mapping.get(value) ?? value;
|
||||
}
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
return value.map((entry) => replaceImageUrls(entry, mapping));
|
||||
}
|
||||
|
||||
if (value && typeof value === 'object') {
|
||||
const out: Record<string, any> = {};
|
||||
for (const [key, entry] of Object.entries(value)) {
|
||||
out[key] = replaceImageUrls(entry, mapping);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/** Alle Bildpfade aus einem beliebigen Content-JSON. */
|
||||
export function extractImageUrls(value: any): Set<string> {
|
||||
const out = new Set<string>();
|
||||
|
||||
Reference in New Issue
Block a user