def _serve_attachment(cls): env = api.Environment(request.cr, SUPERUSER_ID, request.context) domain = [('type', '=', 'binary'), ('url', '=', request.httprequest.path)] fields = ['__last_update', 'datas', 'name', 'mimetype', 'checksum'] attach = env['ir.attachment'].search_read(domain, fields) if attach: wdate = attach[0]['__last_update'] datas = attach[0]['datas'] or b'' name = attach[0]['name'] checksum = attach[0]['checksum'] or hashlib.sha1(datas).hexdigest() if (not datas and name != request.httprequest.path and name.startswith(('http://', 'https://', '/'))): return werkzeug.utils.redirect(name, 301) response = werkzeug.wrappers.Response() server_format = tools.DEFAULT_SERVER_DATETIME_FORMAT try: response.last_modified = datetime.datetime.strptime(wdate, server_format + '.%f') except ValueError: # just in case we have a timestamp without microseconds response.last_modified = datetime.datetime.strptime(wdate, server_format) response.set_etag(checksum) response.make_conditional(request.httprequest) if response.status_code == 304: return response response.mimetype = attach[0]['mimetype'] or 'application/octet-stream' response.data = base64.b64decode(datas) return response
def authenticate(cls, db, login, password, user_agent_env): """Verifies and returns the user ID corresponding to the given ``login`` and ``password`` combination, or False if there was no matching user. :param str db: the database on which user is trying to authenticate :param str login: username :param str password: user password :param dict user_agent_env: environment dictionary describing any relevant environment attributes """ uid = cls._login(db, login, password) if uid == SUPERUSER_ID: # Successfully logged in as admin! # Attempt to guess the web base url... if user_agent_env and user_agent_env.get('base_location'): try: with cls.pool.cursor() as cr: base = user_agent_env['base_location'] ICP = api.Environment(cr, uid, {})['ir.config_parameter'] if not ICP.get_param('web.base.url.freeze'): ICP.set_param('web.base.url', base) except Exception: _logger.exception( "Failed to update web.base.url configuration parameter" ) return uid
def oea(self, **kw): """login user via izi Account provider""" dbname = kw.pop('db', None) if not dbname: dbname = db_monodb() if not dbname: return BadRequest() registry = registry_get(dbname) with registry.cursor() as cr: try: env = api.Environment(cr, SUPERUSER_ID, {}) provider = env.ref('auth_oauth.provider_openerp') except ValueError: return set_cookie_and_redirect('/web?db=%s' % dbname) assert provider._name == 'auth.oauth.provider' state = { 'd': dbname, 'p': provider.id, 'c': { 'no_user_creation': True }, } kw['state'] = json.dumps(state) return self.signin(**kw)
def environment(): """ Return an environment with a new cursor for the current database; the cursor is committed and closed after the context block. """ reg = registry(common.get_db_name()) with reg.cursor() as cr: yield api.Environment(cr, SUPERUSER_ID, {}) cr.commit()
def update_dashboard_graph_model(dbname): db_registry = izi.modules.registry.Registry.new(dbname) with api.Environment.manage(), db_registry.cursor() as cr: env = api.Environment(cr, SUPERUSER_ID, {}) if 'crm.team' in env: recs = env['crm.team'].search([]) for rec in recs: rec._onchange_team_type()
def poll(self, dbname, channels, last, options=None, timeout=TIMEOUT): if options is None: options = {} # Dont hang ctrl-c for a poll request, we need to bypass private # attribute access because we dont know before starting the thread that # it will handle a longpolling request if not izi.evented: current = threading.current_thread() current._Thread__daemonic = True # PY2 current._daemonic = True # PY3 # rename the thread to avoid tests waiting for a longpolling current.setName("openerp.longpolling.request.%s" % current.ident) registry = izi.registry(dbname) # immediatly returns if past notifications exist with registry.cursor() as cr: env = api.Environment(cr, SUPERUSER_ID, {}) notifications = env['bus.bus'].poll(channels, last, options) # immediatly returns in peek mode if options.get('peek'): return dict(notifications=notifications, channels=channels) # or wait for future ones if not notifications: if not self.started: # Lazy start of events listener self.start() event = self.Event() for channel in channels: self.channels.setdefault(hashable(channel), []).append(event) try: event.wait(timeout=timeout) with registry.cursor() as cr: env = api.Environment(cr, SUPERUSER_ID, {}) notifications = env['bus.bus'].poll(channels, last, options, force_status=True) except Exception: # timeout pass return notifications
def _setup_inalterability(cr, registry): env = api.Environment(cr, SUPERUSER_ID, {}) # enable ping for this module env['publisher_warranty.contract'].update_notification(cron_mode=True) fr_companies = env['res.company'].search([('partner_id.country_id.code', 'in', UNALTERABLE_COUNTRIES)]) if fr_companies: # create the securisation sequence per company fr_companies._create_secure_sequence(['l10n_fr_pos_cert_sequence_id'])
def to_python(self, value): matching = re.match(self.regex, value) _uid = RequestUID(value=value, match=matching, converter=self) record_id = int(matching.group(2)) env = api.Environment(request.cr, _uid, request.context) if record_id < 0: # limited support for negative IDs due to our slug pattern, assume abs() if not found if not env[self.model].browse(record_id).exists(): record_id = abs(record_id) return env[self.model].browse(record_id)
def _auth_method_public(cls): """ If no user logged, set the public user of current website, or default public user as request uid. After this method `request.env` can be called, since the `request.uid` is set. The `env` lazy property of `request` will be correct. """ if not request.session.uid: env = api.Environment(request.cr, SUPERUSER_ID, request.context) website = env['website'].get_current_website() if website and website.user_id: request.uid = website.user_id.id if not request.uid: super(Http, cls)._auth_method_public()
def receive(self, req): """ End-point to receive mail from an external SMTP server. """ dbs = req.jsonrequest.get('databases') for db in dbs: message = base64.b64decode(dbs[db]) try: db_registry = registry(db) with db_registry.cursor() as cr: env = api.Environment(cr, SUPERUSER_ID, {}) env['mail.thread'].message_process(None, message) except psycopg2.Error: pass return True
def signin(self, **kw): state = json.loads(kw['state']) dbname = state['d'] provider = state['p'] context = state.get('c', {}) registry = registry_get(dbname) with registry.cursor() as cr: try: env = api.Environment(cr, SUPERUSER_ID, context) credentials = env['res.users'].sudo().auth_oauth(provider, kw) cr.commit() action = state.get('a') menu = state.get('m') redirect = werkzeug.url_unquote_plus( state['r']) if state.get('r') else False url = '/web' if redirect: url = redirect elif action: url = '/web#action=%s' % action elif menu: url = '/web#menu_id=%s' % menu resp = login_and_redirect(*credentials, redirect_url=url) # Since /web is hardcoded, verify user has right to land on it if werkzeug.urls.url_parse( resp.location ).path == '/web' and not request.env.user.has_group( 'base.group_user'): resp.location = '/' return resp except AttributeError: # auth_signup is not installed _logger.error( "auth_signup not installed on database %s: oauth sign up cancelled." % (dbname, )) url = "/web/login?oauth_error=1" except AccessDenied: # oauth credentials not valid, user could be on a temporary session _logger.info( 'OAuth2: access denied, redirect to main page in case a valid session exists, without setting cookies' ) url = "/web/login?oauth_error=3" redirect = werkzeug.utils.redirect(url, 303) redirect.autocorrect_location_header = False return redirect except Exception as e: # signup error _logger.exception("OAuth2: %s" % str(e)) url = "/web/login?oauth_error=2" return set_cookie_and_redirect(url)
def _setup_inalterability(cr, registry): env = api.Environment(cr, SUPERUSER_ID, {}) # enable ping for this module env['publisher_warranty.contract'].update_notification(cron_mode=True) fr_companies = env['res.company'].search([('partner_id.country_id.code', 'in', UNALTERABLE_COUNTRIES)]) if fr_companies: # create the securisation sequence per company fr_companies._create_secure_sequence(['l10n_fr_secure_sequence_id']) #reset the update_posted field on journals journals = env['account.journal'].search([('company_id', 'in', fr_companies.ids)]) journals.write({'update_posted': False})
def check(cls, db, uid, passwd): """Verifies that the given (uid, password) is authorized for the database ``db`` and raise an exception if it is not.""" if not passwd: # empty passwords disallowed for obvious security reasons raise AccessDenied() db = cls.pool.db_name if cls.__uid_cache[db].get(uid) == passwd: return cr = cls.pool.cursor() try: self = api.Environment(cr, uid, {})[cls._name] self.check_credentials(passwd) cls.__uid_cache[db][uid] = passwd finally: cr.close()
def _auto_install_l10n(cr, registry): #check the country of the main company (only) and eventually load some module needed in that country env = api.Environment(cr, SUPERUSER_ID, {}) country_code = env.user.company_id.country_id.code if country_code: #auto install localization module(s) if available module_list = [] if country_code in SYSCOHADA_LIST: #countries using OHADA Chart of Accounts module_list.append('l10n_syscohada') elif country_code == 'GB': module_list.append('l10n_uk') elif country_code == 'DE': module_list.append('l10n_de_skr03') module_list.append('l10n_de_skr04') else: if env['ir.module.module'].search([ ('name', '=', 'l10n_' + country_code.lower()) ]): module_list.append('l10n_' + country_code.lower()) else: module_list.append('l10n_generic_coa') if country_code == 'US': module_list.append('account_plaid') module_list.append('account_check_printing') if country_code in [ 'US', 'AU', 'NZ', 'CA', 'CO', 'EC', 'ES', 'FR', 'IN', 'MX', 'UK' ]: module_list.append('account_yodlee') if country_code in SYSCOHADA_LIST + [ 'AT', 'BE', 'CA', 'CO', 'DE', 'EC', 'ES', 'ET', 'FR', 'GR', 'IT', 'LU', 'MX', 'NL', 'NO', 'PL', 'PT', 'RO', 'SI', 'TR', 'UK', 'VE', 'VN' ]: module_list.append('base_vat') #european countries will be using SEPA europe = env.ref('base.europe', raise_if_not_found=False) if europe: europe_country_codes = [x.code for x in europe.country_ids] if country_code in europe_country_codes: module_list.append('account_sepa') module_ids = env['ir.module.module'].search([ ('name', 'in', module_list), ('state', '=', 'uninstalled') ]) module_ids.sudo().button_install()
def _login(cls, db, login, password): user_id = super(Users, cls)._login(db, login, password) if user_id: return user_id with registry(db).cursor() as cr: cr.execute("SELECT id FROM res_users WHERE lower(login)=%s", (login,)) res = cr.fetchone() if res: return False env = api.Environment(cr, SUPERUSER_ID, {}) Ldap = env['res.company.ldap'] for conf in Ldap.get_ldap_dicts(): entry = Ldap.authenticate(conf, login, password) if entry: user_id = Ldap.get_or_create_user(conf, login, entry) if user_id: break return user_id
def post_init(cr, registry): """ Set the timesheet project and task on existing leave type. Do it in post_init to be sure the internal project/task of res.company are set. (Since timesheet_generate field is true by default, those 2 fields are required on the leave type). """ from izi import api, SUPERUSER_ID env = api.Environment(cr, SUPERUSER_ID, {}) for leave_type in env['hr.holidays.status'].search([ ('timesheet_generate', '=', True), ('timesheet_project_id', '=', False) ]): company = leave_type.company_id or env.user.company_id leave_type.write({ 'timesheet_project_id': company.leave_timesheet_project_id.id, 'timesheet_task_id': company.leave_timesheet_task_id.id, })
def setUp(self): self.registry = izi.registry(get_db_name()) #: current transaction's cursor self.cr = self.cursor() self.uid = izi.SUPERUSER_ID #: :class:`~izi.api.Environment` for the current test case self.env = api.Environment(self.cr, self.uid, {}) @self.addCleanup def reset(): # rollback and close the cursor, and reset the environments self.registry.clear_caches() self.registry.reset_changes() self.env.reset() self.cr.rollback() self.cr.close() self.patch(type(self.env['res.partner']), '_get_gravatar_image', lambda *a: False)
def _process_job(cls, job_cr, job, cron_cr): """ Run a given job taking care of the repetition. :param job_cr: cursor to use to execute the job, safe to commit/rollback :param job: job to be run (as a dictionary). :param cron_cr: cursor holding lock on the cron job row, to use to update the next exec date, must not be committed/rolled back! """ try: with api.Environment.manage(): cron = api.Environment(job_cr, job['user_id'], {})[cls._name] # Use the user's timezone to compare and compute datetimes, # otherwise unexpected results may appear. For instance, adding # 1 month in UTC to July 1st at midnight in GMT+2 gives July 30 # instead of August 1st! now = fields.Datetime.context_timestamp(cron, datetime.now()) nextcall = fields.Datetime.context_timestamp( cron, fields.Datetime.from_string(job['nextcall'])) numbercall = job['numbercall'] ok = False while nextcall < now and numbercall: if numbercall > 0: numbercall -= 1 if not ok or job['doall']: cron._callback(job['cron_name'], job['ir_actions_server_id'], job['id']) if numbercall: nextcall += _intervalTypes[job['interval_type']]( job['interval_number']) ok = True addsql = '' if not numbercall: addsql = ', active=False' cron_cr.execute( "UPDATE ir_cron SET nextcall=%s, numbercall=%s" + addsql + " WHERE id=%s", (fields.Datetime.to_string( nextcall.astimezone(pytz.UTC)), numbercall, job['id'])) cron.invalidate_cache() finally: job_cr.commit() cron_cr.commit()
def _login(cls, db, login, password): if not password: return False user_id = False try: with cls.pool.cursor() as cr: self = api.Environment(cr, SUPERUSER_ID, {})[cls._name] user = self.search([('login', '=', login)]) if user: user_id = user.id user.sudo(user_id).check_credentials(password) user.sudo(user_id)._update_last_login() except AccessDenied: user_id = False status = "successful" if user_id else "failed" ip = request.httprequest.environ['REMOTE_ADDR'] if request else 'n/a' _logger.info("Login %s for db:%s login:%s from %s", status, db, login, ip) return user_id
def authenticate(self, user, password): # stay non-authenticated if user is None: return db = get_db_name() uid = self.registry['res.users'].authenticate(db, user, password, None) env = api.Environment(self.cr, uid, {}) # self.session.authenticate(db, user, password, uid=uid) # OpenERPSession.authenticate accesses the current request, which we # don't have, so reimplement it manually... session = self.session session.db = db session.uid = uid session.login = user session.session_token = uid and security.compute_session_token(session) session.context = env['res.users'].context_get() or {} session.context['uid'] = uid session._fix_lang(session.context) izi.http.root.session_store.save(session)
def _button_immediate_function(self, function): function(self) self._cr.commit() api.Environment.reset() modules.registry.Registry.new(self._cr.dbname, update_module=True) self._cr.commit() env = api.Environment(self._cr, self._uid, self._context) # pylint: disable=next-method-called config = env['ir.module.module'].next() or {} if config.get('type') not in ('ir.actions.act_window_close', ): return config # reload the client; open the first available root menu menu = env['ir.ui.menu'].search([('parent_id', '=', False)])[:1] return { 'type': 'ir.actions.client', 'tag': 'reload', 'params': { 'menu_id': menu.id }, }
def log_xml(self, xml_string, func): self.ensure_one() if self.debug_logging: db_name = self._cr.dbname # Use a new cursor to avoid rollback that could be caused by an upper method try: db_registry = registry(db_name) with db_registry.cursor() as cr: env = api.Environment(cr, SUPERUSER_ID, {}) IrLogging = env['ir.logging'] IrLogging.sudo().create({ 'name': 'delivery.carrier', 'type': 'server', 'dbname': db_name, 'level': 'DEBUG', 'message': xml_string, 'path': self.delivery_type, 'func': func, 'line': 1 }) except psycopg2.Error: pass
def post_init(cr, registry): env = api.Environment(cr, SUPERUSER_ID, {}) load_translations(env) init_settings(env)
def load_modules(db, force_demo=False, status=None, update_module=False): initialize_sys_path() force = [] if force_demo: force.append('demo') models_to_check = set() cr = db.cursor() try: if not izi.modules.db.is_initialized(cr): _logger.info("init db") izi.modules.db.initialize(cr) update_module = True # process auto-installed modules tools.config["init"]["all"] = 1 tools.config['update']['all'] = 1 if not tools.config['without_demo']: tools.config["demo"]['all'] = 1 # This is a brand new registry, just created in # izi.modules.registry.Registry.new(). registry = izi.registry(cr.dbname) if 'base' in tools.config['update'] or 'all' in tools.config['update']: cr.execute( "update ir_module_module set state=%s where name=%s and state=%s", ('to upgrade', 'base', 'installed')) # STEP 1: LOAD BASE (must be done before module dependencies can be computed for later steps) graph = izi.modules.graph.Graph() graph.add_module(cr, 'base', force) if not graph: _logger.critical( 'module base cannot be loaded! (hint: verify addons-path)') raise ImportError( 'Module `base` cannot be loaded! (hint: verify addons-path)') # processed_modules: for cleanup step after install # loaded_modules: to avoid double loading report = registry._assertion_report loaded_modules, processed_modules = load_module_graph( cr, graph, status, perform_checks=update_module, report=report, models_to_check=models_to_check) load_lang = tools.config.pop('load_language') if load_lang or update_module: # some base models are used below, so make sure they are set up registry.setup_models(cr) if load_lang: for lang in load_lang.split(','): tools.load_language(cr, lang) # STEP 2: Mark other modules to be loaded/updated if update_module: env = api.Environment(cr, SUPERUSER_ID, {}) Module = env['ir.module.module'] _logger.info('updating modules list') Module.update_list() _check_module_names( cr, itertools.chain(tools.config['init'], tools.config['update'])) module_names = [k for k, v in tools.config['init'].items() if v] if module_names: modules = Module.search([('state', '=', 'uninstalled'), ('name', 'in', module_names)]) if modules: modules.button_install() module_names = [k for k, v in tools.config['update'].items() if v] if module_names: modules = Module.search([('state', '=', 'installed'), ('name', 'in', module_names)]) if modules: modules.button_upgrade() cr.execute("update ir_module_module set state=%s where name=%s", ('installed', 'base')) Module.invalidate_cache(['state']) # STEP 3: Load marked modules (skipping base which was done in STEP 1) # IMPORTANT: this is done in two parts, first loading all installed or # partially installed modules (i.e. installed/to upgrade), to # offer a consistent system to the second part: installing # newly selected modules. # We include the modules 'to remove' in the first step, because # they are part of the "currently installed" modules. They will # be dropped in STEP 6 later, before restarting the loading # process. # IMPORTANT 2: We have to loop here until all relevant modules have been # processed, because in some rare cases the dependencies have # changed, and modules that depend on an uninstalled module # will not be processed on the first pass. # It's especially useful for migrations. previously_processed = -1 while previously_processed < len(processed_modules): previously_processed = len(processed_modules) processed_modules += load_marked_modules( cr, graph, ['installed', 'to upgrade', 'to remove'], force, status, report, loaded_modules, update_module, models_to_check) if update_module: processed_modules += load_marked_modules( cr, graph, ['to install'], force, status, report, loaded_modules, update_module, models_to_check) registry.loaded = True registry.setup_models(cr) # STEP 3.5: execute migration end-scripts migrations = izi.modules.migration.MigrationManager(cr, graph) for package in graph: migrations.migrate_module(package, 'end') # STEP 4: Finish and cleanup installations if processed_modules: env = api.Environment(cr, SUPERUSER_ID, {}) cr.execute( """select model,name from ir_model where id NOT IN (select distinct model_id from ir_model_access)""" ) for (model, name) in cr.fetchall(): if model in registry and not registry[ model]._abstract and not registry[model]._transient: _logger.warning( 'The model %s has no access rules, consider adding one. E.g. access_%s,access_%s,model_%s,,1,0,0,0', model, model.replace('.', '_'), model.replace('.', '_'), model.replace('.', '_')) # Temporary warning while we remove access rights on osv_memory objects, as they have # been replaced by owner-only access rights cr.execute( """select distinct mod.model, mod.name from ir_model_access acc, ir_model mod where acc.model_id = mod.id""" ) for (model, name) in cr.fetchall(): if model in registry and registry[model]._transient: _logger.warning( 'The transient model %s (%s) should not have explicit access rules!', model, name) cr.execute("SELECT model from ir_model") for (model, ) in cr.fetchall(): if model in registry: env[model]._check_removed_columns(log=True) elif _logger.isEnabledFor( logging.INFO): # more an info that a warning... _logger.warning( "Model %s is declared but cannot be loaded! (Perhaps a module was partially removed or renamed)", model) # Cleanup orphan records env['ir.model.data']._process_end(processed_modules) for kind in ('init', 'demo', 'update'): tools.config[kind] = {} cr.commit() # STEP 5: Uninstall modules to remove if update_module: # Remove records referenced from ir_model_data for modules to be # removed (and removed the references from ir_model_data). cr.execute("SELECT name, id FROM ir_module_module WHERE state=%s", ('to remove', )) modules_to_remove = dict(cr.fetchall()) if modules_to_remove: env = api.Environment(cr, SUPERUSER_ID, {}) pkgs = reversed( [p for p in graph if p.name in modules_to_remove]) for pkg in pkgs: uninstall_hook = pkg.info.get('uninstall_hook') if uninstall_hook: py_module = sys.modules['izi.addons.%s' % (pkg.name, )] getattr(py_module, uninstall_hook)(cr, registry) Module = env['ir.module.module'] Module.browse(modules_to_remove.values()).module_uninstall() # Recursive reload, should only happen once, because there should be no # modules to remove next time cr.commit() _logger.info( 'Reloading registry once more after uninstalling modules') api.Environment.reset() registry = izi.modules.registry.Registry.new( cr.dbname, force_demo, status, update_module) registry.check_tables_exist(cr) cr.commit() return registry # STEP 5.5: Verify extended fields on every model # This will fix the schema of all models in a situation such as: # - module A is loaded and defines model M; # - module B is installed/upgraded and extends model M; # - module C is loaded and extends model M; # - module B and C depend on A but not on each other; # The changes introduced by module C are not taken into account by the upgrade of B. if models_to_check: registry.init_models(cr, list(models_to_check), {'models_to_check': True}) # STEP 6: verify custom views on every model if update_module: env = api.Environment(cr, SUPERUSER_ID, {}) View = env['ir.ui.view'] for model in registry: try: View._validate_custom_views(model) except Exception as e: _logger.warning('invalid custom view(s) for model %s: %s', model, tools.ustr(e)) if report.failures: _logger.error('At least one test failed when loading the modules.') else: _logger.info('Modules loaded.') # STEP 8: call _register_hook on every model env = api.Environment(cr, SUPERUSER_ID, {}) for model in env.values(): model._register_hook() # STEP 9: save installed/updated modules for post-install tests registry.updated_modules += processed_modules cr.commit() finally: cr.close()
def load_translations(cr, registry): env = api.Environment(cr, SUPERUSER_ID, {}) env.ref('l10n_sa.account_arabic_coa_general').process_coa_translations()
def load_translations(cr, registry): env = api.Environment(cr, SUPERUSER_ID, {}) env.ref('l10n_ca.ca_en_chart_template_en').process_coa_translations()
def setUpClass(cls): cls.registry = izi.registry(get_db_name()) cls.cr = cls.registry.cursor() cls.uid = izi.SUPERUSER_ID cls.env = api.Environment(cls.cr, cls.uid, {})
def pre_init_hook(cr): env = api.Environment(cr, SUPERUSER_ID, {}) env['ir.model.data'].search([('model', 'like', '%stock%'), ('module', '=', 'stock')]).unlink()
def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=None, report=None, models_to_check=None): """Migrates+Updates or Installs all module nodes from ``graph`` :param graph: graph of module nodes to load :param status: deprecated parameter, unused, left to avoid changing signature in 8.0 :param perform_checks: whether module descriptors should be checked for validity (prints warnings for same cases) :param skip_modules: optional list of module names (packages) which have previously been loaded and can be skipped :return: list of modules that were installed or updated """ def load_test(module_name, idref, mode): cr.commit() try: _load_data(cr, module_name, idref, mode, 'test') return True except Exception: _test_logger.exception( 'module %s: an exception occurred in a test', module_name) return False finally: if tools.config.options['test_commit']: cr.commit() else: cr.rollback() # avoid keeping stale xml_id, etc. in cache izi.registry(cr.dbname).clear_caches() def _get_files_of_kind(kind): if kind == 'demo': kind = ['demo_xml', 'demo'] elif kind == 'data': kind = ['init_xml', 'update_xml', 'data'] if isinstance(kind, str): kind = [kind] files = [] for k in kind: for f in package.data[k]: files.append(f) if k.endswith('_xml') and not (k == 'init_xml' and not f.endswith('.xml')): # init_xml, update_xml and demo_xml are deprecated except # for the case of init_xml with yaml, csv and sql files as # we can't specify noupdate for those file. correct_key = 'demo' if k.count('demo') else 'data' _logger.warning( "module %s: key '%s' is deprecated in favor of '%s' for file '%s'.", package.name, k, correct_key, f) return files def _load_data(cr, module_name, idref, mode, kind): """ kind: data, demo, test, init_xml, update_xml, demo_xml. noupdate is False, unless it is demo data or it is csv data in init mode. """ try: if kind in ('demo', 'test'): threading.currentThread().testing = True for filename in _get_files_of_kind(kind): _logger.info("loading %s/%s", module_name, filename) noupdate = False if kind in ('demo', 'demo_xml') or (filename.endswith('.csv') and kind in ('init', 'init_xml')): noupdate = True tools.convert_file(cr, module_name, filename, idref, mode, noupdate, kind, report) finally: if kind in ('demo', 'test'): threading.currentThread().testing = False if models_to_check is None: models_to_check = set() processed_modules = [] loaded_modules = [] registry = izi.registry(cr.dbname) migrations = izi.modules.migration.MigrationManager(cr, graph) module_count = len(graph) _logger.info('loading %d modules...', module_count) registry.clear_caches() # register, instantiate and initialize models for each modules t0 = time.time() t0_sql = izi.sql_db.sql_counter models_updated = set() for index, package in enumerate(graph, 1): module_name = package.name module_id = package.id if skip_modules and module_name in skip_modules: continue _logger.debug('loading module %s (%d/%d)', module_name, index, module_count) migrations.migrate_module(package, 'pre') load_openerp_module(package.name) new_install = package.state == 'to install' if new_install: py_module = sys.modules['izi.addons.%s' % (module_name, )] pre_init = package.info.get('pre_init_hook') if pre_init: getattr(py_module, pre_init)(cr) model_names = registry.load(cr, package) loaded_modules.append(package.name) if (hasattr(package, 'init') or hasattr(package, 'update') or package.state in ('to install', 'to upgrade')): models_updated |= set(model_names) models_to_check -= set(model_names) registry.setup_models(cr) registry.init_models(cr, model_names, {'module': package.name}) cr.commit() elif package.state != 'to remove': # The current module has simply been loaded. The models extended by this module # and for which we updated the schema, must have their schema checked again. # This is because the extension may have changed the model, # e.g. adding required=True to an existing field, but the schema has not been # updated by this module because it's not marked as 'to upgrade/to install'. models_to_check |= set(model_names) & models_updated idref = {} mode = 'update' if hasattr(package, 'init') or package.state == 'to install': mode = 'init' if hasattr(package, 'init') or hasattr( package, 'update') or package.state in ('to install', 'to upgrade'): env = api.Environment(cr, SUPERUSER_ID, {}) # Can't put this line out of the loop: ir.module.module will be # registered by init_models() above. module = env['ir.module.module'].browse(module_id) if perform_checks: module._check() if package.state == 'to upgrade': # upgrading the module information module.write(module.get_values_from_terp(package.data)) _load_data(cr, module_name, idref, mode, kind='data') has_demo = hasattr(package, 'demo') or (package.dbdemo and package.state != 'installed') if has_demo: _load_data(cr, module_name, idref, mode, kind='demo') cr.execute('update ir_module_module set demo=%s where id=%s', (True, module_id)) module.invalidate_cache(['demo']) migrations.migrate_module(package, 'post') # Update translations for all installed languages overwrite = izi.tools.config["overwrite_existing_translations"] module.with_context(overwrite=overwrite)._update_translations() if package.name is not None: registry._init_modules.add(package.name) if new_install: post_init = package.info.get('post_init_hook') if post_init: getattr(py_module, post_init)(cr, registry) # validate all the views at a whole env['ir.ui.view']._validate_module_views(module_name) if has_demo: # launch tests only in demo mode, allowing tests to use demo data. if tools.config.options['test_enable']: # Yamel test report.record_result(load_test(module_name, idref, mode)) # Python tests env['ir.http']._clear_routing_map( ) # force routing map to be rebuilt report.record_result( izi.modules.module.run_unit_tests( module_name, cr.dbname)) # tests may have reset the environment env = api.Environment(cr, SUPERUSER_ID, {}) module = env['ir.module.module'].browse(module_id) processed_modules.append(package.name) ver = adapt_version(package.data['version']) # Set new modules and dependencies module.write({'state': 'installed', 'latest_version': ver}) package.load_state = package.state package.load_version = package.installed_version package.state = 'installed' for kind in ('init', 'demo', 'update'): if hasattr(package, kind): delattr(package, kind) if package.name is not None: registry._init_modules.add(package.name) cr.commit() _logger.log(25, "%s modules loaded in %.2fs, %s queries", len(graph), time.time() - t0, izi.sql_db.sql_counter - t0_sql) registry.clear_caches() cr.commit() return loaded_modules, processed_modules
def to_python(self, value): _uid = RequestUID(value=value, converter=self) env = api.Environment(request.cr, _uid, request.context) return env[self.model].browse(int(v) for v in value.split(','))