Beispiel #1
0
    def __register__(cls, module_name):
        super(Wizard, cls).__register__(module_name)
        pool = Pool()
        Translation = pool.get('ir.translation')
        cursor = Transaction().cursor
        for state_name, state in cls.states.iteritems():
            if isinstance(state, StateView):
                for button in state.buttons:
                    cursor.execute('SELECT id, name, src '
                        'FROM ir_translation '
                        'WHERE module = %s '
                            'AND lang = %s '
                            'AND type = %s '
                            'AND name = %s',
                        (module_name, 'en_US', 'wizard_button',
                            cls.__name__ + ',' + state_name + ',' +
                            button.state))
                    res = cursor.dictfetchall()
                    src_md5 = Translation.get_src_md5(button.string)
                    if not res:
                        cursor.execute('INSERT INTO ir_translation '
                            '(name, lang, type, src, src_md5, value, module, '
                                'fuzzy) '
                            'VALUES (%s, %s, %s, %s, %s, %s, %s, %s)',
                            (cls.__name__ + ',' + state_name + ',' +
                                button.state,
                                'en_US', 'wizard_button', button.string,
                                src_md5, '', module_name, False))
                    elif res[0]['src'] != button.string:
                        cursor.execute('UPDATE ir_translation '
                            'SET src = %s, src_md5 = %s '
                            'WHERE id = %s',
                            (button.string, src_md5, res[0]['id']))

        cursor.execute('SELECT id, src FROM ir_translation '
            'WHERE lang = %s '
                'AND type = %s '
                'AND name = %s',
            ('en_US', 'error', cls.__name__))
        trans_error = {}
        for trans in cursor.dictfetchall():
            trans_error[trans['src']] = trans

        for error in cls._error_messages.values():
            if error not in trans_error:
                error_md5 = Translation.get_src_md5(error)
                cursor.execute('INSERT INTO ir_translation '
                    '(name, lang, type, src, src_md5,  value, module, fuzzy) '
                    'VALUES (%s, %s, %s, %s, %s, %s, %s, %s)',
                    (cls.__name__, 'en_US', 'error', error, error_md5, '',
                        module_name, False))
