def _get_report_data_v5(self, report_name, model, obj_ids, report_type='pdf', context=None): """Download binary data of a report from the server.""" context = context or {} obj_ids = [obj_ids] if isinstance(obj_ids, (int, long)) else obj_ids data = { 'model': model, 'id': obj_ids[0], 'ids': obj_ids, 'report_type': report_type, } try: report_id = self._connector.report.report( self._database, self.user.id, self._password, report_name, obj_ids, data, context) except rpc.error.ConnectorError as exc: raise error.RPCError(exc.message, exc.oerp_traceback) state = False attempt = 0 while not state: try: pdf_data = self._connector.report.report_get( self._database, self.user.id, self._password, report_id) except rpc.error.ConnectorError as exc: raise error.RPCError("Unknown error occurred during the " "download of the report.") state = pdf_data['state'] if not state: time.sleep(1) attempt += 1 if attempt > 200: raise error.RPCError("Download time exceeded, " "the operation has been canceled.") return pdf_data
def login(self, user='******', passwd='admin', database=None): """Log in as the given `user` with the password `passwd` on the database `database` and return the corresponding user as a browsable record (from the ``res.users`` model). If `database` is not specified, the default one will be used instead. >>> user = oerp.login('admin', 'admin', database='db_name') >>> user.name u'Administrator' :return: the user connected as a browsable record :raise: :class:`oerplib.error.RPCError`, :class:`oerplib.error.Error` """ # Raise an error if no database was given self._database = database or self._database_default if not self._database: raise error.Error("No database specified") # Get the user's ID and generate the corresponding User record try: user_id = self.common.login(self._database, user, passwd) except rpc.error.ConnectorError as exc: raise error.RPCError(exc.message, exc.oerp_traceback) else: if user_id: self._uid = user_id self._password = passwd self._context = self.execute('res.users', 'context_get') self._user = self.browse('res.users', user_id, self._context) return self._user else: #FIXME: Raise an error? raise error.RPCError("Wrong login ID or password")
def create_and_wait(self, super_admin_passwd, database, demo_data=False, lang='en_US', admin_passwd='admin'): """ .. note:: This method is not part of the official API. It's just a wrapper around the :func:`create <DB.create>` and :func:`get_progress <DB.get_progress>` methods. For server in version `6.1` or above, please prefer the use of the standard :func:`create_database <DB.create_database>` method. Like the :func:`create <DB.create>` method, but waits the end of the creating process by executing the :func:`get_progress <DB.get_progress>` method regularly to check its state. >>> oerp.db.create_and_wait('super_admin_passwd', 'test_db', False, 'fr_FR', 'my_admin_passwd') [{'login': '******', 'password': '******', 'name': 'Administrateur'}, {'login': '******', 'password': '******', 'name': 'Demo User'}] The super administrator password `super_admin_passwd` is required to perform this action. :return: a list of user accounts created :raise: :class:`oerplib.error.RPCError` """ try: db_id = self._oerp._connector.db.create( super_admin_passwd, database, demo_data, lang, admin_passwd) progress = 0.0 attempt = 0 while progress < 1.0: result = self._oerp._connector.db.get_progress( super_admin_passwd, db_id) progress = result[0] if progress < 1.0: time.sleep(1) attempt += 1 if attempt > 300: raise error.RPCError( "Too many attempts, the operation" " has been canceled.") return result[1] except rpc.error.ConnectorError as exc: #FIXME handle the exception with the UnicodeEncodeError for # the error 'the database already exists'. #print dir(exc) raise error.RPCError(exc.message, exc.oerp_traceback)
def rpc_method(*args): """Return the result of the RPC request.""" try: meth = getattr(self._oerp._connector.wizard, method, False) return meth(self._oerp.database, self._oerp.user.id, *args) except rpc.error.ConnectorError as exc: raise error.RPCError(exc.message, exc.oerp_traceback)
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 execute_kw(self, model, method, args=None, kwargs=None): """Execute the `method` of `model`. `args` is a list of parameters (in the right order), and `kwargs` a dictionary (named parameters). Both varies according to the `method` used. >>> oerp.execute_kw('res.partner', 'read', [[1, 2]], {'fields': ['name']}) [{'name': u'ASUStek', 'id': 2}, {'name': u'Your Company', 'id': 1}] .. warning:: This method only works on servers in version `6.1` and above. :return: the result returned by the `method` called :raise: :class:`oerplib.error.RPCError` """ self._check_logged_user() # Execute the query args = args or [] kwargs = kwargs or {} try: return self._connector.object.execute_kw( self._database, self._uid, self._password, model, method, args, kwargs) except rpc.error.ConnectorError as exc: raise error.RPCError(exc.message, exc.oerp_traceback)
def exec_workflow(self, model, signal, obj_id): """Execute the workflow `signal` on the instance having the ID `obj_id` of `model`. :raise: :class:`oerplib.error.RPCError` """ #TODO NEED TEST self._check_logged_user() # Execute the workflow query try: self._connector.object.exec_workflow( self._database, self._uid, self._password, model, signal, obj_id) except rpc.error.ConnectorError as exc: raise error.RPCError(exc.message, exc.oerp_traceback)
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 _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 execute(self, model, method, *args): """Execute the `method` of `model`. `*args` parameters varies according to the `method` used. >>> oerp.execute('res.partner', 'read', [1, 2], ['name']) [{'name': u'ASUStek', 'id': 2}, {'name': u'Your Company', 'id': 1}] :return: the result returned by the `method` called :raise: :class:`oerplib.error.RPCError` """ self._check_logged_user() # Execute the query try: return self._connector.object.execute( self._database, self._uid, self._password, model, method, *args) except rpc.error.ConnectorError as exc: raise error.RPCError(exc.message, exc.oerp_traceback)
def _get_report_data_v61(self, report_name, model, obj_ids, report_type='pdf', context=None): """Download binary data of a report from the server. It uses the `render_report` RPC method available since OpenERP 6.1. """ if context is None: context = {} obj_ids = [obj_ids] if isinstance(obj_ids, (int, long)) else obj_ids data = { 'model': model, 'id': obj_ids[0], 'ids': obj_ids, 'report_type': report_type, } try: return self._connector.report.render_report( self._database, self.user.id, self._password, report_name, obj_ids, data, context) except rpc.error.ConnectorError as exc: raise error.RPCError(exc.message, exc.oerp_traceback)
def auth(self, user=None, passwd=None): try: return self.common.login(self._database, user, passwd) except rpc.error.ConnectorError as exc: raise error.RPCError(exc.message, exc.oerp_traceback)