176 lines
4.7 KiB
JavaScript
176 lines
4.7 KiB
JavaScript
'use strict';
|
|
|
|
import Manifest from '../iiif/Manifest.js';
|
|
import Sequence from '../iiif/Sequence.js';
|
|
import Canvas from '../iiif/Canvas.js';
|
|
import Image from '../iiif/Image.js';
|
|
import ManifestMetadata from '../iiif/Metadata.js';
|
|
import { parse, getCanvasLabel, getCanvasName } from './FilenameParser.js';
|
|
import { getImageList } from './ImageRepository.js';
|
|
import { TECH_NAMES } from '../constants.js';
|
|
|
|
/**
|
|
* Builds a manifest object based on canvases
|
|
* and available metadata
|
|
* @module ManifestBuilder
|
|
*/
|
|
|
|
const IIIF_API_VERSION = process.env.IIIF_API_VERSION;
|
|
const BASE_URL = process.env.BASE_URL;
|
|
const IMAGE_SERVER_URL = process.env.IMAGE_SERVER_URL;
|
|
|
|
/**
|
|
* Builds a Manifest object
|
|
* @param {String} manifestId
|
|
* @returns {Object}
|
|
*/
|
|
export async function buildManifest(manifestId) {
|
|
|
|
let manifest = new Manifest(IIIF_API_VERSION, BASE_URL);
|
|
manifest.generateID(manifestId);
|
|
manifest.generateLabel();
|
|
|
|
const images = await getImageList(manifestId);
|
|
|
|
manifest = await populateCanvases(manifest, images, manifestId);
|
|
|
|
manifest.setMetadata(
|
|
createMetadata(
|
|
manifest,
|
|
images[0], // A single image filename is sufficient to extract metadata
|
|
)
|
|
);
|
|
|
|
return manifest.toObject();
|
|
}
|
|
|
|
/**
|
|
* Builds a Canvas object from route parameters
|
|
* @param {String} manifestId
|
|
* @param {String} name The canvas name
|
|
*/
|
|
export async function buildCanvas(manifestId, name) {
|
|
const manifest = new Manifest(IIIF_API_VERSION, BASE_URL);
|
|
manifest.generateID(manifestId);
|
|
let filename = await getImageName(name, manifestId);
|
|
|
|
return createCanvas(manifest, filename);
|
|
}
|
|
/**
|
|
* Create a canvas from an image filename
|
|
* @param {Manifest} manifest
|
|
* @param {string} filename The image filename
|
|
* @returns {Canvas}
|
|
*/
|
|
async function createCanvas (manifest, filename) {
|
|
let canvas = new Canvas(IIIF_API_VERSION, BASE_URL);
|
|
const canvasName = getCanvasName(filename, manifest.technique);
|
|
|
|
canvas.generateID(manifest.resourceId, canvasName.toLowerCase());
|
|
canvas.label = getCanvasLabel(canvasName);
|
|
|
|
let image = new Image(canvas.id);
|
|
image.generateID(IMAGE_SERVER_URL, filename, manifest.technique);
|
|
|
|
const imgSize = await getImageSize(image.id);
|
|
image.setSize(imgSize.height, imgSize.width);
|
|
|
|
canvas.setThumbnail(
|
|
imgSize.thumb.height,
|
|
imgSize.thumb.width,
|
|
image.id
|
|
);
|
|
canvas.addImage(image);
|
|
|
|
return canvas;
|
|
}
|
|
/**
|
|
* @param {string} imageId The image's id as a URL to the image server
|
|
* @returns {{width: number, height: number, thumb: {width: number, height: number}}}
|
|
*/
|
|
async function getImageSize(imageId) {
|
|
let infoURL = imageId.replace(/full.*$/,'info.json');
|
|
const res = await fetch(infoURL);
|
|
|
|
let size = {};
|
|
|
|
if (res.ok) {
|
|
const infoJson = await res.json();
|
|
const maxSize = infoJson.sizes[infoJson.sizes.length - 1];
|
|
size.height = maxSize.height;
|
|
size.width = maxSize.width;
|
|
size.thumb = {
|
|
width: infoJson.sizes[1].width,
|
|
height: infoJson.sizes[1].height,
|
|
}
|
|
}
|
|
|
|
return size;
|
|
}
|
|
/**
|
|
* @param {Manifest} manifest The manifest object
|
|
* @param {string[]} images List of image filenames from folder
|
|
* @returns {Manifest}
|
|
*/
|
|
async function populateCanvases (manifest, images) {
|
|
const sequence = new Sequence(BASE_URL);
|
|
|
|
// There's only one sequence
|
|
sequence.generateID(manifest.resourceId, 0);
|
|
|
|
for (let img of images) {
|
|
// Skip failing images (TODO log error to file)
|
|
try {
|
|
let canvas = await createCanvas(manifest, img);
|
|
sequence.addCanvas(canvas);
|
|
} catch (error) {
|
|
console.error(error);
|
|
console.log(`\nAffected image: ${img}`);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// Sort them according to their ID number... (cornice, colonna, ecc...)
|
|
sequence.canvases.sort((a, b) => {
|
|
const firstId = a['@id'].slice(a['@id'].lastIndexOf('/') + 1).replace(/[a-z]+/ig,'');
|
|
const secondId = b['@id'].slice(b['@id'].lastIndexOf('/') + 1).replace(/[a-z]+/ig,'');
|
|
return Number(firstId) - Number(secondId);
|
|
});
|
|
|
|
manifest.addSequence(sequence);
|
|
|
|
return manifest;
|
|
}
|
|
/**
|
|
* Get image name for given canvas
|
|
* @todo Use regex in filter!!
|
|
* @param {String} name The canvas name
|
|
* @param {String} manifestId The manifest (resource) id
|
|
* @returns {string}
|
|
*/
|
|
async function getImageName(name, manifestId) {
|
|
const images = await getImageList(manifestId);
|
|
|
|
// Adjust canvas name for HSI with PCA...
|
|
if (/pc(1|3)/.test(name)) {
|
|
name = name.replace(
|
|
/pc((1|3))/,
|
|
function (match, group1) {
|
|
return `_HSI_PC${group1}`;
|
|
}
|
|
);
|
|
}
|
|
|
|
return images.filter(i => i.includes(name))[0];
|
|
}
|
|
/**
|
|
* @param {Manifest} manifest The Manifest object
|
|
* @param {string} imgFilename
|
|
* @returns {ManifestMetadata}
|
|
*/
|
|
function createMetadata(manifest, imgFilename) {
|
|
let metadata = parse(imgFilename, manifest.technique);
|
|
metadata.technique = TECH_NAMES[manifest.technique];
|
|
|
|
return new ManifestMetadata(metadata);
|
|
} |