UNPKG

activator-oce-exporter

Version:

Extract Activator binder and convert it to valid OCE mono pacakge

280 lines (261 loc) 9.53 kB
'use strict'; const decompress = require('decompress'); const fs = require('fs'); const gulp = require('gulp'); const clean = require('gulp-clean'); const zip = require('gulp-zip'); const path = require('path'); const exporter = require('anthill-exporter'); const slidesMap = {}; const filesExceptions = ['presentation.json', 'shared']; const getSlideName = (id, nodes) => { const node = nodes.find(obj => obj.version_id === id); return node.name__v || id; }; const addPrefix = (index) => { const newIndex = index + 1; return newIndex < 10 ? '0' + newIndex : newIndex; }; const moveFile = (file, rename, index, dir) => { return new Promise((resolve, reject) => { const prefixIndex = addPrefix(index); const fileName = path.basename(file); const newIndexName = `${prefixIndex}_${rename || fileName}`; const dest = path.resolve(dir, newIndexName); fs.rename(file, dest, (err, data) => { if (err) return reject(err); resolve(data); }); }); }; //Update relative paths in index const updatePaths = (file, currentDirectory, filesUsedInIndex) => { return new Promise((resolve, reject) => { fs.readFile(file, async (err, data) => { if (err) return reject(err); // Update shared path let replaceText = data.toString().replace(/\.\.\//g, './'); // Add OCE script replaceText = replaceText.replace( '</head>', '<script>if (window.CLMPlayer) { window.oce = { config: {{{.}}} } }</script></head>' ); filesUsedInIndex.forEach((fileName) => { if (fileName === 'assets') { const newReg = new RegExp(fileName, 'g'); replaceText = replaceText.replace(newReg, `./${fileName}`); const newReg2 = new RegExp(`src="./shared/./${currentDirectory}/${fileName}`, 'g'); replaceText = replaceText.replace(newReg2, `src="./shared/${fileName}`); // const newReg2 = new RegExp('url(assets', 'g'); // replaceText = replaceText.replace(newReg2, `url("./${currentDirectory}/${fileName}`); } else { const newReg = new RegExp(fileName, 'g'); replaceText = replaceText.replace(newReg, `./${fileName}`); } }); await fs.writeFile(file, replaceText, (err) => { if (err) return reject(err); resolve(data); }); }); }); }; //Return files from a directory const readCurrentDirectory = (dir) => { return new Promise((resolve, reject) => { fs.readdir(dir, (err, files) => { if (err) return reject(err); resolve(files); }); }); }; // ./shared/src/getbundle.js refers to ./shared/dist/main.js const updateGetBundle = (outPutPath) => { return new Promise((resolve, reject) => { const getBundleFile = `${outPutPath}/shared/src/getbundle.js`; fs.readFile(getBundleFile, async (err, data) => { if (err) return reject(err); let replaceText = data.toString().replace(/\..\//g, './'); await fs.writeFile(getBundleFile, replaceText, (err) => { if (err) return reject(err); resolve(data); }); }); }); }; // param binderDocs - The nodes object from presentation.json const createNavigationConfig = (binderDocs, outPutPath) => { return new Promise((resolve, reject) => { const oceFolder = `${outPutPath}/shared/src/fusion/oce/navigation`; const mapContent = binderDocs.reduce((map, doc) => { const id = doc['version_id'].split('_'); map[id[0]] = doc.name__v; return map; }, {}); const navigationMap = {"navigationMap": mapContent}; fs.writeFile(`${oceFolder}/oce.navigation-config.json`, JSON.stringify(navigationMap), (err) => { if (err) return reject(err); resolve(navigationMap); }); }); }; const convertFiles = (files, output, input) => { return new Promise(async (resolve, reject) => { try { // Read presentation.json. Check first if presentation.json exists const presentationJson = files.find((file) => file.path.includes('presentation.json')); if (!presentationJson) throw Error('ERROR: Presentation.json not found'); const temp = JSON.parse(presentationJson.data.toString()); const nodes = temp.nodes; const presentationJsonPath = path.basename(presentationJson.path); fs.unlink(`${output}/${presentationJsonPath}`, () => {}); if (!nodes.length) throw Error('ERROR: Presentation.json does not have node key'); await renameFiles(output, nodes); await updateGetBundle(output); await createNavigationConfig(nodes, output); for (let index = 0; index < nodes.length; index++) { // const slide = getSlideName(nodes[index].id); const slide = nodes[index].name__v; const currentDirectory = `${output}/${slide}`; const indexFile = `${currentDirectory}/index.html`; //Extract the files which are linked in the index const filesUsedInIndex = await readCurrentDirectory(currentDirectory); await updatePaths(indexFile, `${slide}`, filesUsedInIndex); //Move index.html const indexFile2 = `./${output}/${slide}/index.html`; await moveFile(indexFile2, `${slide}.html`, 0, `${output}/${slide}`); //Move thumb.png and convert to jpg const thumbFile = `./${output}/${slide}/thumb.png`; await moveFile(thumbFile, 'thumbnail.jpg', 0, `${output}/${slide}`); //Move shared to each sequence const sharedFolder = `./${output}/shared/**/*`; await new Promise((resolve, reject) => { gulp.src([sharedFolder, `!${output}/shared/exports/**/*`, `!${output}/shared/node_modules`]) .pipe(gulp.dest(`${output}/${slide}/shared`)) .on('end', resolve); }); //Zip data await new Promise((resolve, reject) => { // const zipName = slide.split('_')[0]; gulp.src(`${output}/${slide}/**/*`) .pipe(zip(`${addPrefix(index)}_${slide}.zip`)) .on('error', reject) .pipe(gulp.dest(`${output}`)) .on('end', async () => { await deleteFolder(`${output}/${slide}`); console.log(`created zip for ${slide}`); resolve(); }); }); } // Delete shared folder await deleteFolder(`${output}/shared`); const config = { path: output, output: output, dot: true, dest: `../`, ignore: ['node_modules', '*/__MACOSX', 'exports', '.DS_Store'] // excludes the folders }; //Compress dist folder const exporterPath = await exporter('.', config); // Only leave the final zip package deleteFolder(`${output}`); resolve('./oce-exports'); } catch (error) { return reject(error); } }); }; const deleteFolder = (path) => { return new Promise(async (resolve, reject) => { gulp.src(path, { read: false }).pipe(clean()) .on('error', reject) .on('finish', () => { console.log('Folder deleted', path); resolve(); }); }); }; const renameFiles = async (input, presentationJsonNodes) => { const filePath = path.resolve(process.cwd(), input); const files = await fs.promises.readdir(filePath); const filesPromises = files.map((file) => { return ( !filesExceptions.includes(file) && fs.promises.rename(path.join(filePath, file), path.join(filePath, getSlideName(file, presentationJsonNodes))) ); }); return Promise.all(filesPromises); }; const oceExporter = (input, output) => { return new Promise(async (resolve, reject) => { const inputPath = path.parse(input); //If the input is a zip file if (inputPath.ext && inputPath.ext.includes('.zip')) { // Unzip binder try { await decompress(input, output).then(async (files) => { const exporterPath = await convertFiles(files, output, input); resolve(exporterPath); }); } catch (error) { deleteFolder(output); reject(error); } } else { //If the input is a directory, extract the files try { const startPath = path.resolve(process.cwd(), input); const srcActivatorPkg = path.join(startPath, '/**/*'); const finalPath = path.resolve(process.cwd(), output); console.log('Paths', startPath, finalPath); gulp.src([ srcActivatorPkg, `!${startPath}/shared/node_modules/**/*`, `!${startPath}/shared/oce-exports/**/*`, ]) .pipe(gulp.dest(finalPath)) .on('end', () => { fs.readdir(finalPath, async (err, files) => { if (err) { deleteFolder(output); return reject(err); } // find presentation.json file inside the directory const presentationJson = files.find((file) => { return file.includes('presentation.json'); }); if (!presentationJson) { deleteFolder(output); return reject('ERROR: Presentation.json not found'); } fs.readFile(`${finalPath}/${presentationJson}`, async (err, data) => { if (err) { deleteFolder(output); return reject(err); } const presentationJsonInfo = [ { path: `${finalPath}/${presentationJson}`, data, }, ]; try { const exporterPath = await convertFiles(presentationJsonInfo, output, input); resolve(exporterPath); } catch (error) { // deleteFolder(output); return reject(error); } }); }); }); } catch (error) { deleteFolder(output); return reject(error); } } }); }; module.exports = oceExporter;