Beispiel #1
0
 def wrapper(*args, **kwargs):
     start_time = time.time()
     res = f(*args, **kwargs)
     function_name = f.func_name if python.is_python2() else f.__name__
     logger.info('<{}> Elapsed time : {}'.format(function_name,
                                                 time.time() - start_time))
     return res
Beispiel #2
0
def register_libs(project_inst):
    """
    Function that registera all available libs for given project
    :param project_inst: ArtellaProject
    """

    from tpDcc.libs.python import python

    if python.is_python2():
        import pkgutil as loader
    else:
        import importlib as loader

    libs_found = project_inst.config_data.get('libs', list())
    libs_to_register = dict()
    libs_path = '{}.libs.{}'
    for lib_name in libs_found:
        for pkg in ['artellapipe', project_inst.get_clean_name()]:
            pkg_path = libs_path.format(pkg, lib_name)
            try:
                pkg_loader = loader.find_loader(pkg_path)
            except Exception:
                pkg_loader = None
            if pkg_loader is not None:
                if lib_name not in libs_to_register:
                    libs_to_register[lib_name] = list()
                libs_to_register[lib_name].append(pkg_loader)

    for pkg_loaders in libs_to_register.values():
        for pkg_loader in pkg_loaders:
            libs.LibsManager().register_lib(project=project_inst,
                                            pkg_loader=pkg_loader)
Beispiel #3
0
    def _load_package_toolsets(self, package_name, tools_to_load):
        """
        Loads all toolsets available in given package
        :param package_name: str
        :param tools_to_load: list
        """

        if not tools_to_load:
            return
        tools_to_load = python.force_list(tools_to_load)

        paths_to_register = OrderedDict()

        tools_path = '{}.tools.{}'
        tools_paths_to_load = list()
        for tool_name in tools_to_load:
            pkg_path = tools_path.format(package_name, tool_name)
            pkg_loader = loader.find_loader(pkg_path)
            if not pkg_loader:
                LOGGER.debug('No loader found for "{}"'.format(tool_name))
                continue
            if tool_name not in paths_to_register:
                paths_to_register[tool_name] = list()

            package_filename = pkg_loader.filename if python.is_python2(
            ) else os.path.dirname(pkg_loader.path)
            if package_filename not in tools_paths_to_load:
                tools_paths_to_load.append(package_filename)

        # Find where toolset widgets are located
        if tools_paths_to_load:
            self._manager.register_paths(tools_paths_to_load,
                                         package_name=package_name)
Beispiel #4
0
def load_module_from_source(file_path, unique_namespace=False):
    """
    Loads a Python from given source file
    :param file_path:
    :param unique_namespace: bool
    :return:
    """

    file_name = os.path.splitext(os.path.basename(file_path))[0]

    module_name = '{}{}'.format(file_name, str(
        uuid.uuid4())) if unique_namespace else file_name

    try:
        if python.is_python2():
            if file_path.endswith('.py'):
                return imp.load_source(module_name, file_path)
            elif file_path.endswith('.pyc'):
                return imp.load_compiled(module_name, file_path)
        else:
            return SourceFileLoader(module_name, file_path).load_module()
    except BaseException:
        logger.debug('Failed trying to direct load : {} | {}'.format(
            file_path, traceback.format_exc()))
        return None
Beispiel #5
0
def wrapinstance(ptr, base=None):
    if ptr is None:
        return None

    ptr_type = long if python.is_python2() else int

    ptr = ptr_type(ptr)
    if 'shiboken' in globals():
        if base is None:
            qObj = shiboken.wrapInstance(ptr_type(ptr), QObject)
            meta_obj = qObj.metaObject()
            cls = meta_obj.className()
            super_cls = meta_obj.superClass().className()
            if hasattr(QtGui, cls):
                base = getattr(QtGui, cls)
            elif hasattr(QtGui, super_cls):
                base = getattr(QtGui, super_cls)
            else:
                base = QWidget
        try:
            return shiboken.wrapInstance(ptr_type(ptr), base)
        except Exception:
            from PySide.shiboken import wrapInstance
            return wrapInstance(ptr_type(ptr), base)
    elif 'sip' in globals():
        base = QObject
        return shiboken.wrapinstance(ptr_type(ptr), base)
    else:
        print('Failed to wrap object ...')
        return None
Beispiel #6
0
    def write(self, msg):
        """
        Add message to the console's output, on a new line
        :param msg: str
        """

        self.insertPlainText(msg + '\n')
        self.moveCursor(QTextCursor.End)
        self._buffer.write(unicode(msg) if python.is_python2() else str(msg))
Beispiel #7
0
def unwrapinstance(object):
    """
    Unwraps objects with PySide
    """

    if python.is_python2():
        return long(shiboken.getCppPointer(object)[0])
    else:
        return int(shiboken.getCppPointer(object)[0])
