Imrpoved addons path support
authorAmit Mendapara <ame@tinyerp.com>
Thu, 17 Jul 2008 09:55:16 +0000 (15:25 +0530)
committerAmit Mendapara <ame@tinyerp.com>
Thu, 17 Jul 2008 09:55:16 +0000 (15:25 +0530)
- Imrpoved tools.file_open to override search path
- Removed addons.get_report_resource
- Code cleanup and minor changes

bzr revid: ame@tinyerp.com-20080717095516-191aflvin9ztd45z

bin/addons/__init__.py
bin/addons/base/ir/ir_actions.py
bin/addons/base/module/module.py
bin/report/interface.py
bin/report/print_xml.py
bin/report/report_sxw.py
bin/tools/misc.py

index f400ad9..cefd685 100644 (file)
@@ -135,17 +135,13 @@ def get_module_path(module):
        """Return the path of the given module.
        """
 
-       if os.path.exists(opj(ad, module)):
+       if os.path.exists(opj(ad, module)) or os.path.exists(opj(ad, '%s.zip' % module)):
                return opj(ad, module)
 
-       if os.path.exists(opj(ad, '%s.zip' % module)):
-               return opj(ad, '%s.zip' % module)
-
-       if os.path.exists(opj(_ad, module)):
+       if os.path.exists(opj(_ad, module)) or os.path.exists(opj(_ad, '%s.zip' % module)):
                return opj(_ad, module)
 
-       if os.path.exists(opj(_ad, '%s.zip' % module)):
-               return opj(_ad, '%s.zip' % module)
+       raise IOError, 'Module not found : %s' % module
 
 def get_module_resource(module, *args):
        """Return the full path of a resource of the given module.
@@ -157,38 +153,6 @@ def get_module_resource(module, *args):
        """
        return opj(get_module_path(module), *args)
 
-def get_report_resource(resource, base=None):
-       """Return the full path of the given report resource.
-       
-       >>>
-       >>> get_report_resource('hr/reports/timesheet.xsl')
-       >>> get_report_resource('addons/hr/reports/timesheet.xsl')
-       >>> get_report_resource('../../base/reports/rml_template.xsl', '/path/to/addons/hr/reports')
-       >>>
-       """
-
-       if base:
-               # default location
-               fname = os.path.normpath(os.path.join(base, resource))
-               if os.path.exists(fname):
-                       return fname
-
-               # check in base location
-               base = base.replace(ad, _ad)
-               fname = os.path.normpath(os.path.join(base, resource))
-               if os.path.exists(fname):
-                       return fname
-
-               assert os.path.exists(fname), 'File does not exist: %s' % fname
-
-       if resource.startswith('addons'):
-               resource = resource.replace('addons', '', 1)
-
-       fname = os.path.join(ad, resource)
-       if os.path.exists(fname):
-               return fname
-       return os.path.join(_ad, resource)
-
 def get_modules():
        """Returns the list of module names
        """
@@ -284,24 +248,24 @@ def load_module_graph(cr, graph, status=None, **kwargs):
                                        logger.notifyChannel('init', netsvc.LOG_INFO, 'addon:%s:loading %s' % (m, filename))
                                        name, ext = os.path.splitext(filename)
                                        if ext == '.csv':
-                                               tools.convert_csv_import(cr, m, os.path.basename(filename), tools.file_open(get_module_resource(m, filename)).read(), idref, mode=mode)
+                                               tools.convert_csv_import(cr, m, os.path.basename(filename), tools.file_open(opj(m, filename)).read(), idref, mode=mode)
                                        elif ext == '.sql':
-                                               queries = tools.file_open(get_module_resource(m, filename)).read().split(';')
+                                               queries = tools.file_open(opj(m, filename)).read().split(';')
                                                for query in queries:
                                                        new_query = ' '.join(query.split())
                                                        if new_query:
                                                                cr.execute(new_query)
                                        else:
-                                               tools.convert_xml_import(cr, m, tools.file_open(get_module_resource(m, filename)), idref, mode=mode, **kwargs)
+                                               tools.convert_xml_import(cr, m, tools.file_open(opj(m, filename)), idref, mode=mode, **kwargs)
                        if hasattr(package, 'demo') or (package_demo and package_state != 'installed'):
                                status['progress'] = (float(statusi)+0.75)/len(graph)
                                for xml in package.datas.get('demo_xml', []):
                                        name, ext = os.path.splitext(xml)
                                        logger.notifyChannel('init', netsvc.LOG_INFO, 'addon:%s:loading %s' % (m, xml))
                                        if ext == '.csv':
-                                               tools.convert_csv_import(cr, m, os.path.basename(xml), tools.file_open(get_module_resource(m, xml)).read(), idref, noupdate=True)
+                                               tools.convert_csv_import(cr, m, os.path.basename(xml), tools.file_open(opj(m, xml)).read(), idref, noupdate=True)
                                        else:
-                                               tools.convert_xml_import(cr, m, tools.file_open(get_module_resource(m, xml)), idref, noupdate=True, **kwargs)
+                                               tools.convert_xml_import(cr, m, tools.file_open(opj(m, xml)), idref, noupdate=True, **kwargs)
                                cr.execute('update ir_module_module set demo=%s where name=%s', (True, package.name))
                        package_todo.append(package.name)
                        cr.execute("update ir_module_module set state='installed' where state in ('to upgrade', 'to install') and name=%s", (package.name,))
@@ -324,13 +288,13 @@ def register_classes():
                sys.stdout.flush()
 
                mod_path = get_module_path(m)
-               if not os.path.isfile(mod_path):
+               if not os.path.isfile(mod_path+'.zip'):
                        # XXX must restrict to only addons paths
                        imp.load_module(m, *imp.find_module(m))
                else:
                        import zipimport
                        try:
-                               zimp = zipimport.zipimporter(mod_path)
+                               zimp = zipimport.zipimporter(mod_path+'.zip')
                                zimp.load_module(m)
                        except zipimport.ZipImportError:
                                logger.notifyChannel('init', netsvc.LOG_ERROR, 'Couldn\'t find module %s' % m)
index 6d9d418..a4a7ae7 100644 (file)
@@ -29,7 +29,6 @@
 
 from osv import fields,osv
 import tools
-import addons
 import time
 
 class actions(osv.osv):
@@ -72,7 +71,7 @@ class report_xml(osv.osv):
                        data = report[name + '_data']
                        if not data and report[name[:-8]]:
                                try:
-                                       fp = tools.file_open(addons.get_report_resource(report[name[:-8]]), mode='rb')
+                                       fp = tools.file_open(report[name[:-8]], mode='rb')
                                        data = fp.read()
                                except:
                                        data = False
index a876b43..1ad9a84 100644 (file)
@@ -197,7 +197,7 @@ class module(osv.osv):
 
        def get_module_info(self, name):
                try:
-                       f = tools.file_open(addons.get_module_resource(name, '__terp__.py'))
+                       f = tools.file_open(os.path.join(name, '__terp__.py'))
                        data = f.read()
                        info = eval(data)
                        if 'version' in info:
@@ -387,13 +387,13 @@ class module(osv.osv):
                                terp = self.get_module_info(mod_name)
                                if not terp or not terp.get('installable', True):
                                        continue
-                               if not os.path.isfile(mod_path):
+                               if not os.path.isfile(mod_path+'.zip'):
                                        import imp
                                        # XXX must restrict to only addons paths
                                        imp.load_module(name, *imp.find_module(mod_name))
                                else:
                                        import zipimport
