def exp_get_available_updates(self, contract_id, contract_password): import openerp.tools.maintenance as tm try: rc = tm.remote_contract(contract_id, contract_password) if not rc.id: raise tm.RemoteContractException('This contract does not exist or is not active') 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))
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)
def _check_report(self, report_id): result = self._reports[report_id] exc = result['exception'] if exc: netsvc.abort_response(exc, exc.message, 'warning', exc.traceback) res = {'state': result['state']} if res['state']: if tools.config['reportgz']: import zlib res2 = zlib.compress(result['result']) res['code'] = 'zlib' else: #CHECKME: why is this needed??? if isinstance(result['result'], unicode): res2 = result['result'].encode('latin1', 'replace') else: res2 = result['result'] if res2: res['result'] = base64.encodestring(res2) res['format'] = result['format'] del self._reports[report_id] return res
def _check_report(self, report_id): result = self._reports[report_id] exc = result["exception"] if exc: netsvc.abort_response(exc, exc.message, "warning", exc.traceback) res = {"state": result["state"]} if res["state"]: if tools.config["reportgz"]: import zlib res2 = zlib.compress(result["result"]) res["code"] = "zlib" else: # CHECKME: why is this needed??? if isinstance(result["result"], unicode): res2 = result["result"].encode("latin1", "replace") else: res2 = result["result"] if res2: res["result"] = base64.encodestring(res2) res["format"] = result["format"] del self._reports[report_id] return res
def exp_get_migration_scripts(self, contract_id, contract_password): import openerp.tools.maintenance as tm try: rc = tm.remote_contract(contract_id, contract_password) if not rc.id: raise tm.RemoteContractException('This contract does not exist or is not active') if rc.status != 'full': raise tm.RemoteContractException('Can not get updates for a partial contract') _logger.info('starting migration with contract %s', rc.name) zips = rc.retrieve_updates(rc.id, openerp.modules.get_modules_with_version()) from shutil import rmtree, copytree, copy backup_directory = os.path.join(tools.config['root_path'], 'backup', time.strftime('%Y-%m-%d-%H-%M')) if zips and not os.path.isdir(backup_directory): _logger.info('create a new backup directory to store the old modules: %s', backup_directory) os.makedirs(backup_directory) for module in zips: _logger.info('upgrade module %s', module) mp = openerp.modules.get_module_path(module) if mp: if os.path.isdir(mp): copytree(mp, os.path.join(backup_directory, module)) if os.path.islink(mp): os.unlink(mp) else: rmtree(mp) else: copy(mp + 'zip', backup_directory) os.unlink(mp + '.zip') try: try: base64_decoded = base64.decodestring(zips[module]) except Exception: _logger.error('unable to read the module %s', module) raise zip_contents = StringIO(base64_decoded) zip_contents.seek(0) try: try: tools.extract_zip_file(zip_contents, tools.config['addons_path'] ) except Exception: _logger.error('unable to extract the module %s', module) rmtree(module) raise finally: zip_contents.close() except Exception: _logger.error('restore the previous version of the module %s', module) nmp = os.path.join(backup_directory, module) if os.path.isdir(nmp): copytree(nmp, tools.config['addons_path']) else: copy(nmp+'.zip', tools.config['addons_path']) raise return True except tm.RemoteContractException, e: netsvc.abort_response(1, 'Migration Error', 'warning', str(e))
def exp_get_migration_scripts(self, contract_id, contract_password): import openerp.tools.maintenance as tm try: rc = tm.remote_contract(contract_id, contract_password) if not rc.id: raise tm.RemoteContractException('This contract does not exist or is not active') if rc.status != 'full': raise tm.RemoteContractException('Can not get updates for a partial contract') _logger.info('starting migration with contract %s', rc.name) zips = rc.retrieve_updates(rc.id, openerp.modules.get_modules_with_version()) from shutil import rmtree, copytree, copy backup_directory = os.path.join(tools.config['root_path'], 'backup', time.strftime('%Y-%m-%d-%H-%M')) if zips and not os.path.isdir(backup_directory): _logger.info('create a new backup directory to \ store the old modules: %s', backup_directory) os.makedirs(backup_directory) for module in zips: _logger.info('upgrade module %s', module) mp = openerp.modules.get_module_path(module) if mp: if os.path.isdir(mp): copytree(mp, os.path.join(backup_directory, module)) if os.path.islink(mp): os.unlink(mp) else: rmtree(mp) else: copy(mp + 'zip', backup_directory) os.unlink(mp + '.zip') try: try: base64_decoded = base64.decodestring(zips[module]) except Exception: _logger.error('unable to read the module %s', module) raise zip_contents = StringIO(base64_decoded) zip_contents.seek(0) try: try: tools.extract_zip_file(zip_contents, tools.config['addons_path'] ) except Exception: _logger.error('unable to extract the module %s', module) rmtree(module) raise finally: zip_contents.close() except Exception: _logger.error('restore the previous version of the module %s', module) nmp = os.path.join(backup_directory, module) if os.path.isdir(nmp): copytree(nmp, tools.config['addons_path']) else: copy(nmp+'.zip', tools.config['addons_path']) raise return True except tm.RemoteContractException, e: netsvc.abort_response(1, 'Migration Error', 'warning', str(e))
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') tries = 0 while True: 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 OperationalError, e: # Automatically retry the typical transaction serialization errors if e.pgcode not in PG_CONCURRENCY_ERRORS_TO_RETRY: raise if tries >= MAX_TRIES_ON_CONCURRENCY_FAILURE: _logger.warning("%s, maximum number of tries reached" % errorcodes.lookup(e.pgcode)) raise wait_time = random.uniform(0.0, 2**tries) tries += 1 _logger.info("%s, retrying %d/%d in %.04f sec..." % (errorcodes.lookup(e.pgcode), tries, MAX_TRIES_ON_CONCURRENCY_FAILURE, wait_time)) time.sleep(wait_time) 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 = _( u'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' ) msg += u'\n {error}'.format( error=str(inst).decode('utf-8')) _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])
def execute_cr(self, cr, uid, data, state='init', context=None): if not context: context = {} res = {} try: state_def = self.states[state] result_def = state_def.get('result', {}) actions_res = {} # iterate through the list of actions defined for this state for action in state_def.get('actions', []): # execute them action_res = action(self, cr, uid, data, context) assert isinstance( action_res, dict ), 'The return value of wizard actions should be a dictionary' actions_res.update(action_res) res = copy.copy(result_def) res['datas'] = actions_res lang = context.get('lang', False) if result_def['type'] == 'action': res['action'] = result_def['action'](self, cr, uid, data, context) elif result_def['type'] == 'form': fields = copy.deepcopy(result_def['fields']) arch = copy.copy(result_def['arch']) button_list = copy.copy(result_def['state']) if isinstance(fields, UpdateableDict): fields = fields.dict if isinstance(arch, UpdateableStr): arch = arch.string # fetch user-set defaut values for the field... shouldn't we pass it the uid? ir_values_obj = pooler.get_pool(cr.dbname).get('ir.values') defaults = ir_values_obj.get( cr, uid, 'default', False, [('wizard.' + self.wiz_name, False)]) default_values = dict([(x[1], x[2]) for x in defaults]) for val in fields.keys(): if 'default' in fields[val]: # execute default method for this field if callable(fields[val]['default']): fields[val]['value'] = fields[val]['default']( uid, data, state) else: fields[val]['value'] = fields[val]['default'] del fields[val]['default'] else: # if user has set a default value for the field, use it if val in default_values: fields[val]['value'] = default_values[val] if 'selection' in fields[val]: if not isinstance(fields[val]['selection'], (tuple, list)): fields[val] = copy.copy(fields[val]) fields[val]['selection'] = fields[val][ 'selection'](self, cr, uid, context) elif lang: res_name = "%s,%s,%s" % (self.wiz_name, state, val) trans = lambda x: translate( cr, res_name, 'selection', lang, x) or x for idx, (key, val2) in enumerate( fields[val]['selection']): fields[val]['selection'][idx] = (key, trans(val2)) if lang: # translate fields for field in fields: res_name = "%s,%s,%s" % (self.wiz_name, state, field) trans = translate(cr, res_name, 'wizard_field', lang) if trans: fields[field]['string'] = trans if 'help' in fields[field]: t = translate(cr, res_name, 'help', lang, fields[field]['help']) if t: fields[field]['help'] = t # translate arch if not isinstance(arch, UpdateableStr): doc = etree.XML(arch) self.translate_view(cr, doc, state, lang) arch = etree.tostring(doc) # translate buttons button_list = list(button_list) for i, aa in enumerate(button_list): button_name = aa[0] trans = translate( cr, self.wiz_name + ',' + state + ',' + button_name, 'wizard_button', lang) if trans: aa = list(aa) aa[1] = trans button_list[i] = aa res['fields'] = fields res['arch'] = arch res['state'] = button_list elif result_def['type'] == 'choice': next_state = result_def['next_state'](self, cr, uid, data, context) return self.execute_cr(cr, uid, data, next_state, context) except Exception, e: if isinstance(e, except_wizard) \ or isinstance(e, except_osv) \ or isinstance(e, except_orm): netsvc.abort_response(2, e.name, 'warning', e.value) else: import traceback tb_s = reduce( lambda x, y: x + y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)) _logger.error('Exception in call: ' + tb_s) raise
def execute_cr(self, cr, uid, data, state='init', context=None): if not context: context={} res = {} try: state_def = self.states[state] result_def = state_def.get('result', {}) actions_res = {} # iterate through the list of actions defined for this state for action in state_def.get('actions', []): # execute them action_res = action(self, cr, uid, data, context) assert isinstance(action_res, dict), 'The return value of wizard actions should be a dictionary' actions_res.update(action_res) res = copy.copy(result_def) res['datas'] = actions_res lang = context.get('lang', False) if result_def['type'] == 'action': res['action'] = result_def['action'](self, cr, uid, data, context) elif result_def['type'] == 'form': fields = copy.deepcopy(result_def['fields']) arch = copy.copy(result_def['arch']) button_list = copy.copy(result_def['state']) if isinstance(fields, UpdateableDict): fields = fields.dict if isinstance(arch, UpdateableStr): arch = arch.string # fetch user-set defaut values for the field... shouldn't we pass it the uid? ir_values_obj = pooler.get_pool(cr.dbname).get('ir.values') defaults = ir_values_obj.get(cr, uid, 'default', False, [('wizard.'+self.wiz_name, False)]) default_values = dict([(x[1], x[2]) for x in defaults]) for val in fields.keys(): if 'default' in fields[val]: # execute default method for this field if callable(fields[val]['default']): fields[val]['value'] = fields[val]['default'](uid, data, state) else: fields[val]['value'] = fields[val]['default'] del fields[val]['default'] else: # if user has set a default value for the field, use it if val in default_values: fields[val]['value'] = default_values[val] if 'selection' in fields[val]: if not isinstance(fields[val]['selection'], (tuple, list)): fields[val] = copy.copy(fields[val]) fields[val]['selection'] = fields[val]['selection'](self, cr, uid, context) elif lang: res_name = "%s,%s,%s" % (self.wiz_name, state, val) trans = lambda x: translate(cr, res_name, 'selection', lang, x) or x for idx, (key, val2) in enumerate(fields[val]['selection']): fields[val]['selection'][idx] = (key, trans(val2)) if lang: # translate fields for field in fields: res_name = "%s,%s,%s" % (self.wiz_name, state, field) trans = translate(cr, res_name, 'wizard_field', lang) if trans: fields[field]['string'] = trans if 'help' in fields[field]: t = translate(cr, res_name, 'help', lang, fields[field]['help']) if t: fields[field]['help'] = t # translate arch if not isinstance(arch, UpdateableStr): doc = etree.XML(arch) self.translate_view(cr, doc, state, lang) arch = etree.tostring(doc) # translate buttons button_list = list(button_list) for i, aa in enumerate(button_list): button_name = aa[0] trans = translate(cr, self.wiz_name+','+state+','+button_name, 'wizard_button', lang) if trans: aa = list(aa) aa[1] = trans button_list[i] = aa res['fields'] = fields res['arch'] = arch res['state'] = button_list elif result_def['type'] == 'choice': next_state = result_def['next_state'](self, cr, uid, data, context) return self.execute_cr(cr, uid, data, next_state, context) except Exception, e: if isinstance(e, except_wizard) \ or isinstance(e, except_osv) \ or isinstance(e, except_orm): netsvc.abort_response(2, e.name, 'warning', e.value) else: import traceback tb_s = reduce(lambda x, y: x+y, traceback.format_exception( sys.exc_type, sys.exc_value, sys.exc_traceback)) _logger.error('Exception in call: ' + tb_s) raise