Example #1
0
def trans_load(cr, filename, lang, verbose=True, module_name=None, context=None):
    cr.execute("select id from ir_module_module where name=%s", (module_name,))
    module_id = cr.fetchone()[0]
    cr.execute("select id,checksum from ir_module_module_file"
               " where module_id=%s and filename=%s", (module_id, filename))
    checksum = cr.fetchone()
    module_file_id = checksum and checksum[0] or False
    checksum = checksum and checksum[1] or ''
    sha256 = hashlib.sha256()
    sha256.update(misc.file_open(filename).read())
    checksum_new = sha256.hexdigest()
    file_modified = not checksum == checksum_new
    result = None
    try:
        fileobj = misc.file_open(filename)
        _logger.info("%s %s", file_modified and 'loading' or 'no changes', filename)
        fileformat = os.path.splitext(filename)[-1][1:].lower()
        if file_modified:
            result = trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, module_name=module_name, context=context)
        fileobj.close()
    except IOError:
        if verbose:
            _logger.error("couldn't read translation file %s", filename)
    if file_modified:
        if module_file_id:
            cr.execute("update ir_module_module_file set checksum=%s, write_date=now() where id=%s",
                       (checksum_new, module_file_id))
        else:
            cr.execute(
                "insert into ir_module_module_file(filename,module_id,checksum,create_date,create_uid,write_date,write_uid)"
                " values(%s,%s,%s,now(),1,now(),1)", (filename,module_id,checksum_new))
    return result
Example #2
0
    def process_report(self, node):
        values = {}
        for dest, f in (('name','string'), ('model','model'), ('report_name','name')):
            values[dest] = getattr(node, f)
            assert values[dest], "Attribute %s of report is empty !" % (f,)
        for field,dest in (('rml','report_rml'),('file','report_rml'),('xml','report_xml'),('xsl','report_xsl'),('attachment','attachment'),('attachment_use','attachment_use')):
            if getattr(node, field):
                values[dest] = getattr(node, field)
        if node.auto:
            values['auto'] = eval(node.auto)
        if node.sxw:
            sxw_file = misc.file_open(node.sxw)
            try:
                sxw_content = sxw_file.read()
                values['report_sxw_content'] = sxw_content
            finally:
                sxw_file.close()
        if node.header:
            values['header'] = eval(node.header)
        values['multi'] = node.multi and eval(node.multi)
        xml_id = node.id
        self.validate_xml_id(xml_id)

        self._set_group_values(node, values)

        id = self.pool.get('ir.model.data')._update(self.cr, 1, "ir.actions.report.xml", \
                self.module, values, xml_id, noupdate=self.isnoupdate(node), mode=self.mode)
        self.id_map[xml_id] = int(id)

        if not node.menu or eval(node.menu):
            keyword = node.keyword or 'client_print_multi'
            value = 'ir.actions.report.xml,%s' % id
            replace = node.replace or True
            self.pool.get('ir.model.data').ir_set(self.cr, 1, 'action', \
                    keyword, values['name'], [values['model']], value, replace=replace, isobject=True, xml_id=xml_id)
Example #3
0
def convert_file(cr,
                 module,
                 filename,
                 idref,
                 mode='update',
                 noupdate=False,
                 kind=None,
                 report=None,
                 pathname=None):
    if pathname is None:
        pathname = os.path.join(module, filename)
    fp = misc.file_open(pathname)
    ext = os.path.splitext(filename)[1].lower()

    try:
        if ext == '.csv':
            convert_csv_import(cr, module, pathname, fp.read(), idref, mode,
                               noupdate)
        elif ext == '.sql':
            convert_sql_import(cr, fp)
        elif ext == '.yml':
            convert_yaml_import(cr, module, fp, kind, idref, mode, noupdate,
                                report)
        elif ext == '.xml':
            convert_xml_import(cr, module, fp, idref, mode, noupdate, report)
        elif ext == '.js':
            pass  # .js files are valid but ignored here.
        else:
            _logger.warning("Can't load unknown file type %s.", filename)
    finally:
        fp.close()
    def process_report(self, node):
        values = {}
        for dest, f in (('name','string'), ('model','model'), ('report_name','name')):
            values[dest] = getattr(node, f)
            assert values[dest], "Attribute %s of report is empty !" % (f,)
        for field,dest in (('rml','report_rml'),('file','report_rml'),('xml','report_xml'),('xsl','report_xsl'),('attachment','attachment'),('attachment_use','attachment_use')):
            if getattr(node, field):
                values[dest] = getattr(node, field)
        if node.auto:
            values['auto'] = eval(node.auto)
        if node.sxw:
            sxw_file = misc.file_open(node.sxw)
            try:
                sxw_content = sxw_file.read()
                values['report_sxw_content'] = sxw_content
            finally:
                sxw_file.close()
        if node.header:
            values['header'] = eval(node.header)
        values['multi'] = node.multi and eval(node.multi)
        xml_id = node.id
        self.validate_xml_id(xml_id)

        self._set_group_values(node, values)

        id = self.pool.get('ir.model.data')._update(self.cr, SUPERUSER_ID, "ir.actions.report.xml", \
                self.module, values, xml_id, noupdate=self.isnoupdate(node), mode=self.mode)
        self.id_map[xml_id] = int(id)

        if not node.menu or eval(node.menu):
            keyword = node.keyword or 'client_print_multi'
            value = 'ir.actions.report.xml,%s' % id
            replace = node.replace or True
            self.pool.get('ir.model.data').ir_set(self.cr, SUPERUSER_ID, 'action', \
                    keyword, values['name'], [values['model']], value, replace=replace, isobject=True, xml_id=xml_id)
Example #5
0
    def process_report(self, node):
        values = {}
        for dest, f in (("name", "string"), ("model", "model"), ("report_name", "name")):
            values[dest] = getattr(node, f)
            assert values[dest], "Attribute %s of report is empty !" % (f,)
        for field, dest in (
            ("rml", "report_rml"),
            ("file", "report_rml"),
            ("xml", "report_xml"),
            ("xsl", "report_xsl"),
            ("attachment", "attachment"),
            ("attachment_use", "attachment_use"),
        ):
            if getattr(node, field):
                values[dest] = getattr(node, field)
        if node.auto:
            values["auto"] = eval(node.auto)
        if node.sxw:
            sxw_file = misc.file_open(node.sxw)
            try:
                sxw_content = sxw_file.read()
                values["report_sxw_content"] = sxw_content
            finally:
                sxw_file.close()
        if node.header:
            values["header"] = eval(node.header)
        values["multi"] = node.multi and eval(node.multi)
        xml_id = node.id
        self.validate_xml_id(xml_id)

        self._set_group_values(node, values)

        id = self.pool["ir.model.data"]._update(
            self.cr,
            SUPERUSER_ID,
            "ir.actions.report.xml",
            self.module,
            values,
            xml_id,
            noupdate=self.isnoupdate(node),
            mode=self.mode,
        )
        self.id_map[xml_id] = int(id)

        if not node.menu or eval(node.menu):
            keyword = node.keyword or "client_print_multi"
            value = "ir.actions.report.xml,%s" % id
            replace = node.replace or True
            self.pool["ir.model.data"].ir_set(
                self.cr,
                SUPERUSER_ID,
                "action",
                keyword,
                values["name"],
                [values["model"]],
                value,
                replace=replace,
                isobject=True,
                xml_id=xml_id,
            )
Example #6
0
    def export_code_terms_from_file(fname, path, root, terms_type):
        fabsolutepath = join(root, fname)
        frelativepath = fabsolutepath[len(path):]
        module = get_module_from_path(fabsolutepath, mod_paths=mod_paths)
        is_mod_installed = module in installed_modules
        if (('all' in modules) or (module in modules)) and is_mod_installed:
            _logger.debug("Scanning code of %s at module: %s", frelativepath,
                          module)
            src_file = misc.file_open(fabsolutepath, subdir='')
            try:
                code_string = src_file.read()
            finally:
                src_file.close()
            if module in installed_modules:
                frelativepath = str("addons" + frelativepath)
            ite = re_dquotes.finditer(code_string)
            code_offset = 0
            code_line = 1
            for i in ite:
                src = i.group(1)
                if src.startswith('""'):
                    assert src.endswith(
                        '""'
                    ), "Incorrect usage of _(..) function (should contain only literal strings!) in file %s near: %s" % (
                        frelativepath, src[:30])
                    src = src[2:-2]
                else:
                    src = join_dquotes.sub(r'\1', src)
                # try to count the lines from the last pos to our place:
                code_line += code_string[code_offset:i.start(1)].count('\n')
                # now, since we did a binary read of a python source file, we
                # have to expand pythonic escapes like the interpreter does.
                src = src.decode('string_escape')
                push_translation(module, terms_type, frelativepath, code_line,
                                 encode(src))
                code_line += i.group(1).count('\n')
                code_offset = i.end(
                )  # we have counted newlines up to the match end

            ite = re_quotes.finditer(code_string)
            code_offset = 0  #reset counters
            code_line = 1
            for i in ite:
                src = i.group(1)
                if src.startswith("''"):
                    assert src.endswith(
                        "''"
                    ), "Incorrect usage of _(..) function (should contain only literal strings!) in file %s near: %s" % (
                        frelativepath, src[:30])
                    src = src[2:-2]
                else:
                    src = join_quotes.sub(r'\1', src)
                code_line += code_string[code_offset:i.start(1)].count('\n')
                src = src.decode('string_escape')
                push_translation(module, terms_type, frelativepath, code_line,
                                 encode(src))
                code_line += i.group(1).count('\n')
                code_offset = i.end(
                )  # we have counted newlines up to the match end
Example #7
0
 def f():
     time.sleep(delay)
     cr = None
     fp = None
     try:
         cr = sql_db.db_connect(db_name).cursor()
         fp = misc.file_open(file_name)
         convert_yaml_import(cr, module_name, fp, {}, 'update', True)
     finally:
         if cr: cr.close()
         if fp: fp.close()
 def f():
     time.sleep(delay)
     cr = None
     fp = None
     try:
         cr = sql_db.db_connect(db_name).cursor()
         fp = misc.file_open(file_name)
         convert_yaml_import(cr, module_name, fp, {}, 'update', True)
     finally:
         if cr: cr.close()
         if fp: fp.close()
Example #9
0
def trans_load(cr, filename, lang, verbose=True, module_name=None, context=None):
    try:
        fileobj = misc.file_open(filename)
        _logger.info("loading %s", filename)
        fileformat = os.path.splitext(filename)[-1][1:].lower()
        result = trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, module_name=module_name, context=context)
        fileobj.close()
        return result
    except IOError:
        if verbose:
            _logger.error("couldn't read translation file %s", filename)
        return None
