Skip to content
Snippets Groups Projects
MTS.js 5.31 KiB
Newer Older
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',
        },
      },
      {
        _attributes: {
          'pub-id-type': 'manuscript',
        },
    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}`,
      },
      '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 = [],
      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