示例#1
0
 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
示例#2
0
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_
示例#3
0
    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
示例#4
0
 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
示例#5
0
    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
示例#6
0
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_
示例#7
0
    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
示例#8
0
    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',
                })
示例#9
0
    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))
示例#10
0
    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
示例#11
0
    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
示例#12
0
    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
示例#13
0
    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
示例#14
0
 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
示例#15
0
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
示例#16
0
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)
示例#17
0
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
示例#18
0
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)
示例#19
0
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)
示例#20
0
    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',
                })
示例#21
0
    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',
                })
示例#22
0
    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',
                })
示例#23
0
    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',
                })
示例#24
0
    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',
                })
示例#25
0
文件: module.py 项目: Sisouvan/ogh
    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)
示例#26
0
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_
示例#27
0
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
示例#28
0
    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