Example #10
0
    def _tag_report(self, cr, rec, data_node=None, mode=None):
        res = {}
        for dest,f in (('name','string'),('model','model'),('report_name','name')):
            res[dest] = rec.get(f,'').encode('utf8')
            assert res[dest], "Attribute %s of report is empty !" % (f,)
        for field,dest in (('rml','report_rml'),('file','report_rml'),('xml','report_xml'),('xsl','report_xsl'),
                           ('attachment','attachment'),('attachment_use','attachment_use'), ('usage','usage'),
                           ('report_type', 'report_type'), ('parser', 'parser')):
            if rec.get(field):
                res[dest] = rec.get(field).encode('utf8')
        if rec.get('auto'):
            res['auto'] = eval(rec.get('auto','False'))
        if rec.get('sxw'):
            sxw_content = misc.file_open(rec.get('sxw')).read()
            res['report_sxw_content'] = sxw_content
        if rec.get('header'):
            res['header'] = eval(rec.get('header','False'))

        res['multi'] = rec.get('multi') and eval(rec.get('multi','False'))

        xml_id = rec.get('id','').encode('utf8')
        self._test_xml_id(xml_id)

        if rec.get('groups'):
            g_names = rec.get('groups','').split(',')
            groups_value = []
            for group in g_names:
                if group.startswith('-'):
                    group_id = self.id_get(cr, group[1:])
                    groups_value.append((3, group_id))
                else:
                    group_id = self.id_get(cr, group)
                    groups_value.append((4, group_id))
            res['groups_id'] = groups_value
        if rec.get('paperformat'):
            pf_name = rec.get('paperformat')
            pf_id = self.id_get(cr,pf_name)
            res['paperformat_id'] = pf_id

        id = self.pool['ir.model.data']._update(cr, self.uid, "ir.actions.report.xml", self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode)
        self.idref[xml_id] = int(id)

        if not rec.get('menu') or eval(rec.get('menu','False')):
            keyword = str(rec.get('keyword', 'client_print_multi'))
            value = 'ir.actions.report.xml,'+str(id)
            ir_values_id = self.pool['ir.values'].set_action(cr, self.uid, res['name'], keyword, res['model'], value)
            self.pool['ir.actions.report.xml'].write(cr, self.uid, id, {'ir_values_id': ir_values_id})
        elif self.mode=='update' and eval(rec.get('menu','False'))==False:
            # Special check for report having attribute menu=False on update
            value = 'ir.actions.report.xml,'+str(id)
            self._remove_ir_values(cr, res['name'], value, res['model'])
            self.pool['ir.actions.report.xml'].write(cr, self.uid, id, {'ir_values_id': False})
        return id
Example #11
0
def trans_load(cr, filename, lang, verbose=True, module_name=None, context=None):
    try:
        fileobj = misc.file_open(filename)
        _logger.info("loading %s", filename)
        fileformat = os.path.splitext(filename)[-1][1:].lower()
        result = trans_load_data(cr, fileobj, fileformat, lang, verbose=verbose, module_name=module_name, context=context)
        fileobj.close()
        return result
    except IOError:
        if verbose:
            _logger.error("couldn't read translation file %s", filename)
        return None
Example #12
0
    def _tag_report(self, cr, rec, data_node=None, mode=None):
        res = {}
        for dest,f in (('name','string'),('model','model'),('report_name','name')):
            res[dest] = rec.get(f,'').encode('utf8')
            assert res[dest], "Attribute %s of report is empty !" % (f,)
        for field,dest in (('rml','report_rml'),('file','report_rml'),('xml','report_xml'),('xsl','report_xsl'),
                           ('attachment','attachment'),('attachment_use','attachment_use'), ('usage','usage'),
                           ('report_type', 'report_type'), ('parser', 'parser')):
            if rec.get(field):
                res[dest] = rec.get(field).encode('utf8')
        if rec.get('auto'):
            res['auto'] = eval(rec.get('auto','False'))
        if rec.get('sxw'):
            sxw_content = misc.file_open(rec.get('sxw')).read()
            res['report_sxw_content'] = sxw_content
        if rec.get('header'):
            res['header'] = eval(rec.get('header','False'))

        res['multi'] = rec.get('multi') and eval(rec.get('multi','False'))

        xml_id = rec.get('id','').encode('utf8')
        self._test_xml_id(xml_id)

        if rec.get('groups'):
            g_names = rec.get('groups','').split(',')
            groups_value = []
            for group in g_names:
                if group.startswith('-'):
                    group_id = self.id_get(cr, group[1:])
                    groups_value.append((3, group_id))
                else:
                    group_id = self.id_get(cr, group)
                    groups_value.append((4, group_id))
            res['groups_id'] = groups_value
        if rec.get('paperformat'):
            pf_name = rec.get('paperformat')
            pf_id = self.id_get(cr,pf_name)
            res['paperformat_id'] = pf_id

        id = self.pool['ir.model.data']._update(cr, self.uid, "ir.actions.report.xml", self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode)
        self.idref[xml_id] = int(id)

        if not rec.get('menu') or eval(rec.get('menu','False')):
            keyword = str(rec.get('keyword', 'client_print_multi'))
            value = 'ir.actions.report.xml,'+str(id)
            ir_values_id = self.pool['ir.values'].set_action(cr, self.uid, res['name'], keyword, res['model'], value)
            self.pool['ir.actions.report.xml'].write(cr, self.uid, id, {'ir_values_id': ir_values_id})
        elif self.mode=='update' and eval(rec.get('menu','False'))==False:
            # Special check for report having attribute menu=False on update
            value = 'ir.actions.report.xml,'+str(id)
            self._remove_ir_values(cr, res['name'], value, res['model'])
            self.pool['ir.actions.report.xml'].write(cr, self.uid, id, {'ir_values_id': False})
        return id
Example #13
0
    def export_code_terms_from_file(fname, path, root, terms_type):
        fabsolutepath = join(root, fname)
        frelativepath = fabsolutepath[len(path):]
        module = get_module_from_path(fabsolutepath, mod_paths=mod_paths)
        is_mod_installed = module in installed_modules
        if (('all' in modules) or (module in modules)) and is_mod_installed:
            _logger.debug("Scanning code of %s at module: %s", frelativepath, module)
            src_file = misc.file_open(fabsolutepath, subdir='')
            try:
                code_string = src_file.read()
            finally:
                src_file.close()
            if module in installed_modules:
                frelativepath = str("addons" + frelativepath)
            ite = re_dquotes.finditer(code_string)
            code_offset = 0
            code_line = 1
            for i in ite:
                src = i.group(1)
                if src.startswith('""'):
                    assert src.endswith('""'), "Incorrect usage of _(..) function (should contain only literal strings!) in file %s near: %s" % (frelativepath, src[:30])
                    src = src[2:-2]
                else:
                    src = join_dquotes.sub(r'\1', src)
                # try to count the lines from the last pos to our place:
                code_line += code_string[code_offset:i.start(1)].count('\n')
                # now, since we did a binary read of a python source file, we
                # have to expand pythonic escapes like the interpreter does.
                src = src.decode('string_escape')
                push_translation(module, terms_type, frelativepath, code_line, encode(src))
                code_line += i.group(1).count('\n')
                code_offset = i.end() # we have counted newlines up to the match end

            ite = re_quotes.finditer(code_string)
            code_offset = 0 #reset counters
            code_line = 1
            for i in ite:
                src = i.group(1)
                if src.startswith("''"):
                    assert src.endswith("''"), "Incorrect usage of _(..) function (should contain only literal strings!) in file %s near: %s" % (frelativepath, src[:30])
                    src = src[2:-2]
                else:
                    src = join_quotes.sub(r'\1', src)
                code_line += code_string[code_offset:i.start(1)].count('\n')
                src = src.decode('string_escape')
                push_translation(module, terms_type, frelativepath, code_line, encode(src))
                code_line += i.group(1).count('\n')
                code_offset = i.end() # we have counted newlines up to the match end
Example #14
0
def convert_file(cr, module, filename, idref, mode='update', noupdate=False, kind=None, report=None):
    pathname = os.path.join(module, filename)
    fp = misc.file_open(pathname)
    ext = os.path.splitext(filename)[1].lower()
    try:
        if ext == '.csv':
            convert_csv_import(cr, module, pathname, fp.read(), idref, mode, noupdate)
        elif ext == '.sql':
            convert_sql_import(cr, fp)
        elif ext == '.yml':
            convert_yaml_import(cr, module, fp, kind, idref, mode, noupdate, report)
        elif ext == '.xml':
            convert_xml_import(cr, module, fp, idref, mode, noupdate, report)
        elif ext == '.js':
            pass # .js files are valid but ignored here.
        else:
            _logger.warning("Can't load unknown file type %s.", filename)
    finally:
        fp.close()
Example #15
0
def convert_file(cr, module, filename, idref, mode="update", noupdate=False, kind=None, report=None, pathname=None):
    if pathname is None:
        pathname = os.path.join(module, filename)
    fp = misc.file_open(pathname)
    ext = os.path.splitext(filename)[1].lower()

    try:
        if ext == ".csv":
            convert_csv_import(cr, module, pathname, fp.read(), idref, mode, noupdate)
        elif ext == ".sql":
            convert_sql_import(cr, fp)
        elif ext == ".yml":
            convert_yaml_import(cr, module, fp, kind, idref, mode, noupdate, report)
        elif ext == ".xml":
            convert_xml_import(cr, module, fp, idref, mode, noupdate, report)
        elif ext == ".js":
            pass  # .js files are valid but ignored here.
        else:
            raise ValueError("Can't load unknown file type %s.", filename)
    finally:
        fp.close()
Example #16
0
def trans_generate(lang, modules, cr):
    dbname = cr.dbname

    pool = pooler.get_pool(dbname)
    trans_obj = pool.get('ir.translation')
    model_data_obj = pool.get('ir.model.data')
    uid = 1
    l = pool.models.items()
    l.sort()

    query = 'SELECT name, model, res_id, module'    \
            '  FROM ir_model_data'

    query_models = """SELECT m.id, m.model, imd.module
            FROM ir_model AS m, ir_model_data AS imd
            WHERE m.id = imd.res_id AND imd.model = 'ir.model' """

    if 'all_installed' in modules:
        query += ' WHERE module IN ( SELECT name FROM ir_module_module WHERE state = \'installed\') '
        query_models += " AND imd.module in ( SELECT name FROM ir_module_module WHERE state = 'installed') "
    query_param = None
    if 'all' not in modules:
        query += ' WHERE module IN %s'
        query_models += ' AND imd.module in %s'
        query_param = (tuple(modules),)
    query += ' ORDER BY module, model, name'
    query_models += ' ORDER BY module, model'

    cr.execute(query, query_param)

    _to_translate = []
    def push_translation(module, type, name, id, source, comments=None):
        tuple = (module, source, name, id, type, comments or [])
        # empty and one-letter terms are ignored, they probably are not meant to be
        # translated, and would be very hard to translate anyway.
        if not source or len(source.strip()) <= 1:
            _logger.debug("Ignoring empty or 1-letter source term: %r", tuple)
            return
        if tuple not in _to_translate:
            _to_translate.append(tuple)

    def encode(s):
        if isinstance(s, unicode):
            return s.encode('utf8')
        return s

    for (xml_name,model,res_id,module) in cr.fetchall():
        module = encode(module)
        model = encode(model)
        xml_name = "%s.%s" % (module, encode(xml_name))

        if not pool.get(model):
            _logger.error("Unable to find object %r", model)
            continue

        exists = pool.get(model).exists(cr, uid, res_id)
        if not exists:
            _logger.warning("Unable to find object %r with id %d", model, res_id)
            continue
        obj = pool.get(model).browse(cr, uid, res_id)

        if model=='ir.ui.view':
            d = etree.XML(encode(obj.arch))
            for t in trans_parse_view(d):
                push_translation(module, 'view', encode(obj.model), 0, t)
        elif model=='ir.actions.wizard':
            service_name = 'wizard.'+encode(obj.wiz_name)
            import openerp.netsvc as netsvc
            if netsvc.Service._services.get(service_name):
                obj2 = netsvc.Service._services[service_name]
                for state_name, state_def in obj2.states.iteritems():
                    if 'result' in state_def:
                        result = state_def['result']
                        if result['type'] != 'form':
                            continue
                        name = "%s,%s" % (encode(obj.wiz_name), state_name)

                        def_params = {
                            'string': ('wizard_field', lambda s: [encode(s)]),
                            'selection': ('selection', lambda s: [encode(e[1]) for e in ((not callable(s)) and s or [])]),
                            'help': ('help', lambda s: [encode(s)]),
                        }

                        # export fields
                        if not result.has_key('fields'):
                            _logger.warning("res has no fields: %r", result)
                            continue
                        for field_name, field_def in result['fields'].iteritems():
                            res_name = name + ',' + field_name

                            for fn in def_params:
                                if fn in field_def:
                                    transtype, modifier = def_params[fn]
                                    for val in modifier(field_def[fn]):
                                        push_translation(module, transtype, res_name, 0, val)

                        # export arch
                        arch = result['arch']
                        if arch and not isinstance(arch, UpdateableStr):
                            d = etree.XML(arch)
                            for t in trans_parse_view(d):
                                push_translation(module, 'wizard_view', name, 0, t)

                        # export button labels
                        for but_args in result['state']:
                            button_name = but_args[0]
                            button_label = but_args[1]
                            res_name = name + ',' + button_name
                            push_translation(module, 'wizard_button', res_name, 0, button_label)

        elif model=='ir.model.fields':
            try:
                field_name = encode(obj.name)
            except AttributeError, exc:
                _logger.error("name error in %s: %s", xml_name, str(exc))
                continue
            objmodel = pool.get(obj.model)
            if not objmodel or not field_name in objmodel._columns:
                continue
            field_def = objmodel._columns[field_name]

            name = "%s,%s" % (encode(obj.model), field_name)
            push_translation(module, 'field', name, 0, encode(field_def.string))

            if field_def.help:
                push_translation(module, 'help', name, 0, encode(field_def.help))

            if field_def.translate:
                ids = objmodel.search(cr, uid, [])
                obj_values = objmodel.read(cr, uid, ids, [field_name])
                for obj_value in obj_values:
                    res_id = obj_value['id']
                    if obj.name in ('ir.model', 'ir.ui.menu'):
                        res_id = 0
                    model_data_ids = model_data_obj.search(cr, uid, [
                        ('model', '=', model),
                        ('res_id', '=', res_id),
                        ])
                    if not model_data_ids:
                        push_translation(module, 'model', name, 0, encode(obj_value[field_name]))

            if hasattr(field_def, 'selection') and isinstance(field_def.selection, (list, tuple)):
                for dummy, val in field_def.selection:
                    push_translation(module, 'selection', name, 0, encode(val))

        elif model=='ir.actions.report.xml':
            name = encode(obj.report_name)
            fname = ""
            if obj.report_rml:
                fname = obj.report_rml
                parse_func = trans_parse_rml
                report_type = "report"
            elif obj.report_xsl:
                fname = obj.report_xsl
                parse_func = trans_parse_xsl
                report_type = "xsl"
            if fname and obj.report_type in ('pdf', 'xsl'):
                try:
                    report_file = misc.file_open(fname)
                    try:
                        d = etree.parse(report_file)
                        for t in parse_func(d.iter()):
                            push_translation(module, report_type, name, 0, t)
                    finally:
                        report_file.close()
                except (IOError, etree.XMLSyntaxError):
                    _logger.exception("couldn't export translation for report %s %s %s", name, report_type, fname)
