pad.libre-service.eu-etherpad/src/node/handler/ExportHandler.js

187 lines
5.7 KiB
JavaScript
Raw Normal View History

/**
* Handles the export requests
*/
/*
* 2011 Peter 'Pita' Martischka (Primary Technology Ltd)
2014-12-30 00:13:01 +01:00
* 2014 John McLear (Etherpad Foundation / McLear Ltd)
*
* 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 ERR = require("async-stacktrace");
2011-07-27 19:52:23 +02:00
var exporthtml = require("../utils/ExportHtml");
2013-02-10 18:34:34 +01:00
var exporttxt = require("../utils/ExportTxt");
2014-12-29 20:57:58 +01:00
var exportEtherpad = require("../utils/ExportEtherpad");
var async = require("async");
var fs = require("fs");
2011-07-27 19:52:23 +02:00
var settings = require('../utils/Settings');
var os = require('os');
var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks");
var TidyHtml = require('../utils/TidyHtml');
var convertor = null;
//load abiword only if its enabled
if(settings.abiword != null)
convertor = require("../utils/Abiword");
// Use LibreOffice if an executable has been defined in the settings
if(settings.soffice != null)
convertor = require("../utils/LibreOffice");
var tempDirectory = "/tmp";
//tempDirectory changes if the operating system is windows
if(os.type().indexOf("Windows") > -1)
{
tempDirectory = process.env.TEMP;
}
/**
* do a requested export
*/
exports.doExport = function(req, res, padId, type)
{
2014-05-07 17:27:41 +02:00
var fileName = padId;
// allow fileName to be overwritten by a hook, the type type is kept static for security reasons
hooks.aCallFirst("exportFileName", padId,
2014-05-07 17:27:41 +02:00
function(err, hookFileName){
// if fileName is set then set it to the padId, note that fileName is returned as an array.
if(hookFileName.length) fileName = hookFileName;
2013-02-10 18:34:34 +01:00
2014-05-15 14:47:28 +02:00
//tell the browser that this is a downloadable file
res.attachment(fileName + "." + type);
2014-05-15 14:47:28 +02:00
//if this is a plain text export, we can do this directly
// We have to over engineer this because tabs are stored as attributes and not plain text
2014-12-29 20:57:58 +01:00
if(type == "etherpad"){
exportEtherpad.getPadRaw(padId, function(err, pad){
if(!err){
res.send(pad);
// return;
}
});
}
else if(type == "txt")
2013-02-10 18:34:34 +01:00
{
exporttxt.getPadTXTDocument(padId, req.params.rev, false, function(err, txt)
2014-05-15 14:47:28 +02:00
{
if(ERR(err)) return;
res.send(txt);
});
}
2014-05-15 14:47:28 +02:00
else
{
2014-05-15 14:47:28 +02:00
var html;
var randNum;
var srcFile, destFile;
2014-05-15 14:47:28 +02:00
async.series([
//render the html document
function(callback)
{
exporthtml.getPadHTMLDocument(padId, req.params.rev, function(err, _html)
2014-05-15 14:47:28 +02:00
{
if(ERR(err, callback)) return;
html = _html;
callback();
});
},
2014-05-15 14:47:28 +02:00
//decide what to do with the html export
function(callback)
{
2014-05-15 14:47:28 +02:00
//if this is a html export, we can send this from here directly
if(type == "html")
{
2015-12-01 18:38:52 +01:00
// do any final changes the plugin might want to make
2015-01-06 17:31:52 +01:00
hooks.aCallFirst("exportHTMLSend", html, function(err, newHTML){
if(newHTML.length) html = newHTML;
res.send(html);
callback("stop");
2015-01-06 17:31:52 +01:00
});
}
2014-05-15 14:47:28 +02:00
else //write the html export to a file
{
2014-05-15 14:47:28 +02:00
randNum = Math.floor(Math.random()*0xFFFFFFFF);
srcFile = tempDirectory + "/etherpad_export_" + randNum + ".html";
fs.writeFile(srcFile, html, callback);
}
2014-05-15 14:47:28 +02:00
},
// Tidy up the exported HTML
2014-05-15 14:47:28 +02:00
function(callback)
{
//ensure html can be collected by the garbage collector
html = null;
TidyHtml.tidy(srcFile, callback);
},
//send the convert job to the convertor (abiword, libreoffice, ..)
function(callback)
{
2014-05-15 14:47:28 +02:00
destFile = tempDirectory + "/etherpad_export_" + randNum + "." + type;
2015-12-01 18:38:52 +01:00
// Allow plugins to overwrite the convert in export process
hooks.aCallAll("exportConvert", {srcFile: srcFile, destFile: destFile, req: req, res: res}, function(err, result){
2015-12-01 18:38:52 +01:00
if(!err && result.length > 0){
// console.log("export handled by plugin", destFile);
handledByPlugin = true;
callback();
}else{
convertor.convertFile(srcFile, destFile, type, callback);
}
});
2014-05-15 14:47:28 +02:00
},
//send the file
function(callback)
{
2015-04-07 14:55:05 +02:00
res.sendFile(destFile, null, callback);
2014-05-15 14:47:28 +02:00
},
//clean up temporary files
function(callback)
{
async.parallel([
function(callback)
{
fs.unlink(srcFile, callback);
},
function(callback)
{
//100ms delay to accomidate for slow windows fs
if(os.type().indexOf("Windows") > -1)
{
setTimeout(function()
2014-05-15 14:47:28 +02:00
{
fs.unlink(destFile, callback);
}, 100);
}
else
{
fs.unlink(destFile, callback);
}
}
], callback);
}
2014-05-15 14:47:28 +02:00
], function(err)
{
if(err && err != "stop") ERR(err);
})
}
2014-05-15 14:47:28 +02:00
}
);
};