Beispiel #8
0
def node_handle_exists(node_id):
    """
    Checks if exists a node with the given ID
    :param node_id: int
    :return: bool
    """

    native_node = get_node_by_handle(long(node_id) if python.is_python2() else int(node_id))
    return native_node is not None
Beispiel #9
0
    def register_package_tools(self, package_name, tools_to_register=None):
        """
        Registers all tools available in given package
        """

        found_tools = list()

        if not tools_to_register:
            return
        tools_to_register = python.force_list(tools_to_register)

        tools_path = '{}.tools.{}'
        for tool_name in tools_to_register:
            pkg_path = tools_path.format(package_name, tool_name)
            if python.is_python2():
                pkg_loader = loader.find_loader(pkg_path)
            else:
                pkg_loader = importlib.util.find_spec(pkg_path)
            if not pkg_loader:
                continue

            tool_path = path_utils.clean_path(
                pkg_loader.filename if python.is_python2(
                ) else os.path.dirname(pkg_loader.origin))
            if not tool_path or not os.path.isdir(tool_path):
                continue

            found_tools.append(tool_path)

        if not found_tools:
            logger.warning(
                'No tools found in package "{}"'.format(package_name))

        found_tools = list(set(found_tools))
        self.register_paths(found_tools, package_name=package_name)

        for tool_class in self.plugins(package_name=package_name):
            if not tool_class:
                continue

            if not tool_class.PACKAGE:
                tool_class.PACKAGE = package_name
            if tool_class.TOOLSET_CLASS:
                tool_class.TOOLSET_CLASS.ID = tool_class.ID
Beispiel #10
0
    def write_warning(self, msg):
        """
        Adds a warning yellow message to the console
        :param msg: str
        """

        msg_html = "<font color=\"Yellow\"> " + msg + "\n</font><br>"
        self.insertHtml(msg_html)
        self.moveCursor(QTextCursor.End)
        self._buffer.write(unicode(msg) if python.is_python2() else str(msg))
Beispiel #11
0
    def write_error(self, msg):
        """
        Adds an error message to the console
        :param msg: str
        """

        msg_html = "<font color=\"Red\">ERROR: " + msg + "\n</font><br>"
        msg = 'ERROR: ' + msg
        self.insertHtml(msg_html)
        self.moveCursor(QTextCursor.End)
        self._buffer.write(unicode(msg) if python.is_python2() else str(msg))
Beispiel #12
0
    def format(cls, data=None, options=None, dpi=1, **kwargs):
        """
        Returns style with proper format
        :param data: str
        :param options: dict
        :param dpi: float
        :return: str
        """

        if options:
            keys = options.keys()
            if python.is_python2():
                keys.sort(key=len, reverse=True)
            else:
                keys = sorted(keys, key=len, reverse=True)
            for key in keys:
                key_value = options[key]
                str_key_value = str(key_value)
                option_value = str(key_value)
                if str_key_value.startswith('@^'):
                    option_value = str(utils.dpi_scale(int(str_key_value[2:])))
                elif str_key_value.startswith('^'):
                    option_value = str(utils.dpi_scale(int(str_key_value[1:])))
                elif 'icon' in key:
                    theme_name = kwargs.get('theme_name', 'default') or 'default'
                    resource_path = resources.get('icons', theme_name, str(key_value))
                    if resource_path and os.path.isfile(resource_path):
                        option_value = resource_path
                elif color.string_is_hex(str_key_value):
                    try:
                        color_list = color.hex_to_rgba(str_key_value)
                        option_value = 'rgba({}, {}, {}, {})'.format(
                            color_list[0], color_list[1], color_list[2], color_list[3])
                    except ValueError:
                        # This exception will be raised if we try to convert an attribute that is not a color.
                        option_value = key_value

                data = data.replace('@{}'.format(key), option_value)

        re_dpi = re.compile('[0-9]+[*]DPI')
        new_data = list()

        for line in data.split('\n'):
            dpi_ = re_dpi.search(line)
            if dpi_:
                new = dpi_.group().replace('DPI', str(dpi))
                val = int(eval(new))
                line = line.replace(dpi_.group(), str(val))
            new_data.append(line)

        data = '\n'.join(new_data)

        return data
Beispiel #13
0
    def register_package_libs(self, package_name, libs_to_register=None):
        """
        Registers  all libraries available in given package
        """

        found_libs = list()

        if not libs_to_register:
            return
        libs_to_register = python.force_list(libs_to_register)

        libs_path = '{}.libs.{}'
        for lib_name in libs_to_register:
            pkg_path = libs_path.format(package_name, lib_name)
            if python.is_python2():
                pkg_loader = loader.find_loader(pkg_path)
            else:
                pkg_loader = importlib.util.find_spec(pkg_path)
            if not pkg_loader:
                continue

            lib_path = path_utils.clean_path(
                pkg_loader.filename if python.is_python2(
                ) else os.path.dirname(pkg_loader.origin))
            if not lib_path or not os.path.isdir(lib_path):
                continue

            found_libs.append(lib_path)

        if not found_libs:
            logger.warning(
                'No libraries found in package "{}"'.format(package_name))

        found_libs = list(set(found_libs))
        self.register_paths(found_libs, package_name=package_name)

        # Once plugins are registered we load them
        plugins = self.plugins(package_name=package_name)
        for plugin in plugins:
            plugin.load()
