Пример #1
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
Пример #2
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
Пример #3
0
    def create_project_from_data(cls, project_data_path):
        """
        Creates a new project using a project data JSON file
        :param project_data_path: str, path where project JSON data file is located
        :return: Project
        """

        if project_data_path is None or not path.is_file(project_data_path):
            LOGGER.warning('Project Data Path {} is not valid!'.format(project_data_path))
            return None

        project_data = settings.JSONSettings()
        project_options = settings.JSONSettings()
        project_dir = path.get_dirname(project_data_path)
        project_name = path.get_basename(project_data_path)
        project_data.set_directory(project_dir, project_name)
        project_options.set_directory(project_dir, 'options.json')

        project_name = project_data.get('name')
        project_path = path.get_dirname(path.get_dirname(project_data_path))
        project_image = project_data.get('image')

        LOGGER.debug('New Project found [{}]: {}'.format(project_name, project_path))
        project_data = core_project.ProjectData(
            name=project_name, project_path=project_path, settings=project_data, options=project_options)

        new_project = cls(project_data=project_data)
        if project_image:
            new_project.set_image(project_image)

        return new_project
Пример #4
0
    def open(self, file_path=None):
        if not dcc.is_maya():
            LOGGER.warning('Maya data must be accessed from within Maya!')
            return

        open_file = None
        if file_path:
            open_file = file_path
        if not open_file:
            file_path = self.get_file()
            if not path.is_file(file_path):
                LOGGER.warning('Could not open file: {}'.format(file_path))
                return
            open_file = file_path

        helpers.display_info('Opening: {}'.format(open_file))

        try:
            maya.cmds.file(open_file, f=True, o=True, iv=True, pr=True)
        except Exception:
            LOGGER.error('Impossible to open Maya file: {} | {}'.format(open_file, traceback.format_exc()))

        self._after_open()

        top_transforms = scene.get_top_dag_nodes(exclude_cameras=True)

        return top_transforms
Пример #5
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()
Пример #6
0
    def import_data(self, file_path=''):
        """
        Loads data object
        :param file_path: str, file path of file to load
        """

        if not dcc.is_maya():
            LOGGER.warning('Data must be accessed from within Maya!')
            return

        if file_path:
            import_file = file_path
        else:
            import_file = self.get_file()
        if not path.is_file(import_file):
            LOGGER.warning('Impossible to import invalid data file: {}'.format(file_path))
            return

        track = scene.TrackNodes()
        track.load('transform')

        scene.import_scene(import_file, do_save=False)
        self._after_open()

        transforms = track.get_delta()
        top_transforms = scene.get_top_dag_nodes_in_list(transforms)

        return top_transforms
Пример #7
0
    def save(self, comment=None):
        """
        Saves a new version file
        :param comment: str
        :return: str, new version file name
        """

        from tpDcc.libs.python import folder, path

        if not comment:
            comment = '-'
        comment = comment.replace('\n', '   ').replace('\r', '   ')

        self._create_version_folder()
        self._create_comment_file()

        unique_file_name = self._increment_version_file_name()

        if path.is_dir(self.file_path):
            folder.copy_folder(directory=self.file_path,
                               directory_destination=unique_file_name)
        elif path.is_file(self.file_path):
            copy_file(file_path=self.file_path,
                      file_path_destination=unique_file_name)

        self.save_comment(comment=comment, version_file=unique_file_name)

        return unique_file_name
Пример #8
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
Пример #9
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
Пример #10
0
    def get_version_data(self, version_number):
        """
        Returns the data (comment and user) of the given version
        :param version_number: int
        :return: tuple(str, str)
        """

        comment_path = self._get_comment_path()
        if not comment_path:
            return None, None

        if not path.is_file(comment_path):
            return None, None

        version_data = jsonio.read_file(comment_path)
        if not version_data:
            return None, None

        for version_dict in version_data:

            version = version_dict.get('version', None)
            comment = version_dict.get('comment', '')
            user = version_dict.get('user', '')

            if version == str(version_number):
                return comment, user

        return None, None
Пример #11
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
Пример #12
0
    def get_version_data(self, version_number):
        """
        Returns the data (comment and user) of the given version
        :param version_number: int
        :return: tuple(str, str)
        """

        comment_path = self._get_comment_path()
        if not comment_path:
            return None, None

        if path.is_file(comment_path):
            read = fileio.FileReader(comment_path)
            lines = read.read()
            version = None
            comment = None
            user = None
            for line in lines:
                start_index = line.find('"')
                if start_index > -1:
                    end_index = line.find('";')
                    sub_part = line[start_index + 1:end_index]
                    sub_part = sub_part.replace('"', '\\"')
                    line = line[:start_index + 1] + sub_part + line[end_index:]

                # Get version, comment and user variables by executing the line
                try:
                    exec(line)
                except Exception:
                    pass

                if version == version_number:
                    return comment, user

        return None, None
Пример #13
0
    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
Пример #14
0
def copy(source, target, description=''):
    """
    Copies given file or files and creates a new version of the file with the given description
    :param source: str, source file or folder we want to copy
    :param target: str, destination file or folder we want to copy into
    :param description: str, description of the new version
    """

    is_source_a_file = path_utils.is_file(source)

    if is_source_a_file:
        copied_path = fileio.copy_file(source, target)
    else:
        if not path_utils.exists(source):
            LOGGER.info(
                'Nothing to copy: {}\t\tData was probably created but not saved yet.'
                .format(path_utils.get_dirname(is_source_a_file)))
            return
        if path_utils.exists(target):
            folder.delete_folder(target)
        copied_path = folder.copy_folder(source, target)

    if not copied_path:
        LOGGER.warning('Error copying {}\t to\t{}'.format(source, target))
        return

    if copied_path > -1:
        LOGGER.info('Finished copying {} from {} to {}'.format(
            description, source, target))
        version_file = version.VersionFile(copied_path)
        version_file.save('Copied from {}'.format(source))