-                                       zimp = zipimport.zipimporter(mod_path)
+                                       zimp = zipimport.zipimporter(mod_path+'.zip')
                                        zimp.load_module(mod_name)
                                id = self.create(cr, uid, {
                                        'name': mod_name,
@@ -481,7 +481,7 @@ class module(osv.osv):
                        if not download:
                                continue
                        zipfile = urllib.urlopen(mod.url).read()
-                       fname = addons.get_module_path(mod.name)
+                       fname = addons.get_module_path(mod.name+'.zip')
                        try:
                                fp = file(fname, 'wb')
                                fp.write(zipfile)
index abd955f..63757ad 100644 (file)
@@ -79,7 +79,7 @@ class report_rml(report_int):
        def __init__(self, name, table, tmpl, xsl):
                super(report_rml, self).__init__(name)
                self.table = table
-               self.tmpl = addons.get_report_resource(tmpl)
+               self.tmpl = tmpl
                self.xsl = xsl
                self.bin_datas = {}
                self.generators = {
@@ -122,7 +122,7 @@ class report_rml(report_int):
                pos_xml = i.end()
 
                doc = print_xml.document(cr, uid, {}, {})
-               tmpl_path = addons.get_report_resource('addons/custom/corporate_defaults.xml')
+               tmpl_path = addons.get_module_resource('custom', 'corporate_defaults.xml')
                doc.parse(tmpl_path, [uid], 'res.users', context)
                corporate_header = doc.xml_get()
                doc.close()
@@ -147,13 +147,14 @@ class report_rml(report_int):
                        return xml
 
                # load XSL (parse it to the XML level)
-               styledoc = libxml2.parseDoc(tools.file_open(addons.get_report_resource(self.xsl)).read())
-               xsl_path, tail = os.path.split(addons.get_report_resource(self.xsl))
+               styledoc = libxml2.parseDoc(tools.file_open(self.xsl).read())
+               xsl_path, tail = os.path.split(self.xsl)
                for child in styledoc.children:
                        if child.name == 'import':
                                if child.hasProp('href'):
-                                       file = child.prop('href')
-                                       child.setProp('href', urllib.quote(str(addons.get_report_resource(file, base=xsl_path))))
+                                       imp_file = child.prop('href')
+                                       _x, imp_file = tools.file_open(imp_file, subdir=xsl_path, pathinfo=True)
+                                       child.setProp('href', urllib.quote(str(imp_file)))
 
                #TODO: get all the translation in one query. That means we have to:
                # * build a list of items to translate,
index 2370f53..75c700e 100644 (file)
@@ -353,9 +353,7 @@ class document(object):
                if not context:
                        context={}
                # parses the xml template to memory
-               self.dom = minidom.parseString(tools.file_open(
-                               os.path.join(tools.config['root_path'],
-                                       filename)).read())
+               self.dom = minidom.parseString(tools.file_open(filename).read())
 
                # create the xml data from the xml template
                self.parse_tree(ids, model, context)
index 8e5acba..586527a 100644 (file)
@@ -35,7 +35,6 @@ import osv
 from interface import  report_rml
 import re
 import tools
-import addons
 import pooler
 import netsvc
 import warnings
@@ -573,7 +572,7 @@ class report_sxw(report_rml):
                        rml = report_xml.report_rml_content
                        report_type = report_xml.report_type
                else:
-                       rml = tools.file_open(addons.get_report_resource(self.tmpl), subdir=None).read()
+                       rml = tools.file_open(self.tmpl, subdir=None).read()
                        report_type= data.get('report_type', report_type)
 
                if report_type == 'sxw' and report_xml:
@@ -626,7 +625,7 @@ class report_sxw(report_rml):
 
                        if self.header:
                                #Add corporate header/footer
-                               rml = tools.file_open(addons.get_report_resource('addons/custom/corporate_sxw_header.xml')).read()
+                               rml = tools.file_open('custom/corporate_sxw_header.xml').read()
                                rml_parser = self.parser(cr, uid, self.name2, context)
                                rml_parser.parents = sxw_parents
                                rml_parser.tag = sxw_tag
index 1c0cc89..4523c76 100644 (file)
@@ -61,12 +61,12 @@ def init_db(cr):
                terp_file = addons.get_module_resource(i, '__terp__.py')
                mod_path = addons.get_module_path(i)
                info = False
-               if os.path.isfile(terp_file) and not os.path.isfile(mod_path):
+               if os.path.isfile(terp_file) and not os.path.isfile(mod_path+'.zip'):
                        info = eval(file(terp_file).read())
-               elif zipfile.is_zipfile(mod_path):
-                       zfile = zipfile.ZipFile(mod_path)
+               elif zipfile.is_zipfile(mod_path+'.zip'):
+                       zfile = zipfile.ZipFile(mod_path+'.zip')
                        i = os.path.splitext(i)[0]
-                       info = eval(zfile.read(addons.get_module_resource(i, '__terp__.py')))
+                       info = eval(zfile.read(os.path.join(i, '__terp__.py')))
                if info:
                        categs = info.get('category', 'Uncategorized').split('/')
                        p_id = None
@@ -168,14 +168,55 @@ def exec_command_pipe(name, *args):
 #file_path_root = os.getcwd()
 #file_path_addons = os.path.join(file_path_root, 'addons')
 
-def file_open(name, mode="r", subdir='addons'):
-       """Open a file from the Tiny ERP root, using a subdir folder."""
-       if os.path.isabs(name) and os.path.exists(name):
-               pass
+def file_open(name, mode="r", subdir='addons', pathinfo=False):
+       """Open a file from the Tiny ERP root, using a subdir folder.
+
+       >>> file_open('hr/report/timesheer.xsl')
+       >>> file_open('addons/hr/report/timesheet.xsl')
+       >>> file_open('../../base/report/rml_template.xsl', subdir='addons/hr/report', pathinfo=True)
+
+       @param name: name of the file
+       @param mode: file open mode
+       @param subdir: subdirectory
+       @param pathinfo: if True returns tupple (fileobject, filepath)
+
+       @return: fileobject if pathinfo is False else (fileobject, filepath)
+       """
+
+       adp = os.path.normcase(os.path.abspath(config['addons_path']))
+       rtp = os.path.normcase(os.path.abspath(config['root_path']))
+
+       if name.replace(os.path.sep, '/').startswith('addons/'):
+               subdir = 'addons'
+               name = name[7:]
+
+       # First try to locate in addons_path
+       if subdir:
+               subdir2 = subdir
+               if subdir2.replace(os.path.sep, '/').startswith('addons/'):
+                       subdir2 = subdir2[7:]
+
+               subdir2 = (subdir2 != 'addons' or None) and subdir2
+
+               try:
+                       if subdir2:
+                               fn = os.path.join(adp, subdir2, name)
+                       else:
+                               fn = os.path.join(adp, name)
+                       fn = os.path.normpath(fn)
+                       fo = file_open(fn, mode=mode, subdir=None, pathinfo=pathinfo)
+                       if pathinfo:
+                               return fo, fn
+                       return fo
+               except IOError, e:
+                       pass
+
        if subdir:
-               name = os.path.join(config['root_path'], subdir, name)
+               name = os.path.join(rtp, subdir, name)
        else:
-               name = os.path.join(config['root_path'], name)
+               name = os.path.join(rtp, name)
+
+       name = os.path.normpath(name)
 
        # Check for a zipfile in the path
        head = name
@@ -189,25 +230,26 @@ def file_open(name, mode="r", subdir='addons'):
                        zipname = os.path.join(tail, zipname)
                else:
                        zipname = tail
-
-               zname = head
-               if zipfile.is_zipfile(head + '.zip'):
-                       zname = head + '.zip'
-
-               if zipfile.is_zipfile(zname):
+               if zipfile.is_zipfile(head+'.zip'):
                        import StringIO
-                       zfile = zipfile.ZipFile(zname)
+                       zfile = zipfile.ZipFile(head+'.zip')
                        try:
-                               zname = os.path.splitext(zname)[0]
-                               return StringIO.StringIO(zfile.read(os.path.join(
-                                       os.path.basename(zname), zipname).replace(
+                               fo = StringIO.StringIO(zfile.read(os.path.join(
+                                       os.path.basename(head), zipname).replace(
                                                os.sep, '/')))
+
+                               if pathinfo:
+                                       return fo, name
+                               return fo
                        except:
-                               name2 = os.path.normpath(os.path.join(zname + '.zip', zipname))
+                               name2 = os.path.normpath(os.path.join(head + '.zip', zipname))
                                pass
        for i in (name2, name):
                if i and os.path.isfile(i):
-                       return file(i, mode)
+                       fo = file(i, mode)
+                       if pathinfo:
+                               return fo, i
+                       return fo
 
        raise IOError, 'File not found : '+str(name)