示例#1
0
def get_folders(root_folder, recursive=False, full_path=False):
    """
    Get folders found in the root folder
    :param root_folder: str, folder we ant to search folders on
    :param recursive: bool, Whether to search in all root folder child folders or not
    :return: list<str>
    """

    from tpDcc.libs.python import path

    found_folders = list()
    if not recursive:
        try:
            found_folders = next(os.walk(root_folder))[1]
        except Exception:
            pass
    else:
        try:
            for root, dirs, files in os.walk(root_folder):
                for d in dirs:
                    if full_path:
                        folder_name = path.join_path(root, d)
                        found_folders.append(folder_name)
                    else:
                        folder_name = path.join_path(root, d)
                        folder_name = os.path.relpath(folder_name, root_folder)
                        folder_name = path.clean_path(folder_name)
                        found_folders.append(folder_name)
        except Exception:
            return found_folders

    return found_folders
示例#2
0
def get_files(root_folder, full_path=False, recursive=False, pattern="*"):
    """
    Returns files found in the given folder
    :param root_folder: str, folder we want to search files on
    :param full_path: bool, if true, full path to the files will be returned otherwise file names will be returned
    :return: list<str>
    """

    from tpDcc.libs.python import path

    if not path.is_dir(root_folder):
        return []

    # TODO: For now pattern only works in recursive searches. Fix it to work on both

    found = list()

    if recursive:
        for dir_path, dir_names, file_names in os.walk(root_folder):
            for file_name in fnmatch.filter(file_names, pattern):
                if full_path:
                    found.append(path.join_path(dir_path, file_name))
                else:
                    found.append(file_name)
    else:
        files = os.listdir(root_folder)
        for f in files:
            file_path = path.join_path(root_folder, f)
            if path.is_file(file_path=file_path):
                if full_path:
                    found.append(file_path)
                else:
                    found.append(f)

    return found
示例#3
0
def rename_file(name, directory, new_name, new_version=False):
    """
    Renames the give nfile in the directory with a new name
    :param name:
    :param directory:
    :param new_name:
    :param new_version:
    :return:
    """

    from tpDcc.libs.python import path

    full_path = path.join_path(directory, name)
    if not path.is_file(full_path):
        return full_path

    new_full_path = path.join_path(directory, new_name)
    if path.is_file(new_full_path):
        print('A file named {} already exists in the directory: {}'.format(
            new_name, directory))
        return full_path

    os.chmod(full_path, 0o777)
    os.rename(full_path, new_full_path)

    return new_full_path
示例#4
0
    def _get_version_folder(self):
        if path.is_file(self._file_path):
            version_dir = path.get_dirname(self._file_path)
            version_path = path.join_path(version_dir,
                                          self._version_folder_name)
        else:
            version_path = path.join_path(self._file_path,
                                          self._version_folder_name)

        return version_path
示例#5
0
    def _get_version_folder(self):
        from tpDcc.libs.python import path

        if path.is_file(self.file_path):
            dir_name = path.get_dirname(self.file_path)
            version_path = path.join_path(dir_name, self._version_folder_name)
        else:
            version_path = path.join_path(self.file_path, self._version_folder_name)

        return version_path
示例#6
0
def get_package_path_from_name(module_name, return_module_path=False):
    """
    Returns package path from given package name
    :param module_name: str, name of the module we want to retrieve path of
    :param return_module_path: bool
    :return: str
    """

    split_name = module_name.split('.')
    if len(split_name) > 1:
        sub_path = string.join(split_name[:-1], '/')
    else:
        sub_path = module_name

    paths = sys.path

    found_path = None
    for path in paths:
        test_path = path_utils.join_path(path, sub_path)
        if path_utils.is_dir(test_path):
            found_path = path

    if not found_path:
        return None

    test_path = found_path
    good_path = ''
    index = 0

    for name in split_name:
        if index == len(split_name) - 1:
            if return_module_path:
                good_path = path_utils.join_path(good_path,
                                                 '{}.py'.format(name))
                break

        test_path = path_utils.join_path(test_path, name)
        if not path_utils.is_dir(test_path):
            continue
        files = fileio.get_files(test_path)
        if '__init__.py' in files:
            good_path = test_path
        else:
            return None

        index += 1

    return good_path
