summaryrefslogtreecommitdiff
path: root/addons/pad/py_etherpad
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/pad/py_etherpad
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/pad/py_etherpad')
-rw-r--r--addons/pad/py_etherpad/__init__.py251
1 files changed, 251 insertions, 0 deletions
diff --git a/addons/pad/py_etherpad/__init__.py b/addons/pad/py_etherpad/__init__.py
new file mode 100644
index 00000000..2d4872f3
--- /dev/null
+++ b/addons/pad/py_etherpad/__init__.py
@@ -0,0 +1,251 @@
+"""Module to talk to EtherpadLite API."""
+import requests
+import logging
+
+from odoo.tools import html2plaintext
+
+_logger = logging.getLogger(__name__)
+
+
+class EtherpadLiteClient:
+ """Client to talk to EtherpadLite API."""
+ API_VERSION = 1 # TODO probably 1.1 sometime soon
+
+ CODE_OK = 0
+ CODE_INVALID_PARAMETERS = 1
+ CODE_INTERNAL_ERROR = 2
+ CODE_INVALID_FUNCTION = 3
+ CODE_INVALID_API_KEY = 4
+ TIMEOUT = 20
+
+ apiKey = ""
+ baseUrl = "http://localhost:9001/api"
+
+ def __init__(self, apiKey=None, baseUrl=None):
+ if apiKey:
+ self.apiKey = apiKey
+
+ if baseUrl:
+ self.baseUrl = baseUrl
+
+ def call(self, function, arguments=None):
+ """Create a dictionary of all parameters"""
+ url = '%s/%d/%s' % (self.baseUrl, self.API_VERSION, function)
+
+ params = arguments or {}
+ params['apikey'] = self.apiKey
+
+ r = requests.post(url, data=params, timeout=self.TIMEOUT)
+ r.raise_for_status()
+ return self.handleResult(r.json())
+
+ def handleResult(self, result):
+ """Handle API call result"""
+ if 'code' not in result:
+ raise Exception("API response has no code")
+ if 'message' not in result:
+ raise Exception("API response has no message")
+
+ if 'data' not in result:
+ result['data'] = None
+
+ if result['code'] == self.CODE_OK:
+ return result['data']
+ elif result['code'] == self.CODE_INVALID_PARAMETERS or result['code'] == self.CODE_INVALID_API_KEY:
+ raise ValueError(result['message'])
+ elif result['code'] == self.CODE_INTERNAL_ERROR:
+ raise Exception(result['message'])
+ elif result['code'] == self.CODE_INVALID_FUNCTION:
+ raise Exception(result['message'])
+ else:
+ raise Exception("An unexpected error occurred whilst handling the response")
+
+ # GROUPS
+ # Pads can belong to a group. There will always be public pads that do not belong to a group (or we give this group the id 0)
+
+ def createGroup(self):
+ """creates a new group"""
+ return self.call("createGroup")
+
+ def createGroupIfNotExistsFor(self, groupMapper):
+ """this functions helps you to map your application group ids to etherpad lite group ids"""
+ return self.call("createGroupIfNotExistsFor", {
+ "groupMapper": groupMapper
+ })
+
+ def deleteGroup(self, groupID):
+ """deletes a group"""
+ return self.call("deleteGroup", {
+ "groupID": groupID
+ })
+
+ def listPads(self, groupID):
+ """returns all pads of this group"""
+ return self.call("listPads", {
+ "groupID": groupID
+ })
+
+ def createGroupPad(self, groupID, padName, text=''):
+ """creates a new pad in this group"""
+ params = {
+ "groupID": groupID,
+ "padName": padName,
+ }
+ if text:
+ params['text'] = text
+ return self.call("createGroupPad", params)
+
+ # AUTHORS
+ # Theses authors are bind to the attributes the users choose (color and name).
+
+ def createAuthor(self, name=''):
+ """creates a new author"""
+ params = {}
+ if name:
+ params['name'] = name
+ return self.call("createAuthor", params)
+
+ def createAuthorIfNotExistsFor(self, authorMapper, name=''):
+ """this functions helps you to map your application author ids to etherpad lite author ids"""
+ params = {
+ 'authorMapper': authorMapper
+ }
+ if name:
+ params['name'] = name
+ return self.call("createAuthorIfNotExistsFor", params)
+
+ # SESSIONS
+ # Sessions can be created between a group and a author. This allows
+ # an author to access more than one group. The sessionID will be set as
+ # a cookie to the client and is valid until a certain date.
+
+ def createSession(self, groupID, authorID, validUntil):
+ """creates a new session"""
+ return self.call("createSession", {
+ "groupID": groupID,
+ "authorID": authorID,
+ "validUntil": validUntil
+ })
+
+ def deleteSession(self, sessionID):
+ """deletes a session"""
+ return self.call("deleteSession", {
+ "sessionID": sessionID
+ })
+
+ def getSessionInfo(self, sessionID):
+ """returns informations about a session"""
+ return self.call("getSessionInfo", {
+ "sessionID": sessionID
+ })
+
+ def listSessionsOfGroup(self, groupID):
+ """returns all sessions of a group"""
+ return self.call("listSessionsOfGroup", {
+ "groupID": groupID
+ })
+
+ def listSessionsOfAuthor(self, authorID):
+ """returns all sessions of an author"""
+ return self.call("listSessionsOfAuthor", {
+ "authorID": authorID
+ })
+
+ # PAD CONTENT
+ # Pad content can be updated and retrieved through the API
+
+ def getText(self, padID, rev=None):
+ """returns the text of a pad"""
+ params = {"padID": padID}
+ if rev is not None:
+ params['rev'] = rev
+ return self.call("getText", params)
+
+ # introduced with pull request merge
+ def getHtml(self, padID, rev=None):
+ """returns the html of a pad"""
+ params = {"padID": padID}
+ if rev is not None:
+ params['rev'] = rev
+ return self.call("getHTML", params)
+
+ def setText(self, padID, text):
+ """sets the text of a pad"""
+ return self.call("setText", {
+ "padID": padID,
+ "text": text
+ })
+
+ def setHtmlFallbackText(self, padID, html):
+ try:
+ # Prevents malformed HTML errors
+ html_wellformed = '<html><body>' + html + '</body></html>'
+ return self.setHtml(padID, html_wellformed)
+ except Exception:
+ _logger.exception('Falling back to setText. SetHtml failed with message:')
+ return self.setText(padID, html2plaintext(html).encode('UTF-8'))
+
+ def setHtml(self, padID, html):
+ """sets the text of a pad from html"""
+ return self.call("setHTML", {
+ "padID": padID,
+ "html": html
+ })
+
+ # PAD
+ # Group pads are normal pads, but with the name schema
+ # GROUPID$PADNAME. A security manager controls access of them and its
+ # forbidden for normal pads to include a in the name.
+
+ def createPad(self, padID, text=''):
+ """creates a new pad"""
+ params = {
+ "padID": padID,
+ }
+ if text:
+ params['text'] = text
+ return self.call("createPad", params)
+
+ def getRevisionsCount(self, padID):
+ """returns the number of revisions of this pad"""
+ return self.call("getRevisionsCount", {
+ "padID": padID
+ })
+
+ def deletePad(self, padID):
+ """deletes a pad"""
+ return self.call("deletePad", {
+ "padID": padID
+ })
+
+ def getReadOnlyID(self, padID):
+ """returns the read only link of a pad"""
+ return self.call("getReadOnlyID", {
+ "padID": padID
+ })
+
+ def setPublicStatus(self, padID, publicStatus):
+ """sets a boolean for the public status of a pad"""
+ return self.call("setPublicStatus", {
+ "padID": padID,
+ "publicStatus": publicStatus
+ })
+
+ def getPublicStatus(self, padID):
+ """return true of false"""
+ return self.call("getPublicStatus", {
+ "padID": padID
+ })
+
+ def setPassword(self, padID, password):
+ """returns ok or a error message"""
+ return self.call("setPassword", {
+ "padID": padID,
+ "password": password
+ })
+
+ def isPasswordProtected(self, padID):
+ """returns true or false"""
+ return self.call("isPasswordProtected", {
+ "padID": padID
+ })