@rr0/data
Version:
RR0 data model
133 lines (132 loc) • 4.97 kB
JavaScript
import path from "path";
import fs from "fs";
import { StringUtil } from "./util/string/StringUtil.js";
import { Level2Date as EdtfDate } from "@rr0/time";
import { Source } from "./source/Source.js";
export class AbstractDataFactory {
/**
* @param eventFactory The factory to create sub-events.
* @param previewFileNames
*/
constructor(eventFactory, previewFileNames = AbstractDataFactory.defaultPreviewFileNames) {
this.eventFactory = eventFactory;
this.previewFileNames = previewFileNames;
}
parse(dataJson) {
const title = this.createTitle(dataJson);
const jsonEvents = this.defaultJsonEvents(dataJson);
const data = {
id: dataJson.id,
type: dataJson.type,
dirName: dataJson.dirName,
name: dataJson.name,
title,
url: dataJson.url,
events: [],
surname: dataJson.surname,
notes: dataJson.notes
};
data.sources = this.parseSources(dataJson.sources, data);
data.events = this.parseEvents(jsonEvents, data);
return data;
}
parseSources(json = [], parent) {
return json === null || json === void 0 ? void 0 : json.map(json => this.parseSource(json, parent));
}
parseSource(json, parent) {
const type = json.type;
const source = new Source(type); // TODO: Should be json.sourceType
const publicationJson = json.publication;
Object.assign(source, {
authors: json.authors,
url: json.url,
name: json.name,
title: json.title,
description: json.description,
type: json.type,
index: json.index,
events: this.parseEvents(json.events, parent),
previousSourceRefs: json.previousSourceRefs
});
if (publicationJson) {
source.publication = this.parsePublication(publicationJson);
}
return source;
}
parsePublication(json) {
const publication = {
publisher: json.publisher,
};
const jsonTime = json.time;
if (jsonTime) {
publication.time = EdtfDate.fromString(jsonTime);
}
return publication;
}
defaultJsonEvents(dataJson) {
const jsonEvents = dataJson.events || [];
const birthTime = dataJson.birthTime;
if (birthTime) {
jsonEvents.push({ type: "event", eventType: "birth", time: birthTime, events: [] });
}
const deathTime = dataJson.deathTime;
if (deathTime) {
jsonEvents.push({ type: "event", eventType: "death", time: deathTime, events: [] });
}
let imageJsonEvent = { type: "event", eventType: "image", events: [] };
if (dataJson.image) {
imageJsonEvent.url = dataJson.image;
}
else {
let hasDefaultFile = false;
const dirName = dataJson.dirName;
if (dirName) {
for (const defaultImageFile of this.previewFileNames) {
hasDefaultFile = fs.existsSync(path.join(dirName, defaultImageFile));
if (hasDefaultFile) {
imageJsonEvent.url = defaultImageFile;
imageJsonEvent.name = dataJson.name; // In a default portrait image, label is parent's name
break;
}
}
}
}
if (imageJsonEvent.url) {
jsonEvents.push(imageJsonEvent);
}
return jsonEvents;
}
parseEvents(jsonEvents = [], defaultParent) {
const events = [];
for (const eventJson of jsonEvents) {
const event = this.parseEvent(eventJson, defaultParent);
events.push(event);
}
return events;
}
/**
* Determine people name from directory name.
*
* @param dataJson
*/
createTitle(dataJson) {
let title = dataJson.title;
if (!title && dataJson.dirName) {
title = StringUtil.camelToText(path.basename(dataJson.dirName));
const names = title.split(" ");
title = names.length <= 1 ? title : `${names[0]}, ${names.slice(1).join(" ")}`;
}
return title;
}
parseEvent(eventJson, defaultParent) {
const event = this.eventFactory.parse(eventJson);
switch (event.eventType) {
case "image":
event.name = event.name || (defaultParent === null || defaultParent === void 0 ? void 0 : defaultParent.name) || "<unknown name>";
event.title = event.title || (defaultParent === null || defaultParent === void 0 ? void 0 : defaultParent.title) || "<unknown title>";
break;
}
return event;
}
}
AbstractDataFactory.defaultPreviewFileNames = ["portrait.jpg", "portrait.gif", "portrait.png", "portrait.webp"];