def save_current_session(self): """ Function that stores current session state """ current_session = self._model.session if current_session: current_script = path_utils.clean_path(self._model.current_script) opened_scripts = list() for script_path, script_data in self._model.scripts.items(): file_path = path_utils.clean_path(script_path) name = os.path.basename(file_path) if name.startswith(consts.TEMP_SCRIPT_PREFIX): name = consts.DEFAULT_SCRIPTS_TAB_NAME text = script_data.get('text', '') size = script_data.get('font_size', 12) script = { 'name': name, 'text': text, 'file': file_path, 'active': file_path == current_script, 'size': size } opened_scripts.append(script) session_path = current_session.write(opened_scripts) LOGGER.debug('Script Editor Session saved: {}'.format(session_path.replace('\\', '/'))) self.save_script()
def update_paths(): """ Adds path to system paths at startup """ ext_path = externals_path() python_path = os.path.join(ext_path, 'python') maya_path = os.path.join(python_path, str(maya.cmds.about(v=True))) paths_to_update = [externals_path(), maya_path] for p in paths_to_update: if os.path.isdir(p) and p not in sys.path: sys.path.append(p) # Update custom tpDcc.dccs.maya plugins path tpdcc_maya_plugins_path = os.path.join( os.path.abspath(os.path.dirname(__file__)), 'plugins') if not os.path.isdir(tpdcc_maya_plugins_path): return False tpdcc_maya_plugins_path = path_utils.clean_path(tpdcc_maya_plugins_path) maya_plugin_path = os.getenv('MAYA_PLUG_IN_PATH', None) if not maya_plugin_path: os.environ['MAYA_PLUG_IN_PATH'] = tpdcc_maya_plugins_path else: current_plugin_paths = os.environ['MAYA_PLUG_IN_PATH'].split( os.pathsep) for current_plugin_path in current_plugin_paths: if path_utils.clean_path( current_plugin_path) == tpdcc_maya_plugins_path: return True os.environ['MAYA_PLUG_IN_PATH'] = '{}{}{}'.format( os.environ['MAYA_PLUG_IN_PATH'], os.pathsep, tpdcc_maya_plugins_path)
def convert_to_dotted_path(path): """ Returns a dotted path relative to the given path :param path: str, (eg. randomPath/folder/test.py) :return: str, dotted path (eg. folder.test) """ directory, file_path = os.path.split(path) directory = path_utils.clean_path(directory) file_name = os.path.splitext(file_path)[0] package_path = [file_name] sys_path = list(set([path_utils.clean_path(p) for p in sys.path])) # We ignore current working directory. Useful if we want to execute tools directly inside PyCharm current_work_dir = path_utils.clean_path(os.getcwd()) if current_work_dir in sys_path: sys_path.remove(current_work_dir) drive_letter = os.path.splitdrive(path)[0] + '\\' while directory not in sys_path: directory, name = os.path.split(directory) directory = path_utils.clean_path(directory) if directory == drive_letter or name == '': return '' package_path.append(name) return '.'.join(reversed(package_path))
def identifiers(cls, location, skip_pattern, recursive=True): """ Returns a list of data identifiers found in the given data locations NOTE: This should always yield results! :param location: str, location to scan :param skip_pattern: regex, regular expression object which, if matched on a location should be skipped :param recursive: bool, If True, all locations below the given one will also be scanned, otherwise only the immediate location will be scanned :return: generator """ location = path_utils.clean_path(location) if not skip_pattern or not skip_pattern.search(location): yield location if recursive: for root, _, files in os.walk(location): root = path_utils.clean_path(root) if not skip_pattern or not skip_pattern.search(root): yield root for file_name in files: result = path_utils.clean_path( os.path.join(root, file_name)) if not skip_pattern or not skip_pattern.search(result): yield result else: for file_name in os.listdir(location): result = path_utils.clean_path( os.path.join(location, file_name)) if not skip_pattern or not skip_pattern.search(result): yield result
def _get_paths_to_update(self): """ Internal function that returns all the paths that DCC server should include to properly work with the client """ return { 'tpDcc.loader': path_utils.clean_path( os.path.dirname(os.path.dirname(tpDcc.loader.__file__))), 'tpDcc.config': path_utils.clean_path( os.path.dirname( os.path.dirname(os.path.dirname(tpDcc.config.__file__)))), 'tpDcc.libs.python': path_utils.clean_path( os.path.dirname( os.path.dirname( os.path.dirname( os.path.dirname(tpDcc.libs.python.__file__))))), 'tpDcc.libs.resources': path_utils.clean_path( os.path.dirname( os.path.dirname( os.path.dirname( os.path.dirname(tpDcc.libs.resources.__file__))))), 'tpDcc.libs.qt.loader': path_utils.clean_path( os.path.dirname( os.path.dirname( os.path.dirname( os.path.dirname(tpDcc.libs.qt.loader.__file__))))) }
def _get_data_library(self, library_path): if self._data_library and path_utils.clean_path( self._data_library.identifier) == path_utils.clean_path(library_path): return self._data_library self._data_library = datalib.DataLibrary.load(library_path) return self._data_library
def get_user_folder(absolute=True): """ Get path to the user folder :return: str, path to the user folder """ from tpDcc.libs.python import path if absolute: return path.clean_path(os.path.abspath(os.path.expanduser('~'))) else: return path.clean_path(os.path.expanduser('~'))
def update_pixar_maya_usd_environment(): """ Updates current Python environment to setup Pixar Maya USD plugin """ import tpDcc as tp from tpDcc.libs.python import path if not tp.is_maya(): return False usd_dcc_root_path = usdpaths.get_usd_dcc_path() if not usd_dcc_root_path or not os.path.isdir(usd_dcc_root_path): LOGGER.warning( 'Impossible to setup Pixar USD environment. Maya USD is not available!' ) return maya_usd_plugins = path.clean_path( os.path.join(usd_dcc_root_path, 'plugin')) pixar_plugin_path = path.clean_path(os.path.join(maya_usd_plugins, 'pxr')) maya_pixar_lib_path = path.clean_path( os.path.join(pixar_plugin_path, 'lib')) maya_pixar_lib_python_path = path.clean_path( os.path.join(maya_pixar_lib_path, 'python')) maya_pixar_plugin_path = path.clean_path( os.path.join(pixar_plugin_path, 'maya')) maya_pixar_plugin_lib_path = path.clean_path( os.path.join(maya_pixar_plugin_path, 'lib')) maya_pixar_plugin_plugin_path = path.clean_path( os.path.join(maya_pixar_plugin_path, 'plugin')) maya_pixar_plugin_lib_usd_path = path.clean_path( os.path.join(maya_pixar_plugin_lib_path, 'usd')) maya_pixar_plugin_resources = path.clean_path( os.path.join(maya_pixar_plugin_lib_usd_path, 'usdMaya', 'resources')) maya_pixar_surface_resources = path.clean_path( os.path.join(maya_pixar_plugin_plugin_path, 'pxrUsdPreviewSurface', 'resources')) add_to_env('PYTHONPATH', maya_pixar_lib_python_path) add_to_env('PATH', maya_pixar_plugin_lib_path) add_to_env('XBMLANGPATH', maya_pixar_plugin_resources) add_to_env('XBMLANGPATH', maya_pixar_surface_resources) add_to_env('MAYA_SCRIPT_PATH', maya_pixar_plugin_resources) add_to_env('MAYA_SCRIPT_PATH', maya_pixar_surface_resources) add_to_env('MAYA_PLUG_IN_PATH', maya_pixar_plugin_plugin_path) add_to_env('PXR_PLUGINPATH_NAME', maya_pixar_plugin_lib_usd_path) return True
def _on_current_script_changed(self, script_path): """ Internal callback function that is called each time current selected script is updated in the model :param script_path: str :return: """ script_path = path_utils.clean_path(script_path) for i in range(self._scripts_tab.count()): script_widget = self._scripts_tab.widget(i) if not script_widget: continue if path_utils.clean_path(script_widget.file_path) == script_path: self._scripts_tab.setCurrentIndex(i) return
def get_platform_path(): """ Returns externals path based on current platform :return: str """ from tpDcc.libs.python import path, osplatform externals_dir = get_usd_externals_path() if not externals_dir or not os.path.isdir(externals_dir): LOGGER.warning( 'No externals directory found: "{}"'.format(externals_dir)) return platform_name = osplatform.get_platform().lower() os_architecture = osplatform.get_architecture() platform_path = path.clean_path( os.path.join(externals_dir, platform_name, os_architecture, 'usd')) if not os.path.isdir(platform_path): LOGGER.warning('No USD externals platform folder found: "{}"'.format( platform_path)) return None return platform_path
def version_path(self): """ Returns the path where data versions are located :return: str """ return path_utils.clean_path(self._db.get_version_path(self.format_identifier()))
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
def delete_curve(curve_name, curves_path=None): """ Renames the curve from the library. If not path given, all paths will be checked to find the curve :param curve_name: str, the name of the curve without extension :param curves_path: str, directory path where we want to curve the curve from """ if not curves_path or not os.path.isdir(curves_path): curve_path = find_curve_path_by_name(curve_name) else: curve_path = os.path.join(curves_path, '{}{}'.format(curve_name, consts.CURVE_EXT)) if not curve_path or not os.path.isfile(curve_path): logger.warning( 'Curve file could not be deleted because it does not exists! "{}"'. format(curve_path)) return False curve_path = path_utils.clean_path(curve_path) fileio.delete_file(curve_path) if os.path.isfile(curve_path): logger.warning( 'Was not possible to remove curve "{}" file: "{}'.format( curve_name, curve_path)) return False logger.info('Curve "{}" has been deleted successfully: "{}"'.format( curve_name, curve_path)) return True
def load_curves(curves_path=None): """ Loads all the curves located in the given curves path :param curves_path: str, path where curves are located. If not given, first curve path found will be used :return: """ if not curves_path or not os.path.isdir(curves_path): curves_path = list(iterate_curve_root_paths()) if not curves_path: return None curves_path = curves_path[0] if not curves_path or not os.path.isdir(curves_path): return False curves_data = list() for root_dir, _, filenames in os.walk(curves_path): for file_name in filenames: if file_name.endswith(consts.CURVE_EXT): curve_data = load_curve_from_path( path_utils.clean_path(os.path.join(root_dir, file_name))) if not curve_data: continue curves_data.append(curve_data) return curves_data
def load_curve_from_name(curve_name, curves_path=None): """ Loads the curve data of the given curve by its name :param curve_name: str, name of the curve to load :param curves_path: str :return: dict, dictionary containing curve data """ if curves_path and os.path.isdir(curves_path): curve_path = None for root_dir, _, filenames in os.walk(curves_path): if curve_path: break for file_name in filenames: if file_name.endswith(consts.CURVE_EXT) and file_name: curve_path = path_utils.clean_path( os.path.join(root_dir, file_name)) break else: curve_path = find_curve_path_by_name(curve_name) if not curve_path: logger.warning( 'Curve with name "{}" does not exists!'.format(curve_path)) return None return load_curve_from_path(curve_path)
def get_media_profiles_file_paths(self): """ Returns paths to all media profiles stored in media profiles paths :return: list(str) """ media_paths = self.get_media_profiles_paths() if not media_paths: LOGGER.warning('No media profiles paths found!') return list() supported_extensions = self.get_media_profiles_extensions() paths_found = list() for media_path in media_paths: for root, _, files in os.walk(media_path): for file_name in files: file_ext = os.path.splitext(file_name)[-1].lower() if file_ext in supported_extensions: media_profile_path = path_utils.clean_path( os.path.join(root, file_name)) if media_profile_path not in paths_found: paths_found.append(media_profile_path) return paths_found
def directory(self): """ Returns identifier directory :return: str """ return path_utils.clean_path(os.path.dirname(self.format_identifier()))
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
def create_empty_image(output=None, resolution_x=1920, resolution_y=1080, background_color=None): """ Creates an empty image and stores it in the given path :param output: str :param resolution_x: int :param resolution_y: int :param background_color: list(int, int, int) :return: str or QImage """ if background_color is None: background_color = [0, 0, 0] pixmap = QPixmap(resolution_x, resolution_y) pixmap.fill(QColor(*background_color)) if output: output_path = path_utils.clean_path(output) output_dir = os.path.dirname(output_path) if os.access(output_dir, os.W_OK): pixmap.save(output_path) return output_path return QImage(pixmap)
def __init__(self, ref_name, ref_path, ref_dict): self._dict = ref_dict self._name = ref_name.split('/')[-1] self._path = path_utils.clean_path(os.path.join(ref_path, self._name)) self._maximum_version_deleted = \ ref_dict['maximum_version_deleted'] if 'maximum_version_deleted' in ref_dict else False self._is_directory = ref_dict[ 'is_directory'] if 'is_directory' in ref_dict else False self._deleted = ref_dict['deleted'] if 'deleted' in ref_dict else False self._local_version = ref_dict[ 'local_version'] if 'local_version' in ref_dict else None self._view_version = ref_dict[ 'view_version'] if 'view_version' in ref_dict else None self._relative_path = ref_dict[ 'relative_path'] if 'relative_path' in ref_dict else None self._maximum_version = ref_dict[ 'maximum_version'] if 'maximum_version' in ref_dict else None self._view_version_digest = ref_dict[ 'view_version_digest'] if 'view_version_digest' in ref_dict else None self._locked = ref_dict['locked'] if 'locked' in ref_dict else False self._locked_view = ref_dict[ 'locked_view'] if 'locked_view' in ref_dict else None self._locked_by = ref_dict[ 'locked_by'] if 'locked_by' in ref_dict else None self._locked_by_display = ref_dict[ 'lockedByDisplay'] if 'lockedByDisplay' in ref_dict else None
def create_asset_in_artella(self, asset_name, asset_path, folders_to_create=None): """ Creates a new asset in Artella :param asset_name: str :param asset_path: str :param folders_to_create: list(str) or None """ valid_create = artellalib.create_asset(asset_name, asset_path) if not valid_create: LOGGER.warning('Impossible to create Asset {} in Path: {}!'.format( asset_name, asset_path)) return working_folder = artellapipe.project.get_working_folder() if folders_to_create: for folder_name in folders_to_create: file_path = path_utils.clean_path( os.path.join(asset_path, asset_name, working_folder)) artellalib.new_folder(file_path, folder_name) return True
def get_usd_dcc_path(): """ Returns path where USD plugin is located for current DCC version :return: str """ import tpDcc as tp from tpDcc.libs.python import path platform_dir = get_platform_path() if not platform_dir or not os.path.isdir(platform_dir): LOGGER.warning( 'No USD platform directory found: "{}"'.format(platform_dir)) return dcc_name = tp.Dcc.get_name() dcc_version = tp.Dcc.get_version_name() usd_dcc_path = path.clean_path( os.path.join(platform_dir, dcc_name, dcc_version)) if not os.path.isdir(platform_dir): LOGGER.warning( 'No USD executable folder found: "{}"'.format(usd_dcc_path)) return None return usd_dcc_path
def _read(self): """ Internal function used to read settings from file """ if not self.file_path: return lines = fileio.get_file_lines(self.file_path) if not lines: return self.settings_dict = OrderedDict() for line in lines: if not line: continue split_line = line.split('=') name = split_line[0].strip() value = split_line[-1] if not value: continue value = path.clean_path(value) try: value = eval(str(value)) except Exception: value = str(value) self.settings_dict[name] = value
def fix_path(self, path_to_fix, clean_path=True): """ Converts path to a path relative to project environment variable :param path_to_fix: str :param clean_path: bool :return: str """ self._check_project() project_env_var = artellapipe.project.env_var if clean_path: path_to_fix = path_utils.clean_path(path_to_fix) project_var = os.environ.get(project_env_var) if not project_var: return path_to_fix project_type = artellapipe.project.get_project_type() root_prefix = artellapipe.libs.artella.config.get( 'app', project_type).get('root_prefix', 'ART_LOCAL_ROOT') if path_to_fix.startswith('${}/'.format(project_env_var)): path_to_fix = path_to_fix.replace('${}/'.format(project_env_var), project_var) elif path_to_fix.startswith('${}/'.format(root_prefix)): path_to_fix = path_to_fix.replace('${}/'.format(root_prefix), project_var) return path_to_fix
def find_rcc_executable_file(): """ Returns path pointing to a valid PySide/PyQt RCC executable file :return: str """ # TODO: Implement PyQt RCC search # TODO: Make it work in a cross platform way. For now this only works in Windows. if is_pyside() or is_pyside2(): rcc_exe_path = os.environ.get('PYSIDE_RCC_EXE_PATH', None) if rcc_exe_path: rcc_exe_path = path.clean_path(rcc_exe_path) if os.path.isfile(rcc_exe_path): return rcc_exe_path folders_to_find = list() exe_name = None if is_pyside(): exe_name = 'pyside-rcc.exe' folders_to_find.extend([ 'C:\\Python27\\Lib\\site-packages\\PySide\\', os.path.join(os.path.dirname(sys.executable), 'Lib', 'site-packages', 'PySide'), os.path.join(os.path.dirname(os.path.dirname(sys.executable)), 'Lib', 'site-packages', 'PySide') ]) elif is_pyside2(): exe_name = 'rcc.exe' folders_to_find.extend([ 'C:\\Python38\\Lib\\site-packages\\PySide2\\', os.path.join(os.path.dirname(sys.executable), 'Lib', 'site-packages', 'PySide2'), os.path.join(os.path.dirname(os.path.dirname(sys.executable)), 'Lib', 'site-packages', 'PySide2') ]) if not exe_name: LOGGER.warning('No valid RCC executable find found!') return for folder in folders_to_find: rcc_file_path = path.clean_path(os.path.join(folder, exe_name)) if not os.path.isfile(rcc_file_path): continue return rcc_file_path return None
def open_script(self, script_path): script_path = path_utils.clean_path(script_path) if script_path in self._scripts: return False self._scripts[script_path] = dict() self.scriptOpened.emit(script_path) return True
def update_maya_usd_environment(): """ Updates current Python Maya environment to setup Maya USD plugin """ from tpDcc.libs.python import path usd_dcc_root_path = usdpaths.get_usd_dcc_path() if not usd_dcc_root_path or not os.path.isdir(usd_dcc_root_path): LOGGER.warning( 'Impossible to setup Maya USD environment. Maya USD is not available!' ) return maya_usd_lib = path.clean_path(os.path.join(usd_dcc_root_path, 'lib')) maya_usd_python = path.clean_path(os.path.join(maya_usd_lib, 'python')) maya_usd_plugins = path.clean_path( os.path.join(usd_dcc_root_path, 'plugin')) maya_usd_plugin_name = path.clean_path(os.path.join(maya_usd_lib, 'usd')) maya_adsk_plugin_path = path.clean_path( os.path.join(maya_usd_plugins, 'adsk')) maya_adsk_scripts_path = path.clean_path( os.path.join(maya_adsk_plugin_path, 'scripts')) maya_adsk_usd_plugin_name = path.clean_path( os.path.join(maya_adsk_plugin_path, 'plugin')) add_to_env('PATH', maya_usd_lib) add_to_env('PYTHONPATH', maya_usd_python) add_to_env('PXR_PLUGINPATH_NAME', maya_usd_plugin_name) add_to_env('MAYA_SCRIPT_PATH', maya_adsk_scripts_path) add_to_env('MAYA_PLUG_IN_PATH', maya_adsk_usd_plugin_name) set_env('VP2_RENDER_DELEGATE_PROXY', '1') return True
def get_menu_path(self): """ Returns path where default Artella shelf file is located :return: str """ return path_utils.clean_path( os.path.join(self.get_configurations_folder(), defines.ARTELLA_PROJECT_MENU_FILE_NAME))
def get_changelog_path(self): """ Returns path where default Artella project changelog is located :return: str """ return path_utils.clean_path( os.path.join(self.get_project_path(), defines.ARTELLA_PROJECT_CHANGELOG_FILE_NAME))
def load_pose(path, *args, **kwargs): """ Loads pose from file in disk :param path: str :param args: list :param kwargs: dict :return: Pose """ global _LOADED_POSE clear_cache = kwargs.get('clear_cache', False) if not _LOADED_POSE or path_utils.clean_path( _LOADED_POSE.path) != path_utils.clean_path(path) or clear_cache: _LOADED_POSE = Pose.from_path(path) _LOADED_POSE.load(*args, **kwargs) return _LOADED_POSE