Beispiel #14
0
def image_to_base64(image_path):
    """
    Converts image file to base64
    :param image_path: str
    :return: str
    """

    if os.path.isfile(image_path):
        with open(image_path, 'rb') as image_file:
            base64_data = base64.b64encode(image_file.read())
            if python.is_python2():
                return base64_data
            else:
                return base64_data.decode("utf-8")
    def fields(cls, identifier):

        ctime = str(time.time()).split('.')[0]
        user = getpass.getuser()
        if user and python.is_python2():
            user.decode(locale.getpreferredencoding())

        name, extension = os.path.splitext(os.path.basename(identifier))
        return OrderedDict([('name', name), ('extension', extension),
                            ('directory', os.path.dirname(identifier)),
                            ('folder', os.path.isdir(identifier)),
                            ('user', user),
                            ('modified',
                             fileio.get_last_modified_date(identifier)),
                            ('ctime', ctime)])
Beispiel #16
0
def normalize_path(path):
    """
    Normalizes a path to make sure that path only contains forward slashes
    :param path: str, path to normalize
    :return: str, normalized path
    """

    path = path.replace(BAD_SEPARATOR, SEPARATOR).replace(PATH_SEPARATOR, SEPARATOR)

    if python.is_python2():
        try:
            path = unicode(path.replace(r'\\', r'\\\\'), "unicode_escape").encode('utf-8')
        except TypeError:
            path = path.replace(r'\\', r'\\\\').encode('utf-8')

    return path.rstrip('/')
Beispiel #17
0
    def write_json(self, dict_data):
        """
        Writes given JSON data (dict) into file
        :param dict_data: dict
        """

        self.write_file()
        try:
            if python.is_python2():
                json.dump(dict_data, self.open_file, indent=4, sort_keys=False)
            else:
                json.dump(dict(dict_data),
                          self.open_file,
                          indent=4,
                          sort_keys=False)
        except Exception as exc:
            logger.exception('Impossible to save JSON file: "{}"'.format(exc))
        self.close_file()
Beispiel #18
0
    def read(self):
        contents = dict()
        if not os.path.isfile(self._path):
            return contents

        try:
            with open(self._path, 'r+b') as fh:
                contents = pickle.load(fh) if python.is_python2(
                ) else pickle.load(fh, encoding='bytes')
        except pickle.UnpicklingError:
            _broken_files.setdefault(self._path, 0)
            times_hit = _broken_files[self._path]
            if times_hit < 3:
                logger.error('Failed to load pickle preference "{}"'.format(
                    self._path))
            times_hit += 1
            _broken_files[self._path] = times_hit

        self.clear()
        self.update(contents)
Beispiel #19
0
    def register_package_libs(self,
                              pkg_name,
                              root_pkg_name=None,
                              libs_to_register=None,
                              dev=True,
                              config_dict=None):
        """
        Registers  all libraries available in given package
        """

        environment = 'development' if dev else 'production'

        if not libs_to_register:
            return
        libs_to_register = python.force_list(libs_to_register)

        if config_dict is None:
            config_dict = dict()

        libs_path = '{}.libs.{}'
        for lib_name in libs_to_register:
            pkg_path = libs_path.format(pkg_name, lib_name)
            if python.is_python2():
                pkg_loader = loader.find_loader(pkg_path)
            else:
                pkg_loader = importlib.util.find_spec(pkg_path)
            if not pkg_loader:
                # if tool_name in self._tools_to_load:
                #     self._tools_to_load.pop(tool_name)
                continue
            else:
                lib_data = {
                    'loaders': pkg_loader,
                    'pkg_name': pkg_name,
                    'root_pkg_name': root_pkg_name,
                    'environment': environment,
                    'config_dict': config_dict
                }
                self._libs_to_load[lib_name] = lib_data

        return self._libs_to_load
