def _modules_list(cls): from trytond.modules import create_graph, get_module_list if ModelView.__modules_list: return ModelView.__modules_list graph = create_graph(get_module_list())[0] ModelView.__modules_list = [x.name for x in graph] + [None] return ModelView.__modules_list
def modules_suite(modules=None, doc=True): ''' Return all tests suite of all modules ''' if modules: suite_ = suite() else: suite_ = all_suite() from trytond.modules import create_graph, get_module_list, \ MODULES_PATH, EGG_MODULES graph = create_graph(get_module_list())[0] for package in graph: module = package.name if modules and module not in modules: continue test_module = 'trytond.modules.%s.tests' % module if os.path.isdir(os.path.join(MODULES_PATH, module)) or \ module in EGG_MODULES: try: test_mod = __import__(test_module, fromlist=['']) except ImportError: continue else: continue for test in test_mod.suite(): if isinstance(test, doctest.DocTestCase) and not doc: continue suite_.addTest(test) return suite_
def _get_installed_module_directories(cls): """ A generator that yields tuples of the format (module_name, directory) for every installed module in the current database """ from trytond.modules import create_graph, get_module_list, \ MODULES_PATH, EGG_MODULES IrModule = Pool().get('ir.module.module') packages = list(create_graph(get_module_list())[0])[::-1] installed_module_list = map( lambda module: module.name, IrModule.search([('state', '=', 'installed')])) for package in packages: if package.name not in installed_module_list: # this package is not installed as a module in this # database and hence the tranlation is not relevant continue if package.name in EGG_MODULES: # trytond.tools has a good helper which allows resources to # be loaded from the installed site packages. Just use it # to load the tryton.cfg file which is guaranteed to exist # and from it lookup the directory. From here, its just # another searchpath for the loader. f = file_open(os.path.join(package.name, 'tryton.cfg')) module_dir = os.path.dirname(f.name) else: module_dir = os.path.join(MODULES_PATH, package.name) yield package.name, module_dir
def update_list(cls): 'Update the list of available packages' count = 0 module_names = get_module_list() modules = cls.search([]) name2module = dict((m.name, m) for m in modules) # iterate through installed modules and mark them as being so for name in module_names: if name in name2module: module = name2module[name] tryton = get_module_info(name) cls._update_dependencies(module, tryton.get('depends', [])) continue tryton = get_module_info(name) if not tryton: continue module, = cls.create([{ 'name': name, 'state': 'uninstalled', }]) count += 1 cls._update_dependencies(module, tryton.get('depends', [])) return count
def update_list(cls): 'Update the list of available packages' count = 0 module_names = get_module_list() modules = cls.search([]) name2id = dict((m.name, m.id) for m in modules) cls.delete([ m for m in modules if m.state != 'activated' and m.name not in module_names ]) # iterate through activated modules and mark them as being so for name in module_names: if name in name2id: module = cls(name2id[name]) tryton = get_module_info(name) cls._update_dependencies(module, tryton.get('depends', [])) continue tryton = get_module_info(name) if not tryton: continue module, = cls.create([{ 'name': name, 'state': 'not activated', }]) count += 1 cls._update_dependencies(module, tryton.get('depends', [])) return count
def state_upgrade(self, ids): graph, packages, later = create_graph(get_module_list()) for module in self.browse(ids): if module.name not in graph: missings = [] for package, deps, xdep, info in packages: if package == module.name: missings = [x for x in deps if x not in graph] self.raise_user_error('missing_dep', (missings, module.name)) def get_childs(name, graph): childs = set(x.name for x in graph[name].childs) childs2 = set() for child in childs: childs2.update(get_childs(child, graph)) childs.update(childs2) return childs dependencies = list(get_childs(module.name, graph)) module_installed_ids = self.search([ ('name', 'in', dependencies), ('state', '=', 'installed'), ]) self.write(module_installed_ids + [module.id], { 'state': 'to upgrade', })
def on_write(self, ids): if not ids: return [] res = [] graph, packages, later = create_graph(get_module_list()) for module in self.browse(ids): if module.name not in graph: continue def get_parents(module): parents = set(p.name for p in module.parents) for p in module.parents: parents.update(get_parents(p)) return parents dependencies = get_parents(module) def get_childs(module): childs = set(c.name for c in module.childs) for c in module.childs: childs.update(get_childs(c)) return childs dependencies.update(get_childs(module)) res += self.search([ ('name', 'in', list(dependencies)), ]) return list({}.fromkeys(res))
def _get_installed_module_directories(cls): """ A generator that yields tuples of the format (module_name, directory) for every installed module in the current database """ from trytond.modules import create_graph, get_module_list, \ MODULES_PATH, EGG_MODULES IrModule = Pool().get('ir.module.module') packages = list(create_graph(get_module_list())[0])[::-1] installed_module_list = map( lambda module: module.name, IrModule.search([('state', '=', 'installed')]) ) for package in packages: if package.name not in installed_module_list: # this package is not installed as a module in this # database and hence the tranlation is not relevant continue if package.name in EGG_MODULES: # trytond.tools has a good helper which allows resources to # be loaded from the installed site packages. Just use it # to load the tryton.cfg file which is guaranteed to exist # and from it lookup the directory. From here, its just # another searchpath for the loader. f = file_open(os.path.join(package.name, 'tryton.cfg')) module_dir = os.path.dirname(f.name) else: module_dir = os.path.join(MODULES_PATH, package.name) yield package.name, module_dir
def loaders(self): ''' Lazy load the loaders ''' if self._loaders is None: self._loaders = [] if not Transaction().connection.cursor(): contextmanager = Transaction().start(self.database_name, 0) else: contextmanager = contextlib.nested( Transaction().set_user(0), Transaction().reset_context() ) with contextmanager: cursor = Transaction().connection.cursor() cursor.execute( "SELECT name FROM ir_module " "WHERE state = 'installed'" ) installed_module_list = [name for (name,) in cursor.fetchall()] if self.searchpath is not None: self._loaders.append(FileSystemLoader(self.searchpath)) # Look into the module graph and check if they have template # folders and if they do add them too from trytond.modules import create_graph, get_module_list, \ MODULES_PATH, EGG_MODULES packages = list(create_graph(get_module_list())[0])[::-1] for package in packages: if package.name not in installed_module_list: # If the module is not installed in the current database # then don't load the templates either to be consistent # with Tryton's modularity continue if package.name in EGG_MODULES: # trytond.tools has a good helper which allows resources to # be loaded from the installed site packages. Just use it # to load the tryton.cfg file which is guaranteed to exist # and from it lookup the directory. From here, its just # another searchpath for the loader. f = tools.file_open( os.path.join(package.name, 'tryton.cfg') ) template_dir = os.path.join( os.path.dirname(f.name), 'templates' ) else: template_dir = os.path.join( MODULES_PATH, package.name, 'templates' ) if os.path.isdir(template_dir): # Add to FS Loader only if the folder exists self._loaders.append(FileSystemLoader(template_dir)) return self._loaders
def loaders(self): ''' Lazy load the loaders ''' if self._loaders is None: self._loaders = [] if not Transaction().cursor: contextmanager = Transaction().start(self.database_name, 0) else: contextmanager = contextlib.nested( Transaction().set_user(0), Transaction().reset_context() ) with contextmanager: cursor = Transaction().cursor cursor.execute( "SELECT name FROM ir_module_module " "WHERE state = 'installed'" ) installed_module_list = [name for (name,) in cursor.fetchall()] if self.searchpath is not None: self._loaders.append(FileSystemLoader(self.searchpath)) # Look into the module graph and check if they have template # folders and if they do add them too from trytond.modules import create_graph, get_module_list, \ MODULES_PATH, EGG_MODULES packages = list(create_graph(get_module_list())[0])[::-1] for package in packages: if package.name not in installed_module_list: # If the module is not installed in the current database # then don't load the templates either to be consistent # with Tryton's modularity continue if package.name in EGG_MODULES: # trytond.tools has a good helper which allows resources to # be loaded from the installed site packages. Just use it # to load the tryton.cfg file which is guaranteed to exist # and from it lookup the directory. From here, its just # another searchpath for the loader. f = tools.file_open( os.path.join(package.name, 'tryton.cfg') ) template_dir = os.path.join( os.path.dirname(f.name), 'templates' ) else: template_dir = os.path.join( MODULES_PATH, package.name, 'templates' ) if os.path.isdir(template_dir): # Add to FS Loader only if the folder exists self._loaders.append(FileSystemLoader(template_dir)) return self._loaders
def _module_index(self): from trytond.modules import create_graph, get_module_list if self.__class__.__module_index is None: graph = create_graph(get_module_list()) modules = [m.name for m in graph] self.__class__.__module_index = { m: i for i, m in enumerate(reversed(modules)) } return self.__class__.__module_index
def monitor(files): ''' Monitor files and module files for change :return: True if at least one file has changed ''' global _MODULES modified = False for file_ in files: if _modified(file_): modified = True directories = set() for module in sys.modules.keys(): if not module.startswith('trytond.'): continue if not hasattr(sys.modules[module], '__file__'): continue path = getattr(sys.modules[module], '__file__') if not path: continue if os.path.splitext(path)[1] in ['.pyc', '.pyo', '.pyd']: path = path[:-1] if _modified(path): if subprocess.call( (sys.executable, '-c', 'import %s' % module), cwd=os.path.dirname( os.path.abspath( os.path.normpath(os.path.join(__file__, '..'))))): modified = False break modified = True # Check view XML directory = os.path.dirname(path) if directory not in directories: directories.add(directory) view_dir = os.path.join(directory, 'view') if os.path.isdir(view_dir): for view in os.listdir(view_dir): view = os.path.join(view_dir, view) if os.path.splitext(view)[1] == '.xml': if _modified(view): modified = True modules = set(get_module_list()) if _MODULES is None: _MODULES = modules for module in modules.difference(_MODULES): if subprocess.call( (sys.executable, '-c', 'import trytond.modules.%s' % module)): modified = False break modified = True _MODULES = modules return modified
def monitor(): ''' Monitor module files for change :return: True if at least one file has changed ''' global _MODULES modified = set() directories = set() logger = logging.getLogger('monitor') for module in sys.modules.keys(): if not module.startswith('trytond.'): continue if not hasattr(sys.modules[module], '__file__'): continue path = getattr(sys.modules[module], '__file__') if not path: continue if os.path.splitext(path)[1] in ['.pyc', '.pyo', '.pyd']: path = path[:-1] if _modified(path): if subprocess.call((sys.executable, '-c', 'import %s' % module), cwd=os.path.dirname(os.path.abspath(os.path.normpath( os.path.join(__file__, '..'))))): logger.error('Could not import module %s', module) break modified.add(module) # Check view XML directory = os.path.dirname(path) if directory not in directories: directories.add(directory) view_dir = os.path.join(directory, 'view') if os.path.isdir(view_dir): for view in os.listdir(view_dir): view = os.path.join(view_dir, view) if os.path.splitext(view)[1] == '.xml' and _modified(view): modified.add(module) modules = set(get_module_list()) if _MODULES is None: _MODULES = modules for module in modules.difference(_MODULES): if subprocess.call((sys.executable, '-c', 'import trytond.modules.%s' % module)): break modified.add(module) _MODULES = modules for mod in modified: logger.info('Module modified: %s', mod) return bool(modified)
def monitor(): """ Monitor module files for change :return: True if at least one file has changed """ global _MODULES modified = False directories = set() for module in sys.modules.keys(): if not module.startswith("trytond."): continue if not hasattr(sys.modules[module], "__file__"): continue path = getattr(sys.modules[module], "__file__") if not path: continue if os.path.splitext(path)[1] in [".pyc", ".pyo", ".pyd"]: path = path[:-1] if _modified(path): if subprocess.call( (sys.executable, "-c", "import %s" % module), cwd=os.path.dirname(os.path.abspath(os.path.normpath(os.path.join(__file__, "..")))), ): modified = False break modified = True # Check view XML directory = os.path.dirname(path) if directory not in directories: directories.add(directory) view_dir = os.path.join(directory, "view") if os.path.isdir(view_dir): for view in os.listdir(view_dir): view = os.path.join(view_dir, view) if os.path.splitext(view)[1] == ".xml": if _modified(view): modified = True modules = set(get_module_list()) if _MODULES is None: _MODULES = modules for module in modules.difference(_MODULES): if subprocess.call((sys.executable, "-c", "import trytond.modules.%s" % module)): modified = False break modified = True _MODULES = modules return modified
def modules_suite(modules=None, doc=True): ''' Return all tests suite of all modules ''' if modules: suite_ = suite() else: suite_ = all_suite() from trytond.modules import create_graph, get_module_list, \ MODULES_PATH, EGG_MODULES graph = create_graph(get_module_list())[0] for package in graph: module = package.name if modules and module not in modules: continue test_module = 'trytond.modules.%s.tests' % module if os.path.isdir(os.path.join(MODULES_PATH, module)) or \ module in EGG_MODULES: try: test_mod = __import__(test_module, fromlist=['']) except ImportError: continue else: continue for test in test_mod.suite(): found = False for other in suite_: if type(test) == type(other): if isinstance(test, doctest.DocTestCase): if str(test) == str(other): found = True break elif test._testMethodName == other._testMethodName: found = True break if not found: suite_.addTest(test) tests = [] doc_tests = [] for test in suite_: if isinstance(test, doctest.DocTestCase): if doc: doc_tests.append(test) else: tests.append(test) tests.extend(doc_tests) return unittest.TestSuite(tests)
def upgrade(cls, modules): modules_installed = set(modules) graph, packages, later = create_graph(get_module_list()) def get_childs(module): childs = set(c for c in module.childs) for c in module.childs: childs.update(get_childs(c)) return childs for module in modules: if module.name not in graph: missings = [] for package, deps, xdep, info in packages: if package == module.name: missings = [x for x in deps if x not in graph] cls.raise_user_error('missing_dep', (missings, module.name)) modules_installed.update((m for m in get_childs(module) if m.state == 'installed')) cls.write(list(modules_installed), { 'state': 'to upgrade', })
def install(cls, modules): modules_install = set(modules) graph, packages, later = create_graph(get_module_list()) def get_parents(module): parents = set(p for p in module.parents) for p in module.parents: parents.update(get_parents(p)) return parents for module in modules: if module.name not in graph: missings = [] for package, deps, xdep, info in packages: if package == module.name: missings = [x for x in deps if x not in graph] cls.raise_user_error('missing_dep', (missings, module.name)) modules_install.update((m for m in get_parents(module) if m.state == 'uninstalled')) cls.write(list(modules_install), { 'state': 'to install', })
def state_install(self, ids): graph, packages, later = create_graph(get_module_list()) for module in self.browse(ids): if module.name not in graph: missings = [] for package, deps, xdep, info in packages: if package == module.name: missings = [x for x in deps if x not in graph] self.raise_user_error('missing_dep', (missings, module.name)) def get_parents(module): parents = set(p.name for p in module.parents) for p in module.parents: parents.update(get_parents(p)) return parents dependencies = list(get_parents(module)) module_install_ids = self.search([ ('name', 'in', dependencies), ('state', '=', 'uninstalled'), ]) self.write(module_install_ids + [module.id], { 'state': 'to install', })
def on_write(cls, modules): ids = set() graph, packages, later = create_graph(get_module_list()) for module in modules: if module.name not in graph: continue def get_parents(module): parents = set(p.name for p in module.parents) for p in module.parents: parents.update(get_parents(p)) return parents dependencies = get_parents(module) def get_childs(module): childs = set(c.name for c in module.childs) for c in module.childs: childs.update(get_childs(c)) return childs dependencies.update(get_childs(module)) ids |= set(x.id for x in cls.search([ ('name', 'in', list(dependencies)), ])) return list(ids)
def modules_suite(modules=None, doc=True): ''' Return all tests suite of all modules ''' if modules: suite_ = suite() else: suite_ = all_suite() from trytond.modules import create_graph, get_module_list, import_module graph = create_graph(get_module_list()) for node in graph: module = node.name if modules and module not in modules: continue test_module = 'trytond.modules.%s.tests' % module try: test_mod = import_module(module, test_module) except ImportError: continue for test in test_mod.suite(): if isinstance(test, doctest.DocTestCase) and not doc: continue suite_.addTest(test) return suite_
def monitor(): ''' Monitor module files for change :return: True if at least one file has changed ''' global _MODULES modified = False for module in sys.modules.keys(): if not module.startswith('trytond.'): continue if not hasattr(sys.modules[module], '__file__'): continue path = getattr(sys.modules[module], '__file__') if not path: continue if os.path.splitext(path)[1] in ['.pyc', '.pyo', '.pyd']: path = path[:-1] if _modified(path): if subprocess.call((sys.executable, '-c', 'import %s' % module), cwd=os.path.dirname(os.path.abspath(os.path.normpath( os.path.join(__file__, '..'))))): modified = False break modified = True modules = set(get_module_list()) if _MODULES is None: _MODULES = modules for module in modules.difference(_MODULES): if subprocess.call((sys.executable, '-c', 'import trytond.modules.%s' % module)): modified = False break modified = True _MODULES = modules return modified
def update_list(self): pool = Pool() lang_obj = pool.get('ir.lang') res = 0 with Transaction().set_context(language=False): lang_ids = lang_obj.search([ ('translatable', '=', True), ]) lang_codes = [x.code for x in lang_obj.browse(lang_ids)] module_names = get_module_list() module_ids = self.search([]) modules = self.browse(module_ids) name2module = {} for module in modules: name2module.setdefault(module.name, {}) name2module[module.name]['en_US'] = module for code in lang_codes: with Transaction().set_context(language=code): modules = self.browse(module_ids) for module in modules: name2module[module.name][code] = module # iterate through installed modules and mark them as being so for name in module_names: mod_name = name if mod_name in name2module.keys(): mod = name2module[mod_name]['en_US'] tryton = Module.get_module_info(mod_name) if mod.description != tryton.get('description', '').decode('utf-8', 'ignore') \ or mod.shortdesc != tryton.get('name', '').decode('utf-8', 'ignore') \ or mod.author != tryton.get('author', '').decode('utf-8', 'ignore') \ or mod.website != tryton.get('website', '').decode('utf-8', 'ignore'): self.write(mod.id, { 'description': tryton.get('description', ''), 'shortdesc': tryton.get('name', ''), 'author': tryton.get('author', ''), 'website': tryton.get('website', ''), }) for code in lang_codes: mod2 = name2module[mod_name][code] if mod2.description != \ tryton.get('description_' + code, tryton.get('description', '') ).decode('utf-8', 'ignore') \ or mod2.shortdesc != \ tryton.get('name_' + code, tryton.get('name', '') ).decode('utf-8', 'ignore'): with Transaction().set_context(language=code): self.write(mod.id, { 'description': tryton.get( 'description_' + code, ''), 'shortdesc': tryton.get( 'name_' + code, ''), }) self._update_dependencies(mod, tryton.get('depends', [])) continue tryton = Module.get_module_info(mod_name) if not tryton: continue new_id = self.create({ 'name': mod_name, 'state': 'uninstalled', 'description': tryton.get('description', ''), 'shortdesc': tryton.get('name', ''), 'author': tryton.get('author', 'Unknown'), 'website': tryton.get('website', ''), }) for code in lang_codes: with Transaction().set_context(language=code): self.write(new_id, { 'description': tryton.get( 'description_' + code, ''), 'shortdesc': tryton.get('name_' + code, ''), }) res += 1 name2module.setdefault(mod_name, {}) name2module[mod_name]['en_US'] = self.browse(new_id) self._update_dependencies(name2module[mod_name]['en_US'], tryton.get('depends', [])) return res