summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorniv-openerp <nicolas.vanhoren@openerp.com>2012-01-05 17:56:33 +0100
committerniv-openerp <nicolas.vanhoren@openerp.com>2012-01-05 17:56:33 +0100
commit0baab517f1a02c49d91d6ebca0be2b91784de794 (patch)
tree00a2127253a91496aed22f479be62dc9fc282fec
parent9b998a6551d46bf854a3d06ca6e9bed19fdc8f33 (diff)
[imp] migrated to latest version of client
bzr revid: nicolas.vanhoren@openerp.com-20120105165633-med9y3078abchs5q
-rw-r--r--addons/web/common/http.py58
-rw-r--r--addons/web/common/openerplib/main.py224
-rw-r--r--addons/web/common/session.py2
3 files changed, 88 insertions, 196 deletions
diff --git a/addons/web/common/http.py b/addons/web/common/http.py
index 098731183ba..0c239decb64 100644
--- a/addons/web/common/http.py
+++ b/addons/web/common/http.py
@@ -408,7 +408,7 @@ class Root(object):
self.config = options
if self.config.backend == 'local':
- conn = openerplib.get_connector(protocol='local')
+ conn = LocalConnector()
else:
conn = openerplib.get_connector(hostname=self.config.server_host,
port=self.config.server_port)
@@ -522,4 +522,58 @@ class Root(object):
return m
return None
-#
+class LibException(Exception):
+ """ Base of all client lib exceptions """
+ def __init__(self,code=None,message=None):
+ self.code = code
+ self.message = message
+
+class ApplicationError(LibException):
+ """ maps to code: 1, server side: Exception or openerp.exceptions.DeferredException"""
+
+class Warning(LibException):
+ """ maps to code: 2, server side: openerp.exceptions.Warning"""
+
+class AccessError(LibException):
+ """ maps to code: 3, server side: openerp.exceptions.AccessError"""
+
+class AccessDenied(LibException):
+ """ maps to code: 4, server side: openerp.exceptions.AccessDenied"""
+
+
+class LocalConnector(openerplib.Connector):
+ """
+ A type of connector that uses the XMLRPC protocol.
+ """
+ PROTOCOL = 'local'
+
+ def __init__(self):
+ pass
+
+ def send(self, service_name, method, *args):
+ import openerp
+ import traceback
+ import xmlrpclib
+ try:
+ result = openerp.netsvc.dispatch_rpc(service_name, method, args)
+ except Exception,e:
+ # TODO change the except to raise LibException instead of their emulated xmlrpc fault
+ if isinstance(e, openerp.osv.osv.except_osv):
+ fault = xmlrpclib.Fault('warning -- ' + e.name + '\n\n' + e.value, '')
+ elif isinstance(e, openerp.exceptions.Warning):
+ fault = xmlrpclib.Fault('warning -- Warning\n\n' + str(e), '')
+ elif isinstance(e, openerp.exceptions.AccessError):
+ fault = xmlrpclib.Fault('warning -- AccessError\n\n' + str(e), '')
+ elif isinstance(e, openerp.exceptions.AccessDenied):
+ fault = xmlrpclib.Fault('AccessDenied', str(e))
+ elif isinstance(e, openerp.exceptions.DeferredException):
+ info = e.traceback
+ formatted_info = "".join(traceback.format_exception(*info))
+ fault = xmlrpclib.Fault(openerp.tools.ustr(e.message), formatted_info)
+ else:
+ info = sys.exc_info()
+ formatted_info = "".join(traceback.format_exception(*info))
+ fault = xmlrpclib.Fault(openerp.tools.exception_to_unicode(e), formatted_info)
+ raise fault
+ return result
+
diff --git a/addons/web/common/openerplib/main.py b/addons/web/common/openerplib/main.py
index 76bf7bad6ca..84484e49ae6 100644
--- a/addons/web/common/openerplib/main.py
+++ b/addons/web/common/openerplib/main.py
@@ -36,52 +36,13 @@ Code repository: https://code.launchpad.net/~niv-openerp/openerp-client-lib/trun
"""
import xmlrpclib
-import logging
-import socket
-import sys
-
-try:
- import cPickle as pickle
-except ImportError:
- import pickle
-
-try:
- import cStringIO as StringIO
-except ImportError:
- import StringIO
+import logging
_logger = logging.getLogger(__name__)
def _getChildLogger(logger, subname):
return logging.getLogger(logger.name + "." + subname)
-#----------------------------------------------------------
-# Exceptions
-# TODO openerplib should raise those instead of xmlrpc faults:
-#----------------------------------------------------------
-
-class LibException(Exception):
- """ Base of all client lib exceptions """
- def __init__(self,code=None,message=None):
- self.code = code
- self.message = message
-
-class ApplicationError(LibException):
- """ maps to code: 1, server side: Exception or openerp.exceptions.DeferredException"""
-
-class Warning(LibException):
- """ maps to code: 2, server side: openerp.exceptions.Warning"""
-
-class AccessError(LibException):
- """ maps to code: 3, server side: openerp.exceptions.AccessError"""
-
-class AccessDenied(LibException):
- """ maps to code: 4, server side: openerp.exceptions.AccessDenied"""
-
-#----------------------------------------------------------
-# Connectors
-#----------------------------------------------------------
-
class Connector(object):
"""
The base abstract class representing a connection to an OpenERP Server.
@@ -126,7 +87,6 @@ class XmlRPCConnector(Connector):
def send(self, service_name, method, *args):
url = '%s/%s' % (self.url, service_name)
service = xmlrpclib.ServerProxy(url)
- # TODO should try except and wrap exception into LibException
return getattr(service, method)(*args)
class XmlRPCSConnector(XmlRPCConnector):
@@ -141,145 +101,6 @@ class XmlRPCSConnector(XmlRPCConnector):
super(XmlRPCSConnector, self).__init__(hostname, port)
self.url = 'https://%s:%d/xmlrpc' % (self.hostname, self.port)
-class NetRPC_Exception(Exception):
- """
- Exception for NetRPC errors.
- """
- def __init__(self, faultCode, faultString):
- self.faultCode = faultCode
- self.faultString = faultString
- self.args = (faultCode, faultString)
-
-class NetRPC(object):
- """
- Low level class for NetRPC protocol.
- """
- def __init__(self, sock=None):
- if sock is None:
- self.sock = socket.socket(
- socket.AF_INET, socket.SOCK_STREAM)
- else:
- self.sock = sock
- self.sock.settimeout(120)
- def connect(self, host, port=False):
- if not port:
- buf = host.split('//')[1]
- host, port = buf.split(':')
- self.sock.connect((host, int(port)))
-
- def disconnect(self):
- self.sock.shutdown(socket.SHUT_RDWR)
- self.sock.close()
-
- def mysend(self, msg, exception=False, traceback=None):
- msg = pickle.dumps([msg,traceback])
- size = len(msg)
- self.sock.send('%8d' % size)
- self.sock.send(exception and "1" or "0")
- totalsent = 0
- while totalsent < size:
- sent = self.sock.send(msg[totalsent:])
- if sent == 0:
- raise RuntimeError, "socket connection broken"
- totalsent = totalsent + sent
-
- def myreceive(self):
- buf=''
- while len(buf) < 8:
- chunk = self.sock.recv(8 - len(buf))
- if chunk == '':
- raise RuntimeError, "socket connection broken"
- buf += chunk
- size = int(buf)
- buf = self.sock.recv(1)
- if buf != "0":
- exception = buf
- else:
- exception = False
- msg = ''
- while len(msg) < size:
- chunk = self.sock.recv(size-len(msg))
- if chunk == '':
- raise RuntimeError, "socket connection broken"
- msg = msg + chunk
- msgio = StringIO.StringIO(msg)
- unpickler = pickle.Unpickler(msgio)
- unpickler.find_global = None
- res = unpickler.load()
-
- if isinstance(res[0],Exception):
- if exception:
- raise NetRPC_Exception(str(res[0]), str(res[1]))
- raise res[0]
- else:
- return res[0]
-
-class NetRPCConnector(Connector):
- """
- A type of connector that uses the NetRPC protocol.
- """
-
- PROTOCOL = 'netrpc'
-
- __logger = _getChildLogger(_logger, 'connector.netrpc')
-
- def __init__(self, hostname, port=8070):
- """
- Initialize by specifying the hostname and the port.
- :param hostname: The hostname of the computer holding the instance of OpenERP.
- :param port: The port used by the OpenERP instance for NetRPC (default to 8070).
- """
- Connector.__init__(self, hostname, port)
-
- def send(self, service_name, method, *args):
- socket = NetRPC()
- socket.connect(self.hostname, self.port)
- socket.mysend((service_name, method, )+args)
- result = socket.myreceive()
- socket.disconnect()
- return result
-
-class LocalConnector(Connector):
- """
- A type of connector that uses the XMLRPC protocol.
- """
- PROTOCOL = 'local'
-
- __logger = _getChildLogger(_logger, 'connector.local')
-
- def __init__(self):
- pass
-
- def send(self, service_name, method, *args):
- import openerp
- import traceback
- try:
- result = openerp.netsvc.dispatch_rpc(service_name, method, args)
- except Exception,e:
- # TODO change the except to raise LibException instead of their emulated xmlrpc fault
- if isinstance(e, openerp.osv.osv.except_osv):
- fault = xmlrpclib.Fault('warning -- ' + e.name + '\n\n' + e.value, '')
- elif isinstance(e, openerp.exceptions.Warning):
- fault = xmlrpclib.Fault('warning -- Warning\n\n' + str(e), '')
- elif isinstance(e, openerp.exceptions.AccessError):
- fault = xmlrpclib.Fault('warning -- AccessError\n\n' + str(e), '')
- elif isinstance(e, openerp.exceptions.AccessDenied):
- fault = xmlrpclib.Fault('AccessDenied', str(e))
- elif isinstance(e, openerp.exceptions.DeferredException):
- info = e.traceback
- formatted_info = "".join(traceback.format_exception(*info))
- fault = xmlrpclib.Fault(openerp.tools.ustr(e.message), formatted_info)
- else:
- info = sys.exc_info()
- formatted_info = "".join(traceback.format_exception(*info))
- fault = xmlrpclib.Fault(openerp.tools.exception_to_unicode(e), formatted_info)
- raise fault
- return result
-
-#----------------------------------------------------------
-# Public api
-#----------------------------------------------------------
-
class Service(object):
"""
A class to execute RPC calls on a specific service of the remote server.
@@ -319,7 +140,8 @@ class Connection(object):
database=None,
login=None,
password=None,
- user_id=None):
+ user_id=None,
+ auto_context=True):
"""
Initialize with login information. The login information is facultative to allow specifying
it after the initialization of this object.
@@ -330,10 +152,15 @@ class Connection(object):
:param password: The password of the user.
:param user_id: The user id is a number identifying the user. This is only useful if you
already know it, in most cases you don't need to specify it.
+ :param auto_context: If true, automatically queries the context of the user and adds it to all
+ method calls on models. If a context is already specified, the contexts are merged with it (the
+ user context has the lowest priority). Default to True.
"""
self.connector = connector
self.set_login_info(database, login, password, user_id)
+ self.user_context = None
+ self.auto_context = auto_context
def set_login_info(self, database, login, password, user_id=None):
"""
@@ -369,6 +196,16 @@ class Connection(object):
if not self.user_id:
raise AuthenticationError("Authentication failure")
self.__logger.debug("Authenticated with user id %s", self.user_id)
+
+ def get_user_context(self):
+ """
+ Query the default context of the user.
+ """
+ if not self.user_context:
+ mod = self.get_model('res.users')
+ mod.override_auto_context = False
+ self.user_context = mod.context_get()
+ return self.user_context
def get_model(self, model_name):
"""
@@ -407,6 +244,7 @@ class Model(object):
"""
self.connection = connection
self.model_name = model_name
+ self.override_auto_context = None
self.__logger = _getChildLogger(_getChildLogger(_logger, 'object'), model_name or "")
def __getattr__(self, method):
@@ -415,19 +253,23 @@ class Model(object):
:param method: The method for the linked model (search, read, write, unlink, create, ...)
"""
- def proxy(*args):
+ def proxy(*args, **kw):
"""
:param args: A list of values for the method
"""
self.connection.check_login(False)
self.__logger.debug(args)
- result = self.connection.get_service('object').execute(
+ if (self.override_auto_context is not None and self.override_auto_context) or \
+ (self.override_auto_context is None and self.connection.auto_context):
+ kw = dict(kw)
+ kw['context'] = dict(self.connection.get_user_context(), **kw.get('context', {}))
+ result = self.connection.get_service('object').execute_kw(
self.connection.database,
self.connection.user_id,
self.connection.password,
self.model_name,
method,
- *args)
+ args, kw)
if method == "read":
if isinstance(result, list) and len(result) > 0 and "id" in result[0]:
index = {}
@@ -457,24 +299,20 @@ class Model(object):
def get_connector(hostname=None, protocol="xmlrpc", port="auto"):
"""
- A shortcut method to easily create a connector to a remote server using XMLRPC or NetRPC.
+ A shortcut method to easily create a connector to a remote server using XMLRPC.
:param hostname: The hostname to the remote server.
- :param protocol: The name of the protocol, must be "xmlrpc" or "netrpc".
+ :param protocol: The name of the protocol, must be "xmlrpc" or "xmlrpcs".
:param port: The number of the port. Defaults to auto.
"""
if port == 'auto':
- port = 8069 if protocol=="xmlrpc" else (8070 if protocol == "netrpc" else 8071)
+ port = 8069 if protocol=="xmlrpc" else 8071
if protocol == "xmlrpc":
return XmlRPCConnector(hostname, port)
elif protocol == "xmlrpcs":
return XmlRPCSConnector(hostname, port)
- elif protocol == "netrpc":
- return NetRPCConnector(hostname, port)
- elif protocol == "local":
- return LocalConnector()
else:
- raise ValueError("You must choose xmlrpc(s), netrpc or local")
+ raise ValueError("You must choose xmlrpc or xmlrpcs")
def get_connection(hostname=None, protocol="xmlrpc", port='auto', database=None,
login=None, password=None, user_id=None):
@@ -482,7 +320,7 @@ def get_connection(hostname=None, protocol="xmlrpc", port='auto', database=None,
A shortcut method to easily create a connection to a remote OpenERP server.
:param hostname: The hostname to the remote server.
- :param protocol: The name of the protocol, must be "xmlrpc" or "netrpc".
+ :param protocol: The name of the protocol, must be "xmlrpc" or "xmlrpcs".
:param port: The number of the port. Defaults to auto.
:param connector: A valid Connector instance to send messages to the remote server.
:param database: The name of the database to work on.
diff --git a/addons/web/common/session.py b/addons/web/common/session.py
index 905670404a9..4202ce45507 100644
--- a/addons/web/common/session.py
+++ b/addons/web/common/session.py
@@ -53,7 +53,7 @@ class OpenERPSession(object):
def build_connection(self):
conn = openerplib.Connection(self.config.connector, database=self._db, login=self._login,
- user_id=self._uid, password=self._password)
+ user_id=self._uid, password=self._password, auto_context=False)
return conn
def proxy(self, service):