Beispiel #20
0
def qhash(inputstr):
    instr = ""

    if python.is_python2():
        if isinstance(inputstr, str):
            instr = inputstr
        elif isinstance(inputstr, unicode):
            instr = inputstr.encode("utf8")
        else:
            return -1
    else:
        if python.is_string(inputstr):
            instr = inputstr
        else:
            return -1

    h = 0x00000000
    for i in range(0, len(instr)):
        h = (h << 4) + ord(instr[i])
        h ^= (h & 0xf0000000) >> 23
        h &= 0x0fffffff
    return h
    def __init__(self, title, commands_data, controller, parent=None):

        self._commands_data = commands_data or dict()
        self._widgets = dict()
        self._buttons = list()
        self._current_action = None
        self._controller = controller
        self._controller_functions_mapping = dict()

        super(CommandRigToolBoxWidget, self).__init__(title=title,
                                                      parent=parent)

        if self._controller:
            predicate = inspect.ismethod if python.is_python2(
            ) else inspect.isfunction
            controller_functions = inspect.getmembers(
                self._controller.__class__, predicate=predicate)
            for controller_fn_data in controller_functions:
                if controller_fn_data[0] in ['__init__']:
                    continue
                controller_fn = getattr(self._controller,
                                        controller_fn_data[0])
                if not controller_fn:
                    continue
                self._controller_functions_mapping[
                    controller_fn_data[0]] = controller_fn

        added_categories = list()
        for name, data in self._commands_data.items():
            categories = data.get('categories', list())
            for category in categories:
                if not category or category in added_categories:
                    continue
                category_widget = self._add_category(category)
                if not category_widget:
                    continue
                self._accordion.add_item(category, category_widget)
                added_categories.append(category)
