From c2be65caec5ae5459da71cabed5d28da2af6314a Mon Sep 17 00:00:00 2001 From: Amit Mendapara Date: Wed, 16 Jul 2008 11:15:55 +0530 Subject: [PATCH 01/12] Improved custom addons path - now accepts relative path - `get_module_path` method to get correct path of a module bzr revid: ame@tinyerp.com-20080716054555-rt5dvw0qo118jonz --- bin/addons/__init__.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bin/addons/__init__.py b/bin/addons/__init__.py index f1d74009ff5..264d4bddbc2 100644 --- a/bin/addons/__init__.py +++ b/bin/addons/__init__.py @@ -45,8 +45,8 @@ logger = netsvc.Logger() opj = os.path.join -_ad = opj(tools.config['root_path'], 'addons') # default addons path (base) -ad = tools.config['addons_path'] # alternate addons path +_ad = os.path.abspath(opj(tools.config['root_path'], 'addons')) # default addons path (base) +ad = os.path.abspath(tools.config['addons_path']) # alternate addons path sys.path.insert(1, _ad) if ad != _ad: @@ -131,7 +131,7 @@ class Node(Singleton): s += '%s`-> %s' % (' ' * depth, c._pprint(depth+1)) return s -def _get_module_path(module): +def get_module_path(module): if os.path.exists(opj(ad, module)): return opj(ad, module) return opj(_ad, module) @@ -145,7 +145,7 @@ def create_graph(module_list, force=None): for module in module_list: if module[-4:]=='.zip': module = module[:-4] - mod_path = _get_module_path(module) + mod_path = get_module_path(module) terp_file = opj(mod_path, '__terp__.py') if os.path.isfile(terp_file) or zipfile.is_zipfile(mod_path+'.zip'): try: @@ -263,7 +263,7 @@ def register_classes(): logger.notifyChannel('init', netsvc.LOG_INFO, 'addon:%s:registering classes' % m) sys.stdout.flush() - mod_path = _get_module_path(m) + mod_path = get_module_path(m) if not os.path.isfile(mod_path + '.zip'): # XXX must restrict to only addons paths imp.load_module(m, *imp.find_module(m)) From 92f942b031528b4f87366585f76065902795da79 Mon Sep 17 00:00:00 2001 From: Amit Mendapara Date: Wed, 16 Jul 2008 12:13:50 +0530 Subject: [PATCH 02/12] Custom addons path - get_module_resource - get_modules (list of modules) - fixed `init_db` bzr revid: ame@tinyerp.com-20080716064350-jwvgjvz95ogpsrxl --- bin/addons/__init__.py | 39 +++++++++++++++++++++++++++++---------- bin/tools/misc.py | 18 +++++++++--------- 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/bin/addons/__init__.py b/bin/addons/__init__.py index 264d4bddbc2..13feab81f18 100644 --- a/bin/addons/__init__.py +++ b/bin/addons/__init__.py @@ -132,10 +132,32 @@ class Node(Singleton): return s def get_module_path(module): + """Return the path of the given module. + """ if os.path.exists(opj(ad, module)): return opj(ad, module) return opj(_ad, module) +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 + + @return: absolute path to the resource + """ + return opj(get_module_path(module), *args) + +def get_modules(): + """Returns the list of module names + """ + + module_list = os.listdir(ad) + module_names = [os.path.basename(m) for m in module_list] + module_list += [m for m in os.listdir(_ad) if m not in module_names] + + return module_list + def create_graph(module_list, force=None): if not force: force=[] @@ -146,7 +168,7 @@ def create_graph(module_list, force=None): if module[-4:]=='.zip': module = module[:-4] mod_path = get_module_path(module) - terp_file = opj(mod_path, '__terp__.py') + terp_file = get_module_resource(module, '__terp__.py') if os.path.isfile(terp_file) or zipfile.is_zipfile(mod_path+'.zip'): try: info = eval(tools.file_open(terp_file).read()) @@ -221,24 +243,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(opj(m, filename)).read(), idref, mode=mode) + tools.convert_csv_import(cr, m, os.path.basename(filename), tools.file_open(get_module_resource(m, filename)).read(), idref, mode=mode) elif ext == '.sql': - queries = tools.file_open(opj(m, filename)).read().split(';') + queries = tools.file_open(get_module_resource(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(opj(m, filename)), idref, mode=mode, **kwargs) + tools.convert_xml_import(cr, m, tools.file_open(get_module_resource(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(opj(m, xml)).read(), idref, noupdate=True) + tools.convert_csv_import(cr, m, os.path.basename(xml), tools.file_open(get_module_resource(m, xml)).read(), idref, noupdate=True) else: - tools.convert_xml_import(cr, m, tools.file_open(opj(m, xml)), idref, noupdate=True, **kwargs) + tools.convert_xml_import(cr, m, tools.file_open(get_module_resource(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,)) @@ -254,10 +276,7 @@ def load_module_graph(cr, graph, status=None, **kwargs): cr.commit() def register_classes(): - module_list = os.listdir(ad) - module_names = [os.path.basename(m) for m in module_list] - module_list += [m for m in os.listdir(_ad) if m not in module_names] - + module_list = get_modules() for package in create_graph(module_list): m = package.name logger.notifyChannel('init', netsvc.LOG_INFO, 'addon:%s:registering classes' % m) diff --git a/bin/tools/misc.py b/bin/tools/misc.py index b8f9b61763f..e82534c57dd 100644 --- a/bin/tools/misc.py +++ b/bin/tools/misc.py @@ -50,25 +50,23 @@ else: # initialize a database with base/base.sql def init_db(cr): - f = os.path.join(config['addons_path'], 'base/base.sql') + import addons + f = addons.get_module_resource('base', 'base.sql') for line in file(f).read().split(';'): if (len(line)>0) and (not line.isspace()): cr.execute(line) cr.commit() - opj = os.path.join - ad = config['addons_path'] - - for i in os.listdir(ad): - terp_file = opj(ad, i, '__terp__.py') - mod_path = opj(ad, i) + for i in addons.get_modules(): + 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(opj(ad, i+'.zip')): + 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) i = os.path.splitext(i)[0] - info = eval(zfile.read(opj(i, '__terp__.py'))) + info = eval(zfile.read(addons.get_module_resource(i, '__terp__.py'))) if info: categs = info.get('category', 'Uncategorized').split('/') p_id = None @@ -172,6 +170,8 @@ def exec_command_pipe(name, *args): 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 if subdir: name = os.path.join(config['root_path'], subdir, name) else: From 6c1e9c06271b04afa5f9c52b3c24667b8f0035c9 Mon Sep 17 00:00:00 2001 From: Amit Mendapara Date: Wed, 16 Jul 2008 14:37:15 +0530 Subject: [PATCH 03/12] Improved custom addons path support - get_module_path checks for zip files - fixed zipped module problem bzr revid: ame@tinyerp.com-20080716090715-pbuby8xpuwoam7h1 --- bin/addons/__init__.py | 16 ++++++++++++---- bin/addons/base/module/module.py | 21 ++++++++------------- bin/tools/misc.py | 16 +++++++++++----- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/bin/addons/__init__.py b/bin/addons/__init__.py index 13feab81f18..9d7a651e8a7 100644 --- a/bin/addons/__init__.py +++ b/bin/addons/__init__.py @@ -134,9 +134,18 @@ class Node(Singleton): def get_module_path(module): """Return the path of the given module. """ + if os.path.exists(opj(ad, module)): return opj(ad, 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)): + return opj(_ad, module) + + if os.path.exists(opj(_ad, '%s.zip' % module)): + return opj(_ad, '%s.zip' % module) def get_module_resource(module, *args): """Return the full path of a resource of the given module. @@ -169,7 +178,7 @@ def create_graph(module_list, force=None): module = module[:-4] mod_path = get_module_path(module) terp_file = get_module_resource(module, '__terp__.py') - if os.path.isfile(terp_file) or zipfile.is_zipfile(mod_path+'.zip'): + if os.path.isfile(terp_file) or zipfile.is_zipfile(mod_path): try: info = eval(tools.file_open(terp_file).read()) except: @@ -283,12 +292,11 @@ def register_classes(): sys.stdout.flush() mod_path = get_module_path(m) - if not os.path.isfile(mod_path + '.zip'): + if not os.path.isfile(mod_path): # XXX must restrict to only addons paths imp.load_module(m, *imp.find_module(m)) else: import zipimport - mod_path = mod_path + '.zip' try: zimp = zipimport.zipimporter(mod_path) zimp.load_module(m) diff --git a/bin/addons/base/module/module.py b/bin/addons/base/module/module.py index 0ebb5d9ab79..a876b436801 100644 --- a/bin/addons/base/module/module.py +++ b/bin/addons/base/module/module.py @@ -38,9 +38,7 @@ import release import zipimport import wizard - - - +import addons ver_regexp = re.compile("^(\\d+)((\\.\\d+)*)([a-z]?)((_(pre|p|beta|alpha|rc)\\d*)*)(-r(\\d+))?$") suffix_regexp = re.compile("^(alpha|beta|rc|pre|p)(\\d*)$") @@ -199,7 +197,7 @@ class module(osv.osv): def get_module_info(self, name): try: - f = tools.file_open(os.path.join(tools.config['addons_path'], name, '__terp__.py')) + f = tools.file_open(addons.get_module_resource(name, '__terp__.py')) data = f.read() info = eval(data) if 'version' in info: @@ -343,18 +341,17 @@ class module(osv.osv): filepath = files[lang] # if filepath does not contain :// we prepend the path of the module if filepath.find('://') == -1: - filepath = os.path.join(tools.config['addons_path'], module['name'], filepath) + filepath = addons.get_module_resource(module['name'], filepath) tools.trans_load(filepath, lang) return True # update the list of available packages def update_list(self, cr, uid, context={}): robj = self.pool.get('ir.module.repository') - adp = tools.config['addons_path'] res = [0, 0] # [update, add] # iterate through installed modules and mark them as being so - for name in os.listdir(adp): + for name in addons.get_modules(): mod_name = name if name[-4:]=='.zip': mod_name=name[:-4] @@ -384,19 +381,18 @@ class module(osv.osv): self._update_category(cr, uid, ids[0], terp.get('category', 'Uncategorized')) continue - terp_file = os.path.join(adp, name, '__terp__.py') - mod_path = os.path.join(adp, name) + terp_file = addons.get_module_resource(name, '__terp__.py') + mod_path = addons.get_module_path(name) if os.path.isdir(mod_path) or os.path.islink(mod_path) or zipfile.is_zipfile(mod_path): terp = self.get_module_info(mod_name) if not terp or not terp.get('installable', True): continue - if not os.path.isfile(os.path.join(adp, mod_name+'.zip')): + if not os.path.isfile(mod_path): import imp # XXX must restrict to only addons paths imp.load_module(name, *imp.find_module(mod_name)) else: import zipimport - mod_path = os.path.join(adp, mod_name+'.zip') zimp = zipimport.zipimporter(mod_path) zimp.load_module(mod_name) id = self.create(cr, uid, { @@ -472,7 +468,6 @@ class module(osv.osv): def download(self, cr, uid, ids, download=True, context=None): res = [] - adp = tools.config['addons_path'] for mod in self.browse(cr, uid, ids, context=context): if not mod.url: continue @@ -486,7 +481,7 @@ class module(osv.osv): if not download: continue zipfile = urllib.urlopen(mod.url).read() - fname = os.path.join(adp, mod.name+'.zip') + fname = addons.get_module_path(mod.name) try: fp = file(fname, 'wb') fp.write(zipfile) diff --git a/bin/tools/misc.py b/bin/tools/misc.py index e82534c57dd..1c0cc898beb 100644 --- a/bin/tools/misc.py +++ b/bin/tools/misc.py @@ -61,7 +61,7 @@ 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+'.zip'): + if os.path.isfile(terp_file) and not os.path.isfile(mod_path): info = eval(file(terp_file).read()) elif zipfile.is_zipfile(mod_path): zfile = zipfile.ZipFile(mod_path) @@ -189,15 +189,21 @@ def file_open(name, mode="r", subdir='addons'): zipname = os.path.join(tail, zipname) else: zipname = tail - if zipfile.is_zipfile(head+'.zip'): + + zname = head + if zipfile.is_zipfile(head + '.zip'): + zname = head + '.zip' + + if zipfile.is_zipfile(zname): import StringIO - zfile = zipfile.ZipFile(head+'.zip') + zfile = zipfile.ZipFile(zname) try: + zname = os.path.splitext(zname)[0] return StringIO.StringIO(zfile.read(os.path.join( - os.path.basename(head), zipname).replace( + os.path.basename(zname), zipname).replace( os.sep, '/'))) except: - name2 = os.path.normpath(os.path.join(head + '.zip', zipname)) + name2 = os.path.normpath(os.path.join(zname + '.zip', zipname)) pass for i in (name2, name): if i and os.path.isfile(i): From 0b5bfd8020a3d12d3f40425d61b05868f7020e46 Mon Sep 17 00:00:00 2001 From: Amit Mendapara Date: Wed, 16 Jul 2008 19:08:51 +0530 Subject: [PATCH 04/12] Imrpoved addons path support - added `get_report_resource` method in addons package - properly locate report resources bzr revid: ame@tinyerp.com-20080716133851-fy2be2nqpi3wdbzt --- bin/addons/__init__.py | 9 +++++++++ bin/report/interface.py | 9 ++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/bin/addons/__init__.py b/bin/addons/__init__.py index 9d7a651e8a7..2313d9ccf99 100644 --- a/bin/addons/__init__.py +++ b/bin/addons/__init__.py @@ -157,6 +157,15 @@ def get_module_resource(module, *args): """ return opj(get_module_path(module), *args) +def get_report_resource(resource): + """Return the full path of the given report resource (addons/hr/reports/timesheet.xsl') + """ + + fname = os.path.join(os.path.dirname(ad), resource) + if os.path.exists(fname): + return fname + return os.path.join(os.path.dirname(_ad), resource) + def get_modules(): """Returns the list of module names """ diff --git a/bin/report/interface.py b/bin/report/interface.py index 5a5333cf462..7623d21a59a 100644 --- a/bin/report/interface.py +++ b/bin/report/interface.py @@ -37,6 +37,7 @@ import netsvc import pooler import tools +import addons import print_xml import render import urllib @@ -121,7 +122,7 @@ class report_rml(report_int): pos_xml = i.end() doc = print_xml.document(cr, uid, {}, {}) - tmpl_path = os.path.join(tools.config['root_path'], 'addons/custom/corporate_defaults.xml') + tmpl_path = addons.get_report_resource('addons/custom/corporate_defaults.xml') doc.parse(tmpl_path, [uid], 'res.users', context) corporate_header = doc.xml_get() doc.close() @@ -146,10 +147,8 @@ class report_rml(report_int): return xml # load XSL (parse it to the XML level) - styledoc = libxml2.parseDoc(tools.file_open( - os.path.join(tools.config['root_path'], self.xsl)).read()) - xsl_path, tail = os.path.split(os.path.join(tools.config['root_path'], - self.xsl)) + 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)) for child in styledoc.children: if child.name == 'import': if child.hasProp('href'): From d90ead399afcab1825fc394d05f7022fead6a8e2 Mon Sep 17 00:00:00 2001 From: Amit Mendapara Date: Wed, 16 Jul 2008 20:13:01 +0530 Subject: [PATCH 05/12] Improved addons path support - fixed `xsl:import` search problem (print report) bzr revid: ame@tinyerp.com-20080716144301-x5ajq907yj2qogle --- bin/addons/__init__.py | 23 +++++++++++++++++++++-- bin/report/interface.py | 3 +-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/bin/addons/__init__.py b/bin/addons/__init__.py index 2313d9ccf99..2a9b947f985 100644 --- a/bin/addons/__init__.py +++ b/bin/addons/__init__.py @@ -157,10 +157,29 @@ def get_module_resource(module, *args): """ return opj(get_module_path(module), *args) -def get_report_resource(resource): - """Return the full path of the given report resource (addons/hr/reports/timesheet.xsl') +def get_report_resource(resource, base=None): + """Return the full path of the given report resource. + + >>> + >>> 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 + fname = os.path.join(os.path.dirname(ad), resource) if os.path.exists(fname): return fname diff --git a/bin/report/interface.py b/bin/report/interface.py index 7623d21a59a..51c2ffdf23f 100644 --- a/bin/report/interface.py +++ b/bin/report/interface.py @@ -153,8 +153,7 @@ class report_rml(report_int): if child.name == 'import': if child.hasProp('href'): file = child.prop('href') - child.setProp('href', urllib.quote(str( - os.path.normpath(os.path.join(xsl_path, file))))) + child.setProp('href', urllib.quote(str(addons.get_report_resource(file, base=xsl_path)))) #TODO: get all the translation in one query. That means we have to: # * build a list of items to translate, From 694f88319cea3c0ad4ff3828733c8f0ac895d190 Mon Sep 17 00:00:00 2001 From: Fabien Pinckaers Date: Wed, 16 Jul 2008 22:05:32 +0200 Subject: [PATCH 06/12] Speed Improvement on Every Operation: Removed Inherit Stuff bzr revid: fp@tinyerp.com-20080716200532-iec6d4jfelwhi5rt --- bin/addons/base/base.sql | 8 +------- bin/osv/orm.py | 5 ----- bin/osv/osv.py | 16 ++-------------- bin/tools/graph.py | 7 +++++-- 4 files changed, 8 insertions(+), 28 deletions(-) diff --git a/bin/addons/base/base.sql b/bin/addons/base/base.sql index 05696f4dc56..14a9ad2bf4f 100644 --- a/bin/addons/base/base.sql +++ b/bin/addons/base/base.sql @@ -2,13 +2,6 @@ -- Pure SQL ------------------------------------------------------------------------- -CREATE TABLE inherit ( - obj_type varchar(128) not null, - obj_id int not null, - inst_type varchar(128) not null, - inst_id int not null -); - ------------------------------------------------------------------------- -- IR dictionary ------------------------------------------------------------------------- @@ -336,3 +329,4 @@ CREATE TABLE ir_model_data ( res_id integer, primary key(id) ); +INSERT INTO ir_model_data (name,date_init,date_update,module,model,res_id) VALUES (%s, now(), now(), 'base', 'ir.model', %s) diff --git a/bin/osv/orm.py b/bin/osv/orm.py index 0bf3fb22cab..1f0f2c096bf 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -1839,10 +1839,6 @@ class orm(orm_template): _('You try to bypass an access rule (Document type: %s).') % \ self._description) - cr.execute('delete from inherit ' \ - 'where (obj_type=%s and obj_id in ('+str_d+')) ' \ - 'or (inst_type=%s and inst_id in ('+str_d+'))', - (self._name,)+tuple(sub_ids)+(self._name,)+tuple(sub_ids)) if d1: cr.execute('delete from "'+self._table+'" ' \ 'where id in ('+str_d+')'+d1, sub_ids+d2) @@ -2086,7 +2082,6 @@ class orm(orm_template): upd0 += ','+self._inherits[table] upd1 += ',%d' upd2.append(id) - cr.execute('insert into inherit (obj_type,obj_id,inst_type,inst_id) values (%s,%d,%s,%d)', (table,id,self._name,id_new)) for field in vals: if self._columns[field]._classic_write: diff --git a/bin/osv/osv.py b/bin/osv/osv.py index 49099aa7142..2e8ba1114be 100644 --- a/bin/osv/osv.py +++ b/bin/osv/osv.py @@ -78,20 +78,8 @@ class osv_pool(netsvc.Service): 'Object %s doesn\'t exist' % str(obj)) if (not method in getattr(object,'_protected')) and len(args) \ and args[0] and len(object._inherits): - types = {obj: args[0]} - cr.execute('select inst_type,inst_id,obj_id \ - from inherit \ - where obj_type=%s \ - and obj_id in ('+','.join(map(str,args[0]))+')', (obj,)) - for ty,id,id2 in cr.fetchall(): - if not ty in types: - types[ty]=[] - types[ty].append(id) - types[obj].remove(id2) - for t,ids in types.items(): - if len(ids): - object_t = pooler.get_pool(cr.dbname).get(t) - res = getattr(object_t,method)(cr, uid, ids, *args[1:], **kw) + object_t = pooler.get_pool(cr.dbname).get(obj) + res = getattr(object_t,method)(cr, uid, args, **kw) else: res = getattr(object,method)(cr, uid, *args, **kw) return res diff --git a/bin/tools/graph.py b/bin/tools/graph.py index c14a3e2488b..c271726b79c 100644 --- a/bin/tools/graph.py +++ b/bin/tools/graph.py @@ -290,11 +290,14 @@ class graph(object): return self.result if __name__=='__main__': - starting_node = ['mrp'] # put here nodes with flow_start=True - nodes = ['project','account','hr','base','product','mrp','test'] + starting_node = ['profile'] # put here nodes with flow_start=True + nodes = ['project','account','hr','base','product','mrp','test','profile'] transitions = [ + ('profile','mrp'), ('mrp','project'), ('project','product'), + ('mrp','hr'), + ('mrp','test'), ('project','account'), ('project','hr'), ('product','base'), From fe7176aca322a1e6019d4fe9e26b76d4f22a6de8 Mon Sep 17 00:00:00 2001 From: Fabien Pinckaers Date: Wed, 16 Jul 2008 22:09:51 +0200 Subject: [PATCH 07/12] Speed Improvement (removed inherit checks) bzr revid: fp@tinyerp.com-20080716200951-lbzcbx5x2p7ibgzs --- bin/osv/osv.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/bin/osv/osv.py b/bin/osv/osv.py index 2e8ba1114be..3b948aec5d3 100644 --- a/bin/osv/osv.py +++ b/bin/osv/osv.py @@ -68,21 +68,12 @@ class osv_pool(netsvc.Service): self.exportMethod(self.execute_cr) def execute_cr(self, cr, uid, obj, method, *args, **kw): - # - # TODO: check security level - # try: object = pooler.get_pool(cr.dbname).get(obj) if not object: self.abortResponse(1, 'Object Error', 'warning', 'Object %s doesn\'t exist' % str(obj)) - if (not method in getattr(object,'_protected')) and len(args) \ - and args[0] and len(object._inherits): - object_t = pooler.get_pool(cr.dbname).get(obj) - res = getattr(object_t,method)(cr, uid, args, **kw) - else: - res = getattr(object,method)(cr, uid, *args, **kw) - return res + return getattr(object,method)(cr, uid, *args, **kw) except orm.except_orm, inst: self.abortResponse(1, inst.name, 'warning', inst.value) except except_osv, inst: From d225134d279fcbf2d4a5dde40b20738501c0aec1 Mon Sep 17 00:00:00 2001 From: Amit Mendapara Date: Thu, 17 Jul 2008 10:14:51 +0530 Subject: [PATCH 08/12] Improved custom addons path support - fixed report_swx issue bzr revid: ame@tinyerp.com-20080717044451-0p8xv9fkeqjqcjru --- bin/addons/__init__.py | 8 ++++++-- bin/addons/base/ir/ir_actions.py | 3 ++- bin/report/interface.py | 2 +- bin/report/report_sxw.py | 5 +++-- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/bin/addons/__init__.py b/bin/addons/__init__.py index 2a9b947f985..f400ad99990 100644 --- a/bin/addons/__init__.py +++ b/bin/addons/__init__.py @@ -161,6 +161,7 @@ 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') >>> @@ -180,10 +181,13 @@ def get_report_resource(resource, base=None): assert os.path.exists(fname), 'File does not exist: %s' % fname - fname = os.path.join(os.path.dirname(ad), resource) + 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(os.path.dirname(_ad), resource) + return os.path.join(_ad, resource) def get_modules(): """Returns the list of module names diff --git a/bin/addons/base/ir/ir_actions.py b/bin/addons/base/ir/ir_actions.py index a4a7ae71d1c..6d9d41867bc 100644 --- a/bin/addons/base/ir/ir_actions.py +++ b/bin/addons/base/ir/ir_actions.py @@ -29,6 +29,7 @@ from osv import fields,osv import tools +import addons import time class actions(osv.osv): @@ -71,7 +72,7 @@ class report_xml(osv.osv): data = report[name + '_data'] if not data and report[name[:-8]]: try: - fp = tools.file_open(report[name[:-8]], mode='rb') + fp = tools.file_open(addons.get_report_resource(report[name[:-8]]), mode='rb') data = fp.read() except: data = False diff --git a/bin/report/interface.py b/bin/report/interface.py index 51c2ffdf23f..abd955ffca0 100644 --- a/bin/report/interface.py +++ b/bin/report/interface.py @@ -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 = tmpl + self.tmpl = addons.get_report_resource(tmpl) self.xsl = xsl self.bin_datas = {} self.generators = { diff --git a/bin/report/report_sxw.py b/bin/report/report_sxw.py index 586527a13d0..8e5acba8470 100644 --- a/bin/report/report_sxw.py +++ b/bin/report/report_sxw.py @@ -35,6 +35,7 @@ import osv from interface import report_rml import re import tools +import addons import pooler import netsvc import warnings @@ -572,7 +573,7 @@ class report_sxw(report_rml): rml = report_xml.report_rml_content report_type = report_xml.report_type else: - rml = tools.file_open(self.tmpl, subdir=None).read() + rml = tools.file_open(addons.get_report_resource(self.tmpl), subdir=None).read() report_type= data.get('report_type', report_type) if report_type == 'sxw' and report_xml: @@ -625,7 +626,7 @@ class report_sxw(report_rml): if self.header: #Add corporate header/footer - rml = tools.file_open('custom/corporate_sxw_header.xml').read() + rml = tools.file_open(addons.get_report_resource('addons/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 From a07e811cbd598d2a6928544b586318f46cf86678 Mon Sep 17 00:00:00 2001 From: Amit Mendapara Date: Thu, 17 Jul 2008 15:25:16 +0530 Subject: [PATCH 09/12] Imrpoved addons path support - 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 | 56 ++++----------------- bin/addons/base/ir/ir_actions.py | 3 +- bin/addons/base/module/module.py | 8 +-- bin/report/interface.py | 13 ++--- bin/report/print_xml.py | 4 +- bin/report/report_sxw.py | 5 +- bin/tools/misc.py | 86 ++++++++++++++++++++++++-------- 7 files changed, 89 insertions(+), 86 deletions(-) diff --git a/bin/addons/__init__.py b/bin/addons/__init__.py index f400ad99990..cefd6859e6c 100644 --- a/bin/addons/__init__.py +++ b/bin/addons/__init__.py @@ -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) diff --git a/bin/addons/base/ir/ir_actions.py b/bin/addons/base/ir/ir_actions.py index 6d9d41867bc..a4a7ae71d1c 100644 --- a/bin/addons/base/ir/ir_actions.py +++ b/bin/addons/base/ir/ir_actions.py @@ -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 diff --git a/bin/addons/base/module/module.py b/bin/addons/base/module/module.py index a876b436801..1ad9a844ea0 100644 --- a/bin/addons/base/module/module.py +++ b/bin/addons/base/module/module.py @@ -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) diff --git a/bin/report/interface.py b/bin/report/interface.py index abd955ffca0..63757ad6151 100644 --- a/bin/report/interface.py +++ b/bin/report/interface.py @@ -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, diff --git a/bin/report/print_xml.py b/bin/report/print_xml.py index 2370f5344db..75c700e3927 100644 --- a/bin/report/print_xml.py +++ b/bin/report/print_xml.py @@ -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) diff --git a/bin/report/report_sxw.py b/bin/report/report_sxw.py index 8e5acba8470..586527a13d0 100644 --- a/bin/report/report_sxw.py +++ b/bin/report/report_sxw.py @@ -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 diff --git a/bin/tools/misc.py b/bin/tools/misc.py index 1c0cc898beb..4523c762c0a 100644 --- a/bin/tools/misc.py +++ b/bin/tools/misc.py @@ -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: - name = os.path.join(config['root_path'], subdir, name) + 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(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) From 3d1bd9fe358257288479302c8215306b6af1b379 Mon Sep 17 00:00:00 2001 From: qdp Date: Thu, 17 Jul 2008 15:05:46 +0200 Subject: [PATCH 10/12] *removed print statement bzr revid: qdp@tinyerp.com-20080717130546-k3yj9czzj9y1f1rt --- bin/osv/fields.py | 1 - 1 file changed, 1 deletion(-) diff --git a/bin/osv/fields.py b/bin/osv/fields.py index 32544bcb9c3..8f6ee185ad8 100644 --- a/bin/osv/fields.py +++ b/bin/osv/fields.py @@ -333,7 +333,6 @@ class one2many(_column): for r in obj.pool.get(self._obj).read(cr, user, ids2, [self._fields_id], context=context, load='_classic_write'): if r[self._fields_id] in res: res[r[self._fields_id]].append( r['id'] ) - print 'Ok', res return res def set_memory(self, cr, obj, id, field, values, user=None, context=None): From 66423c25e3e14208cd82fbc766effb541e23176b Mon Sep 17 00:00:00 2001 From: qdp Date: Fri, 18 Jul 2008 10:36:42 +0200 Subject: [PATCH 11/12] *bugfix: removed unecessary sql query that lead to the impossibility to create new databases bzr revid: qdp@tinyerp.com-20080718083642-ie7bq3u0j38q32tp --- bin/addons/base/base.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/addons/base/base.sql b/bin/addons/base/base.sql index 14a9ad2bf4f..5b0ffb138e4 100644 --- a/bin/addons/base/base.sql +++ b/bin/addons/base/base.sql @@ -329,4 +329,4 @@ CREATE TABLE ir_model_data ( res_id integer, primary key(id) ); -INSERT INTO ir_model_data (name,date_init,date_update,module,model,res_id) VALUES (%s, now(), now(), 'base', 'ir.model', %s) + From 4b10e8cea564029614f85623744f56dbd15fb706 Mon Sep 17 00:00:00 2001 From: "mga@tinyerp.com" <> Date: Sat, 19 Jul 2008 11:52:37 +0530 Subject: [PATCH 12/12] modified file to support all character sets bzr revid: mga@tinyerp.com-20080719062237-7liy9fobdhveeaom --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 607fb28c5c5..2c8923f4f3b 100755 --- a/setup.py +++ b/setup.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- #!/usr/bin/env python ############################################################################## # @@ -26,7 +27,6 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ############################################################################### -# -*- coding: utf-8 -*- # setup from TinERP # taken from straw http://www.nongnu.org/straw/index.html # taken from gnomolicious http://www.nongnu.org/gnomolicious/