def _acquire_job(self, db_name, cleanup=False): import odoo.addons.base as base acquired = base.ir.ir_cron.ir_cron._acquire_job(db_name) if cleanup: Registry.delete(db_name) close_db(db_name) return acquired
def new_dump_db(db_name, stream, backup_format='zip', anonymized=True): if anonymized: with Registry.new(db_name).cursor() as cr: env = api.Environment(cr, SUPERUSER_ID, {}) anon_query = env['ir.model.fields'].get_anonymization_query() if not anon_query: db._logger.info("No data to anonymize in database `%s`.", db_name) else: db._logger.info('Anonymize and dump database `%s`.', db_name) anon_db_name = '%s_anon_%s' % (db_name, time.strftime('%Y%m%d_%H%M%S')) db.exp_duplicate_database(db_name, anon_db_name) try: if backup_format == 'zip': # To avoid to archive filestore # with non-anonymized attachments anon_fs = tools.config.filestore(anon_db_name) shutil.rmtree(anon_fs, ignore_errors=True) with Registry.new(anon_db_name).cursor() as cr: db._logger.info('ANONYMIZE DB: %s', anon_db_name) cr.execute(anon_query) except Exception: db.exp_drop(anon_db_name) return NewDbDump(anon_db_name, stream, backup_format) return native_dump_db(db_name, stream, backup_format)
def install_modules(self): """Set all selected modules and actually install them.""" self.ensure_one() self.module_ids.write({"state": "to install"}) self.env.cr.commit() # pylint: disable=invalid-commit Registry.new(self.env.cr.dbname, update_module=True) self.write({"state": "done"}) return self.return_same_form_view()
def export(ctx, language, db_name, module, fix): modules = module or ['all'] from odoo.modules.registry import Registry from odooku.api import environment from odoo.tools import trans_export with tempfile.TemporaryFile() as t: # Perform checks (and possible fixes) registry = Registry(db_name) with registry.cursor() as cr: with environment(cr) as env: lang = env['res.lang'].with_context( dict(active_test=False)).search([('code', '=', language)]) if not lang: raise ValueError("Language %s does not exist" % language) if not lang[0].active: if not fix: raise ValueError("Language %s is not activated" % language) else: installed = env['ir.module.module'].search([ ('state', '=', 'installed') ]) installed._update_translations(language) if module: installed = env['ir.module.module'].search([ ('name', 'in', module), ('state', '=', 'installed') ]) missing = set(module) - set( [mod.name for mod in installed]) if missing: if not fix: raise ValueError("Modules '%s' are not installed" % ", ".join(missing)) else: ctx.obj['config']['init'] = { module_name: 1 for module_name in module } # Export registry = Registry.new(db_name, update_module=fix) with registry.cursor() as cr: with environment(cr) as env: trans_export(language, modules, t, 'po', cr) t.seek(0) # Pipe to stdout while True: chunk = t.read(CHUNK_SIZE) if not chunk: break sys.stdout.buffer.write(chunk)
def newdbuuid(ctx, db_name): config = (ctx.obj['config']) from odoo.modules.registry import Registry from odooku.api import environment registry = Registry(db_name) with registry.cursor() as cr: with environment(cr) as env: env['ir.config_parameter'].init(force=True)
def create_user(self, login_name, help_id, db_name): result = {} result['is_success'] = True registry = Registry(db_name) cr = registry.cursor() env = api.Environment(cr, SUPERUSER_ID, {}) user_id = env['res.users'].create_wechat_mini_user(login_name, help_id) result['user_id'] = user_id cr.commit() cr.close() return json.dumps(result)
def test_02_uninstall(self): """ Check a few things showing the module is uninstalled. """ with environment() as env: module = env['ir.module.module'].search([('name', '=', MODULE)]) assert len(module) == 1 module.button_uninstall() Registry.new(common.get_db_name(), update_module=True) with environment() as env: self.assertNotIn('test_uninstall.model', env.registry) self.assertFalse(env['ir.model.data'].search([('module', '=', MODULE)])) self.assertFalse(env['ir.model.fields'].search([('model', '=', MODEL)]))
def setUp(self): super(TestAdvisoryLock, self).setUp() self.registry2 = Registry(common.get_db_name()) self.cr2 = self.registry2.cursor() self.env2 = api.Environment(self.cr2, self.env.uid, {}) @self.addCleanup def reset_cr2(): # rollback and close the cursor, and reset the environments self.env2.reset() self.cr2.rollback() self.cr2.close()
def test_01_install(self): """ Check a few things showing the module is installed. """ with environment() as env: module = env["ir.module.module"].search([("name", "=", MODULE)]) assert len(module) == 1 module.button_install() Registry.new(common.get_db_name(), update_module=True) with environment() as env: self.assertIn("test_uninstall.model", env.registry) self.assertTrue(env["ir.model.data"].search([("module", "=", MODULE)])) self.assertTrue(env["ir.model.fields"].search([("model", "=", MODEL)]))
def install_all(self): """ Main wizard step. Set all installable modules to install and actually install them. Exclude testing modules. """ modules = self.env['ir.module.module'].search([ ('state', 'not in', ['installed', 'uninstallable', 'unknown']), ('category_id.name', '!=', 'Tests'), ('name', 'not in', BLACKLIST_MODULES), ]) if modules: modules.write({'state': 'to install'}) self.env.cr.commit() Registry.new(self.env.cr.dbname, update_module=True) self.write({'state': 'ready'}) return True
def generate(self): """ Main wizard step. Make sure that all modules are up-to-date, then reinitialize all installed modules. Equivalent of running the server with '-d <database> --init all' The goal of this is to fill the records table. TODO: update module list and versions, then update all modules? """ # Truncate the records table if (openupgrade_tools.table_exists( self.env.cr, 'openupgrade_attribute') and openupgrade_tools.table_exists( self.env.cr, 'openupgrade_record')): self.env.cr.execute( 'TRUNCATE openupgrade_attribute, openupgrade_record;' ) # Need to get all modules in state 'installed' modules = self.env['ir.module.module'].search( [('state', 'in', ['to install', 'to upgrade'])]) if modules: self.env.cr.commit() Registry.new(self.env.cr.dbname, update_module=True) # Did we succeed above? modules = self.env['ir.module.module'].search( [('state', 'in', ['to install', 'to upgrade'])]) if modules: raise UserError( "Cannot seem to install or upgrade modules %s" % ( ', '.join([module.name for module in modules]))) # Now reinitialize all installed modules self.env['ir.module.module'].search( [('state', '=', 'installed')]).write( {'state': 'to install'}) self.env.cr.commit() Registry.new(self.env.cr.dbname, update_module=True) # Set noupdate property from ir_model_data self.env.cr.execute( """ UPDATE openupgrade_record our SET noupdate = imd.noupdate FROM ir_model_data imd WHERE our.type = 'xmlid' AND our.model = imd.model AND our.name = imd.module || '.' || imd.name """) self.env.invalidate([ (self.env['openupgrade.record']._fields['noupdate'], None), ]) return self.write({'state': 'ready'})
def setUp(self): super().setUp() self.registry2 = Registry(common.get_db_name()) self.cr2 = self.registry2.cursor() self.env2 = api.Environment(self.cr2, self.env.uid, {}) @self.addCleanup def reset_cr2(): # rollback and close the cursor, and reset the environments self.env2.reset() self.cr2.rollback() self.cr2.close() self.backend2 = self.env2['infor.backend'].browse(self.backend.id)
def authenticate(token): try: a = 4 - len(token) % 4 if a != 0: token += '==' if a == 2 else '=' SERVER, db, login, uid, ts = base64.urlsafe_b64decode( str(token)).split(',') if int(ts) + 60 * 60 * 24 * 7 * 10 < time.time(): return False registry = Registry(db) cr = registry.cursor() env = api.Environment(cr, int(uid), {}) except Exception as e: return str(e) return env
def __enter__(self): """ Context enter function. Temporarily add odoo 10 server path to system path and pop afterwards. Import odoo 10 server from path as library. Init logger, registry and environment. Add addons path to config. :returns Odoo10Context: This instance """ sys.path.append(self.server_path) from odoo import netsvc, api from odoo.modules.registry import Registry from odoo.tools import trans_export, config, trans_load_data self.trans_export = trans_export self.trans_load_data = trans_load_data sys.path.pop() netsvc.init_logger() config['addons_path'] = ( config.get('addons_path') + ',' + self.addons_path ) registry = Registry.new(self.dbname) self.environment_manage = api.Environment.manage() self.environment_manage.__enter__() self.cr = registry.cursor() return self
class TestLocker(InforTestCase): def setUp(self): super().setUp() self.registry2 = Registry(common.get_db_name()) self.cr2 = self.registry2.cursor() self.env2 = api.Environment(self.cr2, self.env.uid, {}) @self.addCleanup def reset_cr2(): # rollback and close the cursor, and reset the environments self.env2.reset() self.cr2.rollback() self.cr2.close() self.backend2 = self.env2['infor.backend'].browse(self.backend.id) def test_lock(self): """Lock a record""" main_partner = self.env.ref('base.main_partner') work = WorkContext(model_name='res.partner', collection=self.backend) locker = work.component_by_name('infor.record.locker') locker.lock(main_partner) main_partner2 = self.env2.ref('base.main_partner') work2 = WorkContext(model_name='res.partner', collection=self.backend2) locker2 = work2.component_by_name('infor.record.locker') with self.assertRaises(RetryableJobError): locker2.lock(main_partner2)
class TestLocker(TransactionComponentRegistryCase): def setUp(self): super().setUp() self.backend = mock.MagicMock(name="backend") self.backend.env = self.env self.registry2 = Registry(common.get_db_name()) self.cr2 = self.registry2.cursor() self.env2 = api.Environment(self.cr2, self.env.uid, {}) self.backend2 = mock.MagicMock(name="backend2") self.backend2.env = self.env2 @self.addCleanup def reset_cr2(): # rollback and close the cursor, and reset the environments self.env2.reset() self.cr2.rollback() self.cr2.close() def test_lock(self): """Lock a record""" main_partner = self.env.ref("base.main_partner") work = WorkContext(model_name="res.partner", collection=self.backend) work.component("record.locker").lock(main_partner) main_partner2 = self.env2.ref("base.main_partner") work2 = WorkContext(model_name="res.partner", collection=self.backend2) locker2 = work2.component("record.locker") with self.assertRaises(RetryableJobError): locker2.lock(main_partner2)
def __new__(cls, cr, uid, context, su=False): if uid == SUPERUSER_ID: su = True assert context is not None args = (cr, uid, context, su) # determine transaction object transaction = cr.transaction if transaction is None: transaction = cr.transaction = Transaction(Registry(cr.dbname)) # if env already exists, return it for env in transaction.envs: if env.args == args: return env # otherwise create environment, and add it in the set self = object.__new__(cls) args = (cr, uid, frozendict(context), su) self.cr, self.uid, self.context, self.su = self.args = args self.transaction = self.all = transaction self.registry = transaction.registry self.cache = transaction.cache self._cache_key = {} # memo {field: cache_key} self._protected = transaction.protected transaction.envs.add(self) return self
def update(ctx, db_name, module, language, overwrite): context = {'overwrite': overwrite} from odoo.modules.registry import Registry from odooku.api import environment domain = [('state', '=', 'installed')] if module: domain = [('name', 'in', module)] for db in db_name: registry = Registry(db) with registry.cursor() as cr: with environment(cr) as env: mods = env['ir.module.module'].search(domain) mods.with_context( overwrite=overwrite)._update_translations(language)
def setUp(self): super().setUp() self.backend = mock.MagicMock(name="backend") self.backend.env = self.env self.registry2 = Registry(common.get_db_name()) self.cr2 = self.registry2.cursor() self.env2 = api.Environment(self.cr2, self.env.uid, {}) self.backend2 = mock.MagicMock(name="backend2") self.backend2.env = self.env2 @self.addCleanup def reset_cr2(): # rollback and close the cursor, and reset the environments self.env2.reset() self.cr2.rollback() self.cr2.close()
def _update_registry(self): """ Update the registry after a modification on action rules. """ if self.env.registry.ready and not self.env.context.get('import_file'): # for the sake of simplicity, simply force the registry to reload self._cr.commit() self.env.reset() registry = Registry.new(self._cr.dbname) registry.registry_invalidated = True
def shell(ctx, input_file, db_name): from odoo.modules.registry import Registry from odooku.api import environment registry = Registry(db_name) with registry.cursor() as cr: with environment(cr) as env: context = { 'env': env, 'self': env.user } args = [] if input_file is not None: args = [input_file] bpython.embed(context, args=args, banner='Odooku shell')
def _update_registry(self): """ Update the registry after a modification on action rules. """ if self.env.registry.ready: # for the sake of simplicity, simply force the registry to reload self._cr.commit() self.env.reset() registry = Registry.new(self._cr.dbname) registry.signal_registry_change()
class TestAdvisoryLock(TransactionComponentCase): def setUp(self): super(TestAdvisoryLock, self).setUp() self.registry2 = Registry(common.get_db_name()) self.cr2 = self.registry2.cursor() self.env2 = api.Environment(self.cr2, self.env.uid, {}) @self.addCleanup def reset_cr2(): # rollback and close the cursor, and reset the environments self.env2.reset() self.cr2.rollback() self.cr2.close() def test_concurrent_lock(self): """ 2 concurrent transactions cannot acquire the same lock """ # the lock is based on a string, a second transaction trying # to acquire the same lock won't be able to acquire it lock = 'import_record({}, {}, {}, {})'.format( 'backend.name', 1, 'res.partner', '999999', ) acquired = pg_try_advisory_lock(self.env, lock) self.assertTrue(acquired) # we test the base function inner_acquired = pg_try_advisory_lock(self.env2, lock) self.assertFalse(inner_acquired) def test_concurrent_import_lock(self): """ A 2nd concurrent transaction must retry """ # the lock is based on a string, a second transaction trying # to acquire the same lock won't be able to acquire it lock = 'import_record({}, {}, {}, {})'.format( 'backend.name', 1, 'res.partner', '999999', ) backend = mock.MagicMock() backend.env = self.env work = WorkContext(model_name='res.partner', collection=backend) # we test the function through a Component instance component = work.component_by_name('base.connector') # acquire the lock component.advisory_lock_or_retry(lock) # instanciate another component using a different odoo env # hence another PG transaction backend2 = mock.MagicMock() backend2.env = self.env2 work2 = WorkContext(model_name='res.partner', collection=backend2) component2 = work2.component_by_name('base.connector') with self.assertRaises(RetryableJobError) as cm: component2.advisory_lock_or_retry(lock, retry_seconds=3) self.assertEqual(cm.exception.seconds, 3)
def cenit_post(self, action, root=None): status_code = 400 environ = request.httprequest.headers.environ.copy() key = environ.get('HTTP_X_USER_ACCESS_KEY', False) token = environ.get('HTTP_X_USER_ACCESS_TOKEN', False) db_name = environ.get('HTTP_TENANT_DB', False) if not db_name: host = environ.get('HTTP_HOST', "") db_name = host.replace(".", "_").split(":")[0] registry = Registry(db_name) with registry.cursor() as cr: connection_model = registry['cenit.connection'] domain = [('key', '=', key), ('token', '=', token)] _logger.info( "Searching for a 'cenit.connection' with key '%s' and " "matching token", key) rc = connection_model.search(cr, SUPERUSER_ID, domain) _logger.info("Candidate connections: %s", rc) if rc: p = inflect.engine() flow_model = registry['cenit.flow'] context = {'sender': 'client', 'action': action} if root is None: for root, data in request.jsonrequest.items(): root = p.singular_noun(root) or root rc = flow_model.receive(cr, SUPERUSER_ID, root, data, context) if rc: status_code = 200 else: root = p.singular_noun(root) or root rc = flow_model.receive(cr, SUPERUSER_ID, root, request.jsonrequest, context) if rc: status_code = 200 else: status_code = 404 return {'status': status_code}
def reset(self): """ Reset the transaction. This clears the transaction, and reassigns the registry on all its environments. This operation is strongly recommended after reloading the registry. """ self.registry = Registry(self.registry.db_name) for env in self.envs: env.registry = self.registry lazy_property.reset_all(env) self.clear()
def preload(ctx, db_name, module, demo_data): config = (ctx.obj['config']) from odoo.modules.registry import Registry if module: modules = {module_name: 1 for module_name in module} config['init'] = dict(modules) registry = Registry.new(db_name, force_demo=demo_data, update_module=True)
def update(ctx, db_name, module, init): config = (ctx.obj['config']) from odoo.modules.registry import Registry config['init' if init else 'update'] = { module_name: 1 for module_name in module or ['all'] } for db in db_name: registry = Registry.new(db, update_module=True)
def cron_folder_auto_classification(self, path=False, processing_path=False, limit=False): if not path: path = (self.env["ir.config_parameter"].sudo().get_param( "document_quick_access_auto_classification.path", default=False)) if not path: return False if not processing_path and not self.env.context.get( "ignore_process_path"): processing_path = ( self.env["ir.config_parameter"].sudo().get_param( "document_quick_access_auto_classification.process_path", default=False, )) elements = [ os.path.join(path, f) for f in os.listdir(path) if os.path.isfile(os.path.join(path, f)) ] if limit: elements = elements[:limit] for element in elements: obj = self new_element = element if processing_path: new_cr = Registry(self.env.cr.dbname).cursor() try: if processing_path: new_element = os.path.join(processing_path, os.path.basename(element)) shutil.copy(element, new_element) obj = (api.Environment( new_cr, self.env.uid, self.env.context)[self._name].browse().with_delay( **self._delay_vals())) obj._process_document(new_element) if processing_path: new_cr.commit() except Exception: if processing_path: os.unlink(new_element) new_cr.rollback() raise finally: if processing_path: new_cr.close() if processing_path: os.unlink(element) return True
def execute(conf_attrs, dbname, uid, obj, method, *args, **kwargs): _logger.info(str([dbname, uid, obj, method, args, kwargs])) if conf_attrs and len(conf_attrs.keys()) > 1: for attr, value in conf_attrs.items(): odoo.tools.config[attr] = value with Environment.manage(): registry = Registry(dbname) cr = registry.cursor() context = 'context' in kwargs and kwargs.pop('context') or {} env = Environment(cr, uid, context) cr.autocommit(True) # odoo.api.Environment._local.environments = env try: Model = env[obj] args = list(args) _logger.info('>>> %s' % str(args)) ids = args.pop(0) if ids: target = Model.search([('id', 'in', ids)]) else: target = Model getattr(env.registry[obj], method)(target, *args, **kwargs) # Commit only when function finish # env.cr.commit() except Exception as exc: env.cr.rollback() import traceback traceback.print_exc() raise exc #try: # raise execute.retry( # queue=execute.request.delivery_info['routing_key'], # exc=exc, countdown=(execute.request.retries + 1) * 60, # max_retries=5) #except Exception as retry_exc: # raise retry_exc finally: env.cr.close() return True
def cron_move_documents(self, limit=False, path=False): if not path: path = (self.env["ir.config_parameter"].sudo().get_param( "hash_search_document_scanner_queue.preprocess_path", default=False, )) dest_path = (self.env["ir.config_parameter"].sudo().get_param( "hash_search_document_scanner.path", default=False)) if not path or not dest_path: return False elements = [ os.path.join(path, f) for f in os.listdir(path) if os.path.isfile(os.path.join(path, f)) ] if limit: elements = elements[:limit] min_time = int(time.time()) - 60 single_commit = self.env.context.get("scanner_single_commit", False) for element in elements: if os.path.getmtime( element) > min_time and not self.env.context.get( "scanner_ignore_time", False): continue filename = os.path.basename(element) new_element = os.path.join(dest_path, filename) shutil.copy(element, new_element) if not single_commit: new_cr = Registry(self.env.cr.dbname).cursor() try: if not single_commit: obj = (api.Environment( new_cr, self.env.uid, self.env.context)[self._name].browse().with_delay()) else: obj = self.env[self._name].browse() obj.process_document(new_element) if not single_commit: new_cr.commit() except Exception: os.unlink(new_element) if not single_commit: new_cr.rollback() # error, rollback everything atomically raise finally: if not single_commit: new_cr.close() os.unlink(element) return True
def import_(ctx, language, db_name, overwrite): context = {'overwrite': overwrite} from odoo.modules.registry import Registry from odooku.api import environment from odoo.tools import trans_load with tempfile.NamedTemporaryFile(suffix='.po', delete=False) as t: registry = Registry(db_name) # Read from stdin while True: chunk = sys.stdin.buffer.read(CHUNK_SIZE) if not chunk: break t.write(chunk) t.close() with registry.cursor() as cr: with environment(cr) as env: trans_load(cr, t.name, language, context=context) os.unlink(t.name)
def preload_registries(dbnames): """ Preload a registries, possibly run a test file.""" # TODO: move all config checks to args dont check tools.config here dbnames = dbnames or [] rc = 0 for dbname in dbnames: try: update_module = config['init'] or config['update'] registry = Registry.new(dbname, update_module=update_module) # run test_file if provided if config['test_file']: test_file = config['test_file'] _logger.info('loading test file %s', test_file) with odoo.api.Environment.manage(): if test_file.endswith('yml'): load_test_file_yml(registry, test_file) elif test_file.endswith('py'): load_test_file_py(registry, test_file) # run post-install tests if config['test_enable']: t0 = time.time() t0_sql = odoo.sql_db.sql_counter module_names = (registry.updated_modules if update_module else registry._init_modules) with odoo.api.Environment.manage(): for module_name in module_names: result = run_unit_tests(module_name, registry.db_name, position=runs_post_install) registry._assertion_report.record_result(result) _logger.info("All post-tested in %.2fs, %s queries", time.time() - t0, odoo.sql_db.sql_counter - t0_sql) if registry._assertion_report.failures: rc += 1 except Exception: _logger.critical('Failed to initialize database `%s`.', dbname, exc_info=True) return -1 return rc