diff options
| author | ced <> | 2007-04-21 13:32:18 +0000 |
|---|---|---|
| committer | ced <> | 2007-04-21 13:32:18 +0000 |
| commit | 2302e4492c84cff84e4e7731deebfe3330a1f194 (patch) | |
| tree | 80a5309fb928f10d8c38fe88e1deddd56b957b3b | |
| parent | d4d0e528ac7104e21eca7e9087c5e40dc6b37ecf (diff) | |
KERNEL,BASE: allow to create zip modules
bzr revid: ced-4e79fd05ccde4df82f91dece060db6fd1b0e46a3
| -rw-r--r-- | bin/addons/__init__.py | 16 | ||||
| -rw-r--r-- | bin/addons/base/module/module.py | 72 | ||||
| -rw-r--r-- | bin/addons/base/module/module_wizard.xml | 8 | ||||
| -rw-r--r-- | bin/addons/base/module/wizard/add_new.py | 14 | ||||
| -rw-r--r-- | bin/addons/base/module/wizard/wizard_update_module.py | 22 | ||||
| -rw-r--r-- | bin/report/report_sxw.py | 2 | ||||
| -rw-r--r-- | bin/tools/misc.py | 34 |
7 files changed, 114 insertions, 54 deletions
diff --git a/bin/addons/__init__.py b/bin/addons/__init__.py index e1fea8a7bdb..e25b5f081c5 100644 --- a/bin/addons/__init__.py +++ b/bin/addons/__init__.py @@ -39,6 +39,8 @@ import pooler import netsvc from osv import fields +import zipfile + logger = netsvc.Logger() opj = os.path.join @@ -130,8 +132,9 @@ def create_graph(module_list, force=[]): for module in module_list: terp_file = opj(ad, module, '__terp__.py') - if os.path.isfile(terp_file): - info = eval(file(terp_file).read()) + mod_path = opj(ad, module) + if os.path.isfile(terp_file) or zipfile.is_zipfile(mod_path): + info = eval(tools.file_open(terp_file).read()) if info.get('installable', True): packages.append((module, info.get('depends', []), info)) @@ -227,7 +230,14 @@ def register_classes(): m = package.name logger.notifyChannel('init', netsvc.LOG_INFO, 'addon:%s:registering classes' % m) sys.stdout.flush() - imp.load_module(m, *imp.find_module(m)) + try: + # XXX must restrict to only addons paths + imp.load_module(m, *imp.find_module(m)) + except ImportError: + import zipimport + mod_path = opj(ad, m) + zimp = zipimport.zipimporter(mod_path) + zimp.load_module(m) def load_modules(db, force_demo=False, status={}, update_module=False): cr = db.cursor() diff --git a/bin/addons/base/module/module.py b/bin/addons/base/module/module.py index 4c1613200f2..c475b1a1bc3 100644 --- a/bin/addons/base/module/module.py +++ b/bin/addons/base/module/module.py @@ -31,6 +31,7 @@ import urllib import os import tools from osv import fields, osv, orm +import zipfile class module_repository(osv.osv): _name = "ir.module.repository" @@ -41,16 +42,6 @@ class module_repository(osv.osv): } module_repository() -def get_module_info(name): - try: - f = file(os.path.join(tools.config['addons_path'], name, '__terp__.py'), 'r') - data = f.read() - info = eval(data) - f.close() - except: - return {} - return info - class module_category(osv.osv): _name = "ir.module.category" _description = "Module Category" @@ -76,11 +67,21 @@ module_category() class module(osv.osv): _name = "ir.module.module" _description = "Module" - + + def get_module_info(self, name): + try: + f = tools.file_open(os.path.join(tools.config['addons_path'], name, '__terp__.py')) + data = f.read() + info = eval(data) + f.close() + except: + return {} + return info + def _get_installed_version(self, cr, uid, ids, field_name=None, arg=None, context={}): res = {} for m in self.browse(cr, uid, ids): - res[m.id] = get_module_info(m.name).get('version', False) + res[m.id] = self.get_module_info(m.name).get('version', False) return res _columns = { @@ -166,7 +167,7 @@ class module(osv.osv): langs = [l[0] for l in cr.fetchall()] modules = self.read(cr, uid, ids, ['name']) for module in modules: - files = get_module_info(module['name']).get('translations', {}) + files = self.get_module_info(module['name']).get('translations', {}) for lang in langs: if files.has_key(lang): filepath = files[lang] @@ -183,18 +184,37 @@ class module(osv.osv): # iterate through installed modules and mark them as being so for name in os.listdir(adp): - if os.path.isdir(os.path.join(adp, name)): - version = get_module_info(name).get('version', False) - if version: - ids = self.search(cr, uid, [('name','=',name)]) - if not ids: - id = self.create(cr, uid, { - 'name': name, - 'latest_version': version, - 'state': 'installed', - }) - else: - self.write(cr, uid, ids, {'state': 'installed'}) + ids = self.search(cr, uid, [('name','=',name)]) + if ids: + terp = self.get_module_info(name) + if terp.get('installable', True) and self.read(cr, uid, ids, ['state'])[0]['state'] == 'uninstallable': + self.write(cr, uid, [ids], {'state': 'uninstalled'}) + continue + terp_file = os.path.join(adp, name, '__terp__.py') + mod_path = os.path.join(adp, name) + if os.path.isdir(mod_path) or zipfile.is_zipfile(mod_path): + terp = self.get_module_info(name) + if not terp or not terp.get('installable', True): + continue + try: + import imp + # XXX must restrict to only addons paths + imp.load_module(name, *imp.find_module(name)) + except ImportError: + import zipimport + mod_path = os.path.join(adp, name) + zimp = zipimport.zipimporter(mod_path) + zimp.load_module(name) + version = terp.get('version', False) + id = self.create(cr, uid, { + 'name': name, + 'state': 'uninstalled', + 'description': terp.get('description', ''), + 'shortdesc': terp.get('name', ''), + 'author': terp.get('author', 'Unknown') + }) + for d in terp.get('depends', []): + cr.execute('INSERT INTO ir_module_module_dependency (module_id, name) values (%s, %s)', (id, d)) # make the list of all installable modules for repository in robj.browse(cr, uid, robj.search(cr, uid, [])): @@ -233,7 +253,7 @@ class module(osv.osv): if tarinfo.name.endswith('__terp__.py'): info = eval(tar.extractfile(tarinfo).read()) elif os.path.isdir(os.path.join(adp, module.name)): - info = get_module_info(module.name) + info = self.get_module_info(module.name) if info: categ = info.get('category', 'Unclassified') parent = False diff --git a/bin/addons/base/module/module_wizard.xml b/bin/addons/base/module/module_wizard.xml index 4c6182a2055..a3cab0f794e 100644 --- a/bin/addons/base/module/module_wizard.xml +++ b/bin/addons/base/module/module_wizard.xml @@ -7,19 +7,17 @@ model="ir.module.module" name="module.info_get"/> - <!-- <record model="ir.actions.wizard" id="wizard_update"> <field name="name">Download module list</field> <field name="wiz_name">module.module.update</field> </record> <menuitem - name="Administration/Module Management/Download module list" + name="Administration/Modules Management/Update modules list" action="wizard_update" type="wizard" groups="admin" icon="STOCK_CONVERT" id="menu_module_update"/> - --> <record model="ir.actions.wizard" id="wizard_upgrade"> <field name="name">Apply marked changes</field> @@ -41,7 +39,7 @@ id="menu_wizard_lang_install" type="wizard"/> - <record model="ir.actions.wizard" id="wizard_scan_addons"> + <!--record model="ir.actions.wizard" id="wizard_scan_addons"> <field name="name">Scan 'addons' path</field> <field name="wiz_name">module.module.scan</field> </record> @@ -49,7 +47,7 @@ name="Administration/Modules Management/Update modules list" action="wizard_scan_addons" id="menu_wizard_module_scan" - type="wizard" /> + type="wizard" /--> <record model="ir.actions.wizard" id="wizard_lang_export"> <field name="name">Export a language</field> diff --git a/bin/addons/base/module/wizard/add_new.py b/bin/addons/base/module/wizard/add_new.py index 346da18bb11..c86b0812553 100644 --- a/bin/addons/base/module/wizard/add_new.py +++ b/bin/addons/base/module/wizard/add_new.py @@ -46,16 +46,6 @@ _info_arch = '''<?xml version="1.0"?> ''' _info_fields = {} -def get_module_info(name): - try: - f = file(os.path.join(tools.config['addons_path'], name, '__terp__.py'), 'r') - data = f.read() - info = eval(data) - f.close() - except: - return {} - return info - class wizard_install_module(wizard.interface): def watch_dir(self, cr, uid, data, context): mod_obj = pooler.get_pool(cr.dbname).get('ir.module.module') @@ -66,7 +56,7 @@ class wizard_install_module(wizard.interface): for module in modules: if module in known_modules: continue - terp = get_module_info(module) + terp = mod_obj.get_module_info(module) if not terp.get('installable', True): continue imp.load_module(module, *imp.find_module(module)) @@ -80,7 +70,7 @@ class wizard_install_module(wizard.interface): for d in dependencies: cr.execute('insert into ir_module_module_dependency (module_id,name) values (%s, %s)', (mod_id, d)) for module in known_modules: - terp = get_module_info(module) + terp = mod_obj.get_module_info(module) if terp.get('installable', True): for mod in all_mods: if mod['name'] == module and mod['state'] == 'uninstallable': diff --git a/bin/addons/base/module/wizard/wizard_update_module.py b/bin/addons/base/module/wizard/wizard_update_module.py index 5a2ec58912b..996815584a1 100644 --- a/bin/addons/base/module/wizard/wizard_update_module.py +++ b/bin/addons/base/module/wizard/wizard_update_module.py @@ -29,26 +29,38 @@ import wizard import netsvc +import pooler class wizard_update_module(wizard.interface): + + arch = '''<?xml version="1.0"?> +<form string="Scan for new modules"> + <label string="This function will check for new modules in the 'addons' path and on module repository." colspan="4" /> +</form> + ''' + fields = {} + def _update_module(self, cr, uid, data, context): - service = netsvc.LocalService("object_proxy") - service.execute(cr.dbname, uid, 'ir.module.module', 'update_list') + pooler.get_pool(cr.dbname).get('ir.module.module').update_list(cr, uid) return {} def _action_module_open(self, cr, uid, data, context): return { 'domain': "[]", 'name': 'Open Module List', - 'view_type': 'form', - 'view_mode': 'tree,form', - 'res_model': 'ir.module.module', + 'view_type': 'tree', + 'res_model': 'ir.module.category', + 'domain': "[('parent_id', '=', False)]", 'view_id': False, 'type': 'ir.actions.act_window' } states = { 'init': { + 'actions': [], + 'result': {'type': 'form', 'arch': arch, 'fields': fields, 'state': [('end', 'Cancel', 'gtk-cancel'), ('update', 'Check new modules', 'gtk-ok')]} + }, + 'update': { 'actions': [_update_module], 'result': {'type':'state', 'state':'open_window'} }, diff --git a/bin/report/report_sxw.py b/bin/report/report_sxw.py index c6091064e6a..b1034bcab95 100644 --- a/bin/report/report_sxw.py +++ b/bin/report/report_sxw.py @@ -303,7 +303,7 @@ class report_sxw(report_rml): return table_obj.browse(cr, uid, ids, list_class=browse_record_list, context=context) def create(self, cr, uid, ids, data, context={}): - rml = file(os.path.join(tools.config['root_path'], self.tmpl)).read() + rml = tools.file_open(self.tmpl, subdir=None).read() rml_parser = self.parser(cr, uid, self.name2, context) objs = self.getObjects(cr, uid, ids, context) diff --git a/bin/tools/misc.py b/bin/tools/misc.py index d8ff5b76b0c..c41c144e7d6 100644 --- a/bin/tools/misc.py +++ b/bin/tools/misc.py @@ -40,6 +40,8 @@ import netsvc from config import config #import tools +import zipfile + if sys.version_info[:2] < (2, 4): from threadinglocal import local else: @@ -58,8 +60,15 @@ def init_db(cr): for i in os.listdir(ad): terp_file = opj(ad, i, '__terp__.py') + mod_path = opj(ad, i) + info = False if os.path.isfile(terp_file): 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'))) + if info: categs = info.get('category', 'Uncategorized').split('/') p_id = None while categs: @@ -152,8 +161,29 @@ 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.""" - name = os.path.join(config['root_path'], subdir, name) - return file(name, mode) + if subdir: + name = os.path.join(config['root_path'], subdir, name) + else: + name = os.path.join(config['root_path'], name) + if os.path.isfile(name): + return file(name, mode) + + # Check for a zipfile in the path + head = name + name = False + while True: + head, tail = os.path.split(head) + if not tail: + break + if name: + name = os.path.join(tail, name) + else: + name = tail + if zipfile.is_zipfile(head): + import StringIO + zfile = zipfile.ZipFile(head) + return StringIO.StringIO(zfile.read(os.path.join(os.path.basename(head), name))) + return None #---------------------------------------------------------- # Emails |