示例#7
0
    def create_item(self, name=None):
        """
        Creates a new item (folder) inside the selected item
        :param name: str, name of the new item
        """

        current_item = self._current_item
        if current_item:
            item_path = self.get_tree_item_path_string(self._current_item)
            item_path = path.join_path(self._directory, item_path)
            if path.is_file(item_path):
                item_path = path.get_dirname(item_path)
                current_item = self._current_item.parent()

        if not current_item:
            item_path = self._directory

        if not name:
            name = self.NEW_ITEM_NAME

        folder.create_folder(name=name, directory=item_path)

        if current_item:
            self._add_sub_items(current_item)
            self.setItemExpanded(current_item, True)
        else:
            self.refresh()
示例#8
0
def delete_folder(folder_name, directory=None):
    """
    Deletes the folder by name in the given directory
    :param folder_name: str, name of the folder to delete
    :param directory: str, the directory path where the folder is stored
    :return: str, folder that was deleted with path
    """

    from tpDcc.libs.python import path

    def delete_read_only_error(action, name, exc):
        """
        Helper to delete read only files
        """

        os.chmod(name, 0o777)
        action(name)

    full_path = folder_name
    if directory:
        full_path = path.join_path(directory, folder_name)
    if not path.is_dir(full_path):
        return None

    try:
        shutil.rmtree(full_path, onerror=delete_read_only_error)
    except Exception as exc:
        LOGGER.warning('Could not remove children of path "{}" | {}'.format(
            full_path, exc))

    return full_path
示例#9
0
def save_current_scene(force=True, **kwargs):
    """
    Saves current scene
    :param force: bool
    """

    path_to_save = kwargs.get('path_to_save', None)
    name_to_save = kwargs.get('name_to_save', None)
    extension_to_save = kwargs.get('extension_to_save', get_extensions()[0])

    current_scene_name = rt.maxFileName
    if not extension_to_save.startswith('.'):
        extension_to_save = '.{}'.format(extension_to_save)
    name_to_save = name_to_save or current_scene_name
    if not name_to_save:
        return

    file_to_save = path_utils.join_path(path_to_save, name_to_save)
    if not file_to_save.endswith(extension_to_save):
        file_to_save = '{}{}'.format(file_to_save, extension_to_save)

    if force:
        return rt.saveMaxFile(file_to_save, quiet=True)
    else:
        file_check_state = rt.getSaveRequired()
        if not file_check_state:
            return rt.saveMaxFile(file_to_save)
        if rt.checkForSave():
            return rt.saveMaxFile(file_to_save)
示例#10
0
def get_projects(projects_path, project_class=None):
    """
    Returns all projects located in given path
    :param projects_path: str
    :param project_class: cls
    :return: list(Project)
    """

    if not project_class:
        project_class = Project

    projects_found = list()

    if not projects_path or not os.path.isdir(projects_path):
        LOGGER.warning('Projects Path {} is not valid!'.format(projects_path))
        return projects_found

    for root, dirs, files in os.walk(projects_path):
        if consts.PROJECTS_NAME in files:
            new_project = project_class.create_project_from_data(
                path.join_path(root, consts.PROJECTS_NAME))
            if new_project is not None:
                projects_found.append(new_project)

    return projects_found
