Source: job-manager/sampleFileTranslator.js

Source: job-manager/sampleFileTranslator.js

/**
 * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
 * Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl.
 */
/* globals app, module, __dirname */
/* jshint esversion: 6 */
var translationProvider = require('../provider/translationProvider').factory.create(),
    persistenceStore = require('./persistenceStore').factory.create(),
    fileImporter = require('./sampleFileImporter');

/**
 * Request the Language Service Provider translates all Assets & Site files into the requested target languages. <br/>
 * The steps involved are: <br/>
 * <ul>
 *   <li>For each site & assets file: 
 *     <ul>
 *       <li>For each target locale: 
 *         <ul>
 *           <li>Translate the document into the target locale</li>
 *        </ul>
 *     </ul>
 *   </li>
 * </ul>
 * @constructor
 * @alias SampleFileTranslator
 */
var SampleFileTranslator = function () {};


/**
 * Request the Language Service Provider to translate a file into the given target locale. 
 * @param {SampleJobManager.JobConfig} jobConfig - The configuration of the connector job to run. This information is held as metadata in the connector for the job. 
 * @param {SampleJobManager.JobDetails} jobDetails - The details of the combined job.json files.
 * @param {('site'|'assets')} fileType - The type of file being imported
 * @param {SampleJobManager.file} file - Details on the site or assets file to import
 * @param {string} locale - The target locale for the translation.
 * @returns {Promise} A Promise that is resolved when the translation request has been accepted by the Language Service Provider.
 */
SampleFileTranslator.prototype.translateFile = function (jobConfig, jobDetails, fileType, file, locale) {
    // ToDo: check if file is already submitted for translation
    return persistenceStore.getFileMetadata({
        jobId: jobConfig.properties.id,
        fileType: fileType,
        file: file
    }).then(function (fileMetadata) {
        if (file.documentId === fileImporter.EMPTY_DOCUMENT_ID) {
            // handle empty files - nothing to translate
            return Promise.resolve();
        } else {
            return translationProvider.addTranslation(jobConfig.authToken, jobConfig.properties.projectId, fileMetadata.documentId, locale);
        }
    }).catch(function(e) {
        console.log('translateFile metadata file does not exist -', e);
        return Promise.resolve();
    });
};

/**
 * Translate all the files in the file list<br/>
 * Loop through each file in the file list then:<br/>
 *   Loop through each of the target locales and translate the file into the target locale
 * @param {SampleJobManager.JobConfig} jobConfig - The configuration of the connector job to run. This information is held as metadata in the connector for the job. 
 * @param {SampleJobManager.JobDetails} jobDetails - The details of the combined job.json files.
 * @param {('site'|'assets')} fileType - The type of file being imported
 * @param {SampleJobManager.file} file - Details on the site or assets file to import
 * @returns {function[]} An array of functions, each of which returns a promise that resolves when the file is translated.
 */
SampleFileTranslator.prototype.translateFileToLocales = function (jobConfig, jobDetails, fileType, files) {
    var self = this,
        allTranslations = [];

    // get all the file->locale mappings
    (files || []).forEach(function (file) {
        jobDetails.targetLanguages.forEach(function (locale) {
            if (locale !== null && locale !== jobDetails.sourceLanguage) {
                allTranslations.push({
                    file: file,
                    locale: locale
                });
            }
        });
    });

    // create the array of functions to return the translation promises
    return allTranslations.map(function (translation) {
        return function () {
            return self.translateFile(jobConfig, jobDetails, fileType, translation.file, translation.locale);
        };
    });
};

/**
 * Translate all the Site & Assets files into the Language Service Provider for this job <br/>
 * The promises are chained in a "return p1.then(return p2.then(return p3.then(...)))"" model to avoid overloading the Language Service Provider. 
 * @param {SampleJobManager.JobConfig} jobConfig - The configuration of the connector job to run. This information is held as metadata in the connector for the job. 
 * @param {SampleJobManager.JobDetails} jobDetails - The details of the combined job.json files.
 * @returns {Promise} A Promise that resolves when all files have been translated.
 */
SampleFileTranslator.prototype.translateFiles = function (jobConfig, jobDetails) {
    var self = this;

    return new Promise(function (resolve, reject) {
        // make sure necessary files are there and then translate all the jobJSON files
        if (jobDetails.sourceLanguage && jobDetails.targetLanguages) {

            // translate the assets & the site into requested languages
            var translationPromises = [];
            if (jobDetails.site) {
                translationPromises = translationPromises.concat(self.translateFileToLocales(jobConfig, jobDetails, 'site', jobDetails.site.files));
            }
            if (jobDetails.assets) {
                translationPromises = translationPromises.concat(self.translateFileToLocales(jobConfig, jobDetails, 'assets', jobDetails.assets.files));
                translationPromises = translationPromises.concat(self.translateFileToLocales(jobConfig, jobDetails, 'assets', jobDetails.assets.binaryFiles));
            }


            // now run through and get all the file translations
            // chain the promises in the array so that they execute as: return p1.then(return p2.then(return p3.then(...)));
            var doTranslation = translationPromises.reduce(function (previousPromise, nextPromise) {
                    return previousPromise.then(function () {
                        // wait for the previous promise to complete and then return a new promise for the next 
                        return nextPromise();
                    });
                },
                // Start with a previousPromise value that is a resolved promise 
                Promise.resolve());

            // once all submitted for translation, can continue
            doTranslation.then(function () {
                console.log('SampleFileTranslator.translateFiles(): all files submitted for translation');
                resolve();
            }).catch(function (e) {
                console.log('SampleFileTranslator.translateFiles(): error translating files');
                console.log(e && e.toString());
                reject(e);
            });
        } else {
            reject('SampleFileTranslator.translateFiles(): no target languages specified in job.json files');
        }
    });
};


// Export the mock file translator
module.exports = new SampleFileTranslator();