示例#1
0
def load_information_from_description_file(module, mod_path=None):
    """
    :param module: The name of the module (sale, purchase, ...)
    :param mod_path: Physical path of module, if not providedThe name of the module (sale, purchase, ...)
    """

    if not mod_path:
        mod_path = get_module_path(module)
    terp_file = mod_path and opj(mod_path, MANIFEST) or False
    if terp_file:
        info = {}
        if os.path.isfile(terp_file):
            # default values for descriptor
            info = {
                'application': False,
                'author': 'YuanCloud SA',
                'auto_install': False,
                'category': 'Uncategorized',
                'depends': [],
                'description': '',
                'icon': get_module_icon(module),
                'installable': True,
                'license': 'LGPL-3',
                'post_load': None,
                'version': '1.0',
                'web': False,
                'website': 'http://www.yuancloud.cn',
                'sequence': 100,
                'summary': '',
            }
            info.update(itertools.izip(
                'depends data demo test init_xml update_xml demo_xml'.split(),
                iter(list, None)))

            f = tools.file_open(terp_file)
            try:
                info.update(eval(f.read()))
            finally:
                f.close()

            if not info.get('description'):
                readme_path = [opj(mod_path, x) for x in README
                               if os.path.isfile(opj(mod_path, x))]
                if readme_path:
                    readme_text = tools.file_open(readme_path[0]).read()
                    info['description'] = readme_text

            if 'active' in info:
                # 'active' has been renamed 'auto_install'
                info['auto_install'] = info['active']

            info['version'] = adapt_version(info['version'])
            return info

    #TODO: refactor the logger in this file to follow the logging guidelines
    #      for 6.0
    _logger.debug('module %s: no %s file found.', module, MANIFEST)
    return {}
示例#2
0
 def parse(self, filename, ids, model, context=None):
     if not context:
         context={}
     # parses the xml template to memory
     src_file = tools.file_open(filename)
     try:
         self.dom = etree.XML(src_file.read())
         self.doc = etree.Element(self.dom.tag)
         self.parse_tree(ids, model, context)
     finally:
         src_file.close()
示例#3
0
    def create(self, cr, uid, ids, data, context=None):
        context = dict(context or {})
        if self.internal_header:
            context.update(internal_header=self.internal_header)

        # skip osv.fields.sanitize_binary_value() because we want the raw bytes in all cases
        context.update(bin_raw=True)
        registry = yuancloud.registry(cr.dbname)
        ir_obj = registry['ir.actions.report.xml']
        registry['res.font'].font_scan(cr, SUPERUSER_ID, lazy=True, context=context)

        report_xml_ids = ir_obj.search(cr, uid,
                [('report_name', '=', self.name[7:])], context=context)
        if report_xml_ids:
            report_xml = ir_obj.browse(cr, uid, report_xml_ids[0], context=context)
        else:
            title = ''
            report_file = tools.file_open(self.tmpl, subdir=None)
            try:
                rml = report_file.read()
                report_type= data.get('report_type', 'pdf')
                class a(object):
                    def __init__(self, *args, **argv):
                        for key,arg in argv.items():
                            setattr(self, key, arg)
                report_xml = a(title=title, report_type=report_type, report_rml_content=rml, name=title, attachment=False, header=self.header)
            finally:
                report_file.close()

        # We add an attribute on the ir.actions.report.xml instance.
        # This attribute 'use_global_header' will be used by
        # the create_single_XXX function of the report engine.
        # This change has been done to avoid a big change of the API.
        setattr(report_xml, 'use_global_header', self.header if report_xml.header else False)

        report_type = report_xml.report_type
        if report_type in ['sxw','odt']:
            fnct = self.create_source_odt
        elif report_type in ['pdf','raw','txt','html']:
            fnct = self.create_source_pdf
        elif report_type=='html2html':
            fnct = self.create_source_html2html
        elif report_type=='mako2html':
            fnct = self.create_source_mako2html
        else:
            raise NotImplementedError(_('Unknown report type: %s') % report_type)
        fnct_ret = fnct(cr, uid, ids, data, report_xml, context)
        if not fnct_ret:
            return False, False
        return fnct_ret