示例#11
0
def delete_file(name, directory=None, show_warning=True):
    """
    Delete the file by name in the directory
    :param name: str, name of the file to delete
    :param directory: str, the directory where the file is stored
    :param show_warning: bool
    :return: str, file path that was deleted
    """

    from tpDcc.libs.python import path, osplatform

    if not directory:
        full_path = name
    else:
        full_path = path.join_path(directory, name)
    if not path.is_file(full_path):
        if show_warning:
            print('File "{}" was not deleted.'.format(full_path))
        return full_path

    try:
        osplatform.get_permission(full_path)
    except Exception:
        pass
    try:
        os.remove(full_path)
    except Exception:
        pass

    return full_path
    def move(self, new_folder):

        if not new_folder or not os.path.isdir(new_folder):
            return

        identifier = self.format_identifier()

        file_directory, file_name, file_extension = path_utils.split_path(
            identifier)
        new_path = path_utils.join_path(
            new_folder, '{}{}'.format(file_name, file_extension))

        valid = fileio.move_file(self.format_identifier(), new_path)
        if not valid:
            return

        dependencies = self.get_dependencies()

        self._db.move(identifier, new_path)

        skin_folder = dependencies.get('skin_folder', None)
        if not skin_folder or not os.path.isdir(skin_folder):
            return

        skin_folder_item = self.library.get(skin_folder)
        move_function = skin_folder_item.functionality().get('move')
        if move_function:
            move_function(new_folder)

        return new_folder
示例#13
0
def rename_folder(directory, name, make_unique=False):
    """
    Renames given with a new name
    :param directory: str, full path to the diretory we want to rename
    :param name: str, new name of the folder we want to rename
    :param make_unique: bool, Whether to add a number to the folder name to make it unique
    :return: str, path of the renamed folder
    """

    from tpDcc.libs.python import path

    base_name = path.get_basename(directory=directory)
    if base_name == name:
        return

    parent_path = path.get_dirname(directory=directory)
    rename_path = path.join_path(parent_path, name)

    if make_unique:
        rename_path = path.unique_path_name(directory=rename_path)

    if path.is_dir(rename_path) or path.is_file(rename_path):
        return False

    try:
        os.chmod(directory, 0o777)
        message = 'rename: {0} >> {1}'.format(directory, rename_path)
        LOGGER.info(message)
        os.rename(directory, rename_path)
    except Exception:
        LOGGER.error('{}'.format(traceback.format_exc()))
        return False

    return rename_path
示例#14
0
def load_python_module(module_name, directory):
    """
    Loads a given module name located in the given directory
    NOTE: After loading a module you can access programmatically to all functions and attributes of the module
    :param module_name: str, name of the module we want to load
    :param directory: str, directory path where the module is located
    :return: mod, loaded module
    """

    import imp
    from tpDcc.libs.python import path

    if not path.is_dir(directory):
        return None

    full_path = path.join_path(directory, module_name)
    if not path.is_file(full_path):
        return None

    split_name = module_name.split('.')
    file_path, path_name, description = imp.find_module(
        split_name[0], [directory])
    try:
        module = imp.load_module(module_name, file_path, path_name,
                                 description)
    except Exception:
        file_path.close()
        return traceback.format_exc()
    finally:
        if file_path:
            file_path.close()

    return module
示例#15
0
    def show_save_widget(cls, item_class, library_window, item_view=None):
        """
        Function used to show the create widget of the current item
        :param library_window: LibraryWindow
        :param item_view: LibraryItem or None
        """

        path = library_window.selected_folder_path() or library_window.path()
        name, button = messagebox.MessageBox.input(
            library_window, 'Create Folder',
            'Create a new folder with the name:')
        if not name or not button == QDialogButtonBox.Ok:
            return
        path = path_utils.join_path(path, name.strip())

        item_data = item_class(path, library_window.library())
        if not item_data:
            return

        save_function = item_data.functionality().get('save')
        if not save_function:
            return

        valid = save_function()
        if not valid:
            return

        if library_window:
            library_window.sync()
            library_window.refresh()
            library_window.select_folder_path(path)
示例#16
0
def get_folders_without_dot_prefix(directory, recursive=False, base_directory=None):

    from tpDcc.libs.python import path, version

    if not path.exists(directory):
        return

    found_folders = list()
    base_directory = base_directory or directory

    folders = get_folders(directory)
    for folder in folders:
        if folder == 'version':
            version = version.VersionFile(directory)
            if version.updated_old:
                continue
        if folder.startswith('.'):
            continue

        folder_path = path.join_path(directory, folder)
        folder_name = path.clean_path(os.path.relpath(folder_path, base_directory))
        found_folders.append(folder_name)
        if recursive:
            sub_folders = get_folders_without_dot_prefix(
                folder_path, recursive=recursive, base_directory=base_directory)
            found_folders += sub_folders

    return found_folders
