def _write_record(self, obj, context=None): """Send values of fields updated to the server.""" context = context or self._oerp.context obj_data = obj.__data__ vals = {} for field_name in obj_data['updated_values']: if field_name in obj_data['raw_data']: field = self._browse_class.__osv__['columns'][field_name] field_value = obj.__data__['updated_values'][field_name] # Many2One fields if isinstance(field, fields.Many2OneField): vals[field_name] = field_value and field_value[0] # All other fields else: vals[field_name] = field_value try: if v(self._oerp.version) < v('6.1'): res = self.write([obj.id], vals, context) else: res = self.write([obj.id], vals, context=context) except error.Error as exc: raise exc else: # Update raw_data dictionary # FIXME: make it optional to avoid a RPC request? self._refresh(obj, context) return res
def report(self, report_name, model, obj_ids, report_type='pdf', context=None): """Download a report from the server and return the local path of the file. >>> oerp.report('sale.order', 'sale.order', 1) '/tmp/oerplib_uJ8Iho.pdf' >>> oerp.report('sale.order', 'sale.order', [1, 2]) '/tmp/oerplib_giZS0v.pdf' :return: the path to the generated temporary file :raise: :class:`oerplib.error.RPCError` """ #TODO report_type: what it means exactly? self._check_logged_user() # If no context was supplied, get the default one if context is None: context = self.context # Execute the report query try: if v(self.version) < v('6.1'): pdf_data = self._get_report_data_v5( report_name, model, obj_ids, report_type, context) else: pdf_data = self._get_report_data_v61( report_name, model, obj_ids, report_type, context) except rpc.error.ConnectorError as exc: raise error.RPCError(exc.message, exc.oerp_traceback) return self._print_file_data(pdf_data)
def _unlink_record(self, obj, context=None): """Delete the object from the server.""" context = context or self._oerp.context if v(self._oerp.version) < v('6.1'): return self.unlink([obj.id], context) else: return self.unlink([obj.id], context=context)
def setUp(self): self.oerp = oerplib.OERP( ARGS.server, protocol=ARGS.protocol, port=ARGS.port, version=ARGS.version) if v(self.oerp.version) < v('6.1'): raise unittest.SkipTest( "The targetted OpenERP server does not support the " "'execute_kw()' method.") self.user = self.oerp.login(ARGS.user, ARGS.passwd, ARGS.database)
def test_db_drop_no_existing_database(self): if v(self.oerp.version) >= v('6.1'): res = self.oerp.db.drop(ARGS.super_admin_passwd, 'fake_db_name') self.assertFalse(res) else: self.assertRaises( oerplib.error.RPCError, self.oerp.db.drop, ARGS.super_admin_passwd, 'fake_db_name')
def setUp(self): self.oerp = oerplib.OERP(ARGS.server, protocol=ARGS.protocol, port=ARGS.port, version=ARGS.version) if v(self.oerp.version) < v('6.1'): raise unittest.SkipTest( "The targetted OpenERP server does not support the " "'execute_kw()' method.") self.user = self.oerp.login(ARGS.user, ARGS.passwd, ARGS.database)
def test_v_cmp(self): # [(v1, v2, is_inferior), ...] versions = [ ('7.0', '6.1', False), ('6.1', '7.0', True), ('7.0alpha', '6.1', False), ('6.1beta', '7.0', True), ('6.1beta', '5.0.16', False), ('5.0.16alpha', '6.1', True), ('8.0dev-20131102-000101', '7.0-20131014-231047', False), ] for v1, v2, is_inferior in versions: result = tools.v(v1) < tools.v(v2) if is_inferior: self.assertTrue(result) else: self.assertFalse(result)
def rpc_method(*args, **kwargs): """Return the result of the RPC request.""" if v(self._oerp.version) < v('6.1'): if kwargs: raise error.RPCError( "Named parameters are not supported by the version " "of this server.") result = self._oerp.execute( self._browse_class.__osv__['name'], method, *args) else: if self._oerp.config['auto_context'] \ and 'context' not in kwargs: kwargs['context'] = self._oerp.context result = self._oerp.execute_kw( self._browse_class.__osv__['name'], method, args, kwargs) return result
def search(self, model, args=None, offset=0, limit=None, order=None, context=None, count=False): if args is None: args = [] context = context or self._context if v(self.version) >= v('10.0'): return self.execute(model, 'search', args, offset, limit, order, count, context) return super(OdooPasUtility, self).search(model, args, offset, limit, order, context, count)
def _refresh(self, obj, context=None): """Retrieve field values from the server. May be used to restore the original values in the purpose to cancel all changes made. """ context = context or self._oerp.context obj_data = obj.__data__ obj_data['context'] = context # Get basic fields (no relational ones) basic_fields = [] for field_name, field in obj.__osv__['columns'].iteritems(): if not getattr(field, 'relation', False): basic_fields.append(field_name) else: obj_data['raw_data'][field_name] = None # Fill fields with values of the record if obj.id: if v(self._oerp.version) < v('6.1'): data = self.read([obj.id], basic_fields, context) if data: obj_data['raw_data'].update(data[0]) else: obj_data['raw_data'] = False else: data = self.read([obj.id], basic_fields, context=context) if data: obj_data['raw_data'].update(data[0]) else: obj_data['raw_data'] = False if obj_data['raw_data'] is False: raise error.RPCError( "There is no '{model}' record with ID {obj_id}.".format( model=obj.__class__.__osv__['name'], obj_id=obj.id)) # No ID: fields filled with default values else: if v(self._oerp.version) < v('6.1'): default_get = self.default_get( obj.__osv__['columns'].keys(), context) else: default_get = self.default_get( obj.__osv__['columns'].keys(), context=context) obj_data['raw_data'] = {} for field_name in obj.__osv__['columns']: obj_data['raw_data'][field_name] = False obj_data['raw_data'].update(default_get) self._reset(obj)
def _refresh(self, obj, context=None): """Retrieve field values from the server. May be used to restore the original values in the purpose to cancel all changes made. """ context = context or self._oerp.context obj_data = obj.__data__ obj_data['context'] = context # Get basic fields (no relational ones) basic_fields = [] for field_name, field in obj.__osv__['columns'].items(): if not getattr(field, 'relation', False): basic_fields.append(field_name) else: obj_data['raw_data'][field_name] = None # Fill fields with values of the record if obj.id: if v(self._oerp.version) < v('6.1'): data = self.read([obj.id], basic_fields, context) if data: obj_data['raw_data'].update(data[0]) else: obj_data['raw_data'] = False else: data = self.read([obj.id], basic_fields, context=context) if data: obj_data['raw_data'].update(data[0]) else: obj_data['raw_data'] = False if obj_data['raw_data'] is False: raise error.RPCError( "There is no '{model}' record with ID {obj_id}.".format( model=obj.__class__.__osv__['name'], obj_id=obj.id)) # No ID: fields filled with default values else: if v(self._oerp.version) < v('6.1'): default_get = self.default_get( list(obj.__osv__['columns'].keys()), context) else: default_get = self.default_get( list(obj.__osv__['columns'].keys()), context=context) obj_data['raw_data'] = {} for field_name in obj.__osv__['columns']: obj_data['raw_data'][field_name] = False obj_data['raw_data'].update(default_get) self._reset(obj)
def __init__(self, server, port=8069, timeout=120, version=None): super(ConnectorXMLRPC, self).__init__(server, port, timeout, version) if self.version: # Server < 6.1 if v(self.version) < v('6.1'): self._url = 'http://{server}:{port}/xmlrpc'.format( server=self.server, port=self.port) # Server >= 6.1 and < 8.0 elif v(self.version) < v('8.0'): self._url = 'http://{server}:{port}/openerp/xmlrpc/1'.format( server=self.server, port=self.port) # Server >= 8.0 elif v(self.version) >= v('8.0'): self._url = 'http://{server}:{port}/xmlrpc/2'.format( server=self.server, port=self.port) # Detect the XML-RPC path to use if self._url is None: # We begin with the last known XML-RPC path to give the priority to # the last server version supported paths = XML_RPC_PATHS[:] paths.reverse() for path in paths: url = 'http://{server}:{port}{path}'.format( server=self.server, port=self.port, path=path) try: db = service.ServiceXMLRPC( self, 'db', '{url}/{srv}'.format(url=url, srv='db')) version = db.server_version() except error.ConnectorError: continue else: self._url = url self.version = version break
def __init__(self, server, port=8069, timeout=120, version=None, scheme='http'): super(ConnectorXMLRPC, self).__init__(server, port, timeout, version) self.scheme = scheme if self.version: # Server < 6.1 if v(self.version) < v('6.1'): self._url = '{scheme}://{server}:{port}/xmlrpc'.format( scheme=self.scheme, server=self.server, port=self.port) # Server >= 6.1 and < 8.0 elif v(self.version) < v('8.0'): self._url = '{scheme}://{server}:{port}/openerp/xmlrpc/1'.format( scheme=self.scheme, server=self.server, port=self.port) # Server >= 8.0 elif v(self.version) >= v('8.0'): self._url = '{scheme}://{server}:{port}/xmlrpc/2'.format( scheme=self.scheme, server=self.server, port=self.port) # Detect the XML-RPC path to use if self._url is None: # We begin with the last known XML-RPC path to give the priority to # the last server version supported paths = XML_RPC_PATHS[:] paths.reverse() for path in paths: url = '{scheme}://{server}:{port}{path}'.format( scheme=self.scheme, server=self.server, port=self.port, path=path) try: db = service.ServiceXMLRPC( self, 'db', '{url}/{srv}'.format(url=url, srv='db')) version = db.server_version() except error.ConnectorError: continue else: self._url = url self.version = version break
def _get_models_data(self, models, models_blacklist): """Returns a dictionary `{MODEL: DATA, ...}` of models corresponding to `models - models_blacklist` patterns (whitelist substracted by a blacklist). """ res = {} # OpenERP v5 does not have the 'modules' field on 'ir.model' used to # bound a data model and its related modules. if v(self.oerp.version) <= v('6.0'): return res models_patterns = \ [pattern2oerp(model) for model in (models)] models_blacklist_patterns = \ [pattern2oerp(model) for model in (models_blacklist)] if models: model_obj = self.oerp.get('ir.model') args = [('model', '=ilike', model) for model in models_patterns] for _ in range(len(args) - 1): args.insert(0, '|') for model in models_blacklist_patterns: args.append('!') args.append(('model', '=ilike', model)) ids = model_obj.search(args) for data in model_obj.read(ids, ['model', 'modules', 'osv_memory']): if not self._config['show_model_transient'] \ and data['osv_memory']: continue if not self._config['show_model_normal'] \ and not data['osv_memory']: continue res[data['model']] = { 'model': data['model'], 'modules': data['modules'] and data['modules'].split(', ') or [], 'transient': data['osv_memory'], } return res
def _get_proxy(self, ssl=False): """Returns a :class:`Proxy <oerplib.rpc.jsonrpclib.Proxy>` instance corresponding to the server version used. """ # Detect the server version if self.version is None: proxy = jsonrpclib.Proxy( self.server, self.port, self._timeout, ssl=ssl, deserialize=self.deserialize) result = proxy.web.webclient.version_info()['result'] # Server 6.1 if 'version' in result: self.version = result['version'] # Server >= 7.0 elif 'server_version' in result: self.version = result['server_version'] # Select the legacy proxy for OpenERP 6.1 and 7.0 if v(self.version)[:2] <= v('7.0'): proxy = jsonrpclib.ProxyLegacy( self.server, self.port, self._timeout, ssl=ssl, deserialize=self.deserialize) return proxy
def test_db_create(self): if ARGS.database not in self.oerp.db.list(): if v(self.oerp.version) >= v('8.0'): res = self.oerp.db.create_database( ARGS.super_admin_passwd, ARGS.database, False, 'en_US', ARGS.passwd) self.assertTrue(res) else: res = self.oerp.db.create_and_wait( ARGS.super_admin_passwd, ARGS.database, False, 'en_US', ARGS.passwd) self.assertIsInstance(res, list) self.assertNotEqual(res, list()) self.assertEqual(res[0]['login'], 'admin') self.assertEqual(res[0]['password'], ARGS.passwd) import time time.sleep(10)
def test_write_record_many2one(self): self.user.action_id = 1 self.assertEqual(self.user.action_id.id, 1) self.oerp.write_record(self.user) self.assertEqual(self.user.action_id.id, 1) action = self.oerp.get('ir.actions.actions').browse(1) self.user.action_id = action self.oerp.write_record(self.user) self.assertEqual(self.user.action_id.id, 1) # False self.user.action_id = False self.oerp.write_record(self.user) if v(self.oerp.version)[:2] == v('5.0'): self.assertEqual(self.user.action_id.id, 1) elif v(self.oerp.version)[:2] == v('6.0'): self.assertEqual(self.user.action_id, False) elif v(self.oerp.version)[:2] == v('6.1'): self.assertEqual(self.user.action_id, False) else: self.assertEqual(self.user.action_id, False)
def test_v_alphanumeric(self): self.assertEqual(tools.v('7.0alpha'), [7, 0])
def test_v_numeric(self): self.assertEqual(tools.v('7.0'), [7, 0])