'use strict'; import * as fs from 'fs'; import * as path from 'path'; import Manifest from './Manifest.js'; import Sequence from './Sequence.js'; import Canvas from './Canvas.js'; import Image from './Image.js'; import ManifestMetadata from './Metadata.js'; const Common = {}; const TECH_NAMES = { dn: "Disegni Napoletani", do: "Disegni Oxoniensi", nir: "Near Infrared Imaging 1000nm", hsi: "SWIR Hyperspectral Imaging", uvf: "Technical Photography UVF", } const authors = { DAN: 'Danilo P. Pavone', AUR: 'Aurélie Tournié', SAB: 'Sabrina Samelo', }; /** * @param {string} imgFilename * @returns {{papyrus:string,imageAuthor:string,date:string}} */ function extractNIRMetadata(imgFilename) { return { papyrus: imgFilename.split('_')[0].split('-')[2], imageAuthor: authors[imgFilename.split('-')[0].replace(/\d{4}/,'')], date: imgFilename.split('-')[0].match(/\d{4}/)[0], } } /** * @param {string} imgFilename * @returns {{papyrus:string,imageAuthor:string,pca:string,date:string}} */ function extractHSIMetadata(imgFilename) { let hsi = extractNIRMetadata(imgFilename); hsi.pca = imgFilename.split('_')[3].replace(/\..*$/,''); return hsi; } /** * @param {string} imgFilename * @returns {{papyrus:string,imageAuthor:string,date:string,copyright:string}} */ function extractDNMetadata(imgFilename) { return { papyrus: imgFilename.split('_')[1], imageAuthor: '', date: '', copyright: "Ministero della Cultura (Biblioteca Nazionale 'Vittorio Emanuele III' di Napoli)", } } /** * @param {string} imgFilename * @returns {{papyrus:string,imageAuthor:string,date:string,copyright:string}} */ function extractDOMetadata(imgFilename) { return { papyrus: imgFilename.split('_')[1], imageAuthor: '', date: '', copyright: "The Bodleian Libraries, University of Oxford", } } /** * Retrieves available image techniques * for all papyruses based on folder contents * @returns {object} */ Common.getParamsFromFolders = async function() { let params = {}; const papyri = await fs.promises.readdir(process.env.IMAGES_DIR); for (let p of papyri) { params[p] = []; for (let tech of await fs.promises.readdir(`${process.env.IMAGES_DIR}/${p}`)) { params[p].push(tech.toLowerCase().replaceAll('_','-')); } } return params; } /** * @param {string} manifestId * @returns {string[]} */ Common.getImageList = async function (manifestId) { let folderName = manifestId.replace(/pherc-(\d+)-(\w+)$/, function (_match, g1, g2) { return `PHerc_${g1}_${g2.toUpperCase()}`; }); let baseFolder = `${folderName.split('_')[0]}_${folderName.split('_')[1]}`; let files = await fs.promises.readdir( `${process.env.IMAGES_DIR}/${baseFolder}/${folderName}` ); files = files.filter(file => path.extname(file) !== '.csv'); return files; } /** * @param {string} imageId The image's id as a URL to the image server * @returns {{width: number, height: number, thumb: {width: number, height: number}}} */ Common.getImageSize = async function (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; } /** * Get image name for given canvas * @param {Canvas} canvas * @returns {string} */ Common.getImageName = async function (canvas) { const images = await this.getImageList(canvas.resourceId); return images.filter( i => i.includes(canvas.name) )[0]; } /** * Create a canvas from an image filename * @param {Manifest} manifest * @param {string} filename The image filename * @returns {Canvas} */ Common.createCanvas = async function (manifest, filename) { let canvas = new Canvas( process.env.IIIF_API_VERSION, process.env.BASE_URL ); const namePos = { nir: 1, hsi: 1, do: 3, dn: 3 }; const canvasName = filename.split('_')[namePos[manifest.technique]] .replace(/\.\w{1,3}$/, ''); canvas.generateID(manifest.resourceId, canvasName); canvas.label = canvasName .replace(/c(\w{1,2})0+(\d+).*(\.\w{2,3})?$/i, function (str, c, number) { return `C${c}. ${number}`; }); let image = new Image(canvas.id); image.generateID(process.env.IMAGE_SERVER_URL, filename); const imgSize = await this.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 {Manifest} manifest The manifest object * @param {string[]} images List of image filenames from folder * @returns {Manifest} */ Common.populateCanvases = async function (manifest, images) { const sequence = new Sequence(process.env.BASE_URL); // There's only one sequence sequence.generateID(manifest.resourceId, 0); // Camice e copertina all'inizio per DN e DO if (manifest.technique.startsWith('d')) { images = [].concat( images .filter(i => i.includes('camice') || i.includes('copertina')) .reverse(), images .filter(i => !i.includes('camice') && !i.includes('copertina')) ); } for (let img of images) { let canvas = await this.createCanvas(manifest, img); sequence.addCanvas(canvas); } manifest.addSequence(sequence); return manifest; } /** * @todo Implement... * @param {Manifest} manifest The Manifest object * @param {string} imgFilename * @returns {ManifestMetadata} */ Common.createMetadata = function (manifest, imgFilename) { let metadata = this.getMetadataFromImgName(imgFilename, manifest.technique); metadata.technique = TECH_NAMES[manifest.technique]; return new ManifestMetadata(metadata); } /** * @param {string} imgFilename * @param {string} technique * @returns {{papyrus:string,imageAuthor:string,date:string,copyright:?string}} */ Common.getMetadataFromImgName = function (imgFilename, technique) { const extractor = { nir: extractNIRMetadata, dn: extractDNMetadata, do: extractDOMetadata, hsi: extractHSIMetadata, } return extractor[technique](imgFilename); } export default Common;