Example #17
0
def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, module_name=None, context=None):
    """Populates the ir_translation table."""
    if verbose:
        _logger.info('loading translation file for language %s', lang)
    if context is None:
        context = {}
    db_name = cr.dbname
    registry = openerp.registry(db_name)
    lang_obj = registry.get('res.lang')
    trans_obj = registry.get('ir.translation')
    iso_lang = misc.get_iso_codes(lang)
    try:
        ids = lang_obj.search(cr, SUPERUSER_ID, [('code','=', lang)])

        if not ids:
            # lets create the language with locale information
            lang_obj.load_lang(cr, SUPERUSER_ID, lang=lang, lang_name=lang_name)

        # Parse also the POT: it will possibly provide additional targets.
        # (Because the POT comments are correct on Launchpad but not the
        # PO comments due to a Launchpad limitation. See LP bug 933496.)
        pot_reader = []

        # now, the serious things: we read the language file
        fileobj.seek(0)
        if fileformat == 'csv':
            reader = csv.reader(fileobj, quotechar='"', delimiter=',')
            # read the first line of the file (it contains columns titles)
            for row in reader:
                fields = row
                break
        elif fileformat == 'po':
            reader = TinyPoFile(fileobj)
            fields = ['type', 'name', 'res_id', 'src', 'value', 'comments']

            # Make a reader for the POT file and be somewhat defensive for the
            # stable branch.
            if fileobj.name.endswith('.po'):
                try:
                    # Normally the path looks like /path/to/xxx/i18n/lang.po
                    # and we try to find the corresponding
                    # /path/to/xxx/i18n/xxx.pot file.
                    # (Sometimes we have 'i18n_extra' instead of just 'i18n')
                    addons_module_i18n, _ = os.path.split(fileobj.name)
                    addons_module, i18n_dir = os.path.split(addons_module_i18n)
                    addons, module = os.path.split(addons_module)
                    pot_handle = misc.file_open(os.path.join(
                        addons, module, i18n_dir, module + '.pot'))
                    pot_reader = TinyPoFile(pot_handle)
                except:
                    pass

        else:
            _logger.error('Bad file format: %s', fileformat)
            raise Exception(_('Bad file format'))

        # Read the POT references, and keep them indexed by source string.
        class Target(object):
            def __init__(self):
                self.value = None
                self.targets = set()            # set of (type, name, res_id)
                self.comments = None

        pot_targets = defaultdict(Target)
        for type, name, res_id, src, _, comments in pot_reader:
            if type is not None:
                target = pot_targets[src]
                target.targets.add((type, name, res_id))
                target.comments = comments

        # read the rest of the file
        irt_cursor = trans_obj._get_import_cursor(cr, SUPERUSER_ID, context=context)

        def process_row(row):
            """Process a single PO (or POT) entry."""
            # dictionary which holds values for this line of the csv file
            # {'lang': ..., 'type': ..., 'name': ..., 'res_id': ...,
            #  'src': ..., 'value': ..., 'module':...}
            dic = dict.fromkeys(('type', 'name', 'res_id', 'src', 'value',
                                 'comments', 'imd_model', 'imd_name', 'module'))
            dic['lang'] = lang
            dic.update(zip(fields, row))

            # discard the target from the POT targets.
            src = dic['src']
            if src in pot_targets:
                target = pot_targets[src]
                target.value = dic['value']
                target.targets.discard((dic['type'], dic['name'], dic['res_id']))

            # This would skip terms that fail to specify a res_id
            res_id = dic['res_id']
            if not res_id:
                return

            if isinstance(res_id, (int, long)) or \
                    (isinstance(res_id, basestring) and res_id.isdigit()):
                dic['res_id'] = int(res_id)
                dic['module'] = module_name
            else:
                # res_id is an xml id
                dic['res_id'] = None
                dic['imd_model'] = dic['name'].split(',')[0]
                if '.' in res_id:
                    dic['module'], dic['imd_name'] = res_id.split('.', 1)
                else:
                    dic['module'], dic['imd_name'] = False, res_id

            irt_cursor.push(dic)

        # First process the entries from the PO file (doing so also fills/removes
        # the entries from the POT file).
        for row in reader:
            process_row(row)

        # Then process the entries implied by the POT file (which is more
        # correct w.r.t. the targets) if some of them remain.
        pot_rows = []
        for src, target in pot_targets.iteritems():
            if target.value:
                for type, name, res_id in target.targets:
                    pot_rows.append((type, name, res_id, src, target.value, target.comments))
        pot_targets.clear()
        for row in pot_rows:
            process_row(row)

        irt_cursor.finish()
        trans_obj.clear_caches()
        if verbose:
            _logger.info("translation file loaded succesfully")

    except IOError:
        filename = '[lang: %s][format: %s]' % (iso_lang or 'new', fileformat)
        _logger.exception("couldn't read translation file %s", filename)
Example #18
0
def trans_generate(lang, modules, cr):
    dbname = cr.dbname

    registry = openerp.registry(dbname)
    trans_obj = registry['ir.translation']
    model_data_obj = registry['ir.model.data']
    uid = 1

    query = 'SELECT name, model, res_id, module' \
            '  FROM ir_model_data'

    query_models = """SELECT m.id, m.model, imd.module
            FROM ir_model AS m, ir_model_data AS imd
            WHERE m.id = imd.res_id AND imd.model = 'ir.model' """

    if 'all_installed' in modules:
        query += ' WHERE module IN ( SELECT name FROM ir_module_module WHERE state = \'installed\') '
        query_models += " AND imd.module in ( SELECT name FROM ir_module_module WHERE state = 'installed') "
    query_param = None
    if 'all' not in modules:
        query += ' WHERE module IN %s'
        query_models += ' AND imd.module in %s'
        query_param = (tuple(modules),)
    query += ' ORDER BY module, model, name'
    query_models += ' ORDER BY module, model'

    cr.execute(query, query_param)

    _to_translate = set()
    def push_translation(module, type, name, id, source, comments=None):
        # empty and one-letter terms are ignored, they probably are not meant to be
        # translated, and would be very hard to translate anyway.
        if not source or len(source.strip()) <= 1:
            return

        tnx = (module, source, name, id, type, tuple(comments or ()))
        _to_translate.add(tnx)

    def encode(s):
        if isinstance(s, unicode):
            return s.encode('utf8')
        return s

    def push(mod, type, name, res_id, term):
        term = (term or '').strip()
        if len(term) > 2 or term in ENGLISH_SMALL_WORDS:
            push_translation(mod, type, name, res_id, term)

    def get_root_view(xml_id):
        view = model_data_obj.xmlid_to_object(cr, uid, xml_id)
        if view:
            while view.mode != 'primary':
                view = view.inherit_id
        xml_id = view.get_external_id(cr, uid).get(view.id, xml_id)
        return xml_id

    for (xml_name,model,res_id,module) in cr.fetchall():
        module = encode(module)
        model = encode(model)
        xml_name = "%s.%s" % (module, encode(xml_name))

        if model not in registry:
            _logger.error("Unable to find object %r", model)
            continue

        Model = registry[model]
        if not Model._translate:
            # explicitly disabled
            continue

        obj = Model.browse(cr, uid, res_id)
        if not obj.exists():
            _logger.warning("Unable to find object %r with id %d", model, res_id)
            continue

        if model=='ir.ui.view':
            d = etree.XML(encode(obj.arch))
            if obj.type == 'qweb':
                view_id = get_root_view(xml_name)
                push_qweb = lambda t,l: push(module, 'view', 'website', view_id, t)
                _extract_translatable_qweb_terms(d, push_qweb)
            else:
                push_view = lambda t,l: push(module, 'view', obj.model, xml_name, t)
                trans_parse_view(d, push_view)
        elif model=='ir.actions.wizard':
            pass # TODO Can model really be 'ir.actions.wizard' ?

        elif model=='ir.model.fields':
            try:
                field_name = encode(obj.name)
            except AttributeError, exc:
                _logger.error("name error in %s: %s", xml_name, str(exc))
                continue
            objmodel = registry.get(obj.model)
            if (objmodel is None or field_name not in objmodel._columns
                    or not objmodel._translate):
                continue
            field_def = objmodel._columns[field_name]

            name = "%s,%s" % (encode(obj.model), field_name)
            push_translation(module, 'field', name, 0, encode(field_def.string))

            if field_def.help:
                push_translation(module, 'help', name, 0, encode(field_def.help))

            if field_def.translate:
                ids = objmodel.search(cr, uid, [])
                obj_values = objmodel.read(cr, uid, ids, [field_name])
                for obj_value in obj_values:
                    res_id = obj_value['id']
                    if obj.name in ('ir.model', 'ir.ui.menu'):
                        res_id = 0
                    model_data_ids = model_data_obj.search(cr, uid, [
                        ('model', '=', model),
                        ('res_id', '=', res_id),
                        ])
                    if not model_data_ids:
                        push_translation(module, 'model', name, 0, encode(obj_value[field_name]))

            if hasattr(field_def, 'selection') and isinstance(field_def.selection, (list, tuple)):
                for dummy, val in field_def.selection:
                    push_translation(module, 'selection', name, 0, encode(val))

        elif model=='ir.actions.report.xml':
            name = encode(obj.report_name)
            fname = ""
            if obj.report_rml:
                fname = obj.report_rml
                parse_func = trans_parse_rml
                report_type = "report"
            elif obj.report_xsl:
                fname = obj.report_xsl
                parse_func = trans_parse_xsl
                report_type = "xsl"
            if fname and obj.report_type in ('pdf', 'xsl'):
                try:
                    report_file = misc.file_open(fname)
                    try:
                        d = etree.parse(report_file)
                        for t in parse_func(d.iter()):
                            push_translation(module, report_type, name, 0, t)
                    finally:
                        report_file.close()
                except (IOError, etree.XMLSyntaxError):
                    _logger.exception("couldn't export translation for report %s %s %s", name, report_type, fname)