Beispiel #2
0
    def do_update(self, action):
        pool = Pool()
        Translation = pool.get('ir.translation')

        cursor = Transaction().cursor
        lang = self.start.language.code
        translation = Translation.__table__()

        types = ['nereid_template', 'wtforms', 'nereid']
        columns = [
            translation.name.as_('name'),
            translation.res_id.as_('res_id'),
            translation.type.as_('type'),
            translation.src.as_('src'),
            translation.module.as_('module'),
            translation.comments.as_('comments'),
        ]
        cursor.execute(*(
            translation.select(
                *columns,
                where=(translation.lang == 'en_US') &
                translation.type.in_(types)) -
            translation.select(
                *columns,
                where=(translation.lang == lang) &
                translation.type.in_(types))
        ))
        to_create = []
        for row in cursor.dictfetchall():
            to_create.append({
                'name': row['name'],
                'res_id': row['res_id'],
                'lang': lang,
                'type': row['type'],
                'src': row['src'],
                'module': row['module'],
                'comments': row['comments'],
            })
        if to_create:
            with Transaction().set_user(0):
                Translation.create(to_create)
        return super(TranslationUpdate, self).do_update(action)
    def init(self, module_name):
        """
        Add model in ir.model and ir.model.field.

        :param module_name: the module name
        """
        translation_obj = Pool().get('ir.translation')

        cursor = Transaction().cursor
        # Add model in ir_model
        cursor.execute("SELECT id FROM ir_model WHERE model = %s",
                (self._name,))
        model_id = None
        if cursor.rowcount == -1 or cursor.rowcount is None:
            data = cursor.fetchone()
            if data:
                model_id, = data
        elif cursor.rowcount != 0:
            model_id, = cursor.fetchone()
        if not model_id:
            cursor.execute("INSERT INTO ir_model " \
                    "(model, name, info, module) VALUES (%s, %s, %s, %s)",
                    (self._name, self._description, self.__doc__,
                        module_name))
            cursor.execute("SELECT id FROM ir_model WHERE model = %s",
                    (self._name,))
            (model_id,) = cursor.fetchone()
        else:
            cursor.execute('UPDATE ir_model ' \
                    'SET name = %s, ' \
                        'info = %s ' \
                    'WHERE id = %s',
                    (self._description, self.__doc__, model_id))

        # Update translation of model
        for name, src in [(self._name + ',name', self._description)]:
            cursor.execute('SELECT id FROM ir_translation '
                'WHERE lang = %s '
                    'AND type = %s '
                    'AND name = %s '
                    'AND (res_id IS NULL OR res_id = %s)',
                ('en_US', 'model', name, 0))
            trans_id = None
            if cursor.rowcount == -1 or cursor.rowcount is None:
                data = cursor.fetchone()
                if data:
                    trans_id, = data
            elif cursor.rowcount != 0:
                trans_id, = cursor.fetchone()
            src_md5 = translation_obj.get_src_md5(src)
            if trans_id is None:
                cursor.execute('INSERT INTO ir_translation '
                    '(name, lang, type, src, src_md5, value, module, fuzzy) '
                    'VALUES (%s, %s, %s, %s, %s, %s, %s, %s)',
                    (name, 'en_US', 'model', src, src_md5, '', module_name,
                        False))
            else:
                cursor.execute('UPDATE ir_translation '
                    'SET src = %s, src_md5 = %s '
                    'WHERE id = %s',
                        (src, src_md5, trans_id))

        # Add field in ir_model_field and update translation
        cursor.execute('SELECT f.id AS id, f.name AS name, ' \
                    'f.field_description AS field_description, ' \
                    'f.ttype AS ttype, f.relation AS relation, ' \
                    'f.module as module, f.help AS help '\
                'FROM ir_model_field AS f, ir_model AS m ' \
                'WHERE f.model = m.id ' \
                    'AND m.model = %s ',
                        (self._name,))
        model_fields = {}
        for field in cursor.dictfetchall():
            model_fields[field['name']] = field

        # Prefetch field translations
        if self._columns:
            cursor.execute('SELECT id, name, src, type FROM ir_translation ' \
                    'WHERE lang = %s ' \
                        'AND type IN (%s, %s, %s) ' \
                        'AND name IN ' \
                            '(' + ','.join(('%s',) * len(self._columns)) + ')',
                            ('en_US', 'field', 'help', 'selection') + \
                                    tuple([self._name + ',' + x \
                                        for x in self._columns]))
        trans_fields = {}
        trans_help = {}
        trans_selection = {}
        for trans in cursor.dictfetchall():
            if trans['type'] == 'field':
                trans_fields[trans['name']] = trans
            elif trans['type'] == 'help':
                trans_help[trans['name']] = trans
            elif trans['type'] == 'selection':
                trans_selection.setdefault(trans['name'], {})
                trans_selection[trans['name']][trans['src']] = trans

        for field_name in self._columns:
            field = self._columns[field_name]
            relation = ''
            if hasattr(field, 'model_name'):
                relation = field.model_name
            elif hasattr(field, 'relation_name'):
                relation = field.relation_name
            if field_name not in model_fields:
                cursor.execute("INSERT INTO ir_model_field " \
                        "(model, name, field_description, ttype, " \
                            "relation, help, module) " \
                        "VALUES (%s, %s, %s, %s, %s, %s, %s)",
                        (model_id, field_name, field.string, field._type,
                            relation, field.help, module_name))
            elif (model_fields[field_name]['field_description'] != field.string
                    or model_fields[field_name]['ttype'] != field._type
                    or model_fields[field_name]['relation'] != relation
                    or model_fields[field_name]['help'] != field.help):
                cursor.execute('UPDATE ir_model_field ' \
                        'SET field_description = %s, ' \
                            'ttype = %s, ' \
                            'relation = %s, ' \
                            'help = %s ' \
                        'WHERE id = %s ',
                        (field.string, field._type, relation,
                            field.help, model_fields[field_name]['id']))
            trans_name = self._name + ',' + field_name
            string_md5 = translation_obj.get_src_md5(field.string)
            if trans_name not in trans_fields:
                cursor.execute('INSERT INTO ir_translation '
                    '(name, lang, type, src, src_md5, value, module, fuzzy) '
                    'VALUES (%s, %s, %s, %s, %s, %s, %s, %s)',
                    (trans_name, 'en_US', 'field', field.string,
                        string_md5, '', module_name, False))
            elif trans_fields[trans_name]['src'] != field.string:
                cursor.execute('UPDATE ir_translation '
                    'SET src = %s, src_md5 = %s '
                    'WHERE id = %s ',
                    (field.string, string_md5, trans_fields[trans_name]['id']))
            help_md5 = translation_obj.get_src_md5(field.help)
            if trans_name not in trans_help:
                if field.help:
                    cursor.execute('INSERT INTO ir_translation '
                        '(name, lang, type, src, src_md5, value, module, '
                            'fuzzy) '
                        'VALUES (%s, %s, %s, %s, %s, %s, %s, %s)',
                        (trans_name, 'en_US', 'help', field.help, help_md5, '',
                            module_name, False))
            elif trans_help[trans_name]['src'] != field.help:
                cursor.execute('UPDATE ir_translation '
                    'SET src = %s, src_md5 = %s '
                    'WHERE id = %s ',
                    (field.help, help_md5, trans_help[trans_name]['id']))
            if hasattr(field, 'selection') \
                    and isinstance(field.selection, (tuple, list)) \
                    and ((hasattr(field, 'translate_selection') \
                        and field.translate_selection)
                        or not hasattr(field, 'translate_selection')):
                for (_, val) in field.selection:
                    if trans_name not in trans_selection \
                            or val not in trans_selection[trans_name]:
                        val_md5 = translation_obj.get_src_md5(val)
                        cursor.execute('INSERT INTO ir_translation '
                            '(name, lang, type, src, src_md5, value, module, '
                                'fuzzy) '
                            'VALUES (%s, %s, %s, %s, %s, %s, %s, %s)',
                            (trans_name, 'en_US', 'selection', val, val_md5,
                                '', module_name, False))
        # Clean ir_model_field from field that are no more existing.
        for field_name in model_fields:
            if model_fields[field_name]['module'] == module_name \
                    and field_name not in self._columns:
                #XXX This delete field even when it is defined later
                # in the module
                cursor.execute('DELETE FROM ir_model_field '\
                                   'WHERE id = %s',
                               (model_fields[field_name]['id'],))

        # Add error messages in ir_translation
        cursor.execute('SELECT id, src FROM ir_translation ' \
                'WHERE lang = %s ' \
                    'AND type = %s ' \
                    'AND name = %s',
                ('en_US', 'error', self._name))
        trans_error = {}
        for trans in cursor.dictfetchall():
            trans_error[trans['src']] = trans

        errors = self._get_error_messages()
        for error in set(errors):
            if error not in trans_error:
                error_md5 = translation_obj.get_src_md5(error)
                cursor.execute('INSERT INTO ir_translation '
                    '(name, lang, type, src, src_md5, value, module, fuzzy) '
                    'VALUES (%s, %s, %s, %s, %s, %s, %s, %s)',
                    (self._name, 'en_US', 'error', error, error_md5, '',
                        module_name, False))
    def check_xml(self, ids):
        "Check XML"
        pool = Pool()
        translation_obj = pool.get('ir.translation')
        cursor = Transaction().cursor
        views = self.browse(ids)
        for view in views:
            cursor.execute('SELECT id, name, src FROM ir_translation ' \
                    'WHERE lang = %s ' \
                        'AND type = %s ' \
                        'AND name = %s '\
                        'AND module = %s',
                            ('en_US', 'view', view.model, view.module))
            trans_views = {}
            for trans in cursor.dictfetchall():
                trans_views[trans['src']] = trans
            if not view.arch:
                continue
            xml = view.arch.strip()
            if not xml:
                continue
            tree = etree.fromstring(xml)

            # validate the tree using RelaxNG
            rng_name = os.path.join(os.path.dirname(__file__),
                    (view.inherit and view.inherit.type or view.type) + '.rng')
            if hasattr(etree, 'RelaxNG'):
                validator = etree.RelaxNG(file=rng_name)
                if not validator.validate(tree):
                    logger = logging.getLogger('ir')
                    error_log = reduce(lambda x, y: str(x) + '\n' + str(y),
                            validator.error_log.filter_from_errors())
                    logger.error('Invalid xml view:\n%s'
                        % (str(error_log) + '\n' + xml))
                    return False
            root_element = tree.getroottree().getroot()

            # validate pyson attributes
            validates = {
                'states': fields.states_validate,
                'domain': fields.domain_validate,
                'context': fields.context_validate,
                'digits': fields.digits_validate,
                'add_remove': fields.add_remove_validate,
            }

            def encode(element):
                for attr in ('states', 'domain', 'context', 'digits',
                        'add_remove', 'spell', 'colors'):
                    if element.get(attr):
                        try:
                            value = safe_eval(element.get(attr), CONTEXT)
                            validates.get(attr, lambda a: True)(value)
                        except Exception, e:
                            logger = logging.getLogger('ir')
                            logger.error('Invalid pyson view element "%s:%s":'
                                '\n%s\n%s'
                                % (element.get('id') or element.get('name'),
                                    attr, str(e), xml))
                            return False
                for child in element:
                    if not encode(child):
                        return False
                return True
            if not encode(root_element):
                return False

            strings = self._translate_view(root_element)
            with Transaction().set_user(0):
                view_ids = self.search([
                    ('model', '=', view.model),
                    ('id', '!=', view.id),
                    ('module', '=', view.module),
                    ])
                for view2 in self.browse(view_ids):
                    tree2 = etree.fromstring(view2.arch)
                    root2_element = tree2.getroottree().getroot()
                    strings += self._translate_view(root2_element)
            if not strings:
                continue
            for string in set(strings):
                done = False
                if string in trans_views:
                    del trans_views[string]
                    continue
                string_md5 = translation_obj.get_src_md5(string)
                for string_trans in trans_views:
                    if string_trans in strings:
                        continue
                    seqmatch = SequenceMatcher(lambda x: x == ' ',
                            string, string_trans)
                    if seqmatch.ratio() == 1.0:
                        del trans_views[string_trans]
                        done = True
                        break
                    if seqmatch.ratio() > 0.6:
                        cursor.execute('UPDATE ir_translation '
                            'SET src = %s, '
                                'src_md5 = %s, '
                                'fuzzy = %s '
                            'WHERE id = %s ',
                            (string, string_md5, True,
                                trans_views[string_trans]['id']))
                        del trans_views[string_trans]
                        done = True
                        break
                if not done:
                    cursor.execute('INSERT INTO ir_translation '
                        '(name, lang, type, src, src_md5, value, module, '
                            'fuzzy) '
                        'VALUES (%s, %s, %s, %s, %s, %s, %s, %s)',
                        (view.model, 'en_US', 'view', string, string_md5, '',
                            view.module, False))
            if strings:
                cursor.execute('DELETE FROM ir_translation ' \
                        'WHERE name = %s ' \
                            'AND type = %s ' \
                            'AND module = %s ' \
                            'AND src NOT IN ' \
                                '(' + ','.join(('%s',) * len(strings)) + ')',
                        (view.model, 'view', view.module) + tuple(strings))