diff --git a/addons/pad/__init__.py b/addons/pad/__init__.py
index 66d9ec971af..ee80bcaf8d0 100644
--- a/addons/pad/__init__.py
+++ b/addons/pad/__init__.py
@@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
-import ir_attachment
import pad
import res_company
diff --git a/addons/pad/etherpad.py b/addons/pad/etherpad.py
new file mode 100644
index 00000000000..d60fc3672bc
--- /dev/null
+++ b/addons/pad/etherpad.py
@@ -0,0 +1,255 @@
+#!/usr/bin/env python
+"""Module to talk to EtherpadLite API."""
+
+import json
+import urllib
+import urllib2
+
+
+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 = ""
+
+ 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.update({'apikey': self.apiKey})
+ data = urllib.urlencode(params, True)
+
+ try:
+ opener = urllib2.build_opener()
+ request = urllib2.Request(url=url, data=data)
+ print params
+ response = opener.open(request, timeout=self.TIMEOUT)
+ result = response.read()
+ response.close()
+ except urllib2.HTTPError:
+ raise
+
+ result = json.loads(result)
+ if result is None:
+ raise ValueError("JSON response could not be decoded")
+
+ return self.handleResult(result)
+
+ 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
+ })
+
diff --git a/addons/pad/ir_attachment.py b/addons/pad/ir_attachment.py
deleted file mode 100644
index 7cf37211c6f..00000000000
--- a/addons/pad/ir_attachment.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# -*- coding: utf-8 -*-
-from osv import fields, osv
-import random
-import string
-
-class ir_attachment(osv.osv):
- _inherit = 'ir.attachment'
-
- def pad_generate_url(self, cr, uid, model):
- pad_url_template = self.pool.get('res.users').browse(cr,uid,[uid])[0].company_id.pad_url_template
- s = string.ascii_uppercase + string.digits
- salt = ''.join([s[random.randint(0, len(s) - 1)] for i in range(8)])
- template_vars = {
- 'db' : cr.dbname,
- 'model' : model,
- 'salt' : salt,
- }
- return pad_url_template % template_vars
-
- def pad_get(self, cr, uid, model, id):
- if not id: return False
- attachment = self.search(cr, uid, [('res_model', '=', model), ('res_id', '=', id), ('type', '=', 'url'), ('name', '=', 'Pad')])
- if attachment:
- return self.read(cr, uid, attachment)[0]['url']
- else:
- url = self.pad_generate_url(cr, uid, model)
- self.create(cr, uid, {
- 'res_model' : model,
- 'res_id' : id,
- 'type' : 'url',
- 'name' : 'Pad',
- 'url' : url,
- })
- return url
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/pad/pad.py b/addons/pad/pad.py
index 2e69b099d1a..dca8a3241ab 100644
--- a/addons/pad/pad.py
+++ b/addons/pad/pad.py
@@ -3,6 +3,8 @@ from osv import fields, osv
import random
import string
from etherpad import EtherpadLiteClient
+import urllib2
+from tools.translate import _
class pad_common(osv.osv_memory):
@@ -17,7 +19,22 @@ class pad_common(osv.osv_memory):
'model' : model,
'salt' : salt,
}
- return pad_url_template % template_vars
+ url = pad_url_template % template_vars
+ api_key = self._pad_api_key(cr, uid)
+ if api_key:
+ api_url = url[0:url.find("p/")] + "api"
+ pad_id = url[url.find("p/")+2:]
+ pad_author = self._pad_user_name(cr,uid)
+ ep_client = EtherpadLiteClient(api_key, api_url)
+ try:
+ ep_client.createPad(pad_id," ")
+ except ValueError as strerror:
+ raise osv.except_osv(_('Configuration Error !'),_("Etherpad Have Wrong API Key."))
+ except urllib2.HTTPError as e:
+ raise osv.except_osv(_('Configuration Error !'),_("Etherpad Have Wrong API URL."))
+ except urllib2.URLError as e:
+ raise osv.except_osv(_('Configuration Error !'),_("Etherpad Have Wrong Pad URL Template."))
+ return url
def _pad_api_key(self, cr, uid, ids=None, name=None, arg=None , context=None):
if not ids:
@@ -39,29 +56,18 @@ class pad_common(osv.osv_memory):
if not default:
default = {}
default.update({
- 'pad_url':self.pool.get('ir.attachment').pad_generate_url(cr, uid, self._name),
+ 'pad_url':self.pad_generate_url(cr, uid, self._name),
})
return super(pad_common, self).copy(cr, uid, id, default, context)
-
- def create(self, cr, uid, vals, context=None):
- record_id = super(pad_common, self).create(cr, uid, vals, context=context)
- res = self.browse(cr,uid, record_id)
- url = res.pad_url
- api_key = self._pad_api_key(cr, uid)
- if api_key:
- api_url = url[0:url.find("p/")] + "api/"
- pad_id = url[url.find("p/")+2:]
- pad_author = self._pad_user_name(cr,uid)
- ep_client = EtherpadLiteClient(api_key, api_url)
- ep_client.createPad(pad_id,"")
- ep_client.createAuthor(pad_author)
- return record_id
-
+
_columns = {
- 'pad_url': fields.char('Full Screen', size=512),
+ 'pad_url': fields.char('Full Screen', size=512),
+ 'pad_username': fields.function(_pad_user_name, string='Picked', type='char',size=64),
+
}
_defaults = {
- 'pad_url': lambda self, cr, uid, context: self.pool.get('ir.attachment').pad_generate_url(cr, uid, self._name),
+ 'pad_url': lambda self, cr, uid, context: self.pad_generate_url(cr, uid, self._name),
+ 'pad_username': lambda self, cr, uid, context: self._pad_user_name(cr,uid),
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/pad/static/src/js/pad.js b/addons/pad/static/src/js/pad.js
index 287f7389918..c51cc23785a 100644
--- a/addons/pad/static/src/js/pad.js
+++ b/addons/pad/static/src/js/pad.js
@@ -11,8 +11,7 @@ instance.web.form.FieldEtherpad = instance.web.form.AbstractField.extend(_.exten
this.$element.find('span').text((iszoom?'Back to Task':this.field.string));
this.$element.find('div').toggleClass('etherpad_zoom');
$("body").toggleClass('etherpad_body');
- },this));
-
+ },this));
},
set_value: function(value_) {
this._super(value_);
@@ -20,13 +19,12 @@ instance.web.form.FieldEtherpad = instance.web.form.AbstractField.extend(_.exten
},
render_value: function() {
var show_value = instance.web.format_value(this.get('value'), this, '');
- if (!this.get("effective_readonly")) {
- // var pad_url = show_value.split('\n')[0];
-// var api_url = pad_url.substring( 0, (pad_url.search("/p/")+1) );
- // var pad_id = pad_url.substring((pad_url.search("p/")+2) );
- // console.log(this);
- this.$element.find('div').html('');
-
+ if (!this.get("effective_readonly")) {
+ console.log("this is sthis...",this);
+ var pad_username = "noNamed" ;
+ if(this.view.datarecord.hasOwnProperty("pad_username"))
+ pad_username = this.view.datarecord.pad_username;
+ this.$element.find('div').html('');
} else {
if(this.get('value') != false)
{
@@ -37,9 +35,7 @@ instance.web.form.FieldEtherpad = instance.web.form.AbstractField.extend(_.exten
.error(function() { self.$element.text('Unable to load pad'); });
}
}
- },
-
-
+ },
}));
instance.web.form.widgets = instance.web.form.widgets.extend({
diff --git a/addons/project/project_view.xml b/addons/project/project_view.xml
index 03a924ad1bd..c467e76928f 100644
--- a/addons/project/project_view.xml
+++ b/addons/project/project_view.xml
@@ -355,6 +355,7 @@
+