Example #19
0
def trans_generate(lang, modules, cr):
    dbname = cr.dbname

    registry = openerp.registry(dbname)
    trans_obj = registry.get('ir.translation')
    model_data_obj = registry.get('ir.model.data')
    uid = 1
    l = registry.models.items()
    l.sort()

    query = 'SELECT name, model, res_id, module'    \
            '  FROM ir_model_data'

    query_models = """SELECT m.id, m.model, imd.module
            FROM ir_model AS m, ir_model_data AS imd
            WHERE m.id = imd.res_id AND imd.model = 'ir.model' """

    if 'all_installed' in modules:
        query += ' WHERE module IN ( SELECT name FROM ir_module_module WHERE state = \'installed\') '
        query_models += " AND imd.module in ( SELECT name FROM ir_module_module WHERE state = 'installed') "
    query_param = None
    if 'all' not in modules:
        query += ' WHERE module IN %s'
        query_models += ' AND imd.module in %s'
        query_param = (tuple(modules), )
    query += ' ORDER BY module, model, name'
    query_models += ' ORDER BY module, model'

    cr.execute(query, query_param)

    _to_translate = []

    def push_translation(module, type, name, id, source, comments=None):
        tuple = (module, source, name, id, type, comments or [])
        # empty and one-letter terms are ignored, they probably are not meant to be
        # translated, and would be very hard to translate anyway.
        if not source or len(source.strip()) <= 1:
            _logger.debug("Ignoring empty or 1-letter source term: %r", tuple)
            return
        if tuple not in _to_translate:
            _to_translate.append(tuple)

    def encode(s):
        if isinstance(s, unicode):
            return s.encode('utf8')
        return s

    for (xml_name, model, res_id, module) in cr.fetchall():
        module = encode(module)
        model = encode(model)
        xml_name = "%s.%s" % (module, encode(xml_name))

        if model not in registry:
            _logger.error("Unable to find object %r", model)
            continue

        exists = registry[model].exists(cr, uid, res_id)
        if not exists:
            _logger.warning("Unable to find object %r with id %d", model,
                            res_id)
            continue
        obj = registry[model].browse(cr, uid, res_id)

        if model == 'ir.ui.view':
            d = etree.XML(encode(obj.arch))
            for t in trans_parse_view(d):
                push_translation(module, 'view', encode(obj.model), 0, t)
        elif model == 'ir.actions.wizard':
            pass  # TODO Can model really be 'ir.actions.wizard' ?

        elif model == 'ir.model.fields':
            try:
                field_name = encode(obj.name)
            except AttributeError, exc:
                _logger.error("name error in %s: %s", xml_name, str(exc))
                continue
            objmodel = registry[obj.model]
            if not objmodel or not field_name in objmodel._columns:
                continue
            field_def = objmodel._columns[field_name]

            name = "%s,%s" % (encode(obj.model), field_name)
            push_translation(module, 'field', name, 0,
                             encode(field_def.string))

            if field_def.help:
                push_translation(module, 'help', name, 0,
                                 encode(field_def.help))

            if field_def.translate:
                ids = objmodel.search(cr, uid, [])
                obj_values = objmodel.read(cr, uid, ids, [field_name])
                for obj_value in obj_values:
                    res_id = obj_value['id']
                    if obj.name in ('ir.model', 'ir.ui.menu'):
                        res_id = 0
                    model_data_ids = model_data_obj.search(
                        cr, uid, [
                            ('model', '=', model),
                            ('res_id', '=', res_id),
                        ])
                    if not model_data_ids:
                        push_translation(module, 'model', name, 0,
                                         encode(obj_value[field_name]))

            if hasattr(field_def, 'selection') and isinstance(
                    field_def.selection, (list, tuple)):
                for dummy, val in field_def.selection:
                    push_translation(module, 'selection', name, 0, encode(val))

        elif model == 'ir.actions.report.xml':
            name = encode(obj.report_name)
            fname = ""
            if obj.report_rml:
                fname = obj.report_rml
                parse_func = trans_parse_rml
                report_type = "report"
            elif obj.report_xsl:
                fname = obj.report_xsl
                parse_func = trans_parse_xsl
                report_type = "xsl"
            if fname and obj.report_type in ('pdf', 'xsl'):
                try:
                    report_file = misc.file_open(fname)
                    try:
                        d = etree.parse(report_file)
                        for t in parse_func(d.iter()):
                            push_translation(module, report_type, name, 0, t)
                    finally:
                        report_file.close()
                except (IOError, etree.XMLSyntaxError):
                    _logger.exception(
                        "couldn't export translation for report %s %s %s",
                        name, report_type, fname)
Example #20
0
def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, module_name=None, context=None):
    """Populates the ir_translation table."""
    if verbose:
        _logger.info('loading translation file for language %s', lang)
    if context is None:
        context = {}
    db_name = cr.dbname
    pool = pooler.get_pool(db_name)
    lang_obj = pool.get('res.lang')
    trans_obj = pool.get('ir.translation')
    iso_lang = misc.get_iso_codes(lang)
    try:
        ids = lang_obj.search(cr, SUPERUSER_ID, [('code','=', lang)])

        if not ids:
            # lets create the language with locale information
            lang_obj.load_lang(cr, SUPERUSER_ID, lang=lang, lang_name=lang_name)

        # Parse also the POT: it will possibly provide additional targets.
        # (Because the POT comments are correct on Launchpad but not the
        # PO comments due to a Launchpad limitation. See LP bug 933496.)
        pot_reader = []

        # now, the serious things: we read the language file
        fileobj.seek(0)
        if fileformat == 'csv':
            reader = csv.reader(fileobj, quotechar='"', delimiter=',')
            # read the first line of the file (it contains columns titles)
            for row in reader:
                f = row
                break
        elif fileformat == 'po':
            reader = TinyPoFile(fileobj)
            f = ['type', 'name', 'res_id', 'src', 'value', 'comments']

            # Make a reader for the POT file and be somewhat defensive for the
            # stable branch.
            if fileobj.name.endswith('.po'):
                try:
                    # Normally the path looks like /path/to/xxx/i18n/lang.po
                    # and we try to find the corresponding
                    # /path/to/xxx/i18n/xxx.pot file.
                    head, _ = os.path.split(fileobj.name)
                    head2, _ = os.path.split(head)
                    head3, tail3 = os.path.split(head2)
                    pot_handle = misc.file_open(os.path.join(head3, tail3, 'i18n', tail3 + '.pot'))
                    pot_reader = TinyPoFile(pot_handle)
                except:
                    pass

        else:
            _logger.error('Bad file format: %s', fileformat)
            raise Exception(_('Bad file format'))

        # Read the POT `reference` comments, and keep them indexed by source
        # string.
        pot_targets = {}
        for type, name, res_id, src, _, comments in pot_reader:
            if type is not None:
                pot_targets.setdefault(src, {'value': None, 'targets': []})
                pot_targets[src]['targets'].append((type, name, res_id))

        # read the rest of the file
        irt_cursor = trans_obj._get_import_cursor(cr, SUPERUSER_ID, context=context)

        def process_row(row):
            """Process a single PO (or POT) entry."""
            # skip empty rows and rows where the translation field (=last fiefd) is empty
            #if (not row) or (not row[-1]):
            #    return

            # dictionary which holds values for this line of the csv file
            # {'lang': ..., 'type': ..., 'name': ..., 'res_id': ...,
            #  'src': ..., 'value': ..., 'module':...}
            dic = dict.fromkeys(('name', 'res_id', 'src', 'type', 'imd_model', 'imd_name', 'module', 'value', 'comments'))
            dic['lang'] = lang
            for i, field in enumerate(f):
                dic[field] = row[i]

            # Get the `reference` comments from the POT.
            src = row[3]
            if pot_reader and src in pot_targets:
                pot_targets[src]['targets'] = filter(lambda x: x != row[:3], pot_targets[src]['targets'])
                pot_targets[src]['value'] = row[4]
                if not pot_targets[src]['targets']:
                    del pot_targets[src]

            # This would skip terms that fail to specify a res_id
            if not dic.get('res_id'):
                return

            res_id = dic.pop('res_id')
            if res_id and isinstance(res_id, (int, long)) \
                or (isinstance(res_id, basestring) and res_id.isdigit()):
                    dic['res_id'] = int(res_id)
                    dic['module'] = module_name
            else:
                tmodel = dic['name'].split(',')[0]
                if '.' in res_id:
                    tmodule, tname = res_id.split('.', 1)
                else:
                    tmodule = False
                    tname = res_id
                dic['imd_model'] = tmodel
                dic['imd_name'] =  tname
                dic['module'] = tmodule
                dic['res_id'] = None

            irt_cursor.push(dic)

        # First process the entries from the PO file (doing so also fills/removes
        # the entries from the POT file).
        for row in reader:
            process_row(row)

        # Then process the entries implied by the POT file (which is more
        # correct w.r.t. the targets) if some of them remain.
        pot_rows = []
        for src in pot_targets:
            value = pot_targets[src]['value']
            for type, name, res_id in pot_targets[src]['targets']:
                pot_rows.append((type, name, res_id, src, value, comments))
        for row in pot_rows:
            process_row(row)

        irt_cursor.finish()
        trans_obj.clear_caches()
        if verbose:
            _logger.info("translation file loaded succesfully")
    except IOError:
        filename = '[lang: %s][format: %s]' % (iso_lang or 'new', fileformat)
        _logger.exception("couldn't read translation file %s", filename)
Example #21
0
    def _tag_report(self, cr, rec, data_node=None):
        res = {}
        for dest, f in (("name", "string"), ("model", "model"), ("report_name", "name")):
            res[dest] = rec.get(f, "").encode("utf8")
            assert res[dest], "Attribute %s of report is empty !" % (f,)
        for field, dest in (
            ("rml", "report_rml"),
            ("file", "report_rml"),
            ("xml", "report_xml"),
            ("xsl", "report_xsl"),
            ("attachment", "attachment"),
            ("attachment_use", "attachment_use"),
            ("usage", "usage"),
        ):
            if rec.get(field):
                res[dest] = rec.get(field).encode("utf8")
        if rec.get("auto"):
            res["auto"] = eval(rec.get("auto", "False"))
        if rec.get("sxw"):
            sxw_content = misc.file_open(rec.get("sxw")).read()
            res["report_sxw_content"] = sxw_content
        if rec.get("header"):
            res["header"] = eval(rec.get("header", "False"))
        if rec.get("report_type"):
            res["report_type"] = rec.get("report_type")

        res["multi"] = rec.get("multi") and eval(rec.get("multi", "False"))

        xml_id = rec.get("id", "").encode("utf8")
        self._test_xml_id(xml_id)

        if rec.get("groups"):
            g_names = rec.get("groups", "").split(",")
            groups_value = []
            for group in g_names:
                if group.startswith("-"):
                    group_id = self.id_get(cr, group[1:])
                    groups_value.append((3, group_id))
                else:
                    group_id = self.id_get(cr, group)
                    groups_value.append((4, group_id))
            res["groups_id"] = groups_value

        id = self.pool.get("ir.model.data")._update(
            cr,
            self.uid,
            "ir.actions.report.xml",
            self.module,
            res,
            xml_id,
            noupdate=self.isnoupdate(data_node),
            mode=self.mode,
        )
        self.idref[xml_id] = int(id)

        if not rec.get("menu") or eval(rec.get("menu", "False")):
            keyword = str(rec.get("keyword", "client_print_multi"))
            value = "ir.actions.report.xml," + str(id)
            replace = rec.get("replace", True)
            self.pool.get("ir.model.data").ir_set(
                cr,
                self.uid,
                "action",
                keyword,
                res["name"],
                [res["model"]],
                value,
                replace=replace,
                isobject=True,
                xml_id=xml_id,
            )
        elif self.mode == "update" and eval(rec.get("menu", "False")) == False:
            # Special check for report having attribute menu=False on update
            value = "ir.actions.report.xml," + str(id)
            self._remove_ir_values(cr, res["name"], value, res["model"])
        return id