示例#4
0
    def create_single_odt(self, cr, uid, ids, data, report_xml, context=None):
        context = dict(context or {})
        context['parents'] = sxw_parents
        report_type = report_xml.report_type
        binary_report_content = report_xml.report_sxw_content
        if isinstance(report_xml.report_sxw_content, unicode):
            # if binary content was passed as unicode, we must
            # re-encode it as a 8-bit string using the pass-through
            # 'latin1' encoding, to restore the original byte values.
            # See also osv.fields.sanitize_binary_value()
            binary_report_content = report_xml.report_sxw_content.encode("latin1")

        sxw_io = StringIO.StringIO(binary_report_content)
        sxw_z = zipfile.ZipFile(sxw_io, mode='r')
        rml = sxw_z.read('content.xml')
        meta = sxw_z.read('meta.xml')
        mime_type = sxw_z.read('mimetype')
        if mime_type == 'application/vnd.sun.xml.writer':
            mime_type = 'sxw'
        else :
            mime_type = 'odt'
        sxw_z.close()

        rml_parser = self.parser(cr, uid, self.name2, context=context)
        rml_parser.parents = sxw_parents
        rml_parser.tag = sxw_tag
        objs = self.getObjects(cr, uid, ids, context)
        rml_parser.set_context(objs, data, ids, mime_type)

        rml_dom_meta = node = etree.XML(meta)
        elements = node.findall(rml_parser.localcontext['name_space']["meta"]+"user-defined")
        for pe in elements:
            if pe.get(rml_parser.localcontext['name_space']["meta"]+"name"):
                if pe.get(rml_parser.localcontext['name_space']["meta"]+"name") == "Info 3":
                    pe[0].text=data['id']
                if pe.get(rml_parser.localcontext['name_space']["meta"]+"name") == "Info 4":
                    pe[0].text=data['model']
        meta = etree.tostring(rml_dom_meta, encoding='utf-8',
                              xml_declaration=True)

        rml_dom =  etree.XML(rml)
        elements = []
        key1 = rml_parser.localcontext['name_space']["text"]+"p"
        key2 = rml_parser.localcontext['name_space']["text"]+"drop-down"
        for n in rml_dom.iterdescendants():
            if n.tag == key1:
                elements.append(n)
        if mime_type == 'odt':
            for pe in elements:
                e = pe.findall(key2)
                for de in e:
                    pp=de.getparent()
                    if de.text or de.tail:
                        pe.text = de.text or de.tail
                    for cnd in de:
                        if cnd.text or cnd.tail:
                            if pe.text:
                                pe.text +=  cnd.text or cnd.tail
                            else:
                                pe.text =  cnd.text or cnd.tail
                            pp.remove(de)
        else:
            for pe in elements:
                e = pe.findall(key2)
                for de in e:
                    pp = de.getparent()
                    if de.text or de.tail:
                        pe.text = de.text or de.tail
                    for cnd in de:
                        text = cnd.get("{http://openoffice.org/2000/text}value",False)
                        if text:
                            if pe.text and text.startswith('[['):
                                pe.text +=  text
                            elif text.startswith('[['):
                                pe.text =  text
                            if de.getparent():
                                pp.remove(de)

        rml_dom = self.preprocess_rml(rml_dom, mime_type)
        create_doc = self.generators[mime_type]
        odt = etree.tostring(create_doc(rml_dom, rml_parser.localcontext),
                             encoding='utf-8', xml_declaration=True)
        sxw_contents = {'content.xml':odt, 'meta.xml':meta}

        if report_xml.use_global_header:
            #Add corporate header/footer
            rml_file = tools.file_open(os.path.join('base', 'report', 'corporate_%s_header.xml' % report_type))
            try:
                rml = rml_file.read()
                rml_parser = self.parser(cr, uid, self.name2, context=context)
                rml_parser.parents = sxw_parents
                rml_parser.tag = sxw_tag
                objs = self.getObjects(cr, uid, ids, context)
                rml_parser.set_context(objs, data, ids, report_xml.report_type)
                rml_dom = self.preprocess_rml(etree.XML(rml),report_type)
                create_doc = self.generators[report_type]
                odt = create_doc(rml_dom,rml_parser.localcontext)
                if report_xml.use_global_header:
                    rml_parser._add_header(odt)
                odt = etree.tostring(odt, encoding='utf-8',
                                     xml_declaration=True)
                sxw_contents['styles.xml'] = odt
            finally:
                rml_file.close()

        #created empty zip writing sxw contents to avoid duplication
        sxw_out = StringIO.StringIO()
        sxw_out_zip = zipfile.ZipFile(sxw_out, mode='w')
        sxw_template_zip = zipfile.ZipFile (sxw_io, 'r')
        for item in sxw_template_zip.infolist():
            if item.filename not in sxw_contents:
                buffer = sxw_template_zip.read(item.filename)
                sxw_out_zip.writestr(item.filename, buffer)
        for item_filename, buffer in sxw_contents.iteritems():
            sxw_out_zip.writestr(item_filename, buffer)
        sxw_template_zip.close()
        sxw_out_zip.close()
        final_op = sxw_out.getvalue()
        sxw_io.close()
        sxw_out.close()
        return final_op, mime_type
