def test_region_CI_monkey_patch(self): """Test if the patch is apply on the good version of the lib And test some phonenumbers""" if not phonenumbers: self.skipTest('Cannot test without phonenumbers module installed.') # MONKEY PATCHING phonemetadata of Ivory Coast if phonenumbers is too old if parse_version('7.6.1') <= parse_version( phonenumbers.__version__) < parse_version('8.12.32'): # check that _local_load_region is set to `odoo.addons.phone_validation.lib.phonenumbers_patch._local_load_region` # check that you can load a new ivory coast phone number without error parsed_phonenumber_1 = phonenumbers.parse("20 25/35-51 ", region="CI", keep_raw_input=True) self.assertEqual( parsed_phonenumber_1.national_number, 20253551, "The national part of the phonenumber should be 22522586") self.assertEqual(parsed_phonenumber_1.country_code, 225, "The country code of Ivory Coast is 225") parsed_phonenumber_2 = phonenumbers.parse("+225 22 52 25 86 ", region="CI", keep_raw_input=True) self.assertEqual( parsed_phonenumber_2.national_number, 22522586, "The national part of the phonenumber should be 22522586") self.assertEqual(parsed_phonenumber_2.country_code, 225, "The country code of Ivory Coast is 225") else: self.assertFalse( hasattr(phonenumbers_patch, '_local_load_region'), "The code should not be monkey patched with phonenumbers > 8.12.32." )
def parse(self, incoming): if isinstance(incoming, OdooVersion): self.vstring = incoming.vstring self.components = incoming.components else: self.vstring = incoming self.components = parse_version(incoming)
def _get_migration_versions(pkg): versions = sorted({ ver for lv in self.migrations[pkg.name].values() for ver, lf in lv.items() if lf }, key=lambda k: parse_version(convert_version(k))) return versions
def update_list(self): res = [0, 0] # [update, add] default_version = modules.adapt_version('1.0') known_mods = self.search([]) known_mods_names = {mod.name: mod for mod in known_mods} # iterate through detected modules and update/create them in db for mod_name in modules.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 = tools.ustr(values[key]) if isinstance( values[key], basestring) else values[key] if (old or updated) and updated != old: updated_values[key] = values[key] if terp.get('installable', True) and mod.state == 'uninstallable': updated_values['state'] = 'uninstalled' if parse_version(terp.get( 'version', default_version)) > parse_version( mod.latest_version or default_version): res[0] += 1 if updated_values: mod.write(updated_values) else: mod_path = modules.get_module_path(mod_name) if not mod_path: continue if not terp or not terp.get('installable', True): continue mod = self.create( dict(name=mod_name, state='uninstalled', **values)) res[1] += 1 mod._update_dependencies(terp.get('depends', [])) mod._update_exclusions(terp.get('excludes', [])) mod._update_category(terp.get('category', 'Uncategorized')) return res
def _get_migration_versions(pkg): versions = list(set( ver for lv in self.migrations[pkg.name].values() for ver, lf in lv.items() if lf )) 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): res = [0, 0] # [update, add] default_version = modules.adapt_version('1.0') known_mods = self.with_context(lang=None).search([]) known_mods_names = {mod.name: mod for mod in known_mods} # iterate through detected modules and update/create them in db for mod_name in modules.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 = tools.ustr(values[key]) if isinstance(values[key], pycompat.string_types) else values[key] if (old or updated) and updated != old: updated_values[key] = values[key] if terp.get('installable', True) and mod.state == 'uninstallable': updated_values['state'] = 'uninstalled' if parse_version(terp.get('version', default_version)) > parse_version(mod.latest_version or default_version): res[0] += 1 if updated_values: mod.write(updated_values) else: mod_path = modules.get_module_path(mod_name) if not mod_path: continue if not terp or not terp.get('installable', True): continue mod = self.create(dict(name=mod_name, state='uninstalled', **values)) res[1] += 1 mod._update_dependencies(terp.get('depends', [])) mod._update_exclusions(terp.get('excludes', [])) mod._update_category(terp.get('category', 'Uncategorized')) return res
def _get_migration_versions(pkg, stage): versions = list( set(ver for lv in self.migrations[pkg.name].values() for ver, lf in lv.items() if lf)) versions.sort(key=lambda k: parse_version(convert_version(k))) if "0.0.0" in versions: # reorder versions versions.remove("0.0.0") if stage == "pre": versions.insert(0, "0.0.0") else: versions.append("0.0.0") return versions
def _get_migration_versions(pkg): versions = list( set(ver for lv in self.migrations[pkg.name].values() for ver, lf in lv.items() if lf)) versions.sort(key=lambda k: parse_version(convert_version(k))) return versions
def migrate_module(self, pkg, stage): assert stage in ('pre', 'post', 'end') stageformat = { 'pre': '[>%s]', 'post': '[%s>]', 'end': '[$%s]', } state = pkg.state if stage in ('pre', 'post') else getattr( pkg, 'load_state', None) if not (hasattr(pkg, 'update') or state == 'to upgrade') or state == 'to install': return def convert_version(version): if version.count('.') >= 2: return version # the version number already containt the server version return "%s.%s" % (release.major_version, version) def _get_migration_versions(pkg): versions = list( set(ver for lv in self.migrations[pkg.name].values() for ver, lf in lv.items() if lf)) versions.sort(key=lambda k: parse_version(convert_version(k))) return versions def _get_migration_files(pkg, version, stage): """ return a list of migration script files """ 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.get(x): for f in m[x][version]: if not f.startswith(stage + '-'): continue lst.append(opj(mapping[x], version, f)) lst.sort() return lst parsed_installed_version = parse_version( getattr(pkg, 'load_version', pkg.installed_version) or '') current_version = parse_version(convert_version(pkg.data['version'])) 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, fname = tools.file_open(pyfile, pathinfo=True) # FIXME: imp.load_source removed in P3, and so is the ``file`` object... if not isinstance(fp, file): # pylint: disable=file-builtin # 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, fname, fp2 or fp) _logger.info( 'module %(addon)s: Running migration %(version)s %(name)s' % dict(strfmt, name=mod.__name__)) migrate = mod.migrate except ImportError: _logger.exception( 'module %(addon)s: Unable to load %(stage)s-migration file %(file)s' % dict(strfmt, file=pyfile)) raise except AttributeError: _logger.error( 'module %(addon)s: Each %(stage)s-migration file must have a "migrate(cr, installed_version)" function' % strfmt) else: migrate(self.cr, pkg.installed_version) finally: if fp: fp.close() if fp2: fp2.close() if mod: del mod
def migrate_module(self, pkg, stage): assert stage in ('pre', 'post', 'end') stageformat = { 'pre': '[>%s]', 'post': '[%s>]', 'end': '[$%s]', } state = pkg.state if stage in ('pre', 'post') else getattr( pkg, 'load_state', None) # In openupgrade, also run migration scripts upon installation. # We want to always pass in pre and post migration files and use a new # argument in the migrate decorator (explained in the docstring) # to decide if we want to do something if a new module is installed # during the migration. if not (hasattr(pkg, 'update') or state in ('to upgrade', 'to install')): return def convert_version(version): if version.count('.') >= 2: return version # the version number already containt the server version return "%s.%s" % (release.major_version, version) def _get_migration_versions(pkg, stage): versions = sorted( { ver for lv in self.migrations[pkg.name].values() for ver, lf in lv.items() if lf }, key=lambda k: parse_version(convert_version(k))) if "0.0.0" in versions: # reorder versions versions.remove("0.0.0") if stage == "pre": versions.insert(0, "0.0.0") else: versions.append("0.0.0") return versions def _get_migration_files(pkg, version, stage): """ return a list of migration script files """ m = self.migrations[pkg.name] lst = [] mapping = { 'module': opj(pkg.name, 'migrations'), 'module_upgrades': opj(pkg.name, 'upgrades'), } for path in odoo.upgrade.__path__: if os.path.exists(opj(path, pkg.name)): mapping['upgrade'] = opj(path, pkg.name) break for x in mapping: if version in m.get(x): for f in m[x][version]: if not f.startswith(stage + '-'): continue lst.append(opj(mapping[x], version, f)) lst.sort() return lst installed_version = getattr(pkg, 'load_version', pkg.installed_version) or '' parsed_installed_version = parse_version(installed_version) current_version = parse_version(convert_version(pkg.data['version'])) versions = _get_migration_versions(pkg, stage) for version in versions: if ((version == "0.0.0" and parsed_installed_version < current_version) or 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 = None try: mod = load_script(pyfile, name) _logger.info( 'module %(addon)s: Running migration %(version)s %(name)s' % dict(strfmt, name=mod.__name__)) migrate = mod.migrate except ImportError: _logger.exception( 'module %(addon)s: Unable to load %(stage)s-migration file %(file)s' % dict(strfmt, file=pyfile)) raise except AttributeError: _logger.error( 'module %(addon)s: Each %(stage)s-migration file must have a "migrate(cr, installed_version)" function' % strfmt) else: migrate(self.cr, installed_version) finally: 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') or pkg.state == 'to install': return def convert_version(version): if version.count('.') >= 2: 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 parsed_installed_version = parse_version(pkg.installed_version or '') current_version = parse_version(convert_version(pkg.data['version'])) 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, fname = tools.file_open(pyfile, pathinfo=True) if not isinstance(fp, file): # 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, fname, fp2 or fp) _logger.info('module %(addon)s: Running migration %(version)s %(name)s' % dict(strfmt, name=mod.__name__)) migrate = mod.migrate except ImportError: _logger.exception('module %(addon)s: Unable to load %(stage)s-migration file %(file)s' % dict(strfmt, file=pyfile)) raise except AttributeError: _logger.error('module %(addon)s: Each %(stage)s-migration file must have a "migrate(cr, installed_version)" function' % strfmt) else: migrate(self.cr, pkg.installed_version) finally: if fp: fp.close() if fp2: fp2.close() if mod: del mod
# http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # https://github.com/google/libphonenumber from odoo.tools.parse_version import parse_version try: import phonenumbers # MONKEY PATCHING phonemetadata of Ivory Coast if phonenumbers is too old if parse_version('7.6.1') <= parse_version( phonenumbers.__version__) < parse_version('8.12.32'): def _local_load_region(code): __import__("region_%s" % code, globals(), locals(), fromlist=["PHONE_METADATA_%s" % code], level=1) # loading updated region_CI.py from current directory # https://github.com/daviddrysdale/python-phonenumbers/blob/v8.12.32/python/phonenumbers/data/region_CI.py phonenumbers.phonemetadata.PhoneMetadata.register_region_loader( 'CI', _local_load_region) except ImportError: pass
def migrate_module(self, pkg, stage): assert stage in ('pre', 'post', 'end') stageformat = { 'pre': '[>%s]', 'post': '[%s>]', 'end': '[$%s]', } state = pkg.state if stage in ('pre', 'post') else getattr(pkg, 'load_state', None) if not (hasattr(pkg, 'update') or state == 'to upgrade') or state == 'to install': return def convert_version(version): if version.count('.') >= 2: return version # the version number already containt the server version return "%s.%s" % (release.major_version, version) def _get_migration_versions(pkg): versions = sorted({ ver for lv in self.migrations[pkg.name].values() for ver, lf in lv.items() if lf }, key=lambda k: parse_version(convert_version(k))) return versions def _get_migration_files(pkg, version, stage): """ return a list of migration script files """ m = self.migrations[pkg.name] lst = [] mapping = { 'module': opj(pkg.name, 'migrations'), 'maintenance': opj('base', 'maintenance', 'migrations', pkg.name), } for x in mapping: if version in m.get(x): for f in m[x][version]: if not f.startswith(stage + '-'): continue lst.append(opj(mapping[x], version, f)) lst.sort() return lst installed_version = getattr(pkg, 'load_version', pkg.installed_version) or '' parsed_installed_version = parse_version(installed_version) current_version = parse_version(convert_version(pkg.data['version'])) 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 = None try: mod = load_script(pyfile, name) _logger.info('module %(addon)s: Running migration %(version)s %(name)s' % dict(strfmt, name=mod.__name__)) migrate = mod.migrate except ImportError: _logger.exception('module %(addon)s: Unable to load %(stage)s-migration file %(file)s' % dict(strfmt, file=pyfile)) raise except AttributeError: _logger.error('module %(addon)s: Each %(stage)s-migration file must have a "migrate(cr, installed_version)" function' % strfmt) else: migrate(self.cr, installed_version) finally: if mod: del mod
def migrate_module(self, pkg, stage): assert stage in ('pre', 'post', 'end') stageformat = { 'pre': '[>%s]', 'post': '[%s>]', 'end': '[$%s]', } state = pkg.state if stage in ('pre', 'post') else getattr(pkg, 'load_state', None) if not (hasattr(pkg, 'update') or state == 'to upgrade') or state == 'to install': return def convert_version(version): if version.count('.') >= 2: return version # the version number already containt the server version return "%s.%s" % (release.major_version, version) def _get_migration_versions(pkg): versions = sorted({ ver for lv in pycompat.values(self.migrations[pkg.name]) for ver, lf in pycompat.items(lv) if lf }, key=lambda k: parse_version(convert_version(k))) return versions def _get_migration_files(pkg, version, stage): """ return a list of migration script files """ m = self.migrations[pkg.name] lst = [] mapping = { 'module': opj(pkg.name, 'migrations'), 'maintenance': opj('base', 'maintenance', 'migrations', pkg.name), } for x in mapping: if version in m.get(x): for f in m[x][version]: if not f.startswith(stage + '-'): continue lst.append(opj(mapping[x], version, f)) lst.sort() return lst parsed_installed_version = parse_version(getattr(pkg, 'load_version', pkg.installed_version) or '') current_version = parse_version(convert_version(pkg.data['version'])) 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, fname = tools.file_open(pyfile, pathinfo=True) # FIXME: imp.load_source removed in P3, and so is the ``file`` object... if not isinstance(fp, file):# pylint: disable=file-builtin # 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, fname, fp2 or fp) _logger.info('module %(addon)s: Running migration %(version)s %(name)s' % dict(strfmt, name=mod.__name__)) migrate = mod.migrate except ImportError: _logger.exception('module %(addon)s: Unable to load %(stage)s-migration file %(file)s' % dict(strfmt, file=pyfile)) raise except AttributeError: _logger.error('module %(addon)s: Each %(stage)s-migration file must have a "migrate(cr, installed_version)" function' % strfmt) else: migrate(self.cr, pkg.installed_version) finally: if fp: fp.close() if fp2: fp2.close() if mod: del mod
def migrate_module(self, pkg, stage): assert stage in ('pre', 'post', 'end') stageformat = { 'pre': '[>%s]', 'post': '[%s>]', 'end': '[$%s]', } state = pkg.state if stage in ('pre', 'post') else getattr( pkg, 'load_state', None) # In openupgrade, also run migration scripts upon installation. # We want to always pass in pre and post migration files and use a new # argument in the migrate decorator (explained in the docstring) # to decide if we want to do something if a new module is installed # during the migration. if not (hasattr(pkg, 'update') or state in ('to upgrade', 'to install')): return def convert_version(version): if version.count('.') >= 2: return version # the version number already containt the server version return "%s.%s" % (release.major_version, version) def _get_migration_versions(pkg): versions = list( set(ver for lv in self.migrations[pkg.name].values() for ver, lf in lv.items() if lf)) versions.sort(key=lambda k: parse_version(convert_version(k))) return versions def _get_migration_files(pkg, version, stage): """ return a list of migration script files """ 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.get(x): for f in m[x][version]: 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 parsed_installed_version = parse_version( getattr(pkg, 'load_version', pkg.installed_version) or '') current_version = parse_version(convert_version(pkg.data['version'])) 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 # OpenUpgrade edit start: # Removed a copy of migration script to temp directory # Replaced call to load_source with load_module so frame isn't lost and breakpoints can be set mod = fp = None try: fp, pathname = tools.file_open(pyfile, pathinfo=True) try: mod = imp.load_module(name, fp, pathname, ('.py', 'r', imp.PY_SOURCE)) _logger.info( 'module %(addon)s: Running migration %(version)s %(name)s', mergedict({'name': mod.__name__}, strfmt)) except ImportError: _logger.exception( 'module %(addon)s: Unable to load %(stage)s-migration file %(file)s', mergedict({'file': pyfile}, strfmt)) raise _logger.info( 'module %(addon)s: Running migration %(version)s %(name)s', mergedict({'name': mod.__name__}, strfmt)) if hasattr(mod, 'migrate'): mod.migrate(self.cr, pkg.installed_version) else: _logger.error( 'module %(addon)s: Each %(stage)s-migration file must have a "migrate(cr, installed_version)" function', strfmt) finally: if fp: fp.close() if mod: del mod