Example #22
0
def trans_generate(lang, modules, cr):
    dbname = cr.dbname

    pool = pooler.get_pool(dbname)
    trans_obj = pool.get('ir.translation')
    model_data_obj = pool.get('ir.model.data')
    uid = 1
    l = pool.models.items()
    l.sort()

    query = 'SELECT name, model, res_id, module'    \
            '  FROM ir_model_data'

    query_models = """SELECT m.id, m.model, imd.module
            FROM ir_model AS m, ir_model_data AS imd
            WHERE m.id = imd.res_id AND imd.model = 'ir.model' """

    if 'all_installed' in modules:
        query += ' WHERE module IN ( SELECT name FROM ir_module_module WHERE state = \'installed\') '
        query_models += " AND imd.module in ( SELECT name FROM ir_module_module WHERE state = 'installed') "
    query_param = None
    if 'all' not in modules:
        query += ' WHERE module IN %s'
        query_models += ' AND imd.module in %s'
        query_param = (tuple(modules), )
    query += ' ORDER BY module, model, name'
    query_models += ' ORDER BY module, model'

    cr.execute(query, query_param)

    _to_translate = []

    def push_translation(module, type, name, id, source, comments=None):
        tuple = (module, source, name, id, type, comments or [])
        # empty and one-letter terms are ignored, they probably are not meant to be
        # translated, and would be very hard to translate anyway.
        if not source or len(source.strip()) <= 1:
            _logger.debug("Ignoring empty or 1-letter source term: %r", tuple)
            return
        if tuple not in _to_translate:
            _to_translate.append(tuple)

    def encode(s):
        if isinstance(s, unicode):
            return s.encode('utf8')
        return s

    for (xml_name, model, res_id, module) in cr.fetchall():
        module = encode(module)
        model = encode(model)
        xml_name = "%s.%s" % (module, encode(xml_name))

        if not pool.get(model):
            _logger.error("Unable to find object %r", model)
            continue

        exists = pool.get(model).exists(cr, uid, res_id)
        if not exists:
            _logger.warning("Unable to find object %r with id %d", model,
                            res_id)
            continue
        obj = pool.get(model).browse(cr, uid, res_id)

        if model == 'ir.ui.view':
            d = etree.XML(encode(obj.arch))
            for t in trans_parse_view(d):
                push_translation(module, 'view', encode(obj.model), 0, t)
        elif model == 'ir.actions.wizard':
            service_name = 'wizard.' + encode(obj.wiz_name)
            import openerp.netsvc as netsvc
            if netsvc.Service._services.get(service_name):
                obj2 = netsvc.Service._services[service_name]
                for state_name, state_def in obj2.states.iteritems():
                    if 'result' in state_def:
                        result = state_def['result']
                        if result['type'] != 'form':
                            continue
                        name = "%s,%s" % (encode(obj.wiz_name), state_name)

                        def_params = {
                            'string': ('wizard_field', lambda s: [encode(s)]),
                            'selection': ('selection', lambda s: [
                                encode(e[1])
                                for e in ((not callable(s)) and s or [])
                            ]),
                            'help': ('help', lambda s: [encode(s)]),
                        }

                        # export fields
                        if not result.has_key('fields'):
                            _logger.warning("res has no fields: %r", result)
                            continue
                        for field_name, field_def in result[
                                'fields'].iteritems():
                            res_name = name + ',' + field_name

                            for fn in def_params:
                                if fn in field_def:
                                    transtype, modifier = def_params[fn]
                                    for val in modifier(field_def[fn]):
                                        push_translation(
                                            module, transtype, res_name, 0,
                                            val)

                        # export arch
                        arch = result['arch']
                        if arch and not isinstance(arch, UpdateableStr):
                            d = etree.XML(arch)
                            for t in trans_parse_view(d):
                                push_translation(module, 'wizard_view', name,
                                                 0, t)

                        # export button labels
                        for but_args in result['state']:
                            button_name = but_args[0]
                            button_label = but_args[1]
                            res_name = name + ',' + button_name
                            push_translation(module, 'wizard_button', res_name,
                                             0, button_label)

        elif model == 'ir.model.fields':
            try:
                field_name = encode(obj.name)
            except AttributeError, exc:
                _logger.error("name error in %s: %s", xml_name, str(exc))
                continue
            objmodel = pool.get(obj.model)
            if not objmodel or not field_name in objmodel._columns:
                continue
            field_def = objmodel._columns[field_name]

            name = "%s,%s" % (encode(obj.model), field_name)
            push_translation(module, 'field', name, 0,
                             encode(field_def.string))

            if field_def.help:
                push_translation(module, 'help', name, 0,
                                 encode(field_def.help))

            if field_def.translate:
                ids = objmodel.search(cr, uid, [])
                obj_values = objmodel.read(cr, uid, ids, [field_name])
                for obj_value in obj_values:
                    res_id = obj_value['id']
                    if obj.name in ('ir.model', 'ir.ui.menu'):
                        res_id = 0
                    model_data_ids = model_data_obj.search(
                        cr, uid, [
                            ('model', '=', model),
                            ('res_id', '=', res_id),
                        ])
                    if not model_data_ids:
                        push_translation(module, 'model', name, 0,
                                         encode(obj_value[field_name]))

            if hasattr(field_def, 'selection') and isinstance(
                    field_def.selection, (list, tuple)):
                for dummy, val in field_def.selection:
                    push_translation(module, 'selection', name, 0, encode(val))

        elif model == 'ir.actions.report.xml':
            name = encode(obj.report_name)
            fname = ""
            if obj.report_rml:
                fname = obj.report_rml
                parse_func = trans_parse_rml
                report_type = "report"
            elif obj.report_xsl:
                fname = obj.report_xsl
                parse_func = trans_parse_xsl
                report_type = "xsl"
            if fname and obj.report_type in ('pdf', 'xsl'):
                try:
                    report_file = misc.file_open(fname)
                    try:
                        d = etree.parse(report_file)
                        for t in parse_func(d.iter()):
                            push_translation(module, report_type, name, 0, t)
                    finally:
                        report_file.close()
                except (IOError, etree.XMLSyntaxError):
                    _logger.exception(
                        "couldn't export translation for report %s %s %s",
                        name, report_type, fname)
Example #23
0
    def _tag_report(self, cr, rec, data_node=None):
        res = {}
        for dest, f in (('name', 'string'), ('model', 'model'), ('report_name',
                                                                 'name')):
            res[dest] = rec.get(f, '').encode('utf8')
            assert res[dest], "Attribute %s of report is empty !" % (f, )
        for field, dest in (('rml', 'report_rml'), ('file', 'report_rml'),
                            ('xml', 'report_xml'), ('xsl', 'report_xsl'),
                            ('attachment', 'attachment'), ('attachment_use',
                                                           'attachment_use')):
            if rec.get(field):
                res[dest] = rec.get(field).encode('utf8')
        if rec.get('auto'):
            res['auto'] = eval(rec.get('auto', 'False'))
        if rec.get('sxw'):
            sxw_content = misc.file_open(rec.get('sxw')).read()
            res['report_sxw_content'] = sxw_content
        if rec.get('header'):
            res['header'] = eval(rec.get('header', 'False'))
        if rec.get('report_type'):
            res['report_type'] = rec.get('report_type')

        res['multi'] = rec.get('multi') and eval(rec.get('multi', 'False'))

        xml_id = rec.get('id', '').encode('utf8')
        self._test_xml_id(xml_id)

        if rec.get('groups'):
            g_names = rec.get('groups', '').split(',')
            groups_value = []
            # groups_obj = self.pool.get('res.groups')
            for group in g_names:
                if group.startswith('-'):
                    group_id = self.id_get(cr, group[1:])
                    groups_value.append((3, group_id))
                else:
                    group_id = self.id_get(cr, group)
                    groups_value.append((4, group_id))
            res['groups_id'] = groups_value

        id = self.pool.get('ir.model.data')._update(
            cr,
            self.uid,
            "ir.actions.report.xml",
            self.module,
            res,
            xml_id,
            noupdate=self.isnoupdate(data_node),
            mode=self.mode,
            context=self.context)
        self.idref[xml_id] = int(id)

        if not rec.get('menu') or eval(rec.get('menu', 'False')):
            keyword = str(rec.get('keyword', 'client_print_multi'))
            # keys = [('action',keyword),('res_model',res['model'])]
            value = 'ir.actions.report.xml,' + str(id)
            replace = rec.get('replace', True)
            self.pool.get('ir.model.data').ir_set(cr,
                                                  self.uid,
                                                  'action',
                                                  keyword,
                                                  res['name'], [res['model']],
                                                  value,
                                                  replace=replace,
                                                  isobject=True,
                                                  xml_id=xml_id)
        elif self.mode == 'update' and eval(rec.get('menu', 'False')) == False:
            # Special check for report having attribute menu=False on update
            value = 'ir.actions.report.xml,' + str(id)
            self._remove_ir_values(cr, res['name'], value, res['model'])
        return False
