lint: src/node/utils/LibreOffice.js

pull/4667/head
John McLear 2021-01-21 21:06:52 +00:00 committed by Richard Hansen
parent 85d1dc8d71
commit b5e04d867e
1 changed files with 62 additions and 51 deletions

View File

@ -1,3 +1,4 @@
'use strict';
/** /**
* Controls the communication with LibreOffice * Controls the communication with LibreOffice
*/ */
@ -24,52 +25,9 @@ const path = require('path');
const settings = require('./Settings'); const settings = require('./Settings');
const spawn = require('child_process').spawn; const spawn = require('child_process').spawn;
// Conversion tasks will be queued up, so we don't overload the system
const queue = async.queue(doConvertTask, 1);
const libreOfficeLogger = log4js.getLogger('LibreOffice'); const libreOfficeLogger = log4js.getLogger('LibreOffice');
/** const doConvertTask = (task, callback) => {
* Convert a file from one type to another
*
* @param {String} srcFile The path on disk to convert
* @param {String} destFile The path on disk where the converted file should be stored
* @param {String} type The type to convert into
* @param {Function} callback Standard callback function
*/
exports.convertFile = function (srcFile, destFile, type, callback) {
// Used for the moving of the file, not the conversion
const fileExtension = type;
if (type === 'html') {
// "html:XHTML Writer File:UTF8" does a better job than normal html exports
if (path.extname(srcFile).toLowerCase() === '.doc') {
type = 'html';
}
// PDF files need to be converted with LO Draw ref https://github.com/ether/etherpad-lite/issues/4151
if (path.extname(srcFile).toLowerCase() === '.pdf') {
type = 'html:XHTML Draw File';
}
}
// soffice can't convert from html to doc directly (verified with LO 5 and 6)
// we need to convert to odt first, then to doc
// to avoid `Error: no export filter for /tmp/xxxx.doc` error
if (type === 'doc') {
queue.push({
srcFile,
destFile: destFile.replace(/\.doc$/, '.odt'),
type: 'odt',
callback() {
queue.push({srcFile: srcFile.replace(/\.html$/, '.odt'), destFile, type, callback, fileExtension});
},
});
} else {
queue.push({srcFile, destFile, type, callback, fileExtension});
}
};
function doConvertTask(task, callback) {
const tmpDir = os.tmpdir(); const tmpDir = os.tmpdir();
async.series([ async.series([
@ -77,8 +35,10 @@ function doConvertTask(task, callback) {
* use LibreOffice to convert task.srcFile to another format, given in * use LibreOffice to convert task.srcFile to another format, given in
* task.type * task.type
*/ */
function (callback) { (callback) => {
libreOfficeLogger.debug(`Converting ${task.srcFile} to format ${task.type}. The result will be put in ${tmpDir}`); libreOfficeLogger.debug(
`Converting ${task.srcFile} to format ${task.type}. The result will be put in ${tmpDir}`
);
const soffice = spawn(settings.soffice, [ const soffice = spawn(settings.soffice, [
'--headless', '--headless',
'--invisible', '--invisible',
@ -112,7 +72,7 @@ function doConvertTask(task, callback) {
soffice.on('exit', (code) => { soffice.on('exit', (code) => {
clearTimeout(hangTimeout); clearTimeout(hangTimeout);
if (code != 0) { if (code !== 0) {
// Throw an exception if libreoffice failed // Throw an exception if libreoffice failed
return callback(`LibreOffice died with exit code ${code} and message: ${stdoutBuffer}`); return callback(`LibreOffice died with exit code ${code} and message: ${stdoutBuffer}`);
} }
@ -123,10 +83,10 @@ function doConvertTask(task, callback) {
}, },
// Move the converted file to the correct place // Move the converted file to the correct place
function (callback) { (callback) => {
const filename = path.basename(task.srcFile); const filename = path.basename(task.srcFile);
const sourceFilename = `${filename.substr(0, filename.lastIndexOf('.'))}.${task.fileExtension}`; const sourceFile = `${filename.substr(0, filename.lastIndexOf('.'))}.${task.fileExtension}`;
const sourcePath = path.join(tmpDir, sourceFilename); const sourcePath = path.join(tmpDir, sourceFile);
libreOfficeLogger.debug(`Renaming ${sourcePath} to ${task.destFile}`); libreOfficeLogger.debug(`Renaming ${sourcePath} to ${task.destFile}`);
fs.rename(sourcePath, task.destFile, callback); fs.rename(sourcePath, task.destFile, callback);
}, },
@ -137,4 +97,55 @@ function doConvertTask(task, callback) {
// Invoke the callback for the task // Invoke the callback for the task
task.callback(err); task.callback(err);
}); });
} };
// Conversion tasks will be queued up, so we don't overload the system
const queue = async.queue(doConvertTask, 1);
/**
* Convert a file from one type to another
*
* @param {String} srcFile The path on disk to convert
* @param {String} destFile The path on disk where the converted file should be stored
* @param {String} type The type to convert into
* @param {Function} callback Standard callback function
*/
exports.convertFile = (srcFile, destFile, type, callback) => {
// Used for the moving of the file, not the conversion
const fileExtension = type;
if (type === 'html') {
// "html:XHTML Writer File:UTF8" does a better job than normal html exports
if (path.extname(srcFile).toLowerCase() === '.doc') {
type = 'html';
}
// PDF files need to be converted with LO Draw ref https://github.com/ether/etherpad-lite/issues/4151
if (path.extname(srcFile).toLowerCase() === '.pdf') {
type = 'html:XHTML Draw File';
}
}
// soffice can't convert from html to doc directly (verified with LO 5 and 6)
// we need to convert to odt first, then to doc
// to avoid `Error: no export filter for /tmp/xxxx.doc` error
if (type === 'doc') {
queue.push({
srcFile,
destFile: destFile.replace(/\.doc$/, '.odt'),
type: 'odt',
callback: () => {
queue.push(
{
srcFile: srcFile.replace(/\.html$/, '.odt'),
destFile,
type,
callback,
fileExtension,
}
);
},
});
} else {
queue.push({srcFile, destFile, type, callback, fileExtension});
}
};