示例#17
0
def import_python_module(module_name, directory):
    """
    Imports the given module
    :param module_name: str, name of the module
    :param directory: str, path where the module is located
    :return: mod, imported module
    """

    from tpDcc.libs.python import path, fileio

    if not path.is_dir(directory=directory):
        return

    module = None
    full_path = path.join_path(directory, module_name)
    if path.is_file(full_path):
        if directory not in sys.path:
            sys.path.append(directory)

        split_name = module_name.split('.')
        script_name = split_name[0]

        exec('import {}'.format(script_name))
        exec('reload({})'.format(script_name))

        module = eval(script_name)
        sys.path.remove(directory)

    return module
示例#18
0
def get_scene_name_and_path():
    """
    Returns the name and path of the current open 3ds Max scene including the extension (.max)
    :return: str
    """

    return path_utils.join_path(rt.maxFilePath, rt.maxFileName)
示例#19
0
 def dropEvent(self, event):
     item = self.item_at(event.pos())
     if item:
         item_path = self.get_tree_item_path_string(item)
         item_full_path = path.join_path(self._directory, item_path)
         if item_full_path and path.is_dir(item_full_path):
             super(FileTreeWidget, self).dropEvent(event)
示例#20
0
    def _on_sub_path_filter_edited(self):
        """
        Internal callback function that is called when sub path filter text is edited
        """

        current_text = str(self._sub_path_filter.text()).strip()
        if not current_text:
            self.set_directory(self._directory)
            if self._update_tree:
                self._tree_widget.set_directory(self._directory)
            text = self._filter_names.text
            self._on_filter_names(text)
            return

        sub_dir = path.join_path(self._directory, current_text)
        if not sub_dir:
            return

        if path.is_dir(sub_dir):
            if self._update_tree:
                self._tree_widget.set_directory(self._directory)
            text = self._filter_names.text
            self._on_filter_names(text)

        if self._emit_changes:
            self.subPathChanged.emit(current_text)
示例#21
0
def create_file(filename, directory=None, make_unique=False):
    """
    Creates a file
    :param filename: str, name of the new file
    :param directory: str, directory of the new file
    :param make_unique: bool, whether to make the name unique or not
    :return: variant, str || bool, filename with path or False if create file failed
    """

    from tpDcc.libs.python import name, path, osplatform

    if directory is None:
        directory = path.get_dirname(filename)
        filename = path.get_basename(filename)

    filename = name.clean_file_string(filename)
    full_path = path.join_path(directory, filename)

    if make_unique:
        full_path = path.unique_path_name(full_path)

    open_file = None
    try:
        open_file = open(full_path, 'a')
        open_file.close()
    except Exception:
        if open_file:
            open_file.close()
        return False

    osplatform.get_permission(full_path)

    return full_path
示例#22
0
    def get_project_file(self):
        """
        Returns path where project file is located
        :return: str
        """

        return path.join_path(self.full_path, consts.PROJECTS_NAME)
示例#23
0
    def _get_available_modules(self, paths=None):
        imports = list()
        if not paths:
            paths = sys.path
        if paths:
            paths = python.force_list(paths)

        for path in paths:
            fix_path = path_utils.normalize_path(path)
            stuff_in_folder = folder_utils.get_files_and_folders(fix_path)
            for file_or_folder in stuff_in_folder:
                folder_path = path_utils.join_path(fix_path, file_or_folder)
                files = folder_utils.get_files_with_extension('py',
                                                              folder_path,
                                                              full_path=False)
                if '__init__.py' in files:
                    imports.append(str(file_or_folder))

            python_files = folder_utils.get_files_with_extension(
                'py', fix_path, full_path=False)
            for python_file in python_files:
                if python_file.startswith('__'):
                    continue
                python_file_name = python_file.split('.')[0]
                imports.append(str(python_file_name))

        if imports:
            imports = list(set(imports))

        return imports