Example #24
0
def trans_generate(lang, modules, cr):
    dbname = cr.dbname

    registry = openerp.registry(dbname)
    trans_obj = registry["ir.translation"]
    model_data_obj = registry["ir.model.data"]
    uid = 1

    query = "SELECT name, model, res_id, module" "  FROM ir_model_data"

    query_models = """SELECT m.id, m.model, imd.module
            FROM ir_model AS m, ir_model_data AS imd
            WHERE m.id = imd.res_id AND imd.model = 'ir.model' """

    if "all_installed" in modules:
        query += " WHERE module IN ( SELECT name FROM ir_module_module WHERE state = 'installed') "
        query_models += " AND imd.module in ( SELECT name FROM ir_module_module WHERE state = 'installed') "
    query_param = None
    if "all" not in modules:
        query += " WHERE module IN %s"
        query_models += " AND imd.module in %s"
        query_param = (tuple(modules),)
    query += " ORDER BY module, model, name"
    query_models += " ORDER BY module, model"

    cr.execute(query, query_param)

    _to_translate = set()

    def push_translation(module, type, name, id, source, comments=None):
        # empty and one-letter terms are ignored, they probably are not meant to be
        # translated, and would be very hard to translate anyway.
        if not source or len(source.strip()) <= 1:
            return

        tnx = (module, source, name, id, type, tuple(comments or ()))
        _to_translate.add(tnx)

    def encode(s):
        if isinstance(s, unicode):
            return s.encode("utf8")
        return s

    def push(mod, type, name, res_id, term):
        term = (term or "").strip()
        if len(term) > 2 or term in ENGLISH_SMALL_WORDS:
            push_translation(mod, type, name, res_id, term)

    def get_root_view(xml_id):
        view = model_data_obj.xmlid_to_object(cr, uid, xml_id)
        if view:
            while view.mode != "primary":
                view = view.inherit_id
        xml_id = view.get_external_id(cr, uid).get(view.id, xml_id)
        return xml_id

    for (xml_name, model, res_id, module) in cr.fetchall():
        module = encode(module)
        model = encode(model)
        xml_name = "%s.%s" % (module, encode(xml_name))

        if model not in registry:
            _logger.error("Unable to find object %r", model)
            continue

        Model = registry[model]
        if not Model._translate:
            # explicitly disabled
            continue

        obj = Model.browse(cr, uid, res_id)
        if not obj.exists():
            _logger.warning("Unable to find object %r with id %d", model, res_id)
            continue

        if model == "ir.ui.view":
            d = etree.XML(encode(obj.arch))
            if obj.type == "qweb":
                view_id = get_root_view(xml_name)
                push_qweb = lambda t, l: push(module, "view", "website", view_id, t)
                _extract_translatable_qweb_terms(d, push_qweb)
            else:
                push_view = lambda t, l: push(module, "view", obj.model, xml_name, t)
                trans_parse_view(d, push_view)
        elif model == "ir.actions.wizard":
            pass  # TODO Can model really be 'ir.actions.wizard' ?

        elif model == "ir.model.fields":
            try:
                field_name = encode(obj.name)
            except AttributeError, exc:
                _logger.error("name error in %s: %s", xml_name, str(exc))
                continue
            objmodel = registry.get(obj.model)
            if objmodel is None or field_name not in objmodel._columns or not objmodel._translate:
                continue
            field_def = objmodel._columns[field_name]

            name = "%s,%s" % (encode(obj.model), field_name)
            push_translation(module, "field", name, 0, encode(field_def.string))

            if field_def.help:
                push_translation(module, "help", name, 0, encode(field_def.help))

            if field_def.translate:
                ids = objmodel.search(cr, uid, [])
                obj_values = objmodel.read(cr, uid, ids, [field_name])
                for obj_value in obj_values:
                    res_id = obj_value["id"]
                    if obj.name in ("ir.model", "ir.ui.menu"):
                        res_id = 0
                    model_data_ids = model_data_obj.search(cr, uid, [("model", "=", model), ("res_id", "=", res_id)])
                    if not model_data_ids:
                        push_translation(module, "model", name, 0, encode(obj_value[field_name]))

            if hasattr(field_def, "selection") and isinstance(field_def.selection, (list, tuple)):
                for dummy, val in field_def.selection:
                    push_translation(module, "selection", name, 0, encode(val))

        elif model == "ir.actions.report.xml":
            name = encode(obj.report_name)
            fname = ""
            if obj.report_rml:
                fname = obj.report_rml
                parse_func = trans_parse_rml
                report_type = "report"
            elif obj.report_xsl:
                fname = obj.report_xsl
                parse_func = trans_parse_xsl
                report_type = "xsl"
            if fname and obj.report_type in ("pdf", "xsl"):
                try:
                    report_file = misc.file_open(fname)
                    try:
                        d = etree.parse(report_file)
                        for t in parse_func(d.iter()):
                            push_translation(module, report_type, name, 0, t)
                    finally:
                        report_file.close()
                except (IOError, etree.XMLSyntaxError):
                    _logger.exception("couldn't export translation for report %s %s %s", name, report_type, fname)
Example #25
0
def trans_generate(lang, modules, cr):
    dbname = cr.dbname

    registry = openerp.registry(dbname)
    trans_obj = registry["ir.translation"]
    model_data_obj = registry["ir.model.data"]
    uid = 1

    query = "SELECT name, model, res_id, module" "  FROM ir_model_data"

    query_models = """SELECT m.id, m.model, imd.module
            FROM ir_model AS m, ir_model_data AS imd
            WHERE m.id = imd.res_id AND imd.model = 'ir.model' """

    if "all_installed" in modules:
        query += " WHERE module IN ( SELECT name FROM ir_module_module WHERE state = 'installed') "
        query_models += " AND imd.module in ( SELECT name FROM ir_module_module WHERE state = 'installed') "
    query_param = None
    if "all" not in modules:
        query += " WHERE module IN %s"
        query_models += " AND imd.module in %s"
        query_param = (tuple(modules),)
    query += " ORDER BY module, model, name"
    query_models += " ORDER BY module, model"

    cr.execute(query, query_param)

    _to_translate = set()

    def push_translation(module, type, name, id, source, comments=None):
        # empty and one-letter terms are ignored, they probably are not meant to be
        # translated, and would be very hard to translate anyway.
        sanitized_term = (source or "").strip()
        try:
            # verify the minimal size without eventual xml tags
            # wrap to make sure html content like '<a>b</a><c>d</c>' is accepted by lxml
            wrapped = "<div>%s</div>" % sanitized_term
            node = etree.fromstring(wrapped)
            sanitized_term = etree.tostring(node, encoding="UTF-8", method="text")
        except etree.ParseError:
            pass
        # remove non-alphanumeric chars
        sanitized_term = re.sub(r"\W+", "", sanitized_term)
        if not sanitized_term or len(sanitized_term) <= 1:
            return

        tnx = (module, source, name, id, type, tuple(comments or ()))
        _to_translate.add(tnx)

    def push(mod, type, name, res_id, term):
        term = (term or "").strip()
        if len(term) > 2 or term in ENGLISH_SMALL_WORDS:
            push_translation(mod, type, name, res_id, term)

    def get_root_view(xml_id):
        view = model_data_obj.xmlid_to_object(cr, uid, xml_id)
        if view:
            while view.mode != "primary":
                view = view.inherit_id
        xml_id = view.get_external_id(cr, uid).get(view.id, xml_id)
        return xml_id

    for (xml_name, model, res_id, module) in cr.fetchall():
        module = encode(module)
        model = encode(model)
        xml_name = "%s.%s" % (module, encode(xml_name))

        if model not in registry:
            _logger.error("Unable to find object %r", model)
            continue

        Model = registry[model]
        if not Model._translate:
            # explicitly disabled
            continue

        obj = Model.browse(cr, uid, res_id)
        if not obj.exists():
            _logger.warning("Unable to find object %r with id %d", model, res_id)
            continue

        if model == "ir.model.fields":
            try:
                field_name = encode(obj.name)
            except AttributeError, exc:
                _logger.error("name error in %s: %s", xml_name, str(exc))
                continue
            field_model = registry.get(obj.model)
            if field_model is None or not field_model._translate or field_name not in field_model._fields:
                continue
            field_def = field_model._fields[field_name]

            if hasattr(field_def, "selection") and isinstance(field_def.selection, (list, tuple)):
                name = "%s,%s" % (encode(obj.model), field_name)
                for dummy, val in field_def.selection:
                    push_translation(module, "selection", name, 0, encode(val))

        elif model == "ir.actions.report.xml":
            name = encode(obj.report_name)
            fname = ""
            if obj.report_rml:
                fname = obj.report_rml
                parse_func = trans_parse_rml
                report_type = "report"
            elif obj.report_xsl:
                continue
            if fname and obj.report_type in ("pdf", "xsl"):
                try:
                    report_file = misc.file_open(fname)
                    try:
                        d = etree.parse(report_file)
                        for t in parse_func(d.iter()):
                            push_translation(module, report_type, name, 0, t)
                    finally:
                        report_file.close()
                except (IOError, etree.XMLSyntaxError):
                    _logger.exception("couldn't export translation for report %s %s %s", name, report_type, fname)
Example #26
0
def trans_generate(lang, modules, cr):
    dbname = cr.dbname

    registry = openerp.registry(dbname)
    trans_obj = registry.get('ir.translation')
    model_data_obj = registry.get('ir.model.data')
    uid = 1
    l = registry.models.items()
    l.sort()

    query = 'SELECT name, model, res_id, module'    \
            '  FROM ir_model_data'

    query_models = """SELECT m.id, m.model, imd.module
            FROM ir_model AS m, ir_model_data AS imd
            WHERE m.id = imd.res_id AND imd.model = 'ir.model' """

    if 'all_installed' in modules:
        query += ' WHERE module IN ( SELECT name FROM ir_module_module WHERE state = \'installed\') '
        query_models += " AND imd.module in ( SELECT name FROM ir_module_module WHERE state = 'installed') "
    query_param = None
    if 'all' not in modules:
        query += ' WHERE module IN %s'
        query_models += ' AND imd.module in %s'
        query_param = (tuple(modules), )
    query += ' ORDER BY module, model, name'
    query_models += ' ORDER BY module, model'

    cr.execute(query, query_param)

    _to_translate = []

    def push_translation(module, type, name, id, source, comments=None):
        tuple = (module, source, name, id, type, comments or [])
        # empty and one-letter terms are ignored, they probably are not meant to be
        # translated, and would be very hard to translate anyway.
        if not source or len(source.strip()) <= 1:
            _logger.debug("Ignoring empty or 1-letter source term: %r", tuple)
            return
        if tuple not in _to_translate:
            _to_translate.append(tuple)

    def encode(s):
        if isinstance(s, unicode):
            return s.encode('utf8')
        return s

    for (xml_name, model, res_id, module) in cr.fetchall():
        module = encode(module)
        model = encode(model)
        xml_name = "%s.%s" % (module, encode(xml_name))

        if model not in registry:
            _logger.error("Unable to find object %r", model)
            continue

        exists = registry[model].exists(cr, uid, res_id)
        if not exists:
            _logger.warning("Unable to find object %r with id %d", model,
                            res_id)
            continue
        obj = registry[model].browse(cr, uid, res_id)

        if model == 'ir.ui.view':
            d = etree.XML(encode(obj.arch))
            for t in trans_parse_view(d):
                push_translation(module, 'view', encode(obj.model), 0, t)
        elif model == 'ir.actions.wizard':
            pass  # TODO Can model really be 'ir.actions.wizard' ?

        elif model == 'ir.model.fields':
            try:
                field_name = encode(obj.name)
            except AttributeError, exc:
                _logger.error("name error in %s: %s", xml_name, str(exc))
                continue
            objmodel = registry.get(obj.model)
            if not objmodel or not field_name in objmodel._columns:
                continue
            field_def = objmodel._columns[field_name]

            name = "%s,%s" % (encode(obj.model), field_name)
            push_translation(module, 'field', name, 0,
                             encode(field_def.string))

            if field_def.help:
                push_translation(module, 'help', name, 0,
                                 encode(field_def.help))

            if field_def.translate:
                ids = objmodel.search(cr, uid, [])
                obj_values = objmodel.read(cr, uid, ids, [field_name])
                for obj_value in obj_values:
                    res_id = obj_value['id']
                    if obj.name in ('ir.model', 'ir.ui.menu'):
                        res_id = 0
                    model_data_ids = model_data_obj.search(
                        cr, uid, [
                            ('model', '=', model),
                            ('res_id', '=', res_id),
                        ])
                    if not model_data_ids:
                        push_translation(module, 'model', name, 0,
                                         encode(obj_value[field_name]))

            if hasattr(field_def, 'selection') and isinstance(
                    field_def.selection, (list, tuple)):
                for dummy, val in field_def.selection:
                    push_translation(module, 'selection', name, 0, encode(val))

        elif model == 'ir.actions.report.xml':
            name = encode(obj.report_name)
            fname = ""
            if obj.report_rml:
                fname = obj.report_rml
                parse_func = trans_parse_rml
                report_type = "report"
            elif obj.report_xsl:
                fname = obj.report_xsl
                parse_func = trans_parse_xsl
                report_type = "xsl"
            if fname and obj.report_type in ('pdf', 'xsl'):
                try:
                    report_file = misc.file_open(fname)
                    try:
                        d = etree.parse(report_file)
                        for t in parse_func(d.iter()):
                            push_translation(module, report_type, name, 0, t)
                    finally:
                        report_file.close()
                except (IOError, etree.XMLSyntaxError):
                    _logger.exception(
                        "couldn't export translation for report %s %s %s",
                        name, report_type, fname)
