diff --git a/src/node/handler/ExportHandler.js b/src/node/handler/ExportHandler.js index 1b7fcc26d..fffb222b4 100644 --- a/src/node/handler/ExportHandler.js +++ b/src/node/handler/ExportHandler.js @@ -21,6 +21,7 @@ var ERR = require("async-stacktrace"); var exporthtml = require("../utils/ExportHtml"); var exportdokuwiki = require("../utils/ExportDokuWiki"); +var exportjson = require("../utils/ExportJSON"); var padManager = require("../db/PadManager"); var async = require("async"); var fs = require("fs"); @@ -65,6 +66,16 @@ exports.doExport = function(req, res, padId, type) } }); } + else if(type == "json") + { + padManager.getPad(padId, function(err, pad) + { + ERR(err); + exportjson.getPadJSON(pad, req.params.rev, function(err, json) { + res.send(json); + }) + }); + } else if(type == 'dokuwiki') { var randNum; diff --git a/src/node/hooks/express/importexport.js b/src/node/hooks/express/importexport.js index 9754ffa64..d4566dd5a 100644 --- a/src/node/hooks/express/importexport.js +++ b/src/node/hooks/express/importexport.js @@ -5,7 +5,7 @@ var importHandler = require('../../handler/ImportHandler'); exports.expressCreateServer = function (hook_name, args, cb) { args.app.get('/p/:pad/:rev?/export/:type', function(req, res, next) { - var types = ["pdf", "doc", "txt", "html", "odt", "dokuwiki"]; + var types = ["pdf", "doc", "txt", "html", "odt", "dokuwiki", "json"]; //send a 404 if we don't support this filetype if (types.indexOf(req.params.type) == -1) { next(); diff --git a/src/node/utils/ExportJSON.js b/src/node/utils/ExportJSON.js new file mode 100644 index 000000000..c9101702e --- /dev/null +++ b/src/node/utils/ExportJSON.js @@ -0,0 +1,41 @@ +var Changeset = require("ep_etherpad-lite/static/js/Changeset"); +var ERR = require("async-stacktrace"); + +function getJSONAttributes(attribs) { + var pos = 0; + var iter = Changeset.opIterator(attribs); + var attr = []; + while (iter.hasNext()) { + var op = iter.next(); + Changeset.eachAttribNumber(op.attribs, function (a){ + attr.push({id: a, from:pos, to: pos + op.chars}); + }); + pos += op.chars; + } + return attr; +} + +function getPadJSON(pad, rev, callback) { + + //check parameters + if(!pad || !pad.id || !pad.atext || !pad.pool) { + throw new Error('Invalid pad'); + } + + if (!rev) { + rev = pad.getHeadRevisionNumber(); + } else { + rev = parseInt(rev, 10); + if(rev < 0 || rev > pad.getHeadRevisionNumber()) { + throw new Error('Invalid start revision ' + fromRev); + } + } + + pad.getInternalRevisionAText(rev, function (err, atext) { + if(ERR(err, callback)) return; + attributes = getJSONAttributes(atext.attribs); + callback(null, {apool: pad.apool().numToAttrib, atext: { attributes: attributes, text: atext.text}}); + }); +} + +exports.getPadJSON = getPadJSON; \ No newline at end of file