labo-components
Version:
350 lines (316 loc) • 9.99 kB
JavaScript
import CollectionConfig from './CollectionConfig';
import RegexUtil from '../../util/RegexUtil';
import NISV_GTAA_WIKIDATA from './entities/NISV_GTAA_WIKIDATA';
import SearchAPI from '../../api/SearchAPI';
//import MediaObject from '../../model/MediaObject';
//import MediaSegment from '../../model/MediaSegment';
export default class NISVDAANCatalogueConfig extends CollectionConfig {
constructor(clientId, user, collectionId, collectionMetadata) {
super(clientId, user, collectionId, collectionMetadata);
}
getProgramSegmentLabel = () => 'Program segments:';
getNamespace = () => 'http://av.beeldengeluid.nl/';
//the type varies for B&G
getCollectionMediaTypes = () => [];
//used to prevent graphs to blow up in case the minimum date is really low (because of incorrect data)
getMinimumYear = () => 1875;
getMaximumYear = () => -1;
//override so the annotation layer indices are ignored
getCollectionIndices = () => [this.getCollectionId()];
//this means the resource viewer needs to request access to the content before it can show them
requiresPlayoutAccess = () => true;
getAnonymousUserRestrictions = () => ({
prohibitThumbnails : false, // show thumbnails in search results
prohibitPlayout : true // playing content
});
hideOffAirContent = () => true;
getPreferredDateField = () => 'program.sortdate';
//gets the fields for showing highlights in search snippets, in order of preference
/*getPreferredHighlightFields = () => [
'layer__asr.words',
'summary', //aren't these also from the logtracks?
'summaryshort', //aren't these from the logtracks?
'title',
'alttitle',
'summarymuseum',
'subjectterm',
'name',
'actor',
'person',
'corporation',
'geographical',
'usedfootagenpo'
];*/
getFieldsToExclude = () => [
"layer__asr",
"logTrackItems.ltSubtitles",
"logTrackItems.ltFaceLabels",
"logTrackItems.ltSpeakerLabels",
"logTrackItems.ltExtractedLabels",
"logTrackItems.ltSpeechTranscripts"
];
//fields for ES highlighting
getHighlightFields = () => [
"layer__asr.words",
"*.title",
"logTrackItems.ltSubtitles.summary",
"logTrackItems.ltFaceLabels.summary",
"logTrackItems.ltSpeakerLabels.summary",
"logTrackItems.ltExtractedLabels.summary",
"logTrackItems.ltSpeechTranscripts.summary",
'*.summary', //aren't these also from the logtracks?
'*.summaryshort', //aren't these from the logtracks?
'*.title',
'*.alttitle',
'*.summarymuseum',
'*.subjectterm',
'*.name',
'*.actor',
'*.person',
'*.corporation',
'*.geographical',
'*.usedfootagenpo'
];
getDateFields = () => this.dateFields.filter(dateField => !dateField.includes("_"));
getFacets = () => [
{
field: 'mediaType',
title : 'mediaType',
id : 'mediaType',
type : 'string'
},
{
field: 'program.publication.broadcastorg.keyword',
title : 'Broadcaster',
id : 'broadcaster',
type : 'string'
},
{
field: 'series.genre.keyword',
title : 'Genre (series)',
id : 'genre',
type : 'string'
},
{
field: 'program.subjectterm.keyword',
title : 'Keyword',
id : 'keyword',
type : 'string'
}
];
//no nested search layers as ASR no longer nested
getNestedSearchLayers = () => [];
getMetadataFieldCategories = () => [
{
id : 'titles',
label : 'Titles',
fields : [
'series.title',
'season.title',
'program.title',
'logTrackItems.ltSceneDesc.title' //for scene descriptions
]
},
{
id : 'descriptions',
label : 'Descriptions',
fields : [
'program.summaryshort',
'program.summary',
'logTrackItems.ltSceneDesc.summary' //for scene descriptions
//NOTE: museum descriptions in DAAN are now modelled as titles
]
},
//TODO: add back in once have worked out how we will model the subtitle logtrack items
{
id : 'subtitles',
label : 'Keywords from Subtitles',
fields : [
'logTrackItems.ltSubtitles.text' //TODO: is it only Subtitles logtrackitems that have a text field?
]
},
{
id: 'subject',
label: 'Subject keywords',
fields: [
'program.subjectterm',
'season.subjectterm',
'logTrackItems.ltSceneDesc.subjectterm', // for scene descriptions
'series.subjectterm'
]
},
{
id: 'person',
label: 'Persons - all',
fields: [
'program.cast.actor',
'series.cast.actor',
'season.cast.actor',
'logTrackItems.ltSceneDesc.cast.actor',
'program.crew.name',
'series.crew.name',
'season.crew.name',
'logTrackItems.ltSceneDesc.crew.name',
'program.creator.name',
'series.creator.name',
'season.creator.name',
'logTrackItems.ltSceneDesc.creator.name',
'program.performer.name',
'series.performer.name',
'season.performer.name',
'logTrackItems.ltSceneDesc.performer.name',
'program.guest.name',
'series.guest.name',
'season.guest.name',
'logTrackItems.ltSceneDesc.guest.name',
'program.person',
'series.person',
'season.person',
'logTrackItems.ltSceneDesc.person',
]
},
{
id: 'production-person',
label: 'Persons - production',
fields: [
'program.cast.actor',
'series.cast.actor',
'season.cast.actor',
'logTrackItems.ltSceneDesc.cast.actor',
'program.crew.name',
'series.crew.name',
'season.crew.name',
'logTrackItems.ltSceneDesc.crew.name',
'program.creator.name',
'series.creator.name',
'season.creator.name',
'logTrackItems.ltSceneDesc.creator.name',
'program.performer.name',
'series.performer.name',
'season.performer.name',
'logTrackItems.ltSceneDesc.performer.name',
]
},
{
id: 'guest-person',
label: 'Persons - guests',
fields: [
'program.guest.name',
'series.guest.name',
'season.guest.name',
'logTrackItems.ltSceneDesc.guest.name',
]
},
{
id: 'discussed-person',
label: 'Persons - subject of discussion',
fields: [
'program.person',
'series.person',
'season.person',
'logTrackItems.ltSceneDesc.person',
]
},
{
id : 'asr',
label : 'Speech transcripts (ASR)',
enrichment : true,
fields : [
'layer__asr.words'
]
}
];
getEntityConfig = () => ({
person : { //currently only person entities are supported
autocompleteConfig : {
'fieldClusters' : ["person", "production-person", "guest-person", "discussed-person"], //for which field category clusters autocomplete is offered
'autocompleteVocabulary' : 'gtaa-persons', //vocabulary to use for auto-complete
'autocompleteParams' : { //assumes the searchAPI.autocomplete is used
'ConceptScheme' : 'http://data.beeldengeluid.nl/gtaa/Persoonsnamen', //any other parameters
'Fields': [
'@graph.skos:prefLabel.@value',
'@graph.skos:altLabel.@value',
'@graph.skos:hiddenLabel.@value'
],
'Method': 'match',
'Lang': 'nl'
}
},
fetchEntityDetails : (entityUri, callback) => {
SearchAPI.grlc(
'BENG-PERSON-LD',
'getPersonDataForGTAAId',
{gtaa: entityUri}, //TODO make sure the calling code abstracts the gtaa ID to entity ID
NISV_GTAA_WIKIDATA.formatPersonDetails,
callback
);
},
fetchEntitiesInResource : (resourceUri, callback) => {
SearchAPI.grlc(
'BENG-LD',
'getPersonsAndRolesForProgramAndParts',
{resource: resourceUri}, //TODO make sure the calling code abstracts the gtaa ID to entity ID
NISV_GTAA_WIKIDATA.formatPersonsInResource,
callback
);
},
formatEntityForSearch : (id, label, otherLabels) => {
return {
id: id,
label: label,
otherLabels: Array.isArray(otherLabels) ? otherLabels.join(";") : otherLabels
};
}
}
});
//gets the item's URI in the linked data store
//FIXME: IS THIS STILL USED?
getResourceUri = resource => {
return "http://data.rdlabs.beeldengeluid.nl/resource/program/" + resource["rawData"]["program"]["site_id"].replace("PGM", "");
};
getItemDetailData = (result, currentDateField) => result;
//in case the field name cannot be found in the field descriptions
formatIndexFieldName = esFieldName => {
if(esFieldName === 'layer__asr.words') {
return 'Speech transcript'
}
return esFieldName; //don't format, force the field_descriptions to be updated
};
//override to add the level to each field (which will display in the FieldSelector)
//at the same time, exclude the level from the pretty field name
getAllFields = () => {
const fields = super.getAllFields()
fields.forEach(f => {
const tmp = f.id.split('.');
let metadataLayer = 'program';
if (tmp[0].indexOf('series') !== -1) {
metadataLayer = 'series';
}
else if (tmp[0].indexOf('season') !== -1) {
metadataLayer = 'season';
}
f.level = metadataLayer;
f.title = this.toPrettyFieldName(f.id, false);
});
return fields
};
usesLayeredModel = () => true;
// Returns the first media object that matches the search term in the ASR transcript
// If a media object is provided, only looks for matches within that media object
findMatchingMediaFragments = (resource, searchTerm, activeMediaObject=null) => {
if(!resource.rawData.layer__asr) return null;
if(!resource.playableContent) return null;
let regex = null;
try {
regex = RegexUtil.generateRegexForSearchTerm(searchTerm);
} catch (err) {
console.debug('invalid regex');
}
const firstMatch = regex ? resource.rawData.layer__asr.find(phrase => {
return phrase.words.search(regex) !== -1 && (
activeMediaObject ? activeMediaObject.assetId === phrase.carrierId : true
);
}) : null;
return firstMatch ? resource.playableContent.find(mo => mo.assetId === firstMatch.carrierId) : null;
};
}