-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
122 lines (100 loc) · 4.32 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
const { DOMParser } = require('@xmldom/xmldom');
const fs = require('fs');
const _ = require('lodash');
const { namespaces, customXPathFunctions, extract } = require('./src/xpathContextOptions');
const { shortRoleToFullRole, isNonEmptyString, handleError } = require('./src/utils');
const { metadata: { mappings, metadataXpaths } } = require('corhal-config');
const sourceIdsMap = _.transform(mappings, (sourceIds, { source, nameID }) => {
sourceIds[source] = nameID;
}, {});
/**
* Entry point of the module.
* @param {object} docObject The docObject coming from the previous module.
* @param {function} callback The callback.
*/
function doTheJob (docObject, callback) {
if (!docObject.metadata) {
return callback(handleError(docObject, 'NoMetadataError', new Error('No metadata key found in docObject')));
}
const teiObj = _.find(docObject.metadata, { mime: 'application/tei+xml', original: false });
if (!teiObj || !teiObj.path) {
return callback(handleError(docObject, 'NoTeiError', new Error('No TEI found in the docObject.metadata')));
}
fs.readFile(teiObj.path, 'utf8', (err, xml) => {
if (err) {
const errName = err.code === 'ENOENT' ? 'FileNotFoundError' : null;
return callback(handleError(docObject, errName, err));
}
let xmlParsingError;
const xmlParsingOptions = {
errorHandler (level, errMsg) {
xmlParsingError = new Error(errMsg);
},
};
const doc = new DOMParser(xmlParsingOptions).parseFromString(xml, 'text/xml');
if (xmlParsingError) {
return callback(handleError(docObject, 'XmlParsingError', xmlParsingError));
}
doc.documentElement.setAttribute('source', docObject.source);
let duplicateGenre;
const extractMetadata = {};
let flagSource = false;
const evaluatorOptions = {
node: doc,
namespaces,
functions: customXPathFunctions,
};
try {
metadataXpaths.forEach(metadata => {
extractMetadata[metadata.name] = extract(metadata, evaluatorOptions);
});
} catch (err) {
return callback(handleError(docObject, 'XmlPathExtractionError', err));
}
for (const mapping of mappings) {
if (mapping.source.trim() === docObject.source.toLowerCase().trim()) {
const { originalGenre } = extractMetadata;
if (mapping.mapping[originalGenre]) duplicateGenre = mapping.mapping[originalGenre];
// Flag set to true when the source id is present
if (isNonEmptyString(extractMetadata[mapping.nameID])) flagSource = true;
break;
}
}
// Check if the docObject has a source id
if (flagSource === false) {
return callback(handleError(docObject, 'NoSourceIdError', new Error('No source id found')));
}
// If the Conditor type is "Conférence" or "Autre" and an ISSN or EISSN
// are present then set the Conditor type to "Article"
if ((duplicateGenre === 'Conférence' || duplicateGenre === 'Conférence') && (isNonEmptyString(extractMetadata.issn) || isNonEmptyString(extractMetadata.eissn))) {
duplicateGenre = 'Article';
}
// If the Conditor type is "Thèse" and an ISBN is present then set the Conditor type to "Ouvrage"
if (duplicateGenre === 'Thèse' && isNonEmptyString(extractMetadata.isbn)) {
duplicateGenre = 'Ouvrage';
}
// If the Conditor type is "Conférence" and an ISBN is present then set the Conditor type to "Chapitre"
if (duplicateGenre === 'Conférence' && isNonEmptyString(extractMetadata.isbn)) {
duplicateGenre = 'Chapitre';
}
// Check if the Conditor type is set
if (!duplicateGenre) {
return callback(handleError(docObject, 'NoConditorTypeError', new Error('No Conditor type found')));
}
// Convert the roles to their full form
extractMetadata.host.editors.forEach(editor => {
editor.roles = shortRoleToFullRole(editor.roles);
});
// TODO: Try to find a better solution than entirely copying the entity model into the docObject
Object.assign(docObject, extractMetadata);
_.set(docObject, 'business.duplicateGenre', duplicateGenre);
const nameID = sourceIdsMap[docObject.source];
docObject.sourceId = docObject[nameID];
docObject.sourceUid = `${docObject.source}$${docObject[nameID]}`;
docObject.business.sourceUidChain = `!${docObject.sourceUid}!`;
return callback();
});
}
module.exports = {
doTheJob,
};