示例#5
0
    def create_rml(self, cr, xml, uid, context=None):
        if self.tmpl == '' and not self.internal_header:
            self.internal_header = True
        if not context:
            context = {}
        registry = yuancloud.registry(cr.dbname)
        ir_translation_obj = registry['ir.translation']

        # In some case we might not use xsl ...
        if not self.xsl:
            return xml

        stylesheet_file = tools.file_open(self.xsl)
        try:
            stylesheet = etree.parse(stylesheet_file)
            xsl_path, _ = os.path.split(self.xsl)
            for import_child in stylesheet.findall('./import'):
                if 'href' in import_child.attrib:
                    imp_file = import_child.get('href')
                    _, imp_file = tools.file_open(imp_file,
                                                  subdir=xsl_path,
                                                  pathinfo=True)
                    import_child.set('href', urllib.quote(str(imp_file)))
                    imp_file.close()
        finally:
            stylesheet_file.close()

        #TODO: get all the translation in one query. That means we have to:
        # * build a list of items to translate,
        # * issue the query to translate them,
        # * (re)build/update the stylesheet with the translated items

        def translate(doc, lang):
            translate_aux(doc, lang, False)

        def translate_aux(doc, lang, t):
            for node in doc:
                t = t or node.get("t")
                if t:
                    text = None
                    tail = None
                    if node.text:
                        text = node.text.strip().replace('\n', ' ')
                    if node.tail:
                        tail = node.tail.strip().replace('\n', ' ')
                    if text:
                        translation1 = ir_translation_obj._get_source(
                            cr, uid, self.name2, 'xsl', lang, text)
                        if translation1:
                            node.text = node.text.replace(text, translation1)
                    if tail:
                        translation2 = ir_translation_obj._get_source(
                            cr, uid, self.name2, 'xsl', lang, tail)
                        if translation2:
                            node.tail = node.tail.replace(tail, translation2)
                translate_aux(node, lang, t)

        if context.get('lang', False):
            translate(stylesheet.iter(), context['lang'])

        transform = etree.XSLT(stylesheet)
        xml = etree.tostring(transform(etree.fromstring(xml)))

        return xml
示例#6
0
    def migrate_module(self, pkg, stage):
        assert stage in ('pre', 'post')
        stageformat = {
            'pre': '[>%s]',
            'post': '[%s>]',
        }

        if not (hasattr(pkg, 'update')
                or pkg.state == 'to upgrade') or pkg.state == 'to install':
            return

        def convert_version(version):
            if version.count('.') >= 2:
                return version  # the version number already containt the server version
            return "%s.%s" % (release.major_version, version)

        def _get_migration_versions(pkg):
            def __get_dir(tree):
                return [d for d in tree if tree[d] is not None]

            versions = list(
                set(
                    __get_dir(self.migrations[pkg.name]['module']) +
                    __get_dir(self.migrations[pkg.name]['maintenance'])))
            versions.sort(key=lambda k: parse_version(convert_version(k)))
            return versions

        def _get_migration_files(pkg, version, stage):
            """ return a list of tuple (module, file)
            """
            m = self.migrations[pkg.name]
            lst = []

            mapping = {
                'module': opj(pkg.name, 'migrations'),
                'maintenance': opj('base', 'maintenance', 'migrations',
                                   pkg.name),
            }

            for x in mapping.keys():
                if version in m[x]:
                    for f in m[x][version]:
                        if m[x][version][f] is not None:
                            continue
                        if not f.startswith(stage + '-'):
                            continue
                        lst.append(opj(mapping[x], version, f))
            lst.sort()
            return lst

        parsed_installed_version = parse_version(pkg.installed_version or '')
        current_version = parse_version(convert_version(pkg.data['version']))

        versions = _get_migration_versions(pkg)

        for version in versions:
            if parsed_installed_version < parse_version(
                    convert_version(version)) <= current_version:

                strfmt = {
                    'addon': pkg.name,
                    'stage': stage,
                    'version': stageformat[stage] % version,
                }

                for pyfile in _get_migration_files(pkg, version, stage):
                    name, ext = os.path.splitext(os.path.basename(pyfile))
                    if ext.lower() != '.py':
                        continue
                    mod = fp = fp2 = None
                    try:
                        fp, fname = tools.file_open(pyfile, pathinfo=True)

                        if not isinstance(fp, file):
                            # imp.load_source need a real file object, so we create
                            # one from the file-like object we get from file_open
                            fp2 = os.tmpfile()
                            fp2.write(fp.read())
                            fp2.seek(0)
                        try:
                            mod = imp.load_source(name, fname, fp2 or fp)
                            _logger.info(
                                'module %(addon)s: Running migration %(version)s %(name)s'
                                % dict(strfmt, name=mod.__name__))
                            migrate = mod.migrate
                        except ImportError:
                            _logger.exception(
                                'module %(addon)s: Unable to load %(stage)s-migration file %(file)s'
                                % dict(strfmt, file=pyfile))
                            raise
                        except AttributeError:
                            _logger.error(
                                'module %(addon)s: Each %(stage)s-migration file must have a "migrate(cr, installed_version)" function'
                                % strfmt)
                        else:
                            migrate(self.cr, pkg.installed_version)
                    finally:
                        if fp:
                            fp.close()
                        if fp2:
                            fp2.close()
                        if mod:
                            del mod