Skip to content

Commit

Permalink
Read suppmenting annotations from manifest urls in transcripts list
Browse files Browse the repository at this point in the history
  • Loading branch information
Dananji committed Aug 17, 2023
1 parent c1d8ffc commit 265391b
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 27 deletions.
2 changes: 1 addition & 1 deletion src/components/Transcript/Transcript.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ const Transcript = ({ playerID, manifestUrl, transcripts = [] }) => {

// transcripts prop is processed first if given
if (transcripts?.length > 0) {
allTranscripts = sanitizeTranscripts(transcripts);
allTranscripts = await sanitizeTranscripts(transcripts);
} else if (manifestUrl) {
// Read supplementing annotations from the given manifest
allTranscripts = await getSupplementingAnnotations(manifestUrl);
Expand Down
3 changes: 2 additions & 1 deletion src/components/Transcript/Transcript.scss
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,9 @@ a.ramp--transcript_item {
display: inline-block;
position: relative;
width: 80px;
height: 80px;
height: 30rem;
left: 43%;
top: 45%;
}

.lds-spinner div {
Expand Down
8 changes: 7 additions & 1 deletion src/components/Transcript/Transcript.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@ import Transcript from './Transcript';
import * as transcriptParser from '@Services/transcript-parser';

describe('Transcript component', () => {
let promise;
let promise, originalError;
beforeEach(() => {
promise = Promise.resolve();
originalError = console.error;
console.error = jest.fn();
});

afterAll(() => {
console.error = originalError;
});

describe('with valid transcript data', () => {
Expand Down
72 changes: 54 additions & 18 deletions src/services/transcript-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ export const TRANSCRIPT_TYPES = { invalid: -1, noTranscript: 0, timedText: 1, pl
/**
* Parse the transcript information in the Manifest presented as supplementing annotations
* @param {String} manifestURL IIIF Presentation 3.0 manifest URL
* @param {String} title optional title given in the transcripts list in props
* @returns {Array<Object>} array of supplementing annotations for transcripts for all
* canvases in the Manifest
*/
export async function getSupplementingAnnotations(manifestURL) {
export async function getSupplementingAnnotations(manifestURL, title = '') {
let data = await fetch(manifestURL)
.then(function (response) {
const fileType = response.headers.get('Content-Type');
Expand All @@ -47,7 +48,12 @@ export async function getSupplementingAnnotations(manifestURL) {
if (annotations.length > 0) {
let annotBody = annotations[0].getBody()[0];
if (annotBody.getProperty('type') === 'TextualBody') {
let label = annotBody.getLabel()[0] ? annotBody.getLabel()[0].value : `Canvas-${index}`;
let label = title.length > 0
? title
: (annotBody.getLabel()[0]
? annotBody.getLabel()[0].value
: `Canvas-${index}`
);
let { isMachineGen, labelText } = identifyMachineGen(label);
canvasTranscripts.push({
url: annotBody.id === undefined ? manifestURL : annotBody.id,
Expand Down Expand Up @@ -85,29 +91,59 @@ export async function getSupplementingAnnotations(manifestURL) {
return data;
}

export function sanitizeTranscripts(transcripts) {
export async function sanitizeTranscripts(transcripts) {
if (!transcripts || transcripts == undefined || transcripts.length == 0) {
console.error('No transcripts given as input');
return [];
} else {
let sanitizedTrs = transcripts.map((transcript) => {
const { canvasId, items } = transcript;
let sanitizedItems = items.map((item, index) => {
const { title, url } = item;
let { isMachineGen, labelText } = identifyMachineGen(title);
return {
title: labelText,
url: url,
isMachineGen: isMachineGen,
id: `${labelText}-${canvasId}-${index}`,
};
});
return { canvasId, items: sanitizedItems };
});
return sanitizedTrs;
let allTranscripts = [];
transcripts.map((trs => allTranscripts.push({ canvasId: trs.canvasId, items: [] })));
let sanitizedTrs = await Promise.all(
transcripts.map(async (transcript, index) => {
const { canvasId, items } = transcript;
let sanitizedItems = await Promise.all(
items.map(async (item, index) => {
const { title, url } = item;
const manifestTranscripts = await getSupplementingAnnotations(url, title);
const manifestItems = manifestTranscripts.map(mt => mt.items).flat();
let groupedTrs = groupByIndex(allTranscripts.concat(manifestTranscripts), 'canvasId', 'items');
allTranscripts = groupedTrs;
let { isMachineGen, labelText } = identifyMachineGen(title);
// if manifest doesn't have canvases or supplementing annotations add original transcript
// to the list
if (manifestTranscripts.length === 0 || manifestItems.length === 0) {
return {
title: labelText,
url: url,
isMachineGen: isMachineGen,
id: `${labelText}-${canvasId}-${index}`,
};
} else {
return null;
}
})
);
return { canvasId, items: sanitizedItems.filter(i => i != null) };
})
);
let newTranscripts = groupByIndex(allTranscripts.concat(sanitizedTrs), 'canvasId', 'items');
return newTranscripts;
}
}

function groupByIndex(objectArray, indexKey, selectKey) {
return objectArray.reduce((acc, obj) => {
const existing = acc.filter(a => a[indexKey] == obj[indexKey]);
if (existing?.length > 0) {
let current = existing[0];
current[selectKey] = current[selectKey].concat(obj[selectKey]);
} else {
acc.push(obj);
}
return acc;
}, []);
}

/**
* Parse a given transcript file into a format the Transcript component
* can render on the UI. E.g.: text file -> returns null, so that the Google
Expand Down
17 changes: 11 additions & 6 deletions src/services/transcript-parser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import canvasTranscript from '@TestData/transcript-canvas';
import multipleCanvas from '@TestData/transcript-multiple-canvas';
import annotationTranscript from '@TestData/transcript-annotation';
import mammoth from 'mammoth';
import { cleanup, waitFor } from '@testing-library/react';
const utils = require('./utility-helpers');

describe('transcript-parser', () => {
Expand All @@ -13,6 +14,10 @@ describe('transcript-parser', () => {
})
);

afterEach(() => {
cleanup();
});

describe('getSupplementingAnnotations', () => {
test('invalid manifestURL', async () => {
// mock console.error
Expand Down Expand Up @@ -106,30 +111,30 @@ describe('transcript-parser', () => {
});

describe('sanitizeTranscripts()', () => {
test('when transcripts is empty', () => {
test('when transcripts is empty', async () => {
// mock console.error
console.error = jest.fn();

const transcripts = transcriptParser.sanitizeTranscripts([]);
const transcripts = await transcriptParser.sanitizeTranscripts([]);

expect(transcripts).toHaveLength(0);
expect(console.error).toHaveBeenCalledTimes(1);
expect(console.error).toHaveBeenCalledWith('No transcripts given as input');
});

test('when transcripts is undefined', () => {
test('when transcripts is undefined', async () => {
// mock console.error
console.error = jest.fn();

const transcripts = transcriptParser.sanitizeTranscripts(undefined);
const transcripts = await transcriptParser.sanitizeTranscripts(undefined);

expect(transcripts).toHaveLength(0);
expect(console.error).toHaveBeenCalledTimes(1);
expect(console.error).toHaveBeenCalledWith('No transcripts given as input');
});

test('when transcripts list is not empty', () => {
const transcripts = transcriptParser.sanitizeTranscripts(
test('when transcripts list is not empty', async () => {
const transcripts = await transcriptParser.sanitizeTranscripts(
[
{
canvasId: 0,
Expand Down

0 comments on commit 265391b

Please sign in to comment.