def download(self, cr, uid, ids, download=True, context=None): res = [] for mod in self.browse(cr, uid, ids, context=context): if not mod.url: continue match = re.search('-([a-zA-Z0-9\._-]+)(\.zip)', mod.url, re.I) version = '0' if match: version = match.group(1) if parse_version(mod.installed_version or '0') >= parse_version(version): continue res.append(mod.url) if not download: continue zip_content = urllib.urlopen(mod.url).read() fname = addons.get_module_path(str(mod.name)+'.zip', downloaded=True) try: with open(fname, 'wb') as fp: fp.write(zip_content) except Exception: _logger.exception('Error when trying to create module ' 'file %s', fname) raise orm.except_orm(_('Error'), _('Can not create the module file:\n %s') % (fname,)) terp = self.get_module_info(mod.name) self.write(cr, uid, mod.id, self.get_values_from_terp(terp)) cr.execute('DELETE FROM ir_module_module_dependency ' \ 'WHERE module_id = %s', (mod.id,)) self._update_dependencies(cr, uid, mod, terp.get('depends', [])) self._update_category(cr, uid, mod, terp.get('category', 'Uncategorized')) # Import module zimp = zipimport.zipimporter(fname) zimp.load_module(mod.name) return res
def update_list(self, cr, uid, context={}): res = [0, 0] # [update, add] # iterate through installed modules and mark them as being so for mod_name in addons.get_modules(): ids = self.search(cr, uid, [('name','=',mod_name)]) terp = self.get_module_info(mod_name) values = self.get_values_from_terp(terp) if ids: id = ids[0] mod = self.browse(cr, uid, id) if terp.get('installable', True) and mod.state == 'uninstallable': self.write(cr, uid, id, {'state': 'uninstalled'}) if parse_version(terp.get('version', '')) > parse_version(mod.latest_version or ''): self.write(cr, uid, id, {'url': ''}) res[0] += 1 self.write(cr, uid, id, values) cr.execute('DELETE FROM ir_module_module_dependency WHERE module_id = %s', (id,)) else: mod_path = addons.get_module_path(mod_name) if not mod_path: continue if not terp or not terp.get('installable', True): continue ids = self.search(cr, uid, [('name','=',mod_name)]) id = self.create(cr, uid, dict(name=mod_name, state='uninstalled', **values)) res[1] += 1 self._update_dependencies(cr, uid, id, terp.get('depends', [])) self._update_web_dependencies(cr, uid, id, terp.get('web_depends', [])) self._update_category(cr, uid, id, terp.get('category', 'Uncategorized')) return res
def __for_each_module(self, cr, uid, ids, modules, callback): res = {} toload = ids if isinstance(ids, (int, long)): toload = [ids] for c in self.browse(cr, uid, toload): res[str(c.id)] = {} for m in c.module_ids: if (m.name not in modules) or parse_version(modules[m.name]) < parse_version(m.version): res[str(c.id)][m.name] = callback(m) if isinstance(ids, (int, long)): return res[str(ids)] return res
def update_list(self, cr, uid, context=None): res = [0, 0] # [update, add] known_mods = self.browse(cr, uid, self.search(cr, uid, [])) known_mods_names = dict([(m.name, m) for m in known_mods]) # iterate through detected modules and update/create them in db for mod_name in addons.get_modules(): mod = known_mods_names.get(mod_name) terp = self.get_module_info(mod_name) values = self.get_values_from_terp(terp) if mod: updated_values = {} for key in values: old = getattr(mod, key) updated = isinstance(values[key], basestring) and tools.ustr( values[key]) or values[key] if not old == updated: updated_values[key] = values[key] if terp.get('installable', True) and mod.state == 'uninstallable': updated_values['state'] = 'uninstalled' if parse_version(terp.get('version', '')) > parse_version( mod.latest_version or ''): res[0] += 1 if updated_values: self.write(cr, uid, mod.id, updated_values) else: mod_path = addons.get_module_path(mod_name) if not mod_path: continue if not terp or not terp.get('installable', True): continue id = self.create( cr, uid, dict(name=mod_name, state='uninstalled', **values)) mod = self.browse(cr, uid, id) res[1] += 1 self._update_dependencies(cr, uid, mod, terp.get('depends', [])) self._update_category(cr, uid, mod, terp.get('category', 'Uncategorized')) return res
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_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 update_list(self, cr, uid, context={}): res = [0, 0] # [update, add] # iterate through installed modules and mark them as being so for mod_name in addons.get_modules(): ids = self.search(cr, uid, [('name', '=', mod_name)]) terp = self.get_module_info(mod_name) values = self.get_values_from_terp(terp) if ids: id = ids[0] mod = self.browse(cr, uid, id) if terp.get('installable', True) and mod.state == 'uninstallable': self.write(cr, uid, id, {'state': 'uninstalled'}) if parse_version(terp.get('version', '')) > parse_version( mod.latest_version or ''): self.write(cr, uid, id, {'url': ''}) res[0] += 1 self.write(cr, uid, id, values) cr.execute( 'DELETE FROM ir_module_module_dependency WHERE module_id = %s', (id, )) else: mod_path = addons.get_module_path(mod_name) if not mod_path: continue if not terp or not terp.get('installable', True): continue ids = self.search(cr, uid, [('name', '=', mod_name)]) id = self.create( cr, uid, dict(name=mod_name, state='uninstalled', **values)) res[1] += 1 self._update_dependencies(cr, uid, id, terp.get('depends', [])) self._update_web_dependencies(cr, uid, id, terp.get('web_depends', [])) self._update_category(cr, uid, id, terp.get('category', 'Uncategorized')) return res
def download(self, cr, uid, ids, download=True, context=None): res = [] for mod in self.browse(cr, uid, ids, context=context): if not mod.url: continue match = re.search('-([a-zA-Z0-9\._-]+)(\.zip)', mod.url, re.I) version = '0' if match: version = match.group(1) if parse_version(mod.installed_version or '0') >= parse_version(version): continue res.append(mod.url) if not download: continue zipfile = urllib.urlopen(mod.url).read() fname = addons.get_module_path(str(mod.name)+'.zip', downloaded=True) try: fp = file(fname, 'wb') fp.write(zipfile) fp.close() except Exception, e: raise orm.except_orm(_('Error'), _('Can not create the module file:\n %s') % (fname,)) terp = self.get_module_info(mod.name) self.write(cr, uid, mod.id, { 'description': terp.get('description', ''), 'shortdesc': terp.get('name', ''), 'author': terp.get('author', 'Unknown'), 'website': terp.get('website', ''), 'license': terp.get('license', 'GPL-2'), 'certificate': terp.get('certificate') or None, }) cr.execute('DELETE FROM ir_module_module_dependency ' \ 'WHERE module_id = %s', (mod.id,)) self._update_dependencies(cr, uid, mod.id, terp.get('depends', [])) self._update_category(cr, uid, mod.id, terp.get('category', 'Uncategorized')) # Import module zimp = zipimport.zipimporter(fname) zimp.load_module(mod.name)
def update_list(self, cr, uid, context=None): res = [0, 0] # [update, add] known_mods = self.browse(cr, uid, self.search(cr, uid, [])) known_mods_names = dict([(m.name, m) for m in known_mods]) # iterate through detected modules and update/create them in db for mod_name in addons.get_modules(): mod = known_mods_names.get(mod_name) terp = self.get_module_info(mod_name) values = self.get_values_from_terp(terp) if mod: updated_values = {} for key in values: old = getattr(mod, key) updated = isinstance(values[key], basestring) and tools.ustr(values[key]) or values[key] if not old == updated: updated_values[key] = values[key] if terp.get('installable', True) and mod.state == 'uninstallable': updated_values['state'] = 'uninstalled' if parse_version(terp.get('version', '')) > parse_version(mod.latest_version or ''): res[0] += 1 if updated_values: self.write(cr, uid, mod.id, updated_values) else: mod_path = addons.get_module_path(mod_name) if not mod_path: continue if not terp or not terp.get('installable', True): continue id = self.create(cr, uid, dict(name=mod_name, state='uninstalled', **values)) mod = self.browse(cr, uid, id) res[1] += 1 self._update_dependencies(cr, uid, mod, terp.get('depends', [])) self._update_category(cr, uid, mod, terp.get('category', 'Uncategorized')) return res
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'): return def convert_version(version): if version.startswith(release.major_version) and version != release.major_version: 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 def mergedict(a, b): a = a.copy() a.update(b) return a from tools.parse_version import parse_version parsed_installed_version = parse_version(pkg.installed_version or '') current_version = parse_version(convert_version(pkg.data.get('version', '0'))) 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 = tools.file_open(pyfile) # 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, pyfile, fp2) logger.notifyChannel('migration', netsvc.LOG_INFO, 'module %(addon)s: Running migration %(version)s %(name)s' % mergedict({'name': mod.__name__}, strfmt)) mod.migrate(self.cr, pkg.installed_version) except ImportError: logger.notifyChannel('migration', netsvc.LOG_ERROR, 'module %(addon)s: Unable to load %(stage)s-migration file %(file)s' % mergedict({'file': pyfile}, strfmt)) raise except AttributeError: logger.notifyChannel('migration', netsvc.LOG_ERROR, 'module %(addon)s: Each %(stage)s-migration file must have a "migrate(cr, installed_version)" function' % strfmt) except: raise finally: if fp: fp.close() if fp2: fp2.close() if mod: del mod
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'): return def convert_version(version): if version.startswith(release.major_version ) and version != release.major_version: 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 def mergedict(a, b): a = a.copy() a.update(b) return a from tools.parse_version import parse_version parsed_installed_version = parse_version(pkg.installed_version or '') current_version = parse_version( convert_version(pkg.data.get('version', '0'))) 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 = tools.file_open(pyfile) # 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, pyfile, fp2) logger.notifyChannel( 'migration', netsvc.LOG_INFO, 'module %(addon)s: Running migration %(version)s %(name)s' % mergedict({'name': mod.__name__}, strfmt)) mod.migrate(self.cr, pkg.installed_version) except ImportError: logger.notifyChannel( 'migration', netsvc.LOG_ERROR, 'module %(addon)s: Unable to load %(stage)s-migration file %(file)s' % mergedict({'file': pyfile}, strfmt)) raise except AttributeError: logger.notifyChannel( 'migration', netsvc.LOG_ERROR, 'module %(addon)s: Each %(stage)s-migration file must have a "migrate(cr, installed_version)" function' % strfmt) except: raise finally: if fp: fp.close() if fp2: fp2.close() if mod: del mod
def update_list(self, cr, uid, context={}): robj = self.pool.get('ir.module.repository') res = [0, 0] # [update, add] # iterate through installed modules and mark them as being so for mod_name in addons.get_modules(): ids = self.search(cr, uid, [('name','=',mod_name)]) if ids: id = ids[0] mod = self.browse(cr, uid, id) terp = self.get_module_info(mod_name) if terp.get('installable', True) and mod.state == 'uninstallable': self.write(cr, uid, id, {'state': 'uninstalled'}) if parse_version(terp.get('version', '')) > parse_version(mod.latest_version or ''): self.write(cr, uid, id, { 'url': ''}) res[0] += 1 self.write(cr, uid, id, { 'description': terp.get('description', ''), 'shortdesc': terp.get('name', ''), 'author': terp.get('author', 'Unknown'), 'website': terp.get('website', ''), 'license': terp.get('license', 'GPL-2'), 'certificate': terp.get('certificate') or None, }) cr.execute('DELETE FROM ir_module_module_dependency WHERE module_id = %s', (id,)) self._update_dependencies(cr, uid, ids[0], terp.get('depends', [])) self._update_category(cr, uid, ids[0], terp.get('category', 'Uncategorized')) continue mod_path = addons.get_module_path(mod_name) if mod_path: terp = self.get_module_info(mod_name) if not terp or not terp.get('installable', True): continue id = self.create(cr, uid, { 'name': mod_name, 'state': 'uninstalled', 'description': terp.get('description', ''), 'shortdesc': terp.get('name', ''), 'author': terp.get('author', 'Unknown'), 'website': terp.get('website', ''), 'license': terp.get('license', 'GPL-2'), 'certificate': terp.get('certificate') or None, }) res[1] += 1 self._update_dependencies(cr, uid, id, terp.get('depends', [])) self._update_category(cr, uid, id, terp.get('category', 'Uncategorized')) for repository in robj.browse(cr, uid, robj.search(cr, uid, [])): try: index_page = urllib.urlopen(repository.url).read() except IOError, e: if e.errno == 21: raise orm.except_orm(_('Error'), _("This url '%s' must provide an html file with links to zip modules") % (repository.url)) else: raise modules = re.findall(repository.filter, index_page, re.I+re.M) mod_sort = {} for m in modules: name, version, extension = m[0], m[1], m[-1] if not version or version == 'x': # 'x' version was a mistake version = '0' if name in mod_sort: if parse_version(version) <= parse_version(mod_sort[name][0]): continue mod_sort[name] = [version, extension] for name in mod_sort.keys(): version, extension = mod_sort[name] url = repository.url+'/'+name+'-'+version+extension ids = self.search(cr, uid, [('name','=',name)]) if not ids: self.create(cr, uid, { 'name': name, 'published_version': version, 'url': url, 'state': 'uninstalled', }) res[1] += 1 else: id = ids[0] installed_version = self.read(cr, uid, id, ['latest_version'])['latest_version'] if not installed_version or installed_version == 'x': # 'x' version was a mistake installed_version = '0' if parse_version(version) > parse_version(installed_version): self.write(cr, uid, id, { 'url': url }) res[0] += 1 published_version = self.read(cr, uid, id, ['published_version'])['published_version'] if published_version == 'x' or not published_version: published_version = '0' if parse_version(version) > parse_version(published_version): self.write(cr, uid, id, {'published_version': version})