diff options
Diffstat (limited to 'src/node/handler')
-rw-r--r-- | src/node/handler/APIHandler.js | 47 | ||||
-rw-r--r-- | src/node/handler/ExportHandler.js | 300 | ||||
-rw-r--r-- | src/node/handler/ImportHandler.js | 6 | ||||
-rw-r--r-- | src/node/handler/PadMessageHandler.js | 3 |
4 files changed, 209 insertions, 147 deletions
diff --git a/src/node/handler/APIHandler.js b/src/node/handler/APIHandler.js index 62025c50..273a58a6 100644 --- a/src/node/handler/APIHandler.js +++ b/src/node/handler/APIHandler.js @@ -300,10 +300,55 @@ var version = , "getChatHistory" : ["padID", "start", "end"] , "getChatHead" : ["padID"] } +, "1.2.10": + { "createGroup" : [] + , "createGroupIfNotExistsFor" : ["groupMapper"] + , "deleteGroup" : ["groupID"] + , "listPads" : ["groupID"] + , "listAllPads" : [] + , "createDiffHTML" : ["padID", "startRev", "endRev"] + , "createPad" : ["padID", "text"] + , "createGroupPad" : ["groupID", "padName", "text"] + , "createAuthor" : ["name"] + , "createAuthorIfNotExistsFor": ["authorMapper" , "name"] + , "listPadsOfAuthor" : ["authorID"] + , "createSession" : ["groupID", "authorID", "validUntil"] + , "deleteSession" : ["sessionID"] + , "getSessionInfo" : ["sessionID"] + , "listSessionsOfGroup" : ["groupID"] + , "listSessionsOfAuthor" : ["authorID"] + , "getText" : ["padID", "rev"] + , "setText" : ["padID", "text"] + , "getHTML" : ["padID", "rev"] + , "setHTML" : ["padID", "html"] + , "getAttributePool" : ["padID"] + , "getRevisionsCount" : ["padID"] + , "getRevisionChangeset" : ["padID", "rev"] + , "getLastEdited" : ["padID"] + , "deletePad" : ["padID"] + , "copyPad" : ["sourceID", "destinationID", "force"] + , "movePad" : ["sourceID", "destinationID", "force"] + , "getReadOnlyID" : ["padID"] + , "getPadID" : ["roID"] + , "setPublicStatus" : ["padID", "publicStatus"] + , "getPublicStatus" : ["padID"] + , "setPassword" : ["padID", "password"] + , "isPasswordProtected" : ["padID"] + , "listAuthorsOfPad" : ["padID"] + , "padUsersCount" : ["padID"] + , "getAuthorName" : ["authorID"] + , "padUsers" : ["padID"] + , "sendClientsMessage" : ["padID", "msg"] + , "listAllGroups" : [] + , "checkToken" : [] + , "getChatHistory" : ["padID"] + , "getChatHistory" : ["padID", "start", "end"] + , "getChatHead" : ["padID"] + } }; // set the latest available API version here -exports.latestApiVersion = '1.2.9'; +exports.latestApiVersion = '1.2.10'; // exports the versions so it can be used by the new Swagger endpoint exports.version = version; diff --git a/src/node/handler/ExportHandler.js b/src/node/handler/ExportHandler.js index 8ff5bc48..a748d3f2 100644 --- a/src/node/handler/ExportHandler.js +++ b/src/node/handler/ExportHandler.js @@ -27,6 +27,7 @@ var async = require("async"); var fs = require("fs"); var settings = require('../utils/Settings'); var os = require('os'); +var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks"); //load abiword only if its enabled if(settings.abiword != null) @@ -45,175 +46,186 @@ if(os.type().indexOf("Windows") > -1) */ exports.doExport = function(req, res, padId, type) { - //tell the browser that this is a downloadable file - res.attachment(padId + "." + type); + var fileName = padId; - //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 + // allow fileName to be overwritten by a hook, the type type is kept static for security reasons + hooks.aCallFirst("exportFileName", padId, + function(err, hookFileName){ + // if fileName is set then set it to the padId, note that fileName is returned as an array. + if(hookFileName) fileName = hookFileName; - if(type == "txt") - { - var txt; - var randNum; - var srcFile, destFile; - async.series([ - //render the txt document - function(callback) + //tell the browser that this is a downloadable file + res.attachment(fileName + "." + type); + + //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 + + if(type == "txt") { - exporttxt.getPadTXTDocument(padId, req.params.rev, false, function(err, _txt) - { - if(ERR(err, callback)) return; - txt = _txt; - callback(); - }); - }, - //decide what to do with the txt export - function(callback) - { - //if this is a txt export, we can send this from here directly - res.send(txt); - callback("stop"); - }, - //send the convert job to abiword - function(callback) - { - //ensure html can be collected by the garbage collector - txt = null; - - destFile = tempDirectory + "/eplite_export_" + randNum + "." + type; - abiword.convertFile(srcFile, destFile, type, callback); - }, - //send the file - function(callback) - { - res.sendfile(destFile, null, callback); - }, - //clean up temporary files - function(callback) - { - async.parallel([ + var txt; + var randNum; + var srcFile, destFile; + + async.series([ + //render the txt document function(callback) { - fs.unlink(srcFile, callback); + exporttxt.getPadTXTDocument(padId, req.params.rev, false, function(err, _txt) + { + if(ERR(err, callback)) return; + txt = _txt; + callback(); + }); }, + //decide what to do with the txt export function(callback) { - //100ms delay to accomidate for slow windows fs - if(os.type().indexOf("Windows") > -1) - { - setTimeout(function() + //if this is a txt export, we can send this from here directly + res.send(txt); + callback("stop"); + }, + //send the convert job to abiword + function(callback) + { + //ensure html can be collected by the garbage collector + txt = null; + + destFile = tempDirectory + "/etherpad_export_" + randNum + "." + type; + abiword.convertFile(srcFile, destFile, type, callback); + }, + //send the file + function(callback) + { + res.sendfile(destFile, null, callback); + }, + //clean up temporary files + function(callback) + { + async.parallel([ + function(callback) { - fs.unlink(destFile, callback); - }, 100); - } - else - { - fs.unlink(destFile, callback); - } + fs.unlink(srcFile, callback); + }, + function(callback) + { + //100ms delay to accomidate for slow windows fs + if(os.type().indexOf("Windows") > -1) + { + setTimeout(function() + { + fs.unlink(destFile, callback); + }, 100); + } + else + { + fs.unlink(destFile, callback); + } + } + ], callback); } - ], callback); + ], function(err) + { + if(err && err != "stop") ERR(err); + }) } - ], function(err) - { - if(err && err != "stop") ERR(err); - }) - } - else if(type == 'dokuwiki') - { - var randNum; - var srcFile, destFile; - - async.series([ - //render the dokuwiki document - function(callback) + else if(type == 'dokuwiki') { - exportdokuwiki.getPadDokuWikiDocument(padId, req.params.rev, function(err, dokuwiki) + var randNum; + var srcFile, destFile; + + async.series([ + //render the dokuwiki document + function(callback) + { + exportdokuwiki.getPadDokuWikiDocument(padId, req.params.rev, function(err, dokuwiki) + { + res.send(dokuwiki); + callback("stop"); + }); + }, + ], function(err) { - res.send(dokuwiki); - callback("stop"); + if(err && err != "stop") throw err; }); - }, - ], function(err) - { - if(err && err != "stop") throw err; - }); - } - else - { - var html; - var randNum; - var srcFile, destFile; - - async.series([ - //render the html document - function(callback) - { - exporthtml.getPadHTMLDocument(padId, req.params.rev, false, function(err, _html) - { - if(ERR(err, callback)) return; - html = _html; - callback(); - }); - }, - //decide what to do with the html export - function(callback) - { - //if this is a html export, we can send this from here directly - if(type == "html") - { - res.send(html); - callback("stop"); - } - else //write the html export to a file - { - randNum = Math.floor(Math.random()*0xFFFFFFFF); - srcFile = tempDirectory + "/eplite_export_" + randNum + ".html"; - fs.writeFile(srcFile, html, callback); - } - }, - //send the convert job to abiword - function(callback) - { - //ensure html can be collected by the garbage collector - html = null; - - destFile = tempDirectory + "/eplite_export_" + randNum + "." + type; - abiword.convertFile(srcFile, destFile, type, callback); - }, - //send the file - function(callback) - { - res.sendfile(destFile, null, callback); - }, - //clean up temporary files - function(callback) + } + else { - async.parallel([ + var html; + var randNum; + var srcFile, destFile; + + async.series([ + //render the html document function(callback) { - fs.unlink(srcFile, callback); + exporthtml.getPadHTMLDocument(padId, req.params.rev, false, function(err, _html) + { + if(ERR(err, callback)) return; + html = _html; + callback(); + }); }, + //decide what to do with the html export function(callback) { - //100ms delay to accomidate for slow windows fs - if(os.type().indexOf("Windows") > -1) + //if this is a html export, we can send this from here directly + if(type == "html") { - setTimeout(function() - { - fs.unlink(destFile, callback); - }, 100); + res.send(html); + callback("stop"); } - else + else //write the html export to a file { - fs.unlink(destFile, callback); + randNum = Math.floor(Math.random()*0xFFFFFFFF); + srcFile = tempDirectory + "/etherpad_export_" + randNum + ".html"; + fs.writeFile(srcFile, html, callback); } + }, + //send the convert job to abiword + function(callback) + { + //ensure html can be collected by the garbage collector + html = null; + + destFile = tempDirectory + "/etherpad_export_" + randNum + "." + type; + abiword.convertFile(srcFile, destFile, type, callback); + }, + //send the file + function(callback) + { + res.sendfile(destFile, null, callback); + }, + //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() + { + fs.unlink(destFile, callback); + }, 100); + } + else + { + fs.unlink(destFile, callback); + } + } + ], callback); } - ], callback); + ], function(err) + { + if(err && err != "stop") ERR(err); + }) } - ], function(err) - { - if(err && err != "stop") ERR(err); - }) - } + } + ); }; diff --git a/src/node/handler/ImportHandler.js b/src/node/handler/ImportHandler.js index f58076bb..60fa5ffb 100644 --- a/src/node/handler/ImportHandler.js +++ b/src/node/handler/ImportHandler.js @@ -98,7 +98,7 @@ exports.doImport = function(req, res, padId) } }, function(callback){ - destFile = path.join(tmpDirectory, "eplite_import_" + randNum + ".htm"); + destFile = path.join(tmpDirectory, "etherpad_import_" + randNum + ".htm"); // Logic for allowing external Import Plugins hooks.aCallAll("import", {srcFile: srcFile, destFile: destFile}, function(err, result){ @@ -114,7 +114,9 @@ exports.doImport = function(req, res, padId) //convert file to html function(callback) { if(!importHandledByPlugin){ - if (abiword) { + var fileEnding = path.extname(srcFile).toLowerCase(); + var fileIsHTML = (fileEnding === ".html" || fileEnding === ".htm"); + if (abiword && !fileIsHTML) { abiword.convertFile(srcFile, destFile, "htm", function(err) { //catch convert errors if(err) { diff --git a/src/node/handler/PadMessageHandler.js b/src/node/handler/PadMessageHandler.js index 26eb17a6..e1ac994e 100644 --- a/src/node/handler/PadMessageHandler.js +++ b/src/node/handler/PadMessageHandler.js @@ -145,6 +145,9 @@ exports.handleDisconnect = function(client) //Go trough all user that are still on the pad, and send them the USER_LEAVE message client.broadcast.to(session.padId).json.send(messageToTheOtherUsers); + + // Allow plugins to hook into users leaving the pad + hooks.callAll("userLeave", session); }); } |