[MERGE] file_open: give precedence to directory before zip, courtesy of Florent Xicluna

lp bug: https://launchpad.net/bugs/928376 fixed
lp bug: https://launchpad.net/bugs/928507 fixed

bzr revid: odo@openerp.com-20120903130536-5sqwp9tnhk1ntee3
This commit is contained in:
Olivier Dony 2012-09-03 15:05:36 +02:00
commit 869564ce28
2 changed files with 66 additions and 52 deletions

View File

@ -283,25 +283,28 @@ def get_module_as_zip(modulename, b64enc=True, src=True):
def get_module_resource(module, *args):
"""Return the full path of a resource of the given module.
@param module: the module
@param args: the resource path components
:param module: module name
:param list(str) args: resource path components within module
@return: absolute path to the resource
:rtype: str
:return: absolute path to the resource
TODO name it get_resource_path
TODO make it available inside on osv object (self.get_resource_path)
"""
a = get_module_path(module)
if not a: return False
resource_path = opj(a, *args)
if zipfile.is_zipfile( a +'.zip') :
zip = zipfile.ZipFile( a + ".zip")
mod_path = get_module_path(module)
if not mod_path: return False
resource_path = opj(mod_path, *args)
if os.path.isdir(mod_path):
# the module is a directory - ignore zip behavior
if os.path.exists(resource_path):
return resource_path
elif zipfile.is_zipfile(mod_path + '.zip'):
zip = zipfile.ZipFile( mod_path + ".zip")
files = ['/'.join(f.split('/')[1:]) for f in zip.namelist()]
resource_path = '/'.join(args)
if resource_path in files:
return opj(a, resource_path)
elif os.path.exists(resource_path):
return resource_path
return opj(mod_path, resource_path)
return False
def get_module_icon(module):

View File

@ -134,7 +134,7 @@ def file_open(name, mode="r", subdir='addons', pathinfo=False):
@param name name of the file
@param mode file open mode
@param subdir subdirectory
@param pathinfo if True returns tupple (fileobject, filepath)
@param pathinfo if True returns tuple (fileobject, filepath)
@return fileobject if pathinfo is False else (fileobject, filepath)
"""
@ -142,44 +142,60 @@ def file_open(name, mode="r", subdir='addons', pathinfo=False):
adps = addons.module.ad_paths
rtp = os.path.normcase(os.path.abspath(config['root_path']))
if name.replace(os.path.sep, '/').startswith('addons/'):
if os.path.isabs(name):
# It is an absolute path
# Is it below 'addons_path' or 'root_path'?
name = os.path.normcase(os.path.normpath(name))
for root in adps + [rtp]:
if name.startswith(root):
base = root.rstrip(os.sep)
name = name[len(base) + 1:]
break
else:
# It is outside the OpenERP root: skip zipfile lookup.
base, name = os.path.split(name)
return _fileopen(name, mode=mode, basedir=base, pathinfo=pathinfo)
if name.replace(os.sep, '/').startswith('addons/'):
subdir = 'addons'
name = name[7:]
name2 = name[7:]
elif subdir:
name = os.path.join(subdir, name)
if name.replace(os.sep, '/').startswith('addons/'):
subdir = 'addons'
name2 = name[7:]
else:
name2 = name
# First try to locate in addons_path
# 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
for adp in adps:
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
return _fileopen(name2, mode=mode, basedir=adp,
pathinfo=pathinfo)
except IOError:
pass
if subdir:
name = os.path.join(rtp, subdir, name)
else:
name = os.path.join(rtp, name)
# Second, try to locate in root_path
return _fileopen(name, mode=mode, basedir=rtp, pathinfo=pathinfo)
name = os.path.normpath(name)
# Check for a zipfile in the path
head = name
def _fileopen(path, mode, basedir, pathinfo):
name = os.path.normpath(os.path.join(basedir, path))
# Give higher priority to module directories, which is
# a more common case than zipped modules.
if os.path.isfile(name):
fo = open(name, mode)
if pathinfo:
return (fo, name)
return fo
# Support for loading modules in zipped form.
# This will not work for zipped modules that are sitting
# outside of known addons paths.
head = os.path.normpath(path)
zipname = False
name2 = False
while True:
while os.sep in head:
head, tail = os.path.split(head)
if not tail:
break
@ -187,9 +203,10 @@ def file_open(name, mode="r", subdir='addons', pathinfo=False):
zipname = os.path.join(tail, zipname)
else:
zipname = tail
if zipfile.is_zipfile(head+'.zip'):
zpath = os.path.join(basedir, head + '.zip')
if zipfile.is_zipfile(zpath):
from cStringIO import StringIO
zfile = zipfile.ZipFile(head+'.zip')
zfile = zipfile.ZipFile(zpath)
try:
fo = StringIO()
fo.write(zfile.read(os.path.join(
@ -197,20 +214,14 @@ def file_open(name, mode="r", subdir='addons', pathinfo=False):
os.sep, '/')))
fo.seek(0)
if pathinfo:
return fo, name
return (fo, name)
return fo
except Exception:
name2 = os.path.normpath(os.path.join(head + '.zip', zipname))
pass
for i in (name2, name):
if i and os.path.isfile(i):
fo = file(i, mode)
if pathinfo:
return fo, i
return fo
if os.path.splitext(name)[1] == '.rml':
raise IOError, 'Report %s doesn\'t exist or deleted : ' %str(name)
raise IOError, 'File not found : %s' % name
# Not found
if name.endswith('.rml'):
raise IOError('Report %r doesn\'t exist or deleted' % name)
raise IOError('File not found: %s' % name)
#----------------------------------------------------------