Example #27
0
def trans_load_data(cr,
                    fileobj,
                    fileformat,
                    lang,
                    lang_name=None,
                    verbose=True,
                    module_name=None,
                    context=None):
    """Populates the ir_translation table."""
    if verbose:
        _logger.info('loading translation file for language %s', lang)
    if context is None:
        context = {}
    db_name = cr.dbname
    pool = pooler.get_pool(db_name)
    lang_obj = pool.get('res.lang')
    trans_obj = pool.get('ir.translation')
    iso_lang = misc.get_iso_codes(lang)
    try:
        ids = lang_obj.search(cr, SUPERUSER_ID, [('code', '=', lang)])

        if not ids:
            # lets create the language with locale information
            lang_obj.load_lang(cr,
                               SUPERUSER_ID,
                               lang=lang,
                               lang_name=lang_name)

        # Parse also the POT: it will possibly provide additional targets.
        # (Because the POT comments are correct on Launchpad but not the
        # PO comments due to a Launchpad limitation. See LP bug 933496.)
        pot_reader = []

        # now, the serious things: we read the language file
        fileobj.seek(0)
        if fileformat == 'csv':
            reader = csv.reader(fileobj, quotechar='"', delimiter=',')
            # read the first line of the file (it contains columns titles)
            for row in reader:
                f = row
                break
        elif fileformat == 'po':
            reader = TinyPoFile(fileobj)
            f = ['type', 'name', 'res_id', 'src', 'value', 'comments']

            # Make a reader for the POT file and be somewhat defensive for the
            # stable branch.
            if fileobj.name.endswith('.po'):
                try:
                    # Normally the path looks like /path/to/xxx/i18n/lang.po
                    # and we try to find the corresponding
                    # /path/to/xxx/i18n/xxx.pot file.
                    head, _ = os.path.split(fileobj.name)
                    head2, _ = os.path.split(head)
                    head3, tail3 = os.path.split(head2)
                    pot_handle = misc.file_open(
                        os.path.join(head3, tail3, 'i18n', tail3 + '.pot'))
                    pot_reader = TinyPoFile(pot_handle)
                except:
                    pass

        else:
            _logger.error('Bad file format: %s', fileformat)
            raise Exception(_('Bad file format'))

        # Read the POT `reference` comments, and keep them indexed by source
        # string.
        pot_targets = {}
        for type, name, res_id, src, _, comments in pot_reader:
            if type is not None:
                pot_targets.setdefault(src, {'value': None, 'targets': []})
                pot_targets[src]['targets'].append((type, name, res_id))

        # read the rest of the file
        irt_cursor = trans_obj._get_import_cursor(cr,
                                                  SUPERUSER_ID,
                                                  context=context)

        def process_row(row):
            """Process a single PO (or POT) entry."""
            # skip empty rows and rows where the translation field (=last fiefd) is empty
            #if (not row) or (not row[-1]):
            #    return

            # dictionary which holds values for this line of the csv file
            # {'lang': ..., 'type': ..., 'name': ..., 'res_id': ...,
            #  'src': ..., 'value': ..., 'module':...}
            dic = dict.fromkeys(('name', 'res_id', 'src', 'type', 'imd_model',
                                 'imd_name', 'module', 'value', 'comments'))
            dic['lang'] = lang
            for i, field in enumerate(f):
                dic[field] = row[i]

            # Get the `reference` comments from the POT.
            src = row[3]
            if pot_reader and src in pot_targets:
                pot_targets[src]['targets'] = filter(
                    lambda x: x != row[:3], pot_targets[src]['targets'])
                pot_targets[src]['value'] = row[4]
                if not pot_targets[src]['targets']:
                    del pot_targets[src]

            # This would skip terms that fail to specify a res_id
            if not dic.get('res_id'):
                return

            res_id = dic.pop('res_id')
            if res_id and isinstance(res_id, (int, long)) \
                or (isinstance(res_id, basestring) and res_id.isdigit()):
                dic['res_id'] = int(res_id)
                dic['module'] = module_name
            else:
                tmodel = dic['name'].split(',')[0]
                if '.' in res_id:
                    tmodule, tname = res_id.split('.', 1)
                else:
                    tmodule = False
                    tname = res_id
                dic['imd_model'] = tmodel
                dic['imd_name'] = tname
                dic['module'] = tmodule
                dic['res_id'] = None

            irt_cursor.push(dic)

        # First process the entries from the PO file (doing so also fills/removes
        # the entries from the POT file).
        for row in reader:
            process_row(row)

        # Then process the entries implied by the POT file (which is more
        # correct w.r.t. the targets) if some of them remain.
        pot_rows = []
        for src in pot_targets:
            value = pot_targets[src]['value']
            for type, name, res_id in pot_targets[src]['targets']:
                pot_rows.append((type, name, res_id, src, value, comments))
        for row in pot_rows:
            process_row(row)

        irt_cursor.finish()
        trans_obj.clear_caches()
        if verbose:
            _logger.info("translation file loaded succesfully")
    except IOError:
        filename = '[lang: %s][format: %s]' % (iso_lang or 'new', fileformat)
        _logger.exception("couldn't read translation file %s", filename)
Example #28
0
def trans_generate(lang, modules, cr):
    dbname = cr.dbname

    registry = openerp.registry(dbname)
    trans_obj = registry['ir.translation']
    model_data_obj = registry['ir.model.data']
    uid = 1

    query = 'SELECT name, model, res_id, module' \
            '  FROM ir_model_data'

    query_models = """SELECT m.id, m.model, imd.module
            FROM ir_model AS m, ir_model_data AS imd
            WHERE m.id = imd.res_id AND imd.model = 'ir.model' """

    if 'all_installed' in modules:
        query += ' WHERE module IN ( SELECT name FROM ir_module_module WHERE state = \'installed\') '
        query_models += " AND imd.module in ( SELECT name FROM ir_module_module WHERE state = 'installed') "
    query_param = None
    if 'all' not in modules:
        query += ' WHERE module IN %s'
        query_models += ' AND imd.module in %s'
        query_param = (tuple(modules),)
    query += ' ORDER BY module, model, name'
    query_models += ' ORDER BY module, model'

    cr.execute(query, query_param)

    _to_translate = set()
    def push_translation(module, type, name, id, source, comments=None):
        # empty and one-letter terms are ignored, they probably are not meant to be
        # translated, and would be very hard to translate anyway.
        if not source or len(source.strip()) <= 1:
            return

        tnx = (module, source, name, id, type, tuple(comments or ()))
        _to_translate.add(tnx)

    def push(mod, type, name, res_id, term):
        term = (term or '').strip()
        if len(term) > 2 or term in ENGLISH_SMALL_WORDS:
            push_translation(mod, type, name, res_id, term)

    def get_root_view(xml_id):
        view = model_data_obj.xmlid_to_object(cr, uid, xml_id)
        if view:
            while view.mode != 'primary':
                view = view.inherit_id
        xml_id = view.get_external_id(cr, uid).get(view.id, xml_id)
        return xml_id

    for (xml_name,model,res_id,module) in cr.fetchall():
        module = encode(module)
        model = encode(model)
        xml_name = "%s.%s" % (module, encode(xml_name))

        if model not in registry:
            _logger.error("Unable to find object %r", model)
            continue

        Model = registry[model]
        if not Model._translate:
            # explicitly disabled
            continue

        obj = Model.browse(cr, uid, res_id)
        if not obj.exists():
            _logger.warning("Unable to find object %r with id %d", model, res_id)
            continue

        if model=='ir.model.fields':
            try:
                field_name = encode(obj.name)
            except AttributeError, exc:
                _logger.error("name error in %s: %s", xml_name, str(exc))
                continue
            field_model = registry.get(obj.model)
            if (field_model is None or not field_model._translate or
                    field_name not in field_model._fields):
                continue
            field_def = field_model._fields[field_name]

            if hasattr(field_def, 'selection') and isinstance(field_def.selection, (list, tuple)):
                name = "%s,%s" % (encode(obj.model), field_name)
                for dummy, val in field_def.selection:
                    push_translation(module, 'selection', name, 0, encode(val))

        elif model=='ir.actions.report.xml':
            name = encode(obj.report_name)
            fname = ""
            if obj.report_rml:
                fname = obj.report_rml
                parse_func = trans_parse_rml
                report_type = "report"
            elif obj.report_xsl:
                continue
            if fname and obj.report_type in ('pdf', 'xsl'):
                try:
                    report_file = misc.file_open(fname)
                    try:
                        d = etree.parse(report_file)
                        for t in parse_func(d.iter()):
                            push_translation(module, report_type, name, 0, t)
                    finally:
                        report_file.close()
                except (IOError, etree.XMLSyntaxError):
                    _logger.exception("couldn't export translation for report %s %s %s", name, report_type, fname)
Example #29
0
    def _tag_report(self, cr, rec, data_node=None, mode=None):
        res = {}
        #funkring.net begin
        report_type = rec.get('report_type')
        is_aeroo_report = report_type and report_type == "aeroo"
        if is_aeroo_report:
            res["tml_source"] = "file"
            res["parser_state"] = "loc"
            res["styles_mode"] = "global"
            res["active"] = True
            res["stylesheet_id"] = None
            for dest, f in (('in_format', 'in_format'), ('out_format',
                                                         'out_format')):
                res[dest] = rec.get(f, '').encode('utf8')
                assert res[dest], "Attribute %s of report is empty !" % (f, )
                if dest == 'out_format':
                    t_outFormatCode = res[dest]
                    t_ids = self.pool.get('report.mimetypes').search(
                        cr, self.uid, [('code', '=', t_outFormatCode)])
                    if t_ids:
                        res[dest] = t_ids[0]
                    else:
                        assert res[
                            dest], "Output format %s of report not found !" % (
                                f, )
        #funkring.net end
        for dest, f in (('name', 'string'), ('model', 'model'), ('report_name',
                                                                 'name')):
            res[dest] = rec.get(f, '').encode('utf8')
            assert res[dest], "Attribute %s of report is empty !" % (f, )
        for field, dest in (
            ('rml', 'report_rml'),
            ('file', 'report_rml'),
            ('xml', 'report_xml'),
            ('xsl', 'report_xsl'),
            ('attachment', 'attachment'),
            ('attachment_use', 'attachment_use'),
            ('usage', 'usage'),
                #funkring.net begin // aeroo report specific
            ('parser', 'parser_loc'),
            ('parser_state', 'parser_state'),
            ('stylesheet', 'styles_mode'),
            ('process_sep', 'process_sep'),
                #funkring.net end
            ('report_type', 'report_type'),
            ('parser', 'parser')):
            if rec.get(field):
                #funkring.net begin
                if field == "stylesheet":
                    value = rec.get(field).encode('utf8')
                    value_lower = value.lower()
                    if value_lower in ["none", "default"]:
                        res[dest] = "default"
                    elif value_lower in [
                            "global", "global_landscape", "intern",
                            "intern_landscape"
                    ]:
                        res[dest] = value_lower
                    else:
                        res[dest] = "specified"
                        stylesheet_ids = self.pool.get(
                            "report.stylesheets").search(
                                cr, self.uid, [("name", "=", value)])
                        assert stylesheet_ids, "Stylesheet %s not found!" % (
                            value, )
                        res["stylesheet_id"] = stylesheet_ids[0]
                elif field == "process_sep":
                    res["process_sep"] = eval(rec.get('process_sep', 'False'))
                else:
                    res[dest] = rec.get(field).encode('utf8')
                #funkrnig.net end
        if rec.get('auto'):
            res['auto'] = safe_eval(rec.get('auto', 'False'))
        if rec.get('sxw'):
            sxw_content = misc.file_open(rec.get('sxw')).read()
            res['report_sxw_content'] = sxw_content
        if rec.get('header'):
            res['header'] = safe_eval(rec.get('header', 'False'))

        res['multi'] = rec.get('multi') and safe_eval(rec.get(
            'multi', 'False'))

        xml_id = rec.get('id', '').encode('utf8')
        self._test_xml_id(xml_id)

        if rec.get('groups'):
            g_names = rec.get('groups', '').split(',')
            groups_value = []
            for group in g_names:
                if group.startswith('-'):
                    group_id = self.id_get(cr, group[1:])
                    groups_value.append((3, group_id))
                else:
                    group_id = self.id_get(cr, group)
                    groups_value.append((4, group_id))
            res['groups_id'] = groups_value

        #funkring.net begin // aeroo report specific
        full_xml_id = xml_id
        if not "." in full_xml_id:
            full_xml_id = "%s.%s" % (self.module, xml_id)

        report_rec = self.pool['ir.model.data'].xmlid_to_object(
            cr, self.uid, full_xml_id, raise_if_not_found=False)
        if report_rec and report_rec.report_type in (
                "qweb-pdf", "aeroo") and hasattr(
                    report_rec, "user_defined") and report_rec.user_defined:
            res["tml_source"] = report_rec.tml_source
            res["parser_state"] = report_rec.parser_state
            if report_rec.styles_mode == "specified":
                res["styles_mode"] = "specified"
                res["stylesheet_id"] = report_rec.stylesheet_id.id
        #funkring.net end

        id = self.pool['ir.model.data']._update(
            cr,
            self.uid,
            "ir.actions.report.xml",
            self.module,
            res,
            xml_id,
            noupdate=self.isnoupdate(data_node),
            mode=self.mode)
        self.idref[xml_id] = int(id)

        if not rec.get('menu') or safe_eval(rec.get('menu', 'False')):
            keyword = str(rec.get('keyword', 'client_print_multi'))
            value = 'ir.actions.report.xml,' + str(id)
            replace = rec.get('replace', True)
            self.pool['ir.model.data'].ir_set(cr,
                                              self.uid,
                                              'action',
                                              keyword,
                                              res['name'], [res['model']],
                                              value,
                                              replace=replace,
                                              isobject=True,
                                              xml_id=xml_id)
        elif self.mode == 'update' and safe_eval(rec.get('menu',
                                                         'False')) == False:
            # Special check for report having attribute menu=False on update
            value = 'ir.actions.report.xml,' + str(id)
            self._remove_ir_values(cr, res['name'], value, res['model'])
        return id