Пример #15
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(os.path.join(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
Пример #16
0
    def _has_changed(self):
        if self._file_path:
            if path_utils.is_file(self._file_path):
                last_modified = fileio.get_last_modified_date(self._file_path)
                if last_modified != self._last_modified:
                    return True

        return False
Пример #17
0
    def has_default(self):
        if not self._version_name:
            return

        file_name = self._default_version_file_name()
        if path.is_file(file_name):
            return True

        return False
Пример #18
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
Пример #19
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
Пример #20
0
    def delete_version(self, version_number):
        """
        Deletes specific version file
        :param version_number: int
        """

        version_path = self.get_version_path(version_number)
        if path.is_file(version_path):
            fileio.delete_file(version_path)
        else:
            folder.delete_folder(path)
Пример #21
0
    def _get_influences(self, folder_path):
        influence_dict = 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)

        return influence_dict
Пример #22
0
    def check_file(self, warning_text=None):
        """
        Check if a file is an invalid one and raise error if necessary
        :param warning_text: str
        :return: bool
        """

        from tpDcc.libs.python import path

        if not path.is_file(self.file_path):
            if warning_text is not None:
                raise UserWarning(str(warning_text))
            return False

        return True
Пример #23
0
    def _has_json_file(self):
        """
        Checks if the JSON file where settings should be stored exists or not
        :return: bool
        """

        if not self.file_path:
            return False

        settings_directory = path.get_dirname(self.file_path)
        name = path.get_basename(self.file_path, with_extension=False)
        file_path = path.join_path(settings_directory, name + '.json')
        if path.is_file(file_path):
            return True

        return False
Пример #24
0
    def clean_student_license(self, file_path=''):
        if not dcc.is_maya():
            LOGGER.warning('Data must be accessed from within Maya!')
            return

        if file_path:
            file_to_clean = file_path
        else:
            file_to_clean = self.get_file()
        if not path.is_file(file_to_clean):
            LOGGER.warning('Impossible to reference invalid data file: {}'.format(file_path))
            return

        changed = helpers.clean_student_line(file_to_clean)
        if changed:
            LOGGER.debug('Cleaned student license from file: {}'.format(file_to_clean))
Пример #25
0
    def set_directory(self, directory, filename='settings.json'):
        self.directory = directory

        # Check that given file name is a valid JSON file
        if not filename.endswith('.json'):
            old = path.join_path(directory, filename)
            if path.is_file(old):
                self.file_path = old
                self._read()
                return

        self.file_path = fileio.create_file(filename=filename, directory=directory)

        self._read()

        return self.file_path
    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
Пример #27
0
    def _on_set_project_image(self):
        """
        Internal callback function that is called when project image is set
        """

        image_file = dcc.select_file_dialog(title='Select Project Image File',
                                            pattern="PNG Files (*.png)")

        if image_file is None or not path.is_file(image_file):
            LOGGER.warning(
                'Selected Image "{}" is not valid!'.format(image_file))
            return

        valid_change = self._project_data.set_project_image(image_file)

        if valid_change:
            self.projectImageChanged.emit(image_file)
Пример #28
0
def get_size(file_path, round_value=2):
    """
    Return the size of the given directory or file path
    :param file_path: str
    :param round_value: int, value to round size to
    :return: int
    """

    from tpDcc.libs.python import fileio, path

    size = 0
    if path.is_dir(file_path):
        size = get_folder_size(file_path, round_value)
    if path.is_file(file_path):
        size = fileio.get_file_size(file_path, round_value)

    return size
Пример #29
0
    def _get_json_file(self):
        """
        Internal function that returns JSON file where settings are stored
        :return: str
        """

        if not self.file_path:
            return

        settings_directory = path.get_dirname(self.file_path)
        name = path.get_basename(self.file_path, with_extension=False)
        file_path = fileio.create_file(name + '.json', settings_directory)
        if not file_path:
            test_path = path.join_path(settings_directory, name + '.json')
            if path.is_file(test_path):
                file_path = test_path

        return file_path
Пример #30
0
    def get_folder_data_instance(self):
        """
        Returns the data instance for this data
        Depending on the data type this folder contains a differnet object is created
        :return: variant
        """

        if not self.settings:
            self._load_folder()

        if not self.name:
            return

        data_type = self.settings.get('data_type')
        if not data_type:
            data_type = self.data_type

        if data_type is None:
            test_file = os.path.join(
                self.folder_path,
                '{}.{}'.format(self.name, scripts.ScriptExtensions.Python))
            if path_utils.is_file(test_file):
                data_type = scripts.ScriptTypes.Python
                self.settings.set('data_type', data_type)
        if not data_type:
            LOGGER.warning(
                'Impossible to instantiate Data Folder because given Data Type: {} is not valid!'
                .format(data_type))
            return

        data_manager = self.get_manager()
        if not data_manager:
            LOGGER.warning(
                'Impossible to instantiate Data Folder because LibraryManager is not defined!'
            )
            return

        data_inst = data_manager.get_type_instance(data_type)
        if data_inst:
            data_inst.set_directory(self.folder_path)
            data_inst.set_name(self.name)

        return data_inst