Complete manifest JSON + working canvas JSON
This commit is contained in:
parent
550fe0f4ef
commit
127b2b302f
@ -2,6 +2,6 @@ PORT = 8080
|
||||
BASE_URL = 'https://something.com'
|
||||
# The most recent API version number that should be supported
|
||||
IIIF_API_VERSION = 2
|
||||
# The Image API service's base URL
|
||||
# The Image API service's base URL. No trailing slash!
|
||||
IMAGE_SERVER_URL = 'https://images.something.com'
|
||||
IMAGES_DIR = '/path/to/iiif/images'
|
||||
|
@ -1,19 +1,30 @@
|
||||
import Canvas from '../src/Canvas.js';
|
||||
import Image from '../src/Image.js';
|
||||
import Common from '../src/common.js';
|
||||
/**
|
||||
* Generate a canvas object to serve
|
||||
* @param {string} manifestId The corresponding manifest's id
|
||||
* @param {int|string} name The canvas name
|
||||
* @param {number|string} name The canvas name
|
||||
*/
|
||||
export default function generateCanvas(manifestId, name) {
|
||||
export default async function generateCanvas(manifestId, name) {
|
||||
const IIIF_API_VERSION = process.env.IIIF_API_VERSION;
|
||||
const BASE_URL = process.env.BASE_URL;
|
||||
|
||||
const canvas = new Canvas(IIIF_API_VERSION, BASE_URL);
|
||||
canvas.generateID(manifestId, name);
|
||||
canvas.setLabel(`${manifestId}-${name.toLowerCase()}`);
|
||||
|
||||
const image = new Image(canvas.id);
|
||||
image.generateID(process.env.IMAGE_SERVER_URL, await Common.getImageName(canvas));
|
||||
const imgSize = await Common.getImageSize(image.id);
|
||||
image.setSize(imgSize.height, imgSize.width);
|
||||
|
||||
canvas.setThumbnail(
|
||||
imgSize.thumb.height,
|
||||
imgSize.thumb.width,
|
||||
image.id
|
||||
);
|
||||
|
||||
const image = new Image(4000, 3000);
|
||||
canvas.setThumbnail();
|
||||
canvas.addImage(image);
|
||||
|
||||
return canvas.toObject();
|
||||
|
@ -1,15 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
import Manifest from '../src/Manifest.js';
|
||||
import Sequence from '../src/Sequence.js';
|
||||
import Canvas from '../src/Canvas.js';
|
||||
import Image from '../src/Image.js';
|
||||
import Common from '../src/common.js';
|
||||
|
||||
import * as fs from 'fs';
|
||||
|
||||
/**
|
||||
* @typedef {Obj}
|
||||
*/
|
||||
/**
|
||||
* Generate a manifest object to serve
|
||||
* @param {string} manifestId
|
||||
@ -21,86 +14,11 @@ export default async function generateManifest(manifestId) {
|
||||
let manifest = new Manifest(IIIF_API_VERSION, BASE_URL);
|
||||
manifest.generateID(manifestId);
|
||||
|
||||
manifest = await populateCanvases(
|
||||
manifest = await Common.populateCanvases(
|
||||
manifest,
|
||||
await getImageList(manifestId),
|
||||
await Common.getImageList(manifestId),
|
||||
manifestId
|
||||
);
|
||||
|
||||
return manifest.toObject();
|
||||
}
|
||||
/**
|
||||
* @param {string} manifestId
|
||||
*/
|
||||
async function getImageList(manifestId) {
|
||||
let folderName = manifestId.replace(/pherc-(\d+)-(\w+)$/, function (_match, g1, g2) {
|
||||
return `PHerc_${g1}_${g2.toUpperCase()}`;
|
||||
});
|
||||
|
||||
folderName += '_iiif';
|
||||
|
||||
return await fs.promises.readdir(`${process.env.IMAGES_DIR}/${folderName}`);
|
||||
}
|
||||
/**
|
||||
* @todo Read height & width from info.json
|
||||
* @param {Manifest} manifest
|
||||
* @param {string[]} images List of image filenames from folder
|
||||
* @returns {Manifest}
|
||||
*/
|
||||
async function populateCanvases(manifest, images, manifestId) {
|
||||
const IIIF_API_VERSION = process.env.IIIF_API_VERSION;
|
||||
const BASE_URL = process.env.BASE_URL;
|
||||
const sequence = new Sequence(BASE_URL);
|
||||
// There's only one sequence
|
||||
sequence.generateID(manifestId, 0);
|
||||
|
||||
for (let img of images) {
|
||||
let canvas = new Canvas(IIIF_API_VERSION, BASE_URL);
|
||||
const canvasName = img.split('_')[3].replace(/\.[\w\d]{2,3}$/,'');
|
||||
|
||||
canvas.generateID(manifestId, canvasName);
|
||||
canvas.setLabel(`${manifestId}-${canvasName.toLowerCase()}`);
|
||||
|
||||
let image = new Image(canvas.id);
|
||||
image.generateID(process.env.IMAGE_SERVER_URL, img);
|
||||
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);
|
||||
sequence.addCanvas(canvas);
|
||||
}
|
||||
|
||||
manifest.addSequence(sequence);
|
||||
|
||||
return manifest;
|
||||
}
|
||||
/**
|
||||
* @todo Read height & width from info.json
|
||||
* @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;
|
||||
}
|
@ -11,8 +11,8 @@ router.get('/iiif/:manifestid/manifest', async function(req, res) {
|
||||
});
|
||||
|
||||
/* GET manifest JSON */
|
||||
router.get('/iiif/:manifestid/canvas/:name', function(req, res) {
|
||||
const canvas = generateCanvas(req.params.manifestid, req.params.name)
|
||||
router.get('/iiif/:manifestid/canvas/:name', async function(req, res) {
|
||||
const canvas = await generateCanvas(req.params.manifestid, req.params.name)
|
||||
res.json(canvas);
|
||||
});
|
||||
|
||||
|
@ -7,6 +7,8 @@ class Canvas {
|
||||
id = '';
|
||||
type = 'sc:Canvas';
|
||||
label = '';
|
||||
resourceId = '';
|
||||
name = '';
|
||||
images = [];
|
||||
thumbnail = {};
|
||||
/**
|
||||
@ -23,6 +25,8 @@ class Canvas {
|
||||
*/
|
||||
generateID(resourceId, name) {
|
||||
this.id = `${this.BASE_URL}/iiif/${resourceId}/canvas/${name}`;
|
||||
this.resourceId = resourceId;
|
||||
this.name = name;
|
||||
}
|
||||
/**
|
||||
* @param {string} label A label for this canvas
|
||||
|
@ -5,6 +5,7 @@ class IIIFResource {
|
||||
id;
|
||||
type;
|
||||
|
||||
generateId(serviceURL, filename) {}
|
||||
toObject() {}
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,11 @@ class Image {
|
||||
__format = 'image/jpeg';
|
||||
height = 0;
|
||||
width = 0;
|
||||
service = {};
|
||||
service = {
|
||||
"@context" : this.context,
|
||||
"@id" : '',
|
||||
profile : 'https://iiif.io/api/image/2/level2.json',
|
||||
};
|
||||
canvasId = '';
|
||||
/**
|
||||
*
|
||||
@ -40,6 +44,7 @@ class Image {
|
||||
const subfolder = splitFilename.slice(0,3).join('_') + '_iiif';
|
||||
|
||||
this.id = `${serviceURL}/2/${baseFolder}%2F${subfolder}%2F${filename}/full/full/0/default.jpg`;
|
||||
this.service['@id'] = this.id.replace(/full.*$/,'');
|
||||
}
|
||||
/**
|
||||
* Object representation of
|
||||
|
@ -6,6 +6,7 @@ import Sequence from "./Sequence.js";
|
||||
class Manifest {
|
||||
id = '';
|
||||
type = 'sc:Manifest';
|
||||
resourceId = '';
|
||||
/**
|
||||
* @var {Sequence[]}
|
||||
*/
|
||||
@ -22,10 +23,11 @@ class Manifest {
|
||||
this.sequences.push(sequence.toObject());
|
||||
}
|
||||
/**
|
||||
* @param {string} idParam From the request
|
||||
* @param {string} resourceId From the request
|
||||
*/
|
||||
generateID(idParam) {
|
||||
this.id = `${this.BASE_URL}/iiif/${idParam}/manifest` ;
|
||||
generateID(resourceId) {
|
||||
this.id = `${this.BASE_URL}/iiif/${resourceId}/manifest` ;
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
/**
|
||||
* Object representation of this
|
||||
|
@ -1,4 +1,5 @@
|
||||
import IIIFResource from './IIIFResource.js';
|
||||
import Canvas from './Canvas.js';
|
||||
/**
|
||||
* @todo Not needed in IIIF API v3,
|
||||
* replaced by items
|
||||
@ -8,6 +9,7 @@ class Sequence {
|
||||
canvases = [];
|
||||
id = '';
|
||||
type = 'sc:Sequence';
|
||||
resourceId = '';
|
||||
|
||||
constructor(baseUrl) {
|
||||
this.BASE_URL = baseUrl;
|
||||
@ -18,6 +20,7 @@ class Sequence {
|
||||
*/
|
||||
generateID(resourceId, name) {
|
||||
this.id = `${this.BASE_URL}/iiif/${resourceId}/sequence/${name}`;
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
/**
|
||||
* @param {Canvas} canvas The Canvas object
|
||||
|
91
src/common.js
Normal file
91
src/common.js
Normal file
@ -0,0 +1,91 @@
|
||||
import * as fs from 'fs';
|
||||
import Manifest from './Manifest.js';
|
||||
import Sequence from './Sequence.js';
|
||||
import Canvas from './Canvas.js';
|
||||
import Image from './Image.js';
|
||||
const Common = {};
|
||||
|
||||
/**
|
||||
* @param {string} manifestId
|
||||
*/
|
||||
Common.getImageList = async function (manifestId) {
|
||||
let folderName = manifestId.replace(/pherc-(\d+)-(\w+)$/, function (_match, g1, g2) {
|
||||
return `PHerc_${g1}_${g2.toUpperCase()}`;
|
||||
});
|
||||
|
||||
folderName += '_iiif';
|
||||
|
||||
return await fs.promises.readdir(`${process.env.IMAGES_DIR}/${folderName}`);
|
||||
}
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
Common.getImageName = async function (canvas) {
|
||||
const images = await this.getImageList(canvas.resourceId);
|
||||
|
||||
return images.filter(i => i.includes(canvas.name))[0];
|
||||
}
|
||||
/**
|
||||
* @param {Manifest} manifest The manifest object
|
||||
* @param {string[]} images List of image filenames from folder
|
||||
* @returns {Manifest}
|
||||
*/
|
||||
Common.populateCanvases = async function (manifest, images) {
|
||||
const IIIF_API_VERSION = process.env.IIIF_API_VERSION;
|
||||
const BASE_URL = process.env.BASE_URL;
|
||||
const sequence = new Sequence(BASE_URL);
|
||||
// There's only one sequence
|
||||
sequence.generateID(manifest.resourceId, 0);
|
||||
|
||||
for (let img of images) {
|
||||
let canvas = new Canvas(IIIF_API_VERSION, BASE_URL);
|
||||
const canvasName = img.split('_')[3].replace(/\.[\w\d]{2,3}$/,'');
|
||||
|
||||
canvas.generateID(manifest.resourceId, canvasName);
|
||||
canvas.setLabel(`${manifest.resourceId}-${canvasName.toLowerCase()}`);
|
||||
|
||||
let image = new Image(canvas.id);
|
||||
image.generateID(process.env.IMAGE_SERVER_URL, img);
|
||||
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);
|
||||
sequence.addCanvas(canvas);
|
||||
}
|
||||
|
||||
manifest.addSequence(sequence);
|
||||
|
||||
return manifest;
|
||||
}
|
||||
|
||||
export default Common;
|
Loading…
Reference in New Issue
Block a user