示例#24
0
 def create_folder(self, name, relative_path=None):
     if relative_path is None:
         folder.create_folder(name=name, directory=self.full_path)
     else:
         folder.create_folder(name=name,
                              directory=path.join_path(
                                  self.full_path, relative_path))
    def _import_mesh_obj(self, data_path):
        """
        Internal function that imports mesh object stored in given path
        :param data_path: str, path that contains already exported mesh object
        :return: str, name of the imported mesh
        """

        dependencies = self.get_dependencies(data_path)
        mesh_path = dependencies.get('geo_file', None)
        if not mesh_path or not os.path.isfile(mesh_path):
            mesh_path = path_utils.join_path(data_path, 'mesh.obj')
        if not path_utils.is_file(mesh_path):
            return None

        nodes = dcc.client().list_nodes(node_type='mesh', full_path=False)
        dcc.client().import_file(mesh_path,
                                 import_type='OBJ',
                                 ignore_version=True,
                                 options='mo=1')
        current_nodes = dcc.client().list_nodes(node_type='mesh',
                                                full_path=False)
        delta = list(set(current_nodes).difference(nodes))
        if delta:
            delta = dcc.client().node_parent(delta, full_path=True)

        return delta
示例#26
0
    def _get_comment_path(self):
        version_folder = self._get_version_folder()
        comment_path = None
        if version_folder:
            comment_path = path.join_path(version_folder, 'comments.txt')

        return comment_path
示例#27
0
def get_comments(comment_directory, comment_filename=None):
    """
    Returns all the comments from a comments.txt file
    :param comment_directory: str, directory where comment.txt file is located
    :param comment_filename: str, name of the c omment file. By default, comment.txt.
    :return: dict(filename, value), (comment, user)
    """

    comment_filename = comment_filename or 'comments.json'
    comment_file = path.join_path(comment_directory, comment_filename)
    if not comment_file or not os.path.isfile(comment_file):
        return

    comments = dict()
    comments_data = jsonio.read_file(comment_file)
    if not comments_data:
        return comments

    for version_dict in comments_data:
        file_name = version_dict.get('version', None)
        comment = version_dict.get('comment', '')
        user = version_dict.get('user', '')
        if comment_filename and comment_filename == file_name:
            return comment,
        comments[file_name] = [comment, user]

    return comments
    def _get_influences(self, folder_path):
        """
        Internal function that returns a dictionary containing influences data from influence files
        contained in the given directory
        :param folder_path: str, path that contains influence file
        :return: dict, influence data
        """

        influence_dict = dict()

        files = fileio.get_files(folder_path)
        dependencies = self.get_dependencies(folder_path) or dict()

        info_file = dependencies.get('info_file', None)
        if not info_file or not os.path.isfile(info_file):
            if not files:
                return influence_dict
            info_file = path_utils.join_path(folder_path, 'influence.info')
            if not path_utils.is_file(info_file):
                return influence_dict

        info_lines = fileio.get_file_lines(info_file)
        for line in info_lines:
            if not line:
                continue
            line_dict = eval(line)
            influence_dict.update(line_dict)

        weight_files = python.force_list(dependencies.get('weight', list()))
        if not weight_files:
            for influence in files:
                if not influence.endswith(
                        '.weights') or influence == 'influence.info':
                    continue
                weight_files.append(
                    path_utils.join_path(folder_path, influence))

        for weight_file in weight_files:
            read_thread = ReadWeightFileThread()
            try:
                influence_dict = read_thread.run(influence_dict, weight_file)
            except Exception as exc:
                logger.error(
                    'Errors with influence "{}" while reading weight file: "{}" | {}'
                    .format(weight_file, info_file, exc))

        return influence_dict
示例#29
0
    def _get_comment_path(self):
        from tpDcc.libs.python import path
        version_folder = self._get_version_folder()
        file_path = None
        if version_folder:
            file_path = path.join_path(version_folder, 'comments.txt')

        return file_path
示例#30
0
    def _default_version_file_name(self):
        if not self._version_name:
            return

        version_folder = self._get_version_folder()
        version_path = path.join_path(version_folder, self._version_name + '.default')

        return version_path