Beispiel #22
0
    def load_plugin(self,
                    pkg_name,
                    pkg_loaders,
                    environment,
                    root_pkg_name=None,
                    config_dict=None,
                    load=True):
        """
        Implements load_plugin function
        Registers a plugin instance to the manager
        :param pkg_name: str
        :param pkg_loaders: plugin instance to register
        :param environment:
        :param root_pkg_name:
        :param config_dict:
        :param load:
        :return: Plugin
        """

        if not pkg_loaders:
            return False

        package_loader = pkg_loaders[0] if isinstance(pkg_loaders,
                                                      (list,
                                                       tuple)) else pkg_loaders
        if not package_loader:
            return False

        if hasattr(package_loader, 'loader'):
            if not package_loader.loader:
                return False

        plugin_path = package_loader.filename if python.is_python2(
        ) else os.path.dirname(package_loader.loader.path)
        plugin_name = package_loader.fullname if python.is_python2(
        ) else package_loader.loader.name

        if not config_dict:
            config_dict = dict()

        local = os.getenv('APPDATA') or os.getenv('HOME')

        config_dict.update({
            'join': os.path.join,
            'user': os.path.expanduser('~'),
            'filename': plugin_path,
            'fullname': plugin_name,
            'root': path_utils.clean_path(plugin_path),
            'local': local,
            'home': local
        })

        if pkg_name not in self._plugins:
            self._plugins[pkg_name] = dict()

        tools_found = list()
        version_found = None
        packages_to_walk = [plugin_path] if python.is_python2() else [
            os.path.dirname(plugin_path)
        ]
        for sub_module in pkgutil.walk_packages(packages_to_walk):
            importer, sub_module_name, _ = sub_module
            qname = '{}.{}'.format(plugin_name, sub_module_name)
            try:
                mod = importer.find_module(sub_module_name).load_module(
                    sub_module_name)
            except Exception:
                # LOGGER.exception('Impossible to register plugin: "{}"'.format(plugin_path))
                continue

            if qname.endswith('__version__') and hasattr(mod, '__version__'):
                if version_found:
                    LOGGER.warning(
                        'Already found version: "{}" for "{}"'.format(
                            version_found, plugin_name))
                else:
                    version_found = getattr(mod, '__version__')

            mod.LOADED = load

            for cname, obj in inspect.getmembers(mod, inspect.isclass):
                for interface in self._interfaces:
                    if issubclass(obj, interface):
                        tool_config_dict = obj.config_dict(
                            file_name=plugin_path) or dict()
                        if not tool_config_dict:
                            continue
                        tool_id = tool_config_dict.get('id', None)
                        tool_config_name = tool_config_dict.get('name', None)
                        # tool_icon = tool_config_dict.get('icon', None)
                        if not tool_id:
                            LOGGER.warning(
                                'Impossible to register tool "{}" because its ID is not defined!'
                                .format(tool_id))
                            continue
                        if not tool_config_name:
                            LOGGER.warning(
                                'Impossible to register tool "{}" because its name is not defined!'
                                .format(tool_config_name))
                            continue
                        if root_pkg_name and root_pkg_name in self._plugins and tool_id in self._plugins[
                                root_pkg_name]:
                            LOGGER.warning(
                                'Impossible to register tool "{}" because its ID "{}" its already defined!'
                                .format(tool_config_name, tool_id))
                            continue

                        if not version_found:
                            version_found = '0.0.0'
                        obj.VERSION = version_found
                        obj.FILE_NAME = plugin_path
                        obj.FULL_NAME = plugin_name

                        tools_found.append((qname, version_found, obj))
                        version_found = True
                        break

        if not tools_found:
            LOGGER.warning(
                'No tools found in module "{}". Skipping ...'.format(
                    plugin_path))
            return False
        if len(tools_found) > 1:
            LOGGER.warning(
                'Multiple tools found ({}) in module "{}". Loading first one. {} ...'
                .format(len(tools_found), plugin_path, tools_found[-1]))
            tool_found = tools_found[-1]
        else:
            tool_found = tools_found[0]
        tool_loader = loader.find_loader(tool_found[0])

        # Check if DCC specific implementation for plugin exists
        dcc_path = '{}.dccs.{}'.format(plugin_name, dcc.get_name())
        dcc_loader = None
        dcc_config = None
        try:
            dcc_loader = loader.find_loader(dcc_path)
        except ImportError:
            pass

        tool_config_dict = tool_found[2].config_dict(
            file_name=plugin_path) or dict()
        tool_id = tool_config_dict['id']
        _tool_name = tool_config_dict['name']
        tool_icon = tool_config_dict['icon']

        tool_config_name = plugin_name.replace('.', '-')
        tool_config = configs.get_config(config_name=tool_config_name,
                                         package_name=pkg_name,
                                         root_package_name=root_pkg_name,
                                         environment=environment,
                                         config_dict=config_dict,
                                         extra_data=tool_config_dict)

        if dcc_loader:
            dcc_path = dcc_loader.fullname
            dcc_config = configs.get_config(config_name=dcc_path.replace(
                '.', '-'),
                                            package_name=pkg_name,
                                            environment=environment,
                                            config_dict=config_dict)
            if not dcc_config.get_path():
                dcc_config = None

        # Register resources
        def_resources_path = os.path.join(plugin_path, 'resources')
        # resources_path = plugin_config.data.get('resources_path', def_resources_path)
        resources_path = tool_config_dict.get('resources_path', None)
        if not resources_path or not os.path.isdir(resources_path):
            resources_path = def_resources_path
        if os.path.isdir(resources_path):
            resources.register_resource(resources_path, key='tools')
        else:
            pass
            # tp.logger.debug('No resources directory found for plugin "{}" ...'.format(_plugin_name))

        # Register DCC specific resources
        if dcc_loader and dcc_config:
            def_resources_path = os.path.join(dcc_loader.filename, 'resources')
            resources_path = dcc_config.data.get('resources_path',
                                                 def_resources_path)
            if not resources_path or not os.path.isdir(resources_path):
                resources_path = def_resources_path
            if os.path.isdir(resources_path):
                resources.register_resource(resources_path, key='plugins')
            else:
                pass
                # tp.logger.debug('No resources directory found for plugin "{}" ...'.format(_plugin_name))

        # Create tool loggers directory
        default_logger_dir = os.path.normpath(
            os.path.join(os.path.expanduser('~'), 'tpDcc', 'logs', 'tools'))
        default_logging_config = os.path.join(plugin_path, '__logging__.ini')
        logger_dir = tool_config_dict.get('logger_dir', default_logger_dir)
        if not os.path.isdir(logger_dir):
            os.makedirs(logger_dir)
        logging_file = tool_config_dict.get('logging_file',
                                            default_logging_config)

        tool_package = plugin_name
        tool_package_path = plugin_path
        dcc_package = None
        dcc_package_path = None
        if dcc_loader:
            dcc_package = dcc_loader.fullname if python.is_python2(
            ) else dcc_loader.loader.path
            dcc_package_path = dcc_loader.filename if python.is_python2(
            ) else dcc_loader.loader.name

        self._plugins[pkg_name][tool_id] = {
            'name': _tool_name,
            'icon': tool_icon,
            'package_name': pkg_name,
            'loader': package_loader,
            'config': tool_config,
            'config_dict': tool_config_dict,
            'plugin_loader': tool_loader,
            'plugin_package': tool_package,
            'plugin_package_path': tool_package_path,
            'version': tool_found[1] if tool_found[1] is not None else "0.0.0",
            'dcc_loader': dcc_loader,
            'dcc_package': dcc_package,
            'dcc_package_path': dcc_package_path,
            'dcc_config': dcc_config,
            'logging_file': logging_file,
            'plugin_instance': None
        }

        LOGGER.info('Tool "{}" registered successfully!'.format(plugin_name))

        return True
