238 lines
7.2 KiB
Python
238 lines
7.2 KiB
Python
|
"""Module to talk to EtherpadLite API."""
|
||
|
import requests
|
||
|
|
||
|
|
||
|
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 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
|
||
|
})
|