const convert = require('xml-js') const { set, get, reduce } = require('lodash') const PackageManager = require('./PackageManager') const mts = require('./mts-json-template') const { defaultConfig, defaultParseXmlOptions, defaultS3Config, defaultFTPConfig, } = require('../config/default') class MTS { constructor( config = defaultConfig, options = defaultParseXmlOptions, s3Config = defaultS3Config, ftpConfig = defaultFTPConfig, ) { this.config = config this.options = options this.jsonTemplate = mts.getJsonTemplate(config) this.s3Config = s3Config this.ftpConfig = ftpConfig } createFileName(id = Date.now()) { return `${this.config.prefix}${id}` } parseHtml(content = '') { if (/<\/?[^>]*>/.test(content)) { return convert.xml2js(content, this.options) } return content } convertToXML(json = {}) { const content = convert.json2xml(json, this.options) const customId = get( json, 'article.front.article-meta.article-id[0]._text', this.createFileName(), ) const name = `${customId}.xml` return { name, content, } } setMetadata(metadata, jsonTemplate) { const fileName = this.createFileName(metadata.customId) const titleGroup = { 'article-title': this.parseHtml(metadata.title), } const articleId = [ { _attributes: { 'pub-id-type': 'publisher-id', }, _text: fileName, }, { _attributes: { 'pub-id-type': 'manuscript', }, _text: fileName, }, ] const articleType = { 'subj-group': [ { _attributes: { 'subj-group-type': 'Article Type', }, subject: { _text: metadata.type, }, }, ], } set(jsonTemplate, 'article.front.article-meta.title-group', titleGroup) set(jsonTemplate, 'article.front.article-meta.article-id', articleId) set( jsonTemplate, 'article.front.article-meta.article-categories', articleType, ) set(jsonTemplate, 'article.front.article-meta.abstract', metadata.abstract) return jsonTemplate } static setHistory(submitted, jsonTemplate) { const date = new Date(submitted) const parsedDate = { date: { _attributes: { 'date-type': 'received', }, day: { _text: date.getDate(), }, month: { _text: date.getMonth() + 1, }, year: { _text: date.getFullYear(), }, }, } set(jsonTemplate, 'article.front.article-meta.history', parsedDate) return jsonTemplate } static setFiles(files, jsonTemplate) { const jsonFiles = reduce( files, (result, value, key) => { value.map(v => result.push({ item_type: { _text: key, }, item_description: { _text: v.originalName, }, item_name: { _text: v.name, }, }), ) return result }, [], ) set(jsonTemplate, 'article.front.files.file', jsonFiles) return jsonTemplate } static setContributors(authors = [], jsonTemplate) { const contrib = authors.map((a, i) => ({ _attributes: { 'contrib-type': 'author', corresp: a.isCorresponding ? 'yes' : 'no', }, role: { _attributes: { 'content-type': '1', }, }, name: { surname: { _text: a.firstName, }, 'given-names': { _text: a.lastName, }, prefix: { _text: a.title || 'Dr.', }, }, email: { _text: a.email, }, xref: { _attributes: { 'ref-type': 'aff', rid: `aff${i + 1}`, }, }, })) const aff = authors.map((a, i) => ({ _attributes: { id: `aff${i + 1}`, }, country: {}, 'addr-line': { _text: a.affiliation || '', }, })) set( jsonTemplate, 'article.front.article-meta.contrib-group.contrib', contrib, ) set(jsonTemplate, 'article.front.article-meta.contrib-group.aff', aff) return jsonTemplate } composeJson(fragment = {}) { const { authors = [], files = [], metadata = { title: 'untitled', abstract: '' }, submitted = new Date(), } = fragment return { ...this.jsonTemplate, ...this.setMetadata(metadata, this.jsonTemplate), ...this.constructor.setContributors(authors, this.jsonTemplate), ...this.constructor.setHistory(submitted, this.jsonTemplate), ...this.constructor.setFiles(files, this.jsonTemplate), } } convertFragmentToXML(fragment = {}) { return this.convertToXML(this.composeJson(fragment)) } sendPackage(fragment = {}) { const xmlFile = this.convertFragmentToXML(fragment) return PackageManager.createFilesPackage(this.s3Config)({ fragment, xmlFile, }).then(() => { const manuscriptName = get(xmlFile, 'name', '').replace('.xml', '') const filename = `${manuscriptName}.zip` return PackageManager.uploadFiles({ filename, s3Config: this.s3Config, config: this.ftpConfig, }) }) } } module.exports = MTS