Beispiel #23
0
    def get_tool_by_id(self,
                       tool_id,
                       package_name=None,
                       dev=False,
                       *args,
                       **kwargs):
        """
        Launches tool of a specific package by its ID
        :param tool_id: str, tool ID
        :param package_name: str, str
        :param dev: bool
        :param args: tuple, arguments to pass to the tool execute function
        :param kwargs: dict, keyword arguments to pas to the tool execute function
        :return: DccTool or None, executed tool instance
        """

        if not package_name:
            package_name = tool_id.replace('.', '-').split('-')[0]

        if package_name not in self._plugins:
            LOGGER.warning(
                'Impossible to load tool by id: package "{}" is not registered!'
                .format(package_name))
            return None

        if tool_id in self._plugins[package_name]:
            tool_inst = self._plugins[package_name][tool_id].get(
                'tool_instance', None)
            if tool_inst:
                return tool_inst

        tool_to_run = None

        for plugin_id in self._plugins[package_name].keys():
            tool_path = self._plugins[package_name][plugin_id][
                'plugin_package']
            sec_path = tool_path.replace('.', '-')
            if sec_path == tool_path or sec_path == tool_id:
                tool_to_run = tool_id
                break
            else:
                tool_name = tool_path.split('.')[-1]
                if tool_name == tool_path:
                    tool_to_run = tool_id
                    break

        if not tool_to_run or tool_to_run not in self._plugins[package_name]:
            LOGGER.warning('Tool "{}" is not registered!'.format(tool_id))
            return None

        tool_loader = self._plugins[package_name][tool_to_run]['loader']
        pkg_loader = self._plugins[package_name][tool_to_run]['loader']
        tool_config = self._plugins[package_name][tool_to_run]['config']
        tool_fullname = tool_loader.fullname if python.is_python2(
        ) else tool_loader.loader.name
        tool_version = self._plugins[package_name][tool_to_run]['version']

        pkg_name = pkg_loader.filename if python.is_python2(
        ) else os.path.dirname(pkg_loader.loader.path)
        pkg_path = pkg_loader.fullname if python.is_python2(
        ) else pkg_loader.loader.name

        tool_found = None
        for sub_module in pkgutil.walk_packages(
            [self._plugins[package_name][tool_to_run]['plugin_package_path']]):
            tool_importer, sub_module_name, _ = sub_module
            mod = tool_importer.find_module(sub_module_name).load_module(
                sub_module_name)
            for cname, obj in inspect.getmembers(mod, inspect.isclass):
                if issubclass(obj, tool.DccTool):
                    obj.FILE_NAME = pkg_name
                    obj.FULL_NAME = pkg_path
                    tool_found = obj
                    break
            if tool_found:
                break

        if not tool_found:
            LOGGER.error(
                "Error while launching tool: {}".format(tool_fullname))
            return None

        # if dcc_loader:
        #     tool_config = dcc_config

        tool_settings = self.get_tool_settings_file(tool_id)
        if not tool_settings.has_setting('theme'):
            tool_settings.set('theme', 'default')
        tool_settings.setFallbacksEnabled(False)

        tool_inst = tool_found(self,
                               config=tool_config,
                               settings=tool_settings,
                               dev=dev,
                               *args,
                               **kwargs)
        tool_inst.ID = tool_id
        tool_inst.VERSION = tool_version
        tool_inst.AUTHOR = tool_inst.config_dict().get('creator', None)
        tool_inst.PACKAGE = package_name

        self._plugins[package_name][tool_id]['tool_instance'] = tool_inst
        # self._plugins[package_name][plugin_id]['tool_instance'] = tool_inst

        return tool_inst
    def _create_editors(self):
        """
        Internal function that creates the editors that should be used by tagger
        Overrides to add custom editors
        """

        if python.is_python2():
            import pkgutil as loader
        else:
            import importlib as loader

        editors_modules = self.config.get('editors_module')
        if not editors_modules:
            LOGGER.warning(
                'No core editors module specified in artellapipe.tools.tagger configuration file!'
            )
            return False

        available_editors = self.config.get('available_editors')
        if not available_editors:
            LOGGER.warning(
                'No available editors defined in artellapipe.tools.tagger configuration file!'
            )
            return False

        LOGGER.info('Loading Available Editors: {}'.format(available_editors))

        modules_to_register = dict()
        all_modules = [editors_modules]
        extra_editors_modules = self.config.get('extra_editors_modules')
        if extra_editors_modules:
            all_modules.extend(extra_editors_modules)

        for module in all_modules:
            try:
                pkg_loader = loader.find_loader(module)
            except Exception:
                continue
            if pkg_loader is not None:
                modules_to_register[module] = pkg_loader

        editors_found = dict()
        for module_path, pkg_loader in modules_to_register.items():
            for sub_module in loader.walk_packages([pkg_loader.filename]):
                importer, sub_module_name, _ = sub_module
                qname = pkg_loader.fullname + '.' + sub_module_name
                editors_found[qname] = list()
                try:
                    mod = importer.find_module(sub_module_name).load_module(
                        sub_module_name)
                except Exception as exc:
                    LOGGER.warning(
                        'Impossible to import tagger editors from: "{}" | {}'.
                        format(module_path, exc))
                    continue

                for cname, obj in inspect.getmembers(mod, inspect.isclass):
                    if issubclass(obj, taggereditor.TaggerEditor):
                        if not hasattr(obj,
                                       'EDITOR_TYPE') or not obj.EDITOR_TYPE:
                            LOGGER.warning(
                                'Editor "{}" has not EDITOR_TYPE defined')
                            continue
                        editors_found[qname].append(obj)

        loaded_editors = list()

        for available_editor in available_editors:
            if available_editor in loaded_editors:
                LOGGER.warning(
                    'Editor "{}" of type "{}" is already loaded. Skipping ...'.
                    format(editor_class, editor_type))
                continue
            for editor_classes in editors_found.values():
                if not editor_classes:
                    continue
                for editor_class in editor_classes:
                    editor_type = editor_class.EDITOR_TYPE
                    if editor_type == available_editor:
                        new_editor = editor_class(project=self._project)
                        self.add_editor(new_editor)
                        loaded_editors.append(editor_type)

        not_loaded_editors = list()
        for available_editor in available_editors:
            if available_editor not in loaded_editors:
                not_loaded_editors.append(available_editor)

        if not_loaded_editors:
            LOGGER.warning(
                'Was not possible to load following tag editors: {}!'.format(
                    not_loaded_editors))
