Vo Minh Thu (OpenERP) has proposed merging
lp:~openerp-dev/openobject-server/trunk-xmlrpc-vmt into lp:openobject-server.
Requested reviews:
OpenERP Core Team (openerp)
For more details, see:
https://code.launchpad.net/~openerp-dev/openobject-server/trunk-xmlrpc-vmt/+merge/71827
--
https://code.launchpad.net/~openerp-dev/openobject-server/trunk-xmlrpc-vmt/+merge/71827
Your team OpenERP R&D Team is subscribed to branch
lp:~openerp-dev/openobject-server/trunk-xmlrpc-vmt.
=== modified file 'openerp/netsvc.py'
--- openerp/netsvc.py 2011-07-29 11:20:19 +0000
+++ openerp/netsvc.py 2011-08-17 09:13:56 +0000
@@ -60,20 +60,21 @@
#.apidoc title: Common Services: netsvc
#.apidoc module-mods: member-order: bysource
+def abort_response(error, description, origin, details):
+ if not tools.config['debug_mode']:
+ raise Exception("%s -- %s\n\n%s"%(origin, description, details))
+ else:
+ raise
+
class Service(object):
""" Base class for *Local* services
Functionality here is trusted, no authentication.
"""
_services = {}
- def __init__(self, name, audience=''):
+ def __init__(self, name):
Service._services[name] = self
self.__name = name
- self._methods = {}
-
- def joinGroup(self, name):
- raise Exception("No group for local services")
- #GROUPS.setdefault(name, {})[self.__name] = self
@classmethod
def exists(cls, name):
@@ -84,6 +85,7 @@
if cls.exists(name):
cls._services.pop(name)
+<<<<<<< TREE
def exportMethod(self, method):
if callable(method):
self._methods[method.__name__] = method
@@ -113,6 +115,15 @@
def __call__(self, method, *params):
return getattr(self, method)(*params)
+=======
+def LocalService(name):
+ # 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 Service._services[name]
+>>>>>>> MERGE-SOURCE
class ExportService(object):
""" Proxy for exported services.
@@ -126,27 +137,34 @@
"""
_services = {}
- _groups = {}
_logger = logging.getLogger('web-services')
+<<<<<<< TREE
def __init__(self, name, audience=''):
+=======
+
+ def __init__(self, name):
+>>>>>>> MERGE-SOURCE
ExportService._services[name] = self
self.__name = name
self._logger.debug("Registered an exported service: %s" % name)
- def joinGroup(self, name):
- ExportService._groups.setdefault(name, {})[self.__name] = self
-
@classmethod
def getService(cls,name):
return cls._services[name]
+ # Dispatch a RPC call w.r.t. the method name. The dispatching
+ # w.r.t. the service (this class) is done by OpenERPDispatcher.
def dispatch(self, method, auth, params):
raise Exception("stub dispatch at %s" % self.__name)
+<<<<<<< TREE
def new_dispatch(self,method,auth,params):
raise Exception("stub dispatch at %s" % self.__name)
+=======
+
+>>>>>>> MERGE-SOURCE
def abortResponse(self, error, description, origin, details):
if not tools.config['debug_mode']:
raise Exception("%s -- %s\n\n%s"%(origin, description, details))
@@ -425,6 +443,11 @@
logger.log(channel, indent+line)
indent=indent_after
+# This class is used to dispatch a RPC to a service. So it is used
+# for both XMLRPC (with a SimpleXMLRPCRequestHandler), and NETRPC.
+# The service (ExportService) will then dispatch on the method name.
+# This can be re-written as a single function
+# def dispatch(self, service_name, method, params, auth_provider).
class OpenERPDispatcher:
def log(self, title, msg, channel=logging.DEBUG_RPC, depth=None, fn=""):
log(title, msg, channel=channel, depth=depth, fn=fn)
=== modified file 'openerp/osv/osv.py'
--- openerp/osv/osv.py 2011-06-23 09:03:57 +0000
+++ openerp/osv/osv.py 2011-08-17 09:13:56 +0000
@@ -39,13 +39,13 @@
self.value = value
self.args = (exc_type, name)
+service = None
-class object_proxy(netsvc.Service):
+class object_proxy():
def __init__(self):
self.logger = logging.getLogger('web-services')
- netsvc.Service.__init__(self, 'object_proxy', audience='')
- self.exportMethod(self.exec_workflow)
- self.exportMethod(self.execute)
+ global service
+ service = self
def check(f):
@wraps(f)
@@ -119,14 +119,14 @@
except orm.except_orm, inst:
if inst.name == 'AccessError':
self.logger.debug("AccessError", exc_info=True)
- self.abortResponse(1, inst.name, 'warning', inst.value)
+ netsvc.abort_response(1, inst.name, 'warning', inst.value)
except except_osv, inst:
- self.abortResponse(1, inst.name, inst.exc_type, inst.value)
+ netsvc.abort_response(1, inst.name, inst.exc_type, inst.value)
except IntegrityError, inst:
osv_pool = pooler.get_pool(dbname)
for key in osv_pool._sql_error.keys():
if key in inst[0]:
- self.abortResponse(1, _('Constraint Error'), 'warning',
+ 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')
@@ -147,9 +147,9 @@
msg += _('\n\n[object with reference: %s - %s]') % (model_name, model)
except Exception:
pass
- self.abortResponse(1, _('Integrity Error'), 'warning', msg)
+ netsvc.abort_response(1, _('Integrity Error'), 'warning', msg)
else:
- self.abortResponse(1, _('Integrity Error'), 'warning', inst[0])
+ netsvc.abort_response(1, _('Integrity Error'), 'warning', inst[0])
except Exception:
self.logger.exception("Uncaught exception")
raise
=== modified file 'openerp/report/custom.py'
--- openerp/report/custom.py 2011-02-07 12:57:23 +0000
+++ openerp/report/custom.py 2011-08-17 09:13:56 +0000
@@ -136,16 +136,15 @@
ids = self.pool.get(report.model_id.model).search(cr, uid, [])
datas['ids'] = ids
- service = netsvc.LocalService("object_proxy")
report_id = datas['report_id']
- report = service.execute(cr.dbname, uid, 'ir.report.custom', 'read', [report_id], context=context)[0]
- fields = service.execute(cr.dbname, uid, 'ir.report.custom.fields', 'read', report['fields_child0'], context=context)
+ report = self.pool.get('ir.report.custom').read(cr, uid, [report_id], context=context)[0]
+ fields = self.pool.get('ir.report.custom.fields').read(cr, uid, report['fields_child0'], context=context)
fields.sort(lambda x,y : x['sequence'] - y['sequence'])
if report['field_parent']:
- parent_field = service.execute(cr.dbname, uid, 'ir.model.fields', 'read', [report['field_parent'][0]],['model'])
- model_name = service.execute(cr.dbname, uid, 'ir.model', 'read', [report['model_id'][0]], ['model'],context=context)[0]['model']
+ parent_field = self.pool.get('ir.model.fields').read(cr, uid, [report['field_parent'][0]], ['model'])
+ model_name = self.pool.get('ir.model').read(cr, uid, [report['model_id'][0]], ['model'], context=context)[0]['model']
fct = {}
fct['id'] = lambda x : x
@@ -160,9 +159,7 @@
field_child = f['field_child'+str(i)]
if field_child:
row.append(
- service.execute(cr.dbname, uid,
- 'ir.model.fields', 'read', [field_child[0]],
- ['name'], context=context)[0]['name']
+ self.pool.get('ir.model.fields').read(cr, uid, [field_child[0]], ['name'], context=context)[0]['name']
)
if f['fc'+str(i)+'_operande']:
fct_name = 'id'
@@ -346,7 +343,7 @@
def _create_lines(self, cr, uid, ids, report, fields, results, context):
- service = netsvc.LocalService("object_proxy")
+ pool = pooler.get_pool(cr.dbname)
pdf_string = cStringIO.StringIO()
can = canvas.init(fname=pdf_string, format='pdf')
@@ -376,7 +373,7 @@
for f in fields:
field_id = (f['field_child3'] and f['field_child3'][0]) or (f['field_child2'] and f['field_child2'][0]) or (f['field_child1'] and f['field_child1'][0]) or (f['field_child0'] and f['field_child0'][0])
if field_id:
- type = service.execute(cr.dbname, uid, 'ir.model.fields', 'read', [field_id],['ttype'])
+ type = pool.get('ir.model.fields').read(cr, uid, [field_id],['ttype'])
if type[0]['ttype'] == 'date':
date_idx = idx
fct[idx] = process_date[report['frequency']]
@@ -449,7 +446,7 @@
def _create_bars(self, cr, uid, ids, report, fields, results, context):
- service = netsvc.LocalService("object_proxy")
+ pool = pooler.get_pool(cr.dbname)
pdf_string = cStringIO.StringIO()
can = canvas.init(fname=pdf_string, format='pdf')
@@ -475,7 +472,7 @@
for f in fields:
field_id = (f['field_child3'] and f['field_child3'][0]) or (f['field_child2'] and f['field_child2'][0]) or (f['field_child1'] and f['field_child1'][0]) or (f['field_child0'] and f['field_child0'][0])
if field_id:
- type = service.execute(cr.dbname, uid, 'ir.model.fields', 'read', [field_id],['ttype'])
+ type = pool.get('ir.model.fields').read(cr, uid, [field_id],['ttype'])
if type[0]['ttype'] == 'date':
date_idx = idx
fct[idx] = process_date[report['frequency']]
=== modified file 'openerp/report/interface.py'
--- openerp/report/interface.py 2011-04-20 15:27:18 +0000
+++ openerp/report/interface.py 2011-08-17 09:13:56 +0000
@@ -41,9 +41,9 @@
return unicode_value.replace('&', '&').replace('<','<').replace('>','>')
class report_int(netsvc.Service):
- def __init__(self, name, audience='*'):
+ def __init__(self, name):
assert not self.exists(name), 'The report "%s" already exists!' % name
- super(report_int, self).__init__(name, audience)
+ super(report_int, self).__init__(name)
if name[0:7]<>'report.':
raise Exception, 'ConceptionError, bad report name, should start with "report."'
self.name = name
@@ -51,8 +51,6 @@
self.name2 = '.'.join(name.split('.')[1:])
# TODO the reports have methods with a 'title' kwarg that is redundant with this attribute
self.title = None
- #self.joinGroup('report')
- self.exportMethod(self.create)
def create(self, cr, uid, ids, datas, context=None):
return False
=== modified file 'openerp/report/print_xml.py'
--- openerp/report/print_xml.py 2011-02-07 12:57:23 +0000
+++ openerp/report/print_xml.py 2011-08-17 09:13:56 +0000
@@ -137,9 +137,8 @@
value = self.get_value(browser, attrs['name'])
- service = netsvc.LocalService("object_proxy")
- ids = service.execute(self.cr.dbname, self.uid, 'ir.attachment', 'search', [('res_model','=',model),('res_id','=',int(value))])
- datas = service.execute(self.cr.dbname, self.uid, 'ir.attachment', 'read', ids)
+ ids = self.pool.get('ir.attachment').search(self.cr, self.uid, [('res_model','=',model),('res_id','=',int(value))])
+ datas = self.pool.get('ir.attachment').read(self.cr, self.uid, ids)
if len(datas):
# if there are several, pick first
=== modified file 'openerp/service/http_server.py'
--- openerp/service/http_server.py 2011-06-23 09:04:57 +0000
+++ openerp/service/http_server.py 2011-08-17 09:13:56 +0000
@@ -213,7 +213,8 @@
return ret
-
+# No need for these two classes: init_server() below can initialize correctly
+# directly the BaseHttpDaemon class.
class HttpDaemon(BaseHttpDaemon):
_RealProto = 'HTTP'
def __init__(self, interface, port):
@@ -270,6 +271,8 @@
raise Exception("Incorrect protocol or no http services")
import SimpleXMLRPCServer
+# Basically, this class extends SimpleXMLRPCRequestHandler to use
+# OpenERPDispatcher as the dispatcher (to select the correct ExportService).
class XMLRPCRequestHandler(netsvc.OpenERPDispatcher,FixSendError,HttpLogHandler,SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
rpc_paths = []
protocol_version = 'HTTP/1.1'
=== modified file 'openerp/service/web_services.py'
--- openerp/service/web_services.py 2011-08-09 12:00:57 +0000
+++ openerp/service/web_services.py 2011-08-17 09:13:56 +0000
@@ -87,7 +87,6 @@
class db(netsvc.ExportService):
def __init__(self, name="db"):
netsvc.ExportService.__init__(self, name)
- self.joinGroup("web-services")
self.actions = {}
self.id = 0
self.id_protect = threading.Semaphore()
@@ -110,8 +109,6 @@
fn = getattr(self, 'exp_'+method)
return fn(*params)
- def new_dispatch(self,method,auth,params):
- pass
def _create_empty_database(self, name):
db = sql_db.db_connect('template1')
cr = db.cursor()
@@ -340,9 +337,9 @@
tools.config['update']['base'] = True
pooler.restart_pool(db, force_demo=False, update_module=True)
except except_orm, inst:
- self.abortResponse(1, inst.name, 'warning', inst.value)
+ netsvc.abort_response(1, inst.name, 'warning', inst.value)
except except_osv, inst:
- self.abortResponse(1, inst.name, inst.exc_type, inst.value)
+ netsvc.abort_response(1, inst.name, inst.exc_type, inst.value)
except Exception:
import traceback
tb_s = reduce(lambda x, y: x+y, traceback.format_exception( sys.exc_type, sys.exc_value, sys.exc_traceback))
@@ -350,24 +347,9 @@
raise
return True
-class _ObjectService(netsvc.ExportService):
- "A common base class for those who have fn(db, uid, password,...) "
-
- def common_dispatch(self, method, auth, params):
- (db, uid, passwd ) = params[0:3]
- params = params[3:]
- security.check(db,uid,passwd)
- cr = pooler.get_db(db).cursor()
- fn = getattr(self, 'exp_'+method)
- res = fn(cr, uid, *params)
- cr.commit()
- cr.close()
- return res
-
-class common(_ObjectService):
+class common(netsvc.ExportService):
def __init__(self,name="common"):
- _ObjectService.__init__(self,name)
- self.joinGroup("web-services")
+ netsvc.ExportService.__init__(self,name)
def dispatch(self, method, auth, params):
logger = netsvc.Logger()
@@ -397,10 +379,6 @@
fn = getattr(self, 'exp_'+method)
return fn(*params)
-
- def new_dispatch(self,method,auth,params):
- pass
-
def exp_about(self, extended=False):
"""Return information about the OpenERP Server.
@@ -434,7 +412,7 @@
return rc.get_available_updates(rc.id, openerp.modules.get_modules_with_version())
except tm.RemoteContractException, e:
- self.abortResponse(1, 'Migration Error', 'warning', str(e))
+ netsvc.abort_response(1, 'Migration Error', 'warning', str(e))
def exp_get_migration_scripts(self, contract_id, contract_password):
@@ -502,7 +480,7 @@
return True
except tm.RemoteContractException, e:
- self.abortResponse(1, 'Migration Error', 'warning', str(e))
+ netsvc.abort_response(1, 'Migration Error', 'warning', str(e))
except Exception, e:
import traceback
tb_s = reduce(lambda x, y: x+y, traceback.format_exception( sys.exc_type, sys.exc_value, sys.exc_traceback))
@@ -566,7 +544,6 @@
class objects_proxy(netsvc.ExportService):
def __init__(self, name="object"):
netsvc.ExportService.__init__(self,name)
- self.joinGroup('web-services')
def dispatch(self, method, auth, params):
(db, uid, passwd ) = params[0:3]
@@ -576,16 +553,12 @@
if method not in ['execute','exec_workflow']:
raise NameError("Method not available %s" % method)
security.check(db,uid,passwd)
- ls = netsvc.LocalService('object_proxy')
- fn = getattr(ls, method)
+ assert openerp.osv.osv.service, "The object_proxy class must be started with start_object_proxy."
+ fn = getattr(openerp.osv.osv.service, method)
res = fn(db, uid, *params)
return res
- def new_dispatch(self,method,auth,params):
- pass
-
-
#
# Wizard ID: 1
# - None = end of wizard
@@ -600,7 +573,6 @@
class wizard(netsvc.ExportService):
def __init__(self, name='wizard'):
netsvc.ExportService.__init__(self,name)
- self.joinGroup('web-services')
self.id = 0
self.wiz_datas = {}
self.wiz_name = {}
@@ -616,9 +588,6 @@
res = fn(db, uid, *params)
return res
- def new_dispatch(self,method,auth,params):
- pass
-
def _execute(self, db, uid, wiz_id, datas, action, context):
self.wiz_datas[wiz_id].update(datas)
wiz = netsvc.LocalService('wizard.'+self.wiz_name[wiz_id])
@@ -662,7 +631,6 @@
class report_spool(netsvc.ExportService):
def __init__(self, name='report'):
netsvc.ExportService.__init__(self, name)
- self.joinGroup('web-services')
self._reports = {}
self.id = 0
self.id_protect = threading.Semaphore()
@@ -677,10 +645,6 @@
res = fn(db, uid, *params)
return res
-
- def new_dispatch(self,method,auth,params):
- pass
-
def exp_report(self, db, uid, object, ids, datas=None, context=None):
if not datas:
datas={}
@@ -730,7 +694,7 @@
result = self._reports[report_id]
exc = result['exception']
if exc:
- self.abortResponse(exc, exc.message, 'warning', exc.traceback)
+ netsvc.abort_response(exc, exc.message, 'warning', exc.traceback)
res = {'state': result['state']}
if res['state']:
if tools.config['reportgz']:
=== modified file 'openerp/wizard/__init__.py'
--- openerp/wizard/__init__.py 2011-05-19 12:27:52 +0000
+++ openerp/wizard/__init__.py 2011-08-17 09:13:56 +0000
@@ -44,7 +44,6 @@
def __init__(self, name):
assert not self.exists('wizard.'+name), 'The wizard "%s" already exists!' % (name,)
super(interface, self).__init__('wizard.'+name)
- self.exportMethod(self.execute)
self.wiz_name = name
def translate_view(self, cr, node, state, lang):
@@ -156,7 +155,7 @@
if isinstance(e, except_wizard) \
or isinstance(e, except_osv) \
or isinstance(e, except_orm):
- self.abortResponse(2, e.name, 'warning', e.value)
+ netsvc.abort_response(2, e.name, 'warning', e.value)
else:
import traceback
tb_s = reduce(lambda x, y: x+y, traceback.format_exception(
=== modified file 'openerp/workflow/wkf_service.py'
--- openerp/workflow/wkf_service.py 2011-02-07 12:57:23 +0000
+++ openerp/workflow/wkf_service.py 2011-08-17 09:13:56 +0000
@@ -27,15 +27,8 @@
import openerp.pooler as pooler
class workflow_service(netsvc.Service):
- def __init__(self, name='workflow', audience='*'):
- netsvc.Service.__init__(self, name, audience)
- self.exportMethod(self.trg_write)
- self.exportMethod(self.trg_delete)
- self.exportMethod(self.trg_create)
- self.exportMethod(self.trg_validate)
- self.exportMethod(self.trg_redirect)
- self.exportMethod(self.trg_trigger)
- self.exportMethod(self.clear_cache)
+ def __init__(self, name='workflow'):
+ netsvc.Service.__init__(self, name)
self.wkf_on_create_cache={}
def clear_cache(self, cr, uid):
_______________________________________________
Mailing list: https://launchpad.net/~openerp-dev-gtk
Post to : [email protected]
Unsubscribe : https://launchpad.net/~openerp-dev-gtk
More help : https://help.launchpad.net/ListHelp