2015-10-20 20:46:08 +02:00
|
|
|
/**
|
|
|
|
* Controls the communication with LibreOffice
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS-IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
var async = require("async");
|
|
|
|
var fs = require("fs");
|
2018-11-01 00:22:27 +01:00
|
|
|
var log4js = require('log4js');
|
2015-10-20 20:46:08 +02:00
|
|
|
var os = require("os");
|
|
|
|
var path = require("path");
|
|
|
|
var settings = require("./Settings");
|
|
|
|
var spawn = require("child_process").spawn;
|
|
|
|
|
|
|
|
// Conversion tasks will be queued up, so we don't overload the system
|
|
|
|
var queue = async.queue(doConvertTask, 1);
|
|
|
|
|
2018-11-01 00:22:27 +01:00
|
|
|
var libreOfficeLogger = log4js.getLogger('LibreOffice');
|
|
|
|
|
2015-10-20 20:46:08 +02:00
|
|
|
/**
|
|
|
|
* 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) {
|
2020-04-07 12:44:54 +02:00
|
|
|
// Used for the moving of the file, not the conversion
|
|
|
|
var fileExtension = type;
|
|
|
|
|
2020-03-29 14:09:08 +02:00
|
|
|
if (type === "html") {
|
|
|
|
// "html:XHTML Writer File:UTF8" does a better job than normal html exports
|
|
|
|
type = "html:XHTML Writer File:UTF8";
|
|
|
|
}
|
|
|
|
|
2018-03-08 14:44:11 +01:00
|
|
|
// 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": srcFile,
|
|
|
|
"destFile": destFile.replace(/\.doc$/, '.odt'),
|
|
|
|
"type": 'odt',
|
|
|
|
"callback": function () {
|
2020-04-07 12:44:54 +02:00
|
|
|
queue.push({"srcFile": srcFile.replace(/\.html$/, '.odt'), "destFile": destFile, "type": type, "callback": callback, "fileExtension": fileExtension });
|
2018-03-08 14:44:11 +01:00
|
|
|
}
|
|
|
|
});
|
|
|
|
} else {
|
2020-04-07 12:44:54 +02:00
|
|
|
queue.push({"srcFile": srcFile, "destFile": destFile, "type": type, "callback": callback, "fileExtension": fileExtension});
|
2018-03-08 14:44:11 +01:00
|
|
|
}
|
2015-10-20 20:46:08 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
function doConvertTask(task, callback) {
|
|
|
|
var tmpDir = os.tmpdir();
|
|
|
|
|
|
|
|
async.series([
|
2018-10-31 22:34:11 +01:00
|
|
|
/*
|
|
|
|
* use LibreOffice to convert task.srcFile to another format, given in
|
|
|
|
* task.type
|
|
|
|
*/
|
2015-10-20 20:46:08 +02:00
|
|
|
function(callback) {
|
2018-11-01 00:22:27 +01:00
|
|
|
libreOfficeLogger.debug(`Converting ${task.srcFile} to format ${task.type}. The result will be put in ${tmpDir}`);
|
2015-10-20 20:46:08 +02:00
|
|
|
var soffice = spawn(settings.soffice, [
|
|
|
|
'--headless',
|
|
|
|
'--invisible',
|
|
|
|
'--nologo',
|
|
|
|
'--nolockcheck',
|
2018-08-24 10:28:57 +02:00
|
|
|
'--writer',
|
2015-10-20 20:46:08 +02:00
|
|
|
'--convert-to', task.type,
|
|
|
|
task.srcFile,
|
|
|
|
'--outdir', tmpDir
|
|
|
|
]);
|
|
|
|
|
|
|
|
var stdoutBuffer = '';
|
|
|
|
|
|
|
|
// Delegate the processing of stdout to another function
|
|
|
|
soffice.stdout.on('data', function(data) {
|
|
|
|
stdoutBuffer += data.toString();
|
|
|
|
});
|
|
|
|
|
|
|
|
// Append error messages to the buffer
|
|
|
|
soffice.stderr.on('data', function(data) {
|
|
|
|
stdoutBuffer += data.toString();
|
|
|
|
});
|
|
|
|
|
|
|
|
soffice.on('exit', function(code) {
|
|
|
|
if (code != 0) {
|
2018-10-31 22:34:11 +01:00
|
|
|
// Throw an exception if libreoffice failed
|
2018-08-27 01:29:37 +02:00
|
|
|
return callback(`LibreOffice died with exit code ${code} and message: ${stdoutBuffer}`);
|
2015-10-20 20:46:08 +02:00
|
|
|
}
|
|
|
|
|
2018-10-31 22:34:11 +01:00
|
|
|
// if LibreOffice exited succesfully, go on with processing
|
2015-10-20 20:46:08 +02:00
|
|
|
callback();
|
|
|
|
})
|
|
|
|
},
|
|
|
|
|
2018-10-31 22:34:11 +01:00
|
|
|
// Move the converted file to the correct place
|
2015-10-20 20:46:08 +02:00
|
|
|
function(callback) {
|
|
|
|
var filename = path.basename(task.srcFile);
|
2020-04-07 12:44:54 +02:00
|
|
|
var sourceFilename = filename.substr(0, filename.lastIndexOf('.')) + '.' + task.fileExtension;
|
2018-11-01 00:18:26 +01:00
|
|
|
var sourcePath = path.join(tmpDir, sourceFilename);
|
2018-11-01 00:22:27 +01:00
|
|
|
libreOfficeLogger.debug(`Renaming ${sourcePath} to ${task.destFile}`);
|
2018-11-01 00:18:26 +01:00
|
|
|
fs.rename(sourcePath, task.destFile, callback);
|
2015-10-20 20:46:08 +02:00
|
|
|
}
|
|
|
|
], function(err) {
|
|
|
|
// Invoke the callback for the local queue
|
|
|
|
callback();
|
|
|
|
|
|
|
|
// Invoke the callback for the task
|
|
|
|
task.callback(err);
|
|
|
|
});
|
|
|
|
}
|