diff --git a/scripts/generate-iiif-manifest.ts b/scripts/generate-iiif-manifest.ts index e1f4720..2d908e6 100644 --- a/scripts/generate-iiif-manifest.ts +++ b/scripts/generate-iiif-manifest.ts @@ -1,125 +1,124 @@ +import { randomUUID } from "node:crypto"; +import { mkdir, writeFile } from "node:fs/promises"; +import { join } from "node:path"; + import { createUrl, log, request } from "@acdh-oeaw/lib"; import { IIIFBuilder } from "@iiif/builder"; -import { randomUUID } from "crypto"; -import type { ErrnoException } from "fast-glob/out/types"; -import * as fs from "fs"; import { z } from "zod"; -const NUXT_PUBLIC_IIIF_BASE_URL = "https://iiif.acdh-dev.oeaw.ac.at/iiif/images/sicprod/"; -const iiifBaseURL = z.string().url().parse(NUXT_PUBLIC_IIIF_BASE_URL); -const outputPath = "./assets/manifests"; +const outputFolder = join(process.cwd(), "assets", "manifests"); + +async function generate() { + log.info("Generating iiif manifest..."); + + const apiBaseUrl = z.string().url().parse(process.env.NUXT_PUBLIC_IIIF_BASE_URL); + + const booksUrl = createUrl({ baseUrl: apiBaseUrl, pathname: "/images/sicprod/" }); + const books = (await request(booksUrl, { responseType: "json" })) as Array; + + const imageFileNamesByBook = new Map>(); + + for (const bookId of books) { + if (bookId === "list") continue; -async function main() { - if (!fs.existsSync(outputPath)) { - fs.mkdirSync(outputPath); + const url = createUrl({ baseUrl: apiBaseUrl, pathname: `/images/sicprod/${bookId}/` }); + const imageFileNames = (await request(url, { responseType: "json" })) as Array; + + imageFileNamesByBook.set(bookId, imageFileNames); } - const builder = new IIIFBuilder(); + // - let books = (await request(iiifBaseURL.replace("/iiif/", "/"), { - responseType: "json", - })) as Array; + const width = 4914; + const height = 3954; - books = books.filter((book) => { - return book !== "list"; - }); + const builder = new IIIFBuilder(); - const imagesPerBook: Array> = (await Promise.all( - books.map((book) => { - return request( - createUrl({ - baseUrl: iiifBaseURL.replace("/iiif/", "/"), - pathname: book, - }).toString(), - { responseType: "json" }, + const collectionManifest = builder.createCollection("ScanCollection", (collection) => { + for (const bookId of books) { + const url = String( + createUrl({ baseUrl: apiBaseUrl, pathname: `/iiif/images/sicprod/${bookId}/` }), ); - }), - )) as Array>; - const collectionManifest = builder.createCollection("ScanCollection", (collection) => { - books.forEach((book: string, idx: number) => { - collection.createManifest( - createUrl({ baseUrl: iiifBaseURL, pathname: book }).toString(), - (manifest) => { - manifest.addLabel(book.replaceAll("_", " "), "de"); - - const bookData = imagesPerBook[idx]; - - if (Array.isArray(bookData)) { - bookData.forEach((img: string) => { - const imgName = img.replace(".jpg", ".jp2"); - - manifest.createCanvas(randomUUID(), (canvas) => { - canvas.addLabel(img.replace(".jpg", ""), "de"); - - canvas.width = 4914; - canvas.height = 3954; - - const annotationID = createUrl({ - baseUrl: iiifBaseURL, - pathname: `${book}/${imgName}/annotation`, - }).toString(); - - canvas.createAnnotation(annotationID, { - id: annotationID, - type: "Annotation", - motivation: "painting", - thumbnail: [ - { - type: "Image", - id: createUrl({ - baseUrl: iiifBaseURL, - pathname: `${book}/${imgName}/full/100,/0/default.jpg`, - }).toString(), - }, - ], - body: { - id: createUrl({ - baseUrl: iiifBaseURL, - pathname: `${book}/${imgName}/full/full/0/default.jpg`, - }).toString(), - type: "Image", - format: "image/jpg", - height: 3954, - width: 4914, - }, - }); - }); + collection.createManifest(url, (manifest) => { + manifest.addLabel(bookId.replaceAll("_", " "), "de"); + + const imageFileNames = imageFileNamesByBook.get(bookId); + + imageFileNames?.forEach((fileName: string) => { + const imageFileName = fileName.replace(".jpg", ".jp2"); + + manifest.createCanvas(randomUUID(), (canvas) => { + canvas.addLabel(fileName.replace(".jpg", ""), "de"); + + canvas.width = width; + canvas.height = height; + + const annotationId = String( + createUrl({ + baseUrl: apiBaseUrl, + pathname: `/iiif/images/sicprod/${bookId}/${imageFileName}/annotation`, + }), + ); + + const thumbnailId = String( + createUrl({ + baseUrl: apiBaseUrl, + pathname: `/iiif/images/sicprod/${bookId}/${imageFileName}/full/100,/0/default.jpg`, + }), + ); + + const bodyId = String( + createUrl({ + baseUrl: apiBaseUrl, + pathname: `/iiif/images/sicprod/${bookId}/${imageFileName}/full/full/0/default.jpg`, + }), + ); + + canvas.createAnnotation(annotationId, { + id: annotationId, + type: "Annotation", + motivation: "painting", + thumbnail: [{ type: "Image", id: thumbnailId }], + body: { + id: bodyId, + type: "Image", + format: "image/jpg", + height, + width, + }, }); - } - }, - ); - }); + }); + }); + }); + } }); - collectionManifest.items.forEach((manifest) => { - fs.writeFile( - `${outputPath}/${decodeURI(manifest.id.split("/").slice(-1).join(""))}.json`, - JSON.stringify( - builder.toPresentation3({ - id: manifest.id, - type: "Manifest", - }), - ), - (msg: ErrnoException | null) => { - if (msg) throw msg; - }, - ); - }); + // + + await mkdir(outputFolder, { recursive: true }); - fs.writeFile( - `${outputPath}/collection-manifest.json`, - JSON.stringify(builder.toPresentation3({ id: collectionManifest.id, type: "Collection" })), - (msg: ErrnoException | null) => { - if (msg) throw msg; - }, - ); + for (const manifest of collectionManifest.items) { + const name = decodeURI(manifest.id.split("/").at(-2)!); + const filePath = join(outputFolder, `${name}.json`); + const fileContent = builder.toPresentation3({ id: manifest.id, type: "Manifest" }); + + await writeFile(filePath, JSON.stringify(fileContent), { encoding: "utf-8" }); + } + + const filePath = join(outputFolder, "collection-manifest.json"); + const fileContent = builder.toPresentation3({ id: collectionManifest.id, type: "Collection" }); + + await writeFile(filePath, JSON.stringify(fileContent), { encoding: "utf-8" }); } -main() +generate() .then(() => { - log.success("Manifest creation completed. \nOutput was written to: ", outputPath); + log.success( + "Successfully generated iiif manifest.\n", + `Output was written to: "${outputFolder}".`, + ); }) - .catch((err: unknown) => { - log.error("Manifest creation failed", String(err)); + .catch((error: unknown) => { + log.error("Failed to generate iiif manifest.\n", String(error)); });