Example #30
0
def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, module_name=None, context=None):
    """Populates the ir_translation table."""
    if verbose:
        _logger.info('loading translation file for language %s', lang)
    if context is None:
        context = {}
    db_name = cr.dbname
    registry = openerp.registry(db_name)
    lang_obj = registry.get('res.lang')
    trans_obj = registry.get('ir.translation')
    iso_lang = misc.get_iso_codes(lang)
    try:
        ids = lang_obj.search(cr, SUPERUSER_ID, [('code','=', lang)])

        if not ids:
            # lets create the language with locale information
            lang_obj.load_lang(cr, SUPERUSER_ID, lang=lang, lang_name=lang_name)

        # Parse also the POT: it will possibly provide additional targets.
        # (Because the POT comments are correct on Launchpad but not the
        # PO comments due to a Launchpad limitation. See LP bug 933496.)
        pot_reader = []

        # now, the serious things: we read the language file
        fileobj.seek(0)
        if fileformat == 'csv':
            reader = csv.reader(fileobj, quotechar='"', delimiter=',')
            # read the first line of the file (it contains columns titles)
            for row in reader:
                fields = row
                break
        elif fileformat == 'po':
            reader = TinyPoFile(fileobj)
            fields = ['type', 'name', 'res_id', 'src', 'value', 'comments']

            # Make a reader for the POT file and be somewhat defensive for the
            # stable branch.
            if fileobj.name.endswith('.po'):
                try:
                    # Normally the path looks like /path/to/xxx/i18n/lang.po
                    # and we try to find the corresponding
                    # /path/to/xxx/i18n/xxx.pot file.
                    # (Sometimes we have 'i18n_extra' instead of just 'i18n')
                    addons_module_i18n, _ = os.path.split(fileobj.name)
                    addons_module, i18n_dir = os.path.split(addons_module_i18n)
                    addons, module = os.path.split(addons_module)
                    pot_handle = misc.file_open(os.path.join(
                        addons, module, i18n_dir, module + '.pot'))
                    pot_reader = TinyPoFile(pot_handle)
                except:
                    pass

        else:
            _logger.info('Bad file format: %s', fileformat)
            raise Exception(_('Bad file format'))

        # Read the POT references, and keep them indexed by source string.
        class Target(object):
            def __init__(self):
                self.value = None
                self.targets = set()            # set of (type, name, res_id)
                self.comments = None

        pot_targets = defaultdict(Target)
        for type, name, res_id, src, _, comments in pot_reader:
            if type is not None:
                target = pot_targets[src]
                target.targets.add((type, name, res_id))
                target.comments = comments

        # read the rest of the file
        irt_cursor = trans_obj._get_import_cursor(cr, SUPERUSER_ID, context=context)

        def process_row(row):
            """Process a single PO (or POT) entry."""
            # dictionary which holds values for this line of the csv file
            # {'lang': ..., 'type': ..., 'name': ..., 'res_id': ...,
            #  'src': ..., 'value': ..., 'module':...}
            dic = dict.fromkeys(('type', 'name', 'res_id', 'src', 'value',
                                 'comments', 'imd_model', 'imd_name', 'module'))
            dic['lang'] = lang
            dic.update(zip(fields, row))

            # discard the target from the POT targets.
            src = dic['src']
            if src in pot_targets:
                target = pot_targets[src]
                target.value = dic['value']
                target.targets.discard((dic['type'], dic['name'], dic['res_id']))

            # This would skip terms that fail to specify a res_id
            res_id = dic['res_id']
            if not res_id:
                return

            if isinstance(res_id, (int, long)) or \
                    (isinstance(res_id, basestring) and res_id.isdigit()):
                dic['res_id'] = int(res_id)
                dic['module'] = module_name
            else:
                # res_id is an xml id
                dic['res_id'] = None
                dic['imd_model'] = dic['name'].split(',')[0]
                if '.' in res_id:
                    dic['module'], dic['imd_name'] = res_id.split('.', 1)
                else:
                    dic['module'], dic['imd_name'] = False, res_id

            irt_cursor.push(dic)

        # First process the entries from the PO file (doing so also fills/removes
        # the entries from the POT file).
        for row in reader:
            process_row(row)

        # Then process the entries implied by the POT file (which is more
        # correct w.r.t. the targets) if some of them remain.
        pot_rows = []
        for src, target in pot_targets.iteritems():
            if target.value:
                for type, name, res_id in target.targets:
                    pot_rows.append((type, name, res_id, src, target.value, target.comments))
        pot_targets.clear()
        for row in pot_rows:
            process_row(row)

        irt_cursor.finish()
        trans_obj.clear_caches()
        if verbose:
            _logger.info("translation file loaded succesfully")

    except IOError:
        filename = '[lang: %s][format: %s]' % (iso_lang or 'new', fileformat)
        _logger.exception("couldn't read translation file %s", filename)
Example #31
0
import fparser
import misc as appmisc
import sys

# make sure this file is being run directly
if __name__ == '__main__':
    if len(sys.argv) == 1:
        appmisc.usage(sys.argv[0])
        exit(1)
    else:
        file = appmisc.file_open(sys.argv[1])
        if (file != None):
            appparser = fparser.Parser(file)
            appparser.parse()
            appmisc.file_close(file)
        else:
            appmisc.print_err("{}: no such file or directory".format(sys.argv[1]))
            exit(1)
        pass
Example #32
0
def trans_generate(lang, modules, cr):
    dbname = cr.dbname

    registry = openerp.registry(dbname)
    trans_obj = registry['ir.translation']
    model_data_obj = registry['ir.model.data']
    uid = 1

    query = 'SELECT name, model, res_id, module' \
            '  FROM ir_model_data'

    query_models = """SELECT m.id, m.model, imd.module
            FROM ir_model AS m, ir_model_data AS imd
            WHERE m.id = imd.res_id AND imd.model = 'ir.model' """

    if 'all_installed' in modules:
        query += ' WHERE module IN ( SELECT name FROM ir_module_module WHERE state = \'installed\') '
        query_models += " AND imd.module in ( SELECT name FROM ir_module_module WHERE state = 'installed') "
    query_param = None
    if 'all' not in modules:
        query += ' WHERE module IN %s'
        query_models += ' AND imd.module in %s'
        query_param = (tuple(modules), )
    query += ' ORDER BY module, model, name'
    query_models += ' ORDER BY module, model'

    cr.execute(query, query_param)

    _to_translate = set()

    def push_translation(module, type, name, id, source, comments=None):
        # empty and one-letter terms are ignored, they probably are not meant to be
        # translated, and would be very hard to translate anyway.
        sanitized_term = (source or '').strip()
        try:
            # verify the minimal size without eventual xml tags
            # wrap to make sure html content like '<a>b</a><c>d</c>' is accepted by lxml
            wrapped = "<div>%s</div>" % sanitized_term
            node = etree.fromstring(wrapped)
            sanitized_term = etree.tostring(node,
                                            encoding='UTF-8',
                                            method='text')
        except etree.ParseError:
            pass
        # remove non-alphanumeric chars
        sanitized_term = re.sub(r'\W+', '', sanitized_term)
        if not sanitized_term or len(sanitized_term) <= 1:
            return

        tnx = (module, source, name, id, type, tuple(comments or ()))
        _to_translate.add(tnx)

    def push(mod, type, name, res_id, term):
        term = (term or '').strip()
        if len(term) > 2 or term in ENGLISH_SMALL_WORDS:
            push_translation(mod, type, name, res_id, term)

    def get_root_view(xml_id):
        view = model_data_obj.xmlid_to_object(cr, uid, xml_id)
        if view:
            while view.mode != 'primary':
                view = view.inherit_id
        xml_id = view.get_external_id(cr, uid).get(view.id, xml_id)
        return xml_id

    for (xml_name, model, res_id, module) in cr.fetchall():
        module = encode(module)
        model = encode(model)
        xml_name = "%s.%s" % (module, encode(xml_name))

        if model not in registry:
            _logger.error("Unable to find object %r", model)
            continue

        Model = registry[model]
        if not Model._translate:
            # explicitly disabled
            continue

        obj = Model.browse(cr, uid, res_id)
        if not obj.exists():
            _logger.warning("Unable to find object %r with id %d", model,
                            res_id)
            continue

        if model == 'ir.model.fields':
            try:
                field_name = encode(obj.name)
            except AttributeError, exc:
                _logger.error("name error in %s: %s", xml_name, str(exc))
                continue
            field_model = registry.get(obj.model)
            if (field_model is None or not field_model._translate
                    or field_name not in field_model._fields):
                continue
            field_def = field_model._fields[field_name]

            if hasattr(field_def, 'selection') and isinstance(
                    field_def.selection, (list, tuple)):
                name = "%s,%s" % (encode(obj.model), field_name)
                for dummy, val in field_def.selection:
                    push_translation(module, 'selection', name, 0, encode(val))

        elif model == 'ir.actions.report.xml':
            name = encode(obj.report_name)
            fname = ""
            if obj.report_rml:
                fname = obj.report_rml
                parse_func = trans_parse_rml
                report_type = "report"
            elif obj.report_xsl:
                continue
            if fname and obj.report_type in ('pdf', 'xsl'):
                try:
                    report_file = misc.file_open(fname)
                    try:
                        d = etree.parse(report_file)
                        for t in parse_func(d.iter()):
                            push_translation(module, report_type, name, 0, t)
                    finally:
                        report_file.close()
                except (IOError, etree.XMLSyntaxError):
                    _logger.exception(
                        "couldn't export translation for report %s %s %s",
                        name, report_type, fname)