Beispiel #25
0
__author__ = "Tomas Poveda"
__license__ = "MIT"
__maintainer__ = "Tomas Poveda"
__email__ = "*****@*****.**"

import os
import logging
import inspect
import traceback
import importlib
from collections import OrderedDict

import tpDcc as tp
from tpDcc.libs.python import python, decorators, strings, path as path_utils

if python.is_python2():
    import pkgutil as loader
else:
    import importlib as loader

import artellapipe
from artellapipe.utils import exceptions
from artellapipe.core import defines
from artellapipe.libs.artella.core import artellalib, artellaclasses

LOGGER = logging.getLogger('artellapipe')


class AssetsManager(object):

    _assets = list()
Beispiel #26
0
    def load_plugin(self,
                    pkg_name,
                    pkg_loaders,
                    environment,
                    root_pkg_name=None,
                    config_dict=None,
                    load=True):
        """
        Implements load_plugin function
        Registers a plugin instance to the manager
        :param pkg_name: str
        :param pkg_loaders: plugin instance to register
        :param environment:
        :param root_pkg_name:
        :param config_dict:
        :param load:
        :return: Plugin
        """

        from tpDcc.managers import configs

        if not pkg_loaders:
            return False

        package_loader = pkg_loaders[0] if isinstance(pkg_loaders,
                                                      (list,
                                                       tuple)) else pkg_loaders
        if not package_loader:
            return False

        if hasattr(package_loader, 'loader'):
            if not package_loader.loader:
                return False

        plugin_path = package_loader.filename if python.is_python2(
        ) else os.path.dirname(package_loader.loader.path)
        plugin_name = package_loader.fullname if python.is_python2(
        ) else package_loader.loader.name

        if not config_dict:
            config_dict = dict()

        config_dict.update({
            'join': os.path.join,
            'user': os.path.expanduser('~'),
            'filename': plugin_path,
            'fullname': plugin_name,
            'root': path_utils.clean_path(plugin_path)
        })

        if pkg_name not in self._plugins:
            self._plugins[pkg_name] = dict()

        libs_found = list()
        version_found = None
        init_fn = None
        mods_found = list()
        # packages_to_walk = [plugin_path] if python.is_python2() else [os.path.dirname(plugin_path)]
        for module_path in modules.iterate_modules(plugin_path,
                                                   skip_inits=False,
                                                   recursive=False):
            module_dot_path = modules.convert_to_dotted_path(module_path)
            try:
                mod = modules.import_module(module_dot_path)
                if not mod:
                    continue
            except Exception:
                continue
            if module_dot_path.endswith('__version__') and hasattr(
                    mod, 'get_version') and callable(mod.get_version):
                if version_found:
                    LOGGER.warning(
                        'Already found version: "{}" for "{}"'.format(
                            version_found, plugin_name))
                else:
                    version_found = getattr(mod, 'get_version')()

            if not init_fn and module_dot_path.endswith('loader') and hasattr(
                    mod, 'init') and callable(mod.init):
                init_fn = mod.init

            mod.LOADED = load
            mods_found.append(mod)

        for mod in mods_found:
            for cname, obj in inspect.getmembers(mod, inspect.isclass):
                for interface in self._interfaces:
                    if issubclass(obj, interface):
                        lib_config_dict = obj.config_dict(
                            file_name=plugin_path) or dict()
                        if not lib_config_dict:
                            continue
                        lib_id = lib_config_dict.get('id', None)
                        tool_config_name = lib_config_dict.get('name', None)
                        if not lib_id:
                            LOGGER.warning(
                                'Impossible to register library "{}" because its ID is not defined!'
                                .format(lib_id))
                            continue
                        if not tool_config_name:
                            LOGGER.warning(
                                'Impossible to register library "{}" because its name is not defined!'
                                .format(tool_config_name))
                            continue
                        if root_pkg_name and root_pkg_name in self._plugins and lib_id in self._plugins[
                                root_pkg_name]:
                            LOGGER.warning(
                                'Impossible to register library "{}" because its ID "{}" its already defined!'
                                .format(tool_config_name, lib_id))
                            continue

                        if not version_found:
                            version_found = '0.0.0'
                        obj.VERSION = version_found
                        obj.FILE_NAME = plugin_path
                        obj.FULL_NAME = plugin_name

                        libs_found.append((module_path, version_found, obj))
                        version_found = True
                        break

        if not libs_found:
            LOGGER.warning(
                'No libraries found in module "{}". Skipping ...'.format(
                    plugin_path))
            return False
        if len(libs_found) > 1:
            LOGGER.warning(
                'Multiple libraries found ({}) in module "{}". Loading first one. {} ...'
                .format(len(libs_found), plugin_path, libs_found[-1]))
            lib_found = libs_found[-1]
        else:
            lib_found = libs_found[0]
        lib_loader = modules.convert_to_dotted_path(lib_found[0])
        lib_loader = loader.find_loader(lib_loader)

        # Check if DCC specific implementation for plugin exists
        dcc_path = '{}.dccs.{}'.format(plugin_name, dcc.get_name())
        dcc_loader = None
        dcc_config = None
        try:
            dcc_loader = loader.find_loader(dcc_path)
        except ImportError:
            pass

        lib_config_dict = lib_found[2].config_dict(
            file_name=plugin_path) or dict()
        lib_id = lib_config_dict['id']
        _tool_name = lib_config_dict['name']

        tool_config_name = plugin_name.replace('.', '-')
        lib_config = configs.get_config(config_name=tool_config_name,
                                        package_name=pkg_name,
                                        root_package_name=root_pkg_name,
                                        environment=environment,
                                        config_dict=config_dict,
                                        extra_data=lib_config_dict)

        if dcc_loader:
            dcc_path = dcc_loader.fullname
            dcc_config = configs.get_config(config_name=dcc_path.replace(
                '.', '-'),
                                            package_name=pkg_name,
                                            environment=environment,
                                            config_dict=config_dict)
            if not dcc_config.get_path():
                dcc_config = None

        # Register resources
        def_resources_path = os.path.join(plugin_path, 'resources')
        # resources_path = plugin_config.data.get('resources_path', def_resources_path)
        resources_path = lib_config_dict.get('resources_path', None)
        if not resources_path or not os.path.isdir(resources_path):
            resources_path = def_resources_path
        if os.path.isdir(resources_path):
            resources.register_resource(resources_path, key='tools')
        else:
            pass
            # tp.logger.debug('No resources directory found for plugin "{}" ...'.format(_plugin_name))

        # Register DCC specific resources
        if dcc_loader and dcc_config:
            def_resources_path = os.path.join(dcc_loader.filename, 'resources')
            resources_path = dcc_config.data.get('resources_path',
                                                 def_resources_path)
            if not resources_path or not os.path.isdir(resources_path):
                resources_path = def_resources_path
            if os.path.isdir(resources_path):
                resources.register_resource(resources_path, key='plugins')
            else:
                pass
                # tp.logger.debug('No resources directory found for plugin "{}" ...'.format(_plugin_name))

        # Create lib loggers directory
        default_logger_dir = os.path.normpath(
            os.path.join(os.path.expanduser('~'), 'tpDcc', 'logs', 'libs'))
        default_logging_config = os.path.join(plugin_path, '__logging__.ini')
        logger_dir = lib_config_dict.get('logger_dir', default_logger_dir)
        if not os.path.isdir(logger_dir):
            os.makedirs(logger_dir)
        logging_file = lib_config_dict.get('logging_file',
                                           default_logging_config)

        lib_package = plugin_name
        lib_package_path = plugin_path
        dcc_package = None
        dcc_package_path = None
        if dcc_loader:
            dcc_package = dcc_loader.fullname if python.is_python2(
            ) else dcc_loader.loader.path
            dcc_package_path = dcc_loader.filename if python.is_python2(
            ) else dcc_loader.loader.name

        self._plugins[pkg_name][lib_id] = {
            'name': _tool_name,
            'package_name': pkg_name,
            'loader': package_loader,
            'config': lib_config,
            'config_dict': lib_config_dict,
            'plugin_loader': lib_loader,
            'plugin_package': lib_package,
            'plugin_package_path': lib_package_path,
            'version': lib_found[1] if lib_found[1] is not None else "0.0.0",
            'dcc_loader': dcc_loader,
            'dcc_package': dcc_package,
            'dcc_package_path': dcc_package_path,
            'dcc_config': dcc_config,
            'logging_file': logging_file,
            'plugin_instance': None
        }

        if init_fn:
            try:
                dev = True if environment == 'development' else False
                init_fn(dev=dev)
                LOGGER.info(
                    'Library "{}" registered and initialized successfully!'.
                    format(plugin_name))
            except Exception:
                LOGGER.warning(
                    'Library "{}" registered successfully but its initialization failed: {}'
                    .format(plugin_name, traceback.format_exc()))
        else:
            LOGGER.info(
                'Library "{}" registered successfully!'.format(plugin_name))

        return True