Vo Minh Thu (OpenERP) has proposed merging lp:~openerp-dev/openobject-server/trunk-service-thu into lp:openobject-server.
Requested reviews: OpenERP Core Team (openerp) For more details, see: https://code.launchpad.net/~openerp-dev/openobject-server/trunk-service-thu/+merge/145610 -- https://code.launchpad.net/~openerp-dev/openobject-server/trunk-service-thu/+merge/145610 Your team OpenERP R&D Team is subscribed to branch lp:~openerp-dev/openobject-server/trunk-service-thu.
=== modified file 'openerp/addons/base/res/ir_property.py' --- openerp/addons/base/res/ir_property.py 2012-12-10 15:27:23 +0000 +++ openerp/addons/base/res/ir_property.py 2013-01-30 14:05:27 +0000 @@ -21,7 +21,8 @@ import time -from openerp.osv import osv,fields +from openerp.osv import osv, fields +from openerp.osv.orm import browse_record from openerp.tools.misc import attrgetter # ------------------------------------------------------------------------- @@ -111,7 +112,7 @@ raise osv.except_osv('Error', 'Invalid type') if field == 'value_reference': - if isinstance(value, osv.orm.browse_record): + if isinstance(value, browse_record): value = '%s,%d' % (value._name, value.id) elif isinstance(value, (int, long)): field_id = values.get('fields_id') === modified file 'openerp/netsvc.py' --- openerp/netsvc.py 2012-12-29 12:59:12 +0000 +++ openerp/netsvc.py 2013-01-30 14:05:27 +0000 @@ -67,10 +67,6 @@ raise sock.close() -def abort_response(dummy_1, description, dummy_2, details): - # TODO Replace except_{osv,orm} with these directly. - raise openerp.osv.osv.except_osv(description, details) - class Service(object): """ Base class for Local services Functionality here is trusted, no authentication. @@ -94,7 +90,7 @@ # Special case for addons support, will be removed in a few days when addons # are updated to directly use openerp.osv.osv.service. if name == 'object_proxy': - return openerp.osv.osv.service + return openerp.service.model return Service._services[name] === modified file 'openerp/osv/osv.py' --- openerp/osv/osv.py 2012-12-09 03:49:10 +0000 +++ openerp/osv/osv.py 2013-01-30 14:05:27 +0000 @@ -21,201 +21,21 @@ #.apidoc title: Objects Services (OSV) -from functools import wraps -import logging -import threading - -from psycopg2 import IntegrityError, errorcodes - -import orm -import openerp -import openerp.netsvc as netsvc -import openerp.pooler as pooler -import openerp.sql_db as sql_db -from openerp.tools.translate import translate -from openerp.osv.orm import MetaModel, Model, TransientModel, AbstractModel -import openerp.exceptions - -_logger = logging.getLogger(__name__) - -# Deprecated. -class except_osv(Exception): - def __init__(self, name, value): - self.name = name - self.value = value - self.args = (name, value) - -service = None - -class object_proxy(object): - def __init__(self): - global service - service = self - - def check(f): - @wraps(f) - def wrapper(self, dbname, *args, **kwargs): - """ Wraps around OSV functions and normalises a few exceptions - """ - - def tr(src, ttype): - # We try to do the same as the _(), but without the frame - # inspection, since we aready are wrapping an osv function - # trans_obj = self.get('ir.translation') cannot work yet :( - ctx = {} - if not kwargs: - if args and isinstance(args[-1], dict): - ctx = args[-1] - elif isinstance(kwargs, dict): - ctx = kwargs.get('context', {}) - - uid = 1 - if args and isinstance(args[0], (long, int)): - uid = args[0] - - lang = ctx and ctx.get('lang') - if not (lang or hasattr(src, '__call__')): - return src - - # We open a *new* cursor here, one reason is that failed SQL - # queries (as in IntegrityError) will invalidate the current one. - cr = False - - if hasattr(src, '__call__'): - # callable. We need to find the right parameters to call - # the orm._sql_message(self, cr, uid, ids, context) function, - # or we skip.. - # our signature is f(osv_pool, dbname [,uid, obj, method, args]) - try: - if args and len(args) > 1: - obj = self.get(args[1]) - if len(args) > 3 and isinstance(args[3], (long, int, list)): - ids = args[3] - else: - ids = [] - cr = sql_db.db_connect(dbname).cursor() - return src(obj, cr, uid, ids, context=(ctx or {})) - except Exception: - pass - finally: - if cr: cr.close() - - return False # so that the original SQL error will - # be returned, it is the best we have. - - try: - cr = sql_db.db_connect(dbname).cursor() - res = translate(cr, name=False, source_type=ttype, - lang=lang, source=src) - if res: - return res - else: - return src - finally: - if cr: cr.close() - - def _(src): - return tr(src, 'code') - - try: - if pooler.get_pool(dbname)._init: - raise except_osv('Database not ready', 'Currently, this database is not fully loaded and can not be used.') - return f(self, dbname, *args, **kwargs) - except orm.except_orm, inst: - raise except_osv(inst.name, inst.value) - except except_osv: - raise - except IntegrityError, inst: - osv_pool = pooler.get_pool(dbname) - for key in osv_pool._sql_error.keys(): - if key in inst[0]: - netsvc.abort_response(1, _('Constraint Error'), 'warning', - tr(osv_pool._sql_error[key], 'sql_constraint') or inst[0]) - if inst.pgcode in (errorcodes.NOT_NULL_VIOLATION, errorcodes.FOREIGN_KEY_VIOLATION, errorcodes.RESTRICT_VIOLATION): - msg = _('The operation cannot be completed, probably due to the following:\n- deletion: you may be trying to delete a record while other records still reference it\n- creation/update: a mandatory field is not correctly set') - _logger.debug("IntegrityError", exc_info=True) - try: - errortxt = inst.pgerror.replace('«','"').replace('»','"') - if '"public".' in errortxt: - context = errortxt.split('"public".')[1] - model_name = table = context.split('"')[1] - else: - last_quote_end = errortxt.rfind('"') - last_quote_begin = errortxt.rfind('"', 0, last_quote_end) - model_name = table = errortxt[last_quote_begin+1:last_quote_end].strip() - model = table.replace("_",".") - model_obj = osv_pool.get(model) - if model_obj: - model_name = model_obj._description or model_obj._name - msg += _('\n\n[object with reference: %s - %s]') % (model_name, model) - except Exception: - pass - netsvc.abort_response(1, _('Integrity Error'), 'warning', msg) - else: - netsvc.abort_response(1, _('Integrity Error'), 'warning', inst[0]) - except Exception: - _logger.exception("Uncaught exception") - raise - - return wrapper - - def execute_cr(self, cr, uid, obj, method, *args, **kw): - object = pooler.get_pool(cr.dbname).get(obj) - if not object: - raise except_osv('Object Error', 'Object %s doesn\'t exist' % str(obj)) - return getattr(object, method)(cr, uid, *args, **kw) - - def execute_kw(self, db, uid, obj, method, args, kw=None): - return self.execute(db, uid, obj, method, *args, **kw or {}) - - @check - def execute(self, db, uid, obj, method, *args, **kw): - threading.currentThread().dbname = db - cr = pooler.get_db(db).cursor() - try: - try: - if method.startswith('_'): - raise except_osv('Access Denied', 'Private methods (such as %s) cannot be called remotely.' % (method,)) - res = self.execute_cr(cr, uid, obj, method, *args, **kw) - if res is None: - _logger.warning('The method %s of the object %s can not return `None` !', method, obj) - cr.commit() - except Exception: - cr.rollback() - raise - finally: - cr.close() - return res - - def exec_workflow_cr(self, cr, uid, obj, signal, *args): - object = pooler.get_pool(cr.dbname).get(obj) - if not object: - raise except_osv('Object Error', 'Object %s doesn\'t exist' % str(obj)) - res_id = args[0] - return object._workflow_signal(cr, uid, [res_id], signal)[res_id] - - @check - def exec_workflow(self, db, uid, obj, signal, *args): - cr = pooler.get_db(db).cursor() - try: - try: - res = self.exec_workflow_cr(cr, uid, obj, signal, *args) - cr.commit() - except Exception: - cr.rollback() - raise - finally: - cr.close() - return res - -# deprecated - for backward compatibility. +from openerp.osv.orm import except_orm, Model, TransientModel, AbstractModel + +# Deprecated, kept for backward compatibility. +# openerp.exceptions.Warning should be used instead. +except_osv = except_orm + +# Deprecated, kept for backward compatibility. osv = Model osv_memory = TransientModel osv_abstract = AbstractModel # ;-) - -def start_object_proxy(): - object_proxy() +# Deprecated, kept for backward compatibility, in particular for audittrail. +class object_proxy(object): + def __init__(self): + import openerp.service.model + # TODO monkeypatch openerp.service.model to call the new object_service instance methods. # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - === modified file 'openerp/service/__init__.py' --- openerp/service/__init__.py 2013-01-07 16:23:02 +0000 +++ openerp/service/__init__.py 2013-01-30 14:05:27 +0000 @@ -29,7 +29,6 @@ import time import cron -import netrpc_server import web_services import web_services import wsgi_server @@ -75,8 +74,6 @@ openerp.netsvc.init_logger() openerp.modules.loading.open_openerp_namespace() - # Instantiate local services (this is a legacy design). - openerp.osv.osv.start_object_proxy() # Export (for RPC) services. web_services.start_service() @@ -84,10 +81,8 @@ start_internal_done = True def start_services(): - """ Start all services including http, netrpc and cron """ + """ Start all services including http, and cron """ start_internal() - # Initialize the NETRPC server. - netrpc_server.start_service() # Start the WSGI server. wsgi_server.start_service() # Start the main cron thread. @@ -97,7 +92,6 @@ """ Stop all services. """ # stop services cron.stop_service() - netrpc_server.stop_service() wsgi_server.stop_service() _logger.info("Initiating shutdown") === added file 'openerp/service/model.py' --- openerp/service/model.py 1970-01-01 00:00:00 +0000 +++ openerp/service/model.py 2013-01-30 14:05:27 +0000 @@ -0,0 +1,168 @@ +# -*- coding: utf-8 -*- + +from functools import wraps +import logging +from psycopg2 import IntegrityError, errorcodes +import threading + +import openerp +from openerp.tools.translate import translate +from openerp.osv.orm import except_orm + +_logger = logging.getLogger(__name__) + +def check(f): + @wraps(f) + def wrapper(dbname, *args, **kwargs): + """ Wraps around OSV functions and normalises a few exceptions + """ + + def tr(src, ttype): + # We try to do the same as the _(), but without the frame + # inspection, since we aready are wrapping an osv function + # trans_obj = self.get('ir.translation') cannot work yet :( + ctx = {} + if not kwargs: + if args and isinstance(args[-1], dict): + ctx = args[-1] + elif isinstance(kwargs, dict): + ctx = kwargs.get('context', {}) + + uid = 1 + if args and isinstance(args[0], (long, int)): + uid = args[0] + + lang = ctx and ctx.get('lang') + if not (lang or hasattr(src, '__call__')): + return src + + # We open a *new* cursor here, one reason is that failed SQL + # queries (as in IntegrityError) will invalidate the current one. + cr = False + + if hasattr(src, '__call__'): + # callable. We need to find the right parameters to call + # the orm._sql_message(self, cr, uid, ids, context) function, + # or we skip.. + # our signature is f(osv_pool, dbname [,uid, obj, method, args]) + try: + if args and len(args) > 1: + # TODO self doesn't exist, but was already wrong before (it was not a registry but just the object_service. + obj = self.get(args[1]) + if len(args) > 3 and isinstance(args[3], (long, int, list)): + ids = args[3] + else: + ids = [] + cr = openerp.sql_db.db_connect(dbname).cursor() + return src(obj, cr, uid, ids, context=(ctx or {})) + except Exception: + pass + finally: + if cr: cr.close() + + return False # so that the original SQL error will + # be returned, it is the best we have. + + try: + cr = openerp.sql_db.db_connect(dbname).cursor() + res = translate(cr, name=False, source_type=ttype, + lang=lang, source=src) + if res: + return res + else: + return src + finally: + if cr: cr.close() + + def _(src): + return tr(src, 'code') + + try: + if openerp.pooler.get_pool(dbname)._init: + raise openerp.exceptions.Warning('Currently, this database is not fully loaded and can not be used.') + return f(dbname, *args, **kwargs) + except except_orm: + raise + except IntegrityError, inst: + osv_pool = openerp.pooler.get_pool(dbname) + for key in osv_pool._sql_error.keys(): + if key in inst[0]: + raise openerp.osv.orm.except_orm(_('Constraint Error'), tr(osv_pool._sql_error[key], 'sql_constraint') or inst[0]) + if inst.pgcode in (errorcodes.NOT_NULL_VIOLATION, errorcodes.FOREIGN_KEY_VIOLATION, errorcodes.RESTRICT_VIOLATION): + msg = _('The operation cannot be completed, probably due to the following:\n- deletion: you may be trying to delete a record while other records still reference it\n- creation/update: a mandatory field is not correctly set') + _logger.debug("IntegrityError", exc_info=True) + try: + errortxt = inst.pgerror.replace('«','"').replace('»','"') + if '"public".' in errortxt: + context = errortxt.split('"public".')[1] + model_name = table = context.split('"')[1] + else: + last_quote_end = errortxt.rfind('"') + last_quote_begin = errortxt.rfind('"', 0, last_quote_end) + model_name = table = errortxt[last_quote_begin+1:last_quote_end].strip() + model = table.replace("_",".") + model_obj = osv_pool.get(model) + if model_obj: + model_name = model_obj._description or model_obj._name + msg += _('\n\n[object with reference: %s - %s]') % (model_name, model) + except Exception: + pass + raise openerp.osv.orm.except_orm(_('Integrity Error'), msg) + else: + raise openerp.osv.orm.except_orm(_('Integrity Error'), inst[0]) + except Exception: + _logger.exception("Uncaught exception") + raise + + return wrapper + +def execute_cr(cr, uid, obj, method, *args, **kw): + object = openerp.pooler.get_pool(cr.dbname).get(obj) + if not object: + raise except_orm('Object Error', 'Object %s doesn\'t exist' % str(obj)) + return getattr(object, method)(cr, uid, *args, **kw) + +def execute_kw(db, uid, obj, method, args, kw=None): + return execute(db, uid, obj, method, *args, **kw or {}) + +@check +def execute(db, uid, obj, method, *args, **kw): + threading.currentThread().dbname = db + cr = openerp.pooler.get_db(db).cursor() + try: + try: + if method.startswith('_'): + raise except_orm('Access Denied', 'Private methods (such as %s) cannot be called remotely.' % (method,)) + res = execute_cr(cr, uid, obj, method, *args, **kw) + if res is None: + _logger.warning('The method %s of the object %s can not return `None` !', method, obj) + cr.commit() + except Exception: + cr.rollback() + raise + finally: + cr.close() + return res + +def exec_workflow_cr(cr, uid, obj, signal, *args): + object = openerp.pooler.get_pool(cr.dbname).get(obj) + if not object: + raise except_orm('Object Error', 'Object %s doesn\'t exist' % str(obj)) + res_id = args[0] + return object._workflow_signal(cr, uid, [res_id], signal)[res_id] + +@check +def exec_workflow(db, uid, obj, signal, *args): + cr = openerp.pooler.get_db(db).cursor() + try: + try: + res = exec_workflow_cr(cr, uid, obj, signal, *args) + cr.commit() + except Exception: + cr.rollback() + raise + finally: + cr.close() + return res + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: === removed file 'openerp/service/netrpc_server.py' --- openerp/service/netrpc_server.py 2012-12-10 13:21:33 +0000 +++ openerp/service/netrpc_server.py 1970-01-01 00:00:00 +0000 @@ -1,245 +0,0 @@ -# -*- coding: utf-8 -*- - -# -# Copyright P. Christeas <p_chr...@hol.gr> 2008,2009 -# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. -# -############################################################################## - -#.apidoc title: NET-RPC Server - -""" This file contains instance of the net-rpc server -""" -import logging -import select -import socket -import sys -import threading -import traceback -import openerp -import openerp.service.netrpc_socket -import openerp.netsvc as netsvc -import openerp.tools as tools - -_logger = logging.getLogger(__name__) - -class Server: - """ Generic interface for all servers with an event loop etc. - Override this to impement http, net-rpc etc. servers. - - Servers here must have threaded behaviour. start() must not block, - there is no run(). - """ - __is_started = False - __servers = [] - __starter_threads = [] - - # we don't want blocking server calls (think select()) to - # wait forever and possibly prevent exiting the process, - # but instead we want a form of polling/busy_wait pattern, where - # _server_timeout should be used as the default timeout for - # all I/O blocking operations - _busywait_timeout = 0.5 - - def __init__(self): - Server.__servers.append(self) - if Server.__is_started: - # raise Exception('All instances of servers must be inited before the startAll()') - # Since the startAll() won't be called again, allow this server to - # init and then start it after 1sec (hopefully). Register that - # timer thread in a list, so that we can abort the start if quitAll - # is called in the meantime - t = threading.Timer(1.0, self._late_start) - t.name = 'Late start timer for %s' % str(self.__class__) - Server.__starter_threads.append(t) - t.start() - - def start(self): - _logger.debug("called stub Server.start") - - def _late_start(self): - self.start() - for thr in Server.__starter_threads: - if thr.finished.is_set(): - Server.__starter_threads.remove(thr) - - def stop(self): - _logger.debug("called stub Server.stop") - - def stats(self): - """ This function should return statistics about the server """ - return "%s: No statistics" % str(self.__class__) - - @classmethod - def startAll(cls): - if cls.__is_started: - return - _logger.info("Starting %d services" % len(cls.__servers)) - for srv in cls.__servers: - srv.start() - cls.__is_started = True - - @classmethod - def quitAll(cls): - if not cls.__is_started: - return - _logger.info("Stopping %d services" % len(cls.__servers)) - for thr in cls.__starter_threads: - if not thr.finished.is_set(): - thr.cancel() - cls.__starter_threads.remove(thr) - - for srv in cls.__servers: - srv.stop() - cls.__is_started = False - - @classmethod - def allStats(cls): - res = ["Servers %s" % ('stopped', 'started')[cls.__is_started]] - res.extend(srv.stats() for srv in cls.__servers) - return '\n'.join(res) - - def _close_socket(self): - netsvc.close_socket(self.socket) - -class TinySocketClientThread(threading.Thread): - def __init__(self, sock, threads): - spn = sock and sock.getpeername() - spn = 'netrpc-client-%s:%s' % spn[0:2] - threading.Thread.__init__(self, name=spn) - self.sock = sock - # Only at the server side, use a big timeout: close the - # clients connection when they're idle for 20min. - self.sock.settimeout(1200) - self.threads = threads - - def run(self): - self.running = True - try: - ts = openerp.server.netrpc_socket.mysocket(self.sock) - except Exception: - self.threads.remove(self) - self.running = False - return False - - while self.running: - try: - msg = ts.myreceive() - result = netsvc.dispatch_rpc(msg[0], msg[1], msg[2:]) - ts.mysend(result) - except socket.timeout: - #terminate this channel because other endpoint is gone - break - except Exception, e: - try: - valid_exception = Exception(netrpc_handle_exception_legacy(e)) - valid_traceback = getattr(e, 'traceback', sys.exc_info()) - formatted_traceback = "".join(traceback.format_exception(*valid_traceback)) - _logger.debug("netrpc: communication-level exception", exc_info=True) - ts.mysend(valid_exception, exception=True, traceback=formatted_traceback) - break - except Exception, ex: - #terminate this channel if we can't properly send back the error - _logger.exception("netrpc: cannot deliver exception message to client") - break - - netsvc.close_socket(self.sock) - self.sock = None - self.threads.remove(self) - self.running = False - return True - - def stop(self): - self.running = False - -def netrpc_handle_exception_legacy(e): - if isinstance(e, openerp.osv.osv.except_osv): - return 'warning -- ' + e.name + '\n\n' + e.value - if isinstance(e, openerp.exceptions.Warning): - return 'warning -- Warning\n\n' + str(e) - if isinstance(e, openerp.exceptions.AccessError): - return 'warning -- AccessError\n\n' + str(e) - if isinstance(e, openerp.exceptions.AccessDenied): - return 'AccessDenied ' + str(e) - return openerp.tools.exception_to_unicode(e) - -class TinySocketServerThread(threading.Thread,Server): - def __init__(self, interface, port, secure=False): - threading.Thread.__init__(self, name="NetRPCDaemon-%d"%port) - Server.__init__(self) - self.__port = port - self.__interface = interface - self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - self.socket.bind((self.__interface, self.__port)) - self.socket.listen(5) - self.threads = [] - _logger.info("starting NET-RPC service on %s:%s", interface or '0.0.0.0', port) - - def run(self): - try: - self.running = True - while self.running: - fd_sets = select.select([self.socket], [], [], self._busywait_timeout) - if not fd_sets[0]: - continue - (clientsocket, address) = self.socket.accept() - ct = TinySocketClientThread(clientsocket, self.threads) - clientsocket = None - self.threads.append(ct) - ct.start() - lt = len(self.threads) - if (lt > 10) and (lt % 10 == 0): - # Not many threads should be serving at the same time, so log - # their abuse. - _logger.debug("Netrpc: %d threads", len(self.threads)) - self.socket.close() - except Exception, e: - _logger.warning("Netrpc: closing because of exception %s", e) - self.socket.close() - return False - - def stop(self): - self.running = False - for t in self.threads: - t.stop() - self._close_socket() - - def stats(self): - res = "Net-RPC: " + ( (self.running and "running") or "stopped") - i = 0 - for t in self.threads: - i += 1 - res += "\nNet-RPC #%d: %s " % (i, t.name) - if t.isAlive(): - res += "running" - else: - res += "finished" - if t.sock: - res += ", socket" - return res - -netrpcd = None - -def start_service(): - global netrpcd - if tools.config.get('netrpc', False): - netrpcd = TinySocketServerThread(tools.config.get('netrpc_interface', ''), int(tools.config.get('netrpc_port', 8070))) - -def stop_service(): - Server.quitAll() - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: === removed file 'openerp/service/netrpc_socket.py' --- openerp/service/netrpc_socket.py 2012-09-22 10:51:07 +0000 +++ openerp/service/netrpc_socket.py 1970-01-01 00:00:00 +0000 @@ -1,99 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. -# -############################################################################## - -import socket -import cPickle -import cStringIO - -import openerp.netsvc as netsvc - -# Pickle protocol version 2 is optimized compared to default (version 0) -PICKLE_PROTOCOL = 2 - -class Myexception(Exception): - """ - custom exception object store - * faultcode - * faulestring - * args - """ - - def __init__(self, faultCode, faultString): - self.faultCode = faultCode - self.faultString = faultString - self.args = (faultCode, faultString) - -class mysocket: - - 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) - # prepare this socket for long operations: it may block for infinite - # time, but should exit as soon as the net is down - self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) - - def connect(self, host, port=False): - if not port: - protocol, buf = host.split('//') - host, port = buf.split(':') - self.sock.connect((host, int(port))) - - def disconnect(self): - netsvc.close_socket(self.sock) - - def mysend(self, msg, exception=False, traceback=None): - msg = cPickle.dumps([msg, traceback], PICKLE_PROTOCOL) - self.sock.sendall('%8d%d%s' % (len(msg), bool(exception), msg)) - - def myreceive(self): - buf='' - while len(buf) < 9: - chunk = self.sock.recv(9 - len(buf)) - if not chunk: - raise socket.timeout - buf += chunk - size = int(buf[:8]) - if buf[8] != "0": - exception = buf[8] - else: - exception = False - msg = '' - while len(msg) < size: - chunk = self.sock.recv(size-len(msg)) - if not chunk: - raise socket.timeout - msg = msg + chunk - msgio = cStringIO.StringIO(msg) - unpickler = cPickle.Unpickler(msgio) - unpickler.find_global = None - res = unpickler.load() - - if isinstance(res[0],Exception): - if exception: - raise Myexception(str(res[0]), str(res[1])) - raise res[0] - else: - return res[0] - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: === modified file 'openerp/service/web_services.py' --- openerp/service/web_services.py 2012-12-21 09:09:25 +0000 +++ openerp/service/web_services.py 2013-01-30 14:05:27 +0000 @@ -32,14 +32,17 @@ import time import traceback from cStringIO import StringIO + from openerp.tools.translate import _ import openerp.netsvc as netsvc import openerp.pooler as pooler import openerp.release as release +import openerp.service.model import openerp.sql_db as sql_db import openerp.tools as tools import openerp.modules import openerp.exceptions +import openerp.osv.orm # TODO use openerp.exceptions from openerp.service import http_server from openerp import SUPERUSER_ID @@ -386,22 +389,10 @@ return release.version def exp_migrate_databases(self,databases): - - from openerp.osv.orm import except_orm - from openerp.osv.osv import except_osv - for db in databases: - try: - _logger.info('migrate database %s', db) - tools.config['update']['base'] = True - pooler.restart_pool(db, force_demo=False, update_module=True) - except except_orm, inst: - netsvc.abort_response(1, inst.name, 'warning', inst.value) - except except_osv, inst: - netsvc.abort_response(1, inst.name, 'warning', inst.value) - except Exception: - _logger.exception('Exception in migrate_databases:') - raise + _logger.info('migrate database %s', db) + tools.config['update']['base'] = True + pooler.restart_pool(db, force_demo=False, update_module=True) return True class common(netsvc.ExportService): @@ -472,7 +463,7 @@ return rc.get_available_updates(rc.id, openerp.modules.get_modules_with_version()) except tm.RemoteContractException, e: - netsvc.abort_response(1, 'Migration Error', 'warning', str(e)) + raise openerp.osv.orm.except_orm('Migration Error', str(e)) def exp_get_migration_scripts(self, contract_id, contract_password): @@ -538,7 +529,7 @@ return True except tm.RemoteContractException, e: - netsvc.abort_response(1, 'Migration Error', 'warning', str(e)) + raise openerp.osv.orm.except_orm('Migration Error', str(e)) except Exception, e: _logger.exception('Exception in get_migration_script:') raise @@ -608,9 +599,8 @@ if method not in ['execute', 'execute_kw', 'exec_workflow']: raise NameError("Method not available %s" % method) security.check(db,uid,passwd) - assert openerp.osv.osv.service, "The object_proxy class must be started with start_object_proxy." openerp.modules.registry.RegistryManager.check_registry_signaling(db) - fn = getattr(openerp.osv.osv.service, method) + fn = getattr(openerp.service.model, method) res = fn(db, uid, *params) openerp.modules.registry.RegistryManager.signal_caches_change(db) return res @@ -723,7 +713,7 @@ result = self._reports[report_id] exc = result['exception'] if exc: - netsvc.abort_response(exc, exc.message, 'warning', exc.traceback) + raise openerp.osv.orm.except_orm(exc.message, exc.traceback) res = {'state': result['state']} if res['state']: if tools.config['reportgz']: === modified file 'openerp/service/wsgi_server.py' --- openerp/service/wsgi_server.py 2013-01-11 15:31:13 +0000 +++ openerp/service/wsgi_server.py 2013-01-30 14:05:27 +0000 @@ -90,7 +90,7 @@ return [response] def xmlrpc_handle_exception(e): - if isinstance(e, openerp.osv.osv.except_osv): # legacy + if isinstance(e, openerp.osv.orm.except_orm): # legacy fault = xmlrpclib.Fault(RPC_FAULT_CODE_WARNING, openerp.tools.ustr(e.value)) response = xmlrpclib.dumps(fault, allow_none=False, encoding=None) elif isinstance(e, openerp.exceptions.Warning): @@ -123,7 +123,7 @@ return response def xmlrpc_handle_exception_legacy(e): - if isinstance(e, openerp.osv.osv.except_osv): + if isinstance(e, openerp.osv.orm.except_orm): fault = xmlrpclib.Fault('warning -- ' + e.name + '\n\n' + e.value, '') response = xmlrpclib.dumps(fault, allow_none=False, encoding=None) elif isinstance(e, openerp.exceptions.Warning): === modified file 'openerp/tests/__init__.py' --- openerp/tests/__init__.py 2012-12-20 02:07:08 +0000 +++ openerp/tests/__init__.py 2013-01-30 14:05:27 +0000 @@ -22,6 +22,7 @@ import test_translate import test_uninstall import test_view_validation +import test_xmlrpc # TODO Remove this before merge, or change oe run-tests to only run fast_suite + checks by default. fast_suite = [ test_ir_sequence,
_______________________________________________ Mailing list: https://launchpad.net/~openerp-dev-gtk Post to : openerp-dev-gtk@lists.launchpad.net Unsubscribe : https://launchpad.net/~openerp-dev-gtk More help : https://help.launchpad.net/ListHelp