Skip to content

Commit

Permalink
add feature - generate manifests for micrographs
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanolamalu committed Jan 11, 2023
1 parent aeb74e0 commit f1a9e83
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 52 deletions.
6 changes: 4 additions & 2 deletions config.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,13 @@ export default {
w: "coordinates_width",
h: "coordinates_height",
uuid: "micrograph",
fullSizeURLParameters: "format=jpg"
thumbnailURLParameters: "format=jpg&width=300&withoutEnlargement&quality=80",
fullSizeURLParameters: "format=jpg&width=1920&withoutEnlargement&quality=80"
},
published: "status"
},
collection: "Fitzwilliam Museum",
license: "http://creativecommons.org/licenses/by-nc-nd/4.0/",
outputDir: "dist"
outputDir: "dist",
micrographBuildManifest: true
}
47 changes: 47 additions & 0 deletions directus.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import fetch from 'node-fetch';
import { promises as fsPromises } from 'fs';
import config from './config.js';

const { apiBase } = config;

export async function fetchMiniatureAll() {
const response = await fetch(apiBase + "items/miniatures");
return (await response.json()).data;
}

export async function fetchMiniature(id) {
const response = await fetch(apiBase + "items/miniatures/" + id);
return (await response.json()).data;
}

export async function fetchMicrographAll() {
const response = await fetch(apiBase + "items/micrographs");
return (await response.json()).data;
}

export async function fetchMicrograph(id) {
const response = await fetch(apiBase + "items/micrographs/" + id);
return (await response.json()).data;
}

export async function fetchAllMaXrf() {
const response = await fetch(apiBase + "items/ma_xrf_scans");
return (await response.json()).data;
}

export async function downloadImage(id, outputFilePath, imageOptions) {
let path = apiBase + "assets/" + id + "?quality=90";
if (imageOptions.width != undefined) {
path += "&width=" + imageOptions.width;
}
if (imageOptions.height != undefined) {
path += "&height=" + imageOptions.height;
}
const response = await fetch(path);
return fsPromises.writeFile(outputFilePath, response.body);
}

export async function fetchFileObject(id) {
const response = await fetch(apiBase + "files/" + id);
return (await response.json()).data;
}
80 changes: 30 additions & 50 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,53 +1,8 @@
import fetch from 'node-fetch';
import { promises as fsPromises } from 'fs';
import config from './config.js';
import path from 'path';

const { apiBase } = config;

//Directus APi endpoints

async function fetchMiniatureAll() {
const response = await fetch(apiBase + "items/miniatures");
return (await response.json()).data;
}

async function fetchMiniature(id) {
const response = await fetch(apiBase + "items/miniatures/" + id);
return (await response.json()).data;
}

async function fetchMicrographAll() {
const response = await fetch(apiBase + "items/micrographs");
return (await response.json()).data;
}

async function fetchMicrograph(id) {
const response = await fetch(apiBase + "items/micrographs/" + id);
return (await response.json()).data;
}

async function fetchAllMaXrf() {
const response = await fetch(apiBase + "items/ma_xrf_scans");
return (await response.json()).data;
}

async function downloadImage(id, outputFilePath, imageOptions) {
let path = apiBase + "assets/" + id + "?quality=90";
if (imageOptions.width != undefined) {
path += "&width=" + imageOptions.width;
}
if (imageOptions.height != undefined) {
path += "&height=" + imageOptions.height;
}
const response = await fetch(path);
return fsPromises.writeFile(outputFilePath, response.body);
}

async function fetchFileObject(id) {
const response = await fetch(apiBase + "files/" + id);
return (await response.json()).data;
}
import { fetchMiniatureAll, fetchMicrograph, fetchAllMaXrf, fetchFileObject, downloadImage } from './directus.js';
import micrographBuildManifest from './micrograph.js';

