diff options
author | Matthias Bartelmeß <mba@fourplusone.de> | 2012-03-13 19:40:33 +0100 |
---|---|---|
committer | Matthias Bartelmeß <mba@fourplusone.de> | 2012-03-13 19:40:33 +0100 |
commit | 70940521f2cdc3cdb3361bd148e141f43505ee4d (patch) | |
tree | 96eb9974ee057b9fc3c8947d33bdd1601de8cd30 /src/node/db/API.js | |
parent | cfb58a80a30486156a15515164c9c0f4647f165b (diff) | |
parent | cccd8a923cfa21c7e248a2a5fcffa54caf512e0b (diff) | |
download | etherpad-lite-70940521f2cdc3cdb3361bd148e141f43505ee4d.zip |
Merge branch 'develop' of git://github.com/Pita/etherpad-lite
Diffstat (limited to 'src/node/db/API.js')
-rw-r--r-- | src/node/db/API.js | 520 |
1 files changed, 520 insertions, 0 deletions
diff --git a/src/node/db/API.js b/src/node/db/API.js new file mode 100644 index 00000000..09cc95af --- /dev/null +++ b/src/node/db/API.js @@ -0,0 +1,520 @@ +/** + * This module provides all API functions + */ + +/* + * 2011 Peter 'Pita' Martischka (Primary Technology 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"); +var customError = require("../utils/customError"); +var padManager = require("./PadManager"); +var padMessageHandler = require("../handler/PadMessageHandler"); +var readOnlyManager = require("./ReadOnlyManager"); +var groupManager = require("./GroupManager"); +var authorManager = require("./AuthorManager"); +var sessionManager = require("./SessionManager"); +var async = require("async"); +var exportHtml = require("../utils/ExportHtml"); +var importHtml = require("../utils/ImportHtml"); +var cleanText = require("./Pad").cleanText; + +/**********************/ +/**GROUP FUNCTIONS*****/ +/**********************/ + +exports.createGroup = groupManager.createGroup; +exports.createGroupIfNotExistsFor = groupManager.createGroupIfNotExistsFor; +exports.deleteGroup = groupManager.deleteGroup; +exports.listPads = groupManager.listPads; +exports.createGroupPad = groupManager.createGroupPad; + +/**********************/ +/**AUTHOR FUNCTIONS****/ +/**********************/ + +exports.createAuthor = authorManager.createAuthor; +exports.createAuthorIfNotExistsFor = authorManager.createAuthorIfNotExistsFor; + +/**********************/ +/**SESSION FUNCTIONS***/ +/**********************/ + +exports.createSession = sessionManager.createSession; +exports.deleteSession = sessionManager.deleteSession; +exports.getSessionInfo = sessionManager.getSessionInfo; +exports.listSessionsOfGroup = sessionManager.listSessionsOfGroup; +exports.listSessionsOfAuthor = sessionManager.listSessionsOfAuthor; + +/************************/ +/**PAD CONTENT FUNCTIONS*/ +/************************/ + +/** +getText(padID, [rev]) returns the text of a pad + +Example returns: + +{code: 0, message:"ok", data: {text:"Welcome Text"}} +{code: 1, message:"padID does not exist", data: null} +*/ +exports.getText = function(padID, rev, callback) +{ + //check if rev is set + if(typeof rev == "function") + { + callback = rev; + rev = undefined; + } + + //check if rev is a number + if(rev !== undefined && typeof rev != "number") + { + //try to parse the number + if(!isNaN(parseInt(rev))) + { + rev = parseInt(rev); + } + else + { + callback(new customError("rev is not a number", "apierror")); + return; + } + } + + //ensure this is not a negativ number + if(rev !== undefined && rev < 0) + { + callback(new customError("rev is a negativ number","apierror")); + return; + } + + //ensure this is not a float value + if(rev !== undefined && !is_int(rev)) + { + callback(new customError("rev is a float value","apierror")); + return; + } + + //get the pad + getPadSafe(padID, true, function(err, pad) + { + if(ERR(err, callback)) return; + + //the client asked for a special revision + if(rev !== undefined) + { + //check if this is a valid revision + if(rev > pad.getHeadRevisionNumber()) + { + callback(new customError("rev is higher than the head revision of the pad","apierror")); + return; + } + + //get the text of this revision + pad.getInternalRevisionAText(rev, function(err, atext) + { + if(ERR(err, callback)) return; + + data = {text: atext.text}; + + callback(null, data); + }) + } + //the client wants the latest text, lets return it to him + else + { + callback(null, {"text": pad.text()}); + } + }); +} + +/** +setText(padID, text) sets the text of a pad + +Example returns: + +{code: 0, message:"ok", data: null} +{code: 1, message:"padID does not exist", data: null} +{code: 1, message:"text too long", data: null} +*/ +exports.setText = function(padID, text, callback) +{ + //get the pad + getPadSafe(padID, true, function(err, pad) + { + if(ERR(err, callback)) return; + + //set the text + pad.setText(text); + + //update the clients on the pad + padMessageHandler.updatePadClients(pad, callback); + }); +} + +/** +getHTML(padID, [rev]) returns the html of a pad + +Example returns: + +{code: 0, message:"ok", data: {text:"Welcome <strong>Text</strong>"}} +{code: 1, message:"padID does not exist", data: null} +*/ +exports.getHTML = function(padID, rev, callback) +{ + if(typeof rev == "function") + { + callback = rev; + rev = undefined; + } + + if (rev !== undefined && typeof rev != "number") + { + if (!isNaN(parseInt(rev))) + { + rev = parseInt(rev); + } + else + { + callback(new customError("rev is not a number","apierror")); + return; + } + } + + if(rev !== undefined && rev < 0) + { + callback(new customError("rev is a negative number","apierror")); + return; + } + + if(rev !== undefined && !is_int(rev)) + { + callback(new customError("rev is a float value","apierror")); + return; + } + + getPadSafe(padID, true, function(err, pad) + { + if(ERR(err, callback)) return; + + //the client asked for a special revision + if(rev !== undefined) + { + //check if this is a valid revision + if(rev > pad.getHeadRevisionNumber()) + { + callback(new customError("rev is higher than the head revision of the pad","apierror")); + return; + } + + //get the html of this revision + exportHtml.getPadHTML(pad, rev, function(err, html) + { + if(ERR(err, callback)) return; + data = {html: html}; + callback(null, data); + }); + } + //the client wants the latest text, lets return it to him + else + { + exportHtml.getPadHTML(pad, undefined, function (err, html) + { + if(ERR(err, callback)) return; + + data = {html: html}; + + callback(null, data); + }); + } + }); +} + +exports.setHTML = function(padID, html, callback) +{ + //get the pad + getPadSafe(padID, true, function(err, pad) + { + if(ERR(err, callback)) return; + + // add a new changeset with the new html to the pad + importHtml.setPadHTML(pad, cleanText(html)); + + //update the clients on the pad + padMessageHandler.updatePadClients(pad, callback); + + }); +} + +/*****************/ +/**PAD FUNCTIONS */ +/*****************/ + +/** +getRevisionsCount(padID) returns the number of revisions of this pad + +Example returns: + +{code: 0, message:"ok", data: {revisions: 56}} +{code: 1, message:"padID does not exist", data: null} +*/ +exports.getRevisionsCount = function(padID, callback) +{ + //get the pad + getPadSafe(padID, true, function(err, pad) + { + if(ERR(err, callback)) return; + + callback(null, {revisions: pad.getHeadRevisionNumber()}); + }); +} + +/** +createPad(padName [, text]) creates a new pad in this group + +Example returns: + +{code: 0, message:"ok", data: null} +{code: 1, message:"pad does already exist", data: null} +*/ +exports.createPad = function(padID, text, callback) +{ + //ensure there is no $ in the padID + if(padID && padID.indexOf("$") != -1) + { + callback(new customError("createPad can't create group pads","apierror")); + return; + } + + //create pad + getPadSafe(padID, false, text, function(err) + { + if(ERR(err, callback)) return; + callback(); + }); +} + +/** +deletePad(padID) deletes a pad + +Example returns: + +{code: 0, message:"ok", data: null} +{code: 1, message:"padID does not exist", data: null} +*/ +exports.deletePad = function(padID, callback) +{ + getPadSafe(padID, true, function(err, pad) + { + if(ERR(err, callback)) return; + + pad.remove(callback); + }); +} + +/** +getReadOnlyLink(padID) returns the read only link of a pad + +Example returns: + +{code: 0, message:"ok", data: null} +{code: 1, message:"padID does not exist", data: null} +*/ +exports.getReadOnlyID = function(padID, callback) +{ + //we don't need the pad object, but this function does all the security stuff for us + getPadSafe(padID, true, function(err) + { + if(ERR(err, callback)) return; + + //get the readonlyId + readOnlyManager.getReadOnlyId(padID, function(err, readOnlyId) + { + if(ERR(err, callback)) return; + callback(null, {readOnlyID: readOnlyId}); + }); + }); +} + +/** +setPublicStatus(padID, publicStatus) sets a boolean for the public status of a pad + +Example returns: + +{code: 0, message:"ok", data: null} +{code: 1, message:"padID does not exist", data: null} +*/ +exports.setPublicStatus = function(padID, publicStatus, callback) +{ + //ensure this is a group pad + if(padID && padID.indexOf("$") == -1) + { + callback(new customError("You can only get/set the publicStatus of pads that belong to a group","apierror")); + return; + } + + //get the pad + getPadSafe(padID, true, function(err, pad) + { + if(ERR(err, callback)) return; + + //convert string to boolean + if(typeof publicStatus == "string") + publicStatus = publicStatus == "true" ? true : false; + + //set the password + pad.setPublicStatus(publicStatus); + + callback(); + }); +} + +/** +getPublicStatus(padID) return true of false + +Example returns: + +{code: 0, message:"ok", data: {publicStatus: true}} +{code: 1, message:"padID does not exist", data: null} +*/ +exports.getPublicStatus = function(padID, callback) +{ + //ensure this is a group pad + if(padID && padID.indexOf("$") == -1) + { + callback(new customError("You can only get/set the publicStatus of pads that belong to a group","apierror")); + return; + } + + //get the pad + getPadSafe(padID, true, function(err, pad) + { + if(ERR(err, callback)) return; + + callback(null, {publicStatus: pad.getPublicStatus()}); + }); +} + +/** +setPassword(padID, password) returns ok or a error message + +Example returns: + +{code: 0, message:"ok", data: null} +{code: 1, message:"padID does not exist", data: null} +*/ +exports.setPassword = function(padID, password, callback) +{ + //ensure this is a group pad + if(padID && padID.indexOf("$") == -1) + { + callback(new customError("You can only get/set the password of pads that belong to a group","apierror")); + return; + } + + //get the pad + getPadSafe(padID, true, function(err, pad) + { + if(ERR(err, callback)) return; + + //set the password + pad.setPassword(password); + + callback(); + }); +} + +/** +isPasswordProtected(padID) returns true or false + +Example returns: + +{code: 0, message:"ok", data: {passwordProtection: true}} +{code: 1, message:"padID does not exist", data: null} +*/ +exports.isPasswordProtected = function(padID, callback) +{ + //ensure this is a group pad + if(padID && padID.indexOf("$") == -1) + { + callback(new customError("You can only get/set the password of pads that belong to a group","apierror")); + return; + } + + //get the pad + getPadSafe(padID, true, function(err, pad) + { + if(ERR(err, callback)) return; + + callback(null, {isPasswordProtected: pad.isPasswordProtected()}); + }); +} + +/******************************/ +/** INTERNAL HELPER FUNCTIONS */ +/******************************/ + +//checks if a number is an int +function is_int(value) +{ + return (parseFloat(value) == parseInt(value)) && !isNaN(value) +} + +//gets a pad safe +function getPadSafe(padID, shouldExist, text, callback) +{ + if(typeof text == "function") + { + callback = text; + text = null; + } + + //check if padID is a string + if(typeof padID != "string") + { + callback(new customError("padID is not a string","apierror")); + return; + } + + //check if the padID maches the requirements + if(!padManager.isValidPadId(padID)) + { + callback(new customError("padID did not match requirements","apierror")); + return; + } + + //check if the pad exists + padManager.doesPadExists(padID, function(err, exists) + { + if(ERR(err, callback)) return; + + //does not exist, but should + if(exists == false && shouldExist == true) + { + callback(new customError("padID does not exist","apierror")); + } + //does exists, but shouldn't + else if(exists == true && shouldExist == false) + { + callback(new customError("padID does already exist","apierror")); + } + //pad exists, let's get it + else + { + padManager.getPad(padID, text, callback); + } + }); +} |