def convert_domain(self, domain, tables, Model): from trytond.ir.lang import get_parent_language pool = Pool() Translation = pool.get('ir.translation') IrModel = pool.get('ir.model') if not self.translate: return super(FieldTranslate, self).convert_domain(domain, tables, Model) table = join = Model.__table__() model = IrModel.__table__() name, operator, value = domain language = Transaction().language column = None while language: translation = Translation.__table__() join = self._get_translation_join(Model, name, translation, model, table, join, language) column = Coalesce(NullIf(column, ''), translation.value) language = get_parent_language(language) column = Coalesce(NullIf(column, ''), self.sql_column(table)) column = self._domain_column(operator, column) Operator = SQL_OPERATORS[operator] assert name == self.name where = Operator(column, self._domain_value(operator, value)) if isinstance(where, operators.In) and not where.right: where = Literal(False) elif isinstance(where, operators.NotIn) and not where.right: where = Literal(True) where = self._domain_add_null(column, operator, value, where) return tables[None][0].id.in_(join.select(table.id, where=where))
def _get_translation_order(self, tables, Model, name): from trytond.ir.lang import get_parent_language pool = Pool() Translation = pool.get('ir.translation') IrModel = pool.get('ir.model') table, _ = tables[None] join = table language = Transaction().language column = None while language: key = name + '.translation-' + language if key not in tables: translation = Translation.__table__() model = IrModel.__table__() translation, join = self._get_translation_join( Model, name, translation, model, table, table, language) if join.left == table: tables[key] = { None: (join.right, join.condition), } else: tables[key] = { None: (join.left.right, join.left.condition), 'translation': { None: (join.right, join.condition), }, } else: if 'translation' not in tables[key]: translation, _ = tables[key][None] else: translation, _ = tables[key]['translation'][None] column = Coalesce(NullIf(column, ''), translation.value) language = get_parent_language(language) return column
def _get_translation_column(self, Model, name): from trytond.ir.lang import get_parent_language pool = Pool() Translation = pool.get('ir.translation') IrModel = pool.get('ir.model') table = join = Model.__table__() model = IrModel.__table__() language = Transaction().language column = None while language: translation = Translation.__table__() translation, join = self._get_translation_join( Model, name, translation, model, table, join, language) column = Coalesce(NullIf(column, ''), translation.value) language = get_parent_language(language) return table, join, column
def __call__(self, text): from trytond.ir.lang import get_parent_language if self.language not in self.cache: cache = self.cache[self.language] = {} code = self.language while code: # Order to get empty module/custom report first translations = self.translation.search([ ('lang', '=', code), ('type', '=', 'report'), ('name', '=', self.report_name), ('value', '!=', ''), ('value', '!=', None), ('fuzzy', '=', False), ('res_id', '=', -1), ], order=[('module', 'DESC')]) for translation in translations: cache.setdefault(translation.src, translation.value) code = get_parent_language(code) return self.cache[self.language].get(text, text)
def load_module_graph(graph, pool, update=None, lang=None): # Prevent to import backend when importing module from trytond.cache import Cache from trytond.ir.lang import get_parent_language if lang is None: lang = [config.get('database', 'language')] if update is None: update = [] modules_todo = [] models_to_update_history = set() # Load also parent languages lang = set(lang) for code in list(lang): while code: lang.add(code) code = get_parent_language(code) transaction = Transaction() with transaction.connection.cursor() as cursor: modules = [x.name for x in graph] module2state = dict() for sub_modules in tools.grouped_slice(modules): cursor.execute( *ir_module.select(ir_module.name, ir_module.state, where=ir_module.name.in_(list(sub_modules)))) module2state.update(cursor) modules = set(modules) for node in graph: module = node.name if module not in MODULES: continue logger.info(module) classes = pool.fill(module, modules) if update: pool.setup(classes) package_state = module2state.get(module, 'not activated') if (is_module_to_install(module, update) or (update and package_state in ('to activate', 'to upgrade'))): if package_state not in ('to activate', 'to upgrade'): if package_state == 'activated': package_state = 'to upgrade' elif package_state != 'to remove': package_state = 'to activate' for child in node: module2state[child.name] = package_state for type in list(classes.keys()): for cls in classes[type]: logger.info('%s:register %s', module, cls.__name__) cls.__register__(module) for model in classes['model']: if hasattr(model, '_history'): models_to_update_history.add(model.__name__) # Instanciate a new parser for the module tryton_parser = convert.TrytondXmlHandler( pool, module, package_state, modules, lang) for filename in node.info.get('xml', []): filename = filename.replace('/', os.sep) logger.info('%s:loading %s', module, filename) # Feed the parser with xml content: with tools.file_open(OPJ(module, filename), 'rb') as fp: tryton_parser.parse_xmlstream(fp) modules_todo.append((module, list(tryton_parser.to_delete))) load_translations(pool, node, lang) if package_state == 'to remove': continue cursor.execute(*ir_module.select( ir_module.id, where=(ir_module.name == module))) try: module_id, = cursor.fetchone() cursor.execute( *ir_module.update([ir_module.state], ['activated'], where=(ir_module.id == module_id))) except TypeError: cursor.execute(*ir_module.insert([ ir_module.create_uid, ir_module.create_date, ir_module.name, ir_module.state ], [ [0, CurrentTimestamp(), module, 'activated'], ])) module2state[module] = 'activated' # Avoid clearing cache to prevent dead lock on ir.cache table Cache.rollback(transaction) transaction.commit() # Clear transaction cache to update default_factory transaction.cache.clear() if not update: pool.setup() else: # Remove unknown models and fields Model = pool.get('ir.model') Model.clean() ModelField = pool.get('ir.model.field') ModelField.clean() transaction.commit() pool.setup_mixin(modules) for model_name in models_to_update_history: model = pool.get(model_name) if model._history: logger.info('history:update %s', model.__name__) model._update_history_table() # Vacuum : while modules_todo: (module, to_delete) = modules_todo.pop() convert.post_import(pool, module, to_delete) # Ensure cache is clear for other instances Cache.clear_all() Cache.refresh_pool(transaction) logger.info('all modules loaded')
def load_module_graph(graph, pool, update=None, lang=None): from trytond.ir.lang import get_parent_language if lang is None: lang = [config.get('database', 'language')] if update is None: update = [] modules_todo = [] models_to_update_history = set() # Load also parent languages lang = set(lang) for code in list(lang): while code: lang.add(code) code = get_parent_language(code) with Transaction().connection.cursor() as cursor: modules = [x.name for x in graph] cursor.execute(*ir_module.select(ir_module.name, ir_module.state, where=ir_module.name.in_(modules))) module2state = dict(cursor.fetchall()) for package in graph: module = package.name if module not in MODULES: continue logger.info(module) classes = pool.fill(module) if update: pool.setup(classes) package_state = module2state.get(module, 'not activated') if (is_module_to_install(module, update) or (update and package_state in ('to activate', 'to upgrade'))): if package_state not in ('to activate', 'to upgrade'): if package_state == 'activated': package_state = 'to upgrade' elif package_state != 'to remove': package_state = 'to activate' for child in package.childs: module2state[child.name] = package_state for type in classes.keys(): for cls in classes[type]: logger.info('%s:register %s', module, cls.__name__) cls.__register__(module) for model in classes['model']: if hasattr(model, '_history'): models_to_update_history.add(model.__name__) # Instanciate a new parser for the package: tryton_parser = convert.TrytondXmlHandler( pool=pool, module=module, module_state=package_state) for filename in package.info.get('xml', []): filename = filename.replace('/', os.sep) logger.info('%s:loading %s', module, filename) # Feed the parser with xml content: with tools.file_open(OPJ(module, filename), 'rb') as fp: tryton_parser.parse_xmlstream(fp) modules_todo.append((module, list(tryton_parser.to_delete))) localedir = '%s/%s' % (package.info['directory'], 'locale') lang2filenames = defaultdict(list) for filename in itertools.chain( iglob('%s/*.po' % localedir), iglob('%s/override/*.po' % localedir)): filename = filename.replace('/', os.sep) lang2 = os.path.splitext(os.path.basename(filename))[0] if lang2 not in lang: continue lang2filenames[lang2].append(filename) base_path_position = len(package.info['directory']) + 1 for language, files in lang2filenames.iteritems(): filenames = [f[base_path_position:] for f in files] logger.info('%s:loading %s', module, ','.join(filenames)) Translation = pool.get('ir.translation') Translation.translation_import(language, module, files) if package_state == 'to remove': continue cursor.execute(*ir_module.select( ir_module.id, where=(ir_module.name == package.name))) try: module_id, = cursor.fetchone() cursor.execute( *ir_module.update([ir_module.state], ['activated'], where=(ir_module.id == module_id))) except TypeError: cursor.execute(*ir_module.insert([ ir_module.create_uid, ir_module.create_date, ir_module.name, ir_module.state ], [ [0, CurrentTimestamp(), package.name, 'activated'], ])) module2state[package.name] = 'activated' Transaction().connection.commit() if not update: pool.setup() pool.setup_mixin(modules) for model_name in models_to_update_history: model = pool.get(model_name) if model._history: logger.info('history:update %s', model.__name__) model._update_history_table() # Vacuum : while modules_todo: (module, to_delete) = modules_todo.pop() convert.post_import(pool, module, to_delete) logger.info('all modules loaded')