async function main() {

Expand All @@ -58,11 +13,14 @@ async function main() {
//Download all MA XRF Scan objects from API listing
const maXrfAll = await fetchAllMaXrf();

const urlSafeRegex = /[^a-zA-Z0-9_. ]/g;

//For each miniature
for (let i = 0; i < miniatureAll.length; i++) {

const data = miniatureAll[i];
const miniatureId = data[fieldMap.publicPath];
const miniatureId = data[fieldMap.publicPath].replace(urlSafeRegex, '-');

const basePath = config.basePath + miniatureId + "/";
const manifestId = basePath + "manifest.json";
const canvasId = basePath + "canvas/0";
Expand Down Expand Up @@ -255,6 +213,7 @@ async function main() {
const annotationItems = [];
if (Array.isArray(data[fieldMap.annotation.key])) {
for (let j = 0; j < data[fieldMap.annotation.key].length; j++) {

const micrographId = data[fieldMap.annotation.key][j];

const currentItem = await fetchMicrograph(micrographId);
Expand All @@ -264,8 +223,21 @@ async function main() {
const annotationItemId = basePath + path.join("annotation/tag/", currentItem.id.toString());
const targetCoords = `${currentItem[fieldMap.annotation.x]},${currentItem[fieldMap.annotation.y]},${currentItem[fieldMap.annotation.w]},${currentItem[fieldMap.annotation.h]}`;
const target = canvasId + "#xywh=" + targetCoords;
const micrographLink = config.micrographBasePath + currentItem[fieldMap.annotation.uuid] + '?' + fieldMap.annotation.fullSizeURLParameters;
const value = `<div><p>${currentItem[fieldMap.annotation.description]}</p><a href=${micrographLink} target="__blank">Open micrograph</a></div>`;

const micrographManifestId = `${config.basePath}${miniatureId}/micrograph/${micrographId}/manifest.json`;
const micrographManifestUrl = encodeURI(micrographManifestId);
const micrographDownloadUrl = config.micrographBasePath + currentItem[fieldMap.annotation.uuid] + '?' + fieldMap.annotation.fullSizeURLParameters;
const micrographThumbnailUrl = config.micrographBasePath + currentItem[fieldMap.annotation.uuid] + '?' + fieldMap.annotation.thumbnailURLParameters;
const micrographLabel = currentItem[fieldMap.annotation.description];

//https://github.com/ProjectMirador/mirador/blob/master/src/config/settings.js#L239
//https://github.com/ProjectMirador/mirador/blob/master/src/lib/htmlRules.js
const value = `<div>
<p>${micrographLabel}</p>
<a href=${micrographManifestUrl} alt="Open in Mirador"><img src="${micrographThumbnailUrl}" alt="${micrographLabel}"/></a>
<a href=${micrographManifestUrl} target="__blank">Open iiif Manifest URL</a>
<a href=${micrographDownloadUrl} target="__blank">Download image</a>
</div>`;

annotationItems.push({
"id": annotationItemId,
Expand All @@ -279,6 +251,14 @@ async function main() {
},
"target": target
});

if (config.micrographBuildManifest) {
await micrographBuildManifest(
currentItem,
miniatureId,
data[fieldMap.label] + ' - ' + micrographLabel
);
}
}
}

Expand Down
108 changes: 108 additions & 0 deletions micrograph.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { promises as fsPromises } from 'fs';
import path from 'path';
import config from './config.js';
import { fetchFileObject } from './directus.js';

export default async function (item, miniatureId, manifestLabel) {

const basePath = config.basePath + miniatureId + "/";

const micrographManifestId = `${config.basePath}${miniatureId}/micrograph/${item.id}/manifest.json`;

const micrographImageData = await fetchFileObject(item.micrograph);
const micrographImageExtension = micrographImageData.type == "image/tiff" ? "tif" : "jpg";
const micrographImageAPIBase = config.imageAPI + micrographImageData.filename_disk;
const micrographImageId = micrographImageAPIBase + "/full/max/0/default." + micrographImageExtension;

const micrographBasePath = basePath + 'micrograph/' + item.id;
const micrographCanvasId = micrographBasePath + '/canvas/0';
const micrographCanvasHeight = micrographImageData?.height || 1800;
const micrographCanvasWidth = micrographImageData?.width || 1200;
const micrographAnnotationPageId = micrographBasePath + "page/0/0";
const micrographAnnotationPaintingId = micrographBasePath + "painting/0";

const micrographManifest = {
"@context": "http://iiif.io/api/presentation/3/context.json",
"id": micrographManifestId,
"type": "Manifest",
"label": {
"en": [
manifestLabel
]
},
"summary": {
"en": [
item[config.fieldMap.annotation.description]
]
},
"requiredStatement": {
"label": {
"en": [
"Collection"
]
},
"value": {
"en": [
config.collection
]
}
},
"rights": config.license,
"items": [
{
"id": micrographCanvasId,
"type": "Canvas",
"height": micrographCanvasHeight,
"width": micrographCanvasWidth,
"items": [
{
"id": micrographAnnotationPageId,
"type": "AnnotationPage",
"items": [
{
"id": micrographAnnotationPaintingId,
"type": "Annotation",
"motivation": "painting",
"body": {
"type": "Choice",
"items": [
{
"id": micrographImageId,
"type": "Image",
"format": micrographImageData.type,
"height": micrographImageData.height,
"width": micrographImageData.width,
"label": {
"en": [
item[config.fieldMap.annotation.description]
]
},
"service": [
{
"id": micrographImageAPIBase,
"type": "ImageService3",
"profile": "level2"
}
]
}
]
},
"target": micrographCanvasId
}
]
}
]
},
],
}

const outputFilePathMicrograph = path.join(config.outputDir, `${miniatureId}/micrograph/${item.id}/manifest.json`);
const outputFilePath = path.join(config.outputDir, miniatureId.toString(), 'micrograph', item.id.toString());
try {
await fsPromises.mkdir(outputFilePath, { recursive: true });
}
catch (error) {

}
await fsPromises.writeFile(outputFilePathMicrograph, JSON.stringify(micrographManifest, null, " "));
}

0 comments on commit f1a9e83

Please sign in to comment.