Download GR00T-WholeBodyControl/decoupled_wbc/control/teleop/gui/library/getpath.py from Timsty/groot_deployment: direct link, hf CLI and curl.
- Browser
- Download file 13.7 kB
-
https://huggingface.co/Timsty/groot_deployment/resolve/main/GR00T-WholeBodyControl/decoupled_wbc/control/teleop/gui/library/getpath.py
- Command line
-
hf download hf://Timsty/groot_deployment/GR00T-WholeBodyControl/decoupled_wbc/control/teleop/gui/library/getpath.py
-
curl -L -o getpath.py https://huggingface.co/Timsty/groot_deployment/resolve/main/GR00T-WholeBodyControl/decoupled_wbc/control/teleop/gui/library/getpath.py
13.7 kB
| #!/usr/bin/env python3 | |
| # -*- coding: utf-8 -*- | |
| """ | |
| **Project Name:** MakeHuman | |
| **Product Home Page:** http://www.makehumancommunity.org/ | |
| **Github Code Home Page:** https://github.com/makehumancommunity/ | |
| **Authors:** Jonas Hauquier, Glynn Clements, Joel Palmius, Marc Flerackers | |
| **Copyright(c):** MakeHuman Team 2001-2020 | |
| **Licensing:** AGPL3 | |
| This file is part of MakeHuman Community (www.makehumancommunity.org). | |
| This program is free software: you can redistribute it and/or modify | |
| it under the terms of the GNU Affero General Public License as | |
| published by the Free Software Foundation, either version 3 of the | |
| License, or (at your option) any later version. | |
| This program is distributed in the hope that it will be useful, | |
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| GNU Affero General Public License for more details. | |
| You should have received a copy of the GNU Affero General Public License | |
| along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| Abstract | |
| -------- | |
| Utility module for finding the user home path. | |
| """ | |
| import os | |
| import sys | |
| from library.xdg_parser import XDG_PATHS | |
| __home_path = None | |
| # Search for an optional configuration file, providing another location for the home folder. | |
| # The encoding of the file must be utf-8 and an absolute path is expected. | |
| if sys.platform.startswith("linux"): | |
| configFile = os.path.expanduser("~/.config/makehuman.conf") | |
| elif sys.platform.startswith("darwin"): | |
| configFile = os.path.expanduser("~/Library/Application Support/MakeHuman/makehuman.conf") | |
| elif sys.platform.startswith("win32"): | |
| configFile = os.path.join(os.getenv("LOCALAPPDATA", ""), "makehuman.conf") | |
| else: | |
| configFile = "" | |
| configPath = "" | |
| if os.path.isfile(configFile): | |
| with open(configFile, "r", encoding="utf-8") as f: | |
| configPath = f.readline().strip() | |
| if os.path.isdir(configPath): | |
| __home_path = os.path.normpath(configPath).replace("\\", "/") | |
| def pathToUnicode(path): | |
| """ | |
| Unicode representation of the filename. | |
| Bytes is decoded with the codeset used by the filesystem of the operating | |
| system. | |
| Unicode representations of paths are fit for use in GUI. | |
| """ | |
| if isinstance(path, bytes): | |
| # Approach for bytes string type | |
| try: | |
| return str(path, "utf-8") | |
| except UnicodeDecodeError: | |
| pass | |
| try: | |
| return str(path, sys.getfilesystemencoding()) | |
| except UnicodeDecodeError: | |
| pass | |
| try: | |
| return str(path, sys.getdefaultencoding()) | |
| except UnicodeDecodeError: | |
| pass | |
| try: | |
| import locale | |
| return str(path, locale.getpreferredencoding()) | |
| except UnicodeDecodeError: | |
| return path | |
| else: | |
| return path | |
| def formatPath(path): | |
| if path is None: | |
| return None | |
| return pathToUnicode(os.path.normpath(path).replace("\\", "/")) | |
| def canonicalPath(path): | |
| """ | |
| Return canonical name for location specified by path. | |
| Useful for comparing paths. | |
| """ | |
| return formatPath(os.path.realpath(path)) | |
| def localPath(path): | |
| """ | |
| Returns the path relative to the MH program directory, | |
| i.e. the inverse of canonicalPath. | |
| """ | |
| path = os.path.realpath(path) | |
| root = os.path.realpath(getSysPath()) | |
| return formatPath(os.path.relpath(path, root)) | |
| def getHomePath(): | |
| """ | |
| Find the user home path. | |
| Note: If you are looking for MakeHuman data, you probably want getPath()! | |
| """ | |
| # Cache the home path | |
| global __home_path | |
| # The environment variable MH_HOME_LOCATION will supersede any other settings for the home folder. | |
| alt_home_path = os.environ.get("MH_HOME_LOCATION", "") | |
| if os.path.isdir(alt_home_path): | |
| __home_path = formatPath(alt_home_path) | |
| if __home_path is not None: | |
| return __home_path | |
| # Windows | |
| if sys.platform.startswith("win"): | |
| import winreg | |
| keyname = r"Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" | |
| # name = 'Personal' | |
| with winreg.OpenKey(winreg.HKEY_CURRENT_USER, keyname) as k: | |
| try: | |
| value, type_ = winreg.QueryValueEx(k, "Personal") | |
| except FileNotFoundError: | |
| value, type_ = r"%USERPROFILE%\Documents", winreg.REG_EXPAND_SZ | |
| if type_ == winreg.REG_EXPAND_SZ: | |
| __home_path = formatPath(winreg.ExpandEnvironmentStrings(value)) | |
| return __home_path | |
| elif type_ == winreg.REG_SZ: | |
| __home_path = formatPath(value) | |
| return __home_path | |
| else: | |
| raise RuntimeError("Couldn't determine user folder") | |
| # Linux | |
| elif sys.platform.startswith("linux"): | |
| doc_folder = XDG_PATHS.get("DOCUMENTS", "") | |
| if os.path.isdir(doc_folder): | |
| __home_path = doc_folder | |
| else: | |
| __home_path = pathToUnicode(os.path.expanduser("~")) | |
| # Darwin | |
| else: | |
| __home_path = os.path.expanduser("~") | |
| return __home_path | |
| def getPath(subPath=""): | |
| """ | |
| Get MakeHuman folder that contains per-user files, located in the user home | |
| path. | |
| """ | |
| path = getHomePath() | |
| # Windows | |
| if sys.platform.startswith("win"): | |
| path = os.path.join(path, "makehuman") | |
| # MAC OSX | |
| elif sys.platform.startswith("darwin"): | |
| path = os.path.join(path, "Documents") | |
| path = os.path.join(path, "MakeHuman") | |
| # Unix/Linux | |
| else: | |
| path = os.path.join(path, "makehuman") | |
| path = os.path.join(path, "v1py3") | |
| if subPath: | |
| path = os.path.join(path, subPath) | |
| return formatPath(path) | |
| def getDataPath(subPath=""): | |
| """ | |
| Path to per-user data folder, should always be the same as getPath('data'). | |
| """ | |
| if subPath: | |
| path = getPath(os.path.join("data", subPath)) | |
| else: | |
| path = getPath("data") | |
| return formatPath(path) | |
| def getSysDataPath(subPath=""): | |
| """ | |
| Path to the data folder that is installed with MakeHuman system-wide. | |
| NOTE: do NOT assume that getSysPath("data") == getSysDataPath()! | |
| """ | |
| if subPath: | |
| path = getSysPath(os.path.join("data", subPath)) | |
| else: | |
| path = getSysPath("data") | |
| return formatPath(path) | |
| def getSysPath(subPath=""): | |
| """ | |
| Path to the system folder where MakeHuman is installed (it is possible that | |
| data is stored in another path). | |
| Writing to this folder or modifying this data usually requires admin rights, | |
| contains system-wide data (for all users). | |
| """ | |
| if subPath: | |
| path = os.path.join(".", subPath) | |
| else: | |
| path = "." | |
| return formatPath(path) | |
| def _allnamesequal(name): | |
| return all(n == name[0] for n in name[1:]) | |
| def commonprefix(paths, sep="/"): | |
| """ | |
| Implementation of os.path.commonprefix that works as you would expect. | |
| Source: http://rosettacode.org/wiki/Find_Common_Directory_Path#Python | |
| """ | |
| from itertools import takewhile | |
| bydirectorylevels = list(zip(*[p.split(sep) for p in paths])) | |
| return sep.join(x[0] for x in takewhile(_allnamesequal, bydirectorylevels)) | |
| def isSubPath(subpath, path): | |
| """ | |
| Verifies whether subpath is within path. | |
| """ | |
| subpath = canonicalPath(subpath) | |
| path = canonicalPath(path) | |
| return commonprefix([subpath, path]) == path | |
| def isSamePath(path1, path2): | |
| """ | |
| Determines whether two paths point to the same location. | |
| """ | |
| return canonicalPath(path1) == canonicalPath(path2) | |
| def getRelativePath(path, relativeTo=[getDataPath(), getSysDataPath()], strict=False): | |
| """ | |
| Return a relative file path, relative to one of the specified search paths. | |
| First valid path is returned, so order in which search paths are given matters. | |
| """ | |
| if not isinstance(relativeTo, list): | |
| relativeTo = [relativeTo] | |
| relto = None | |
| for p in relativeTo: | |
| if isSubPath(path, p): | |
| relto = p | |
| if relto is None: | |
| if strict: | |
| return None | |
| else: | |
| return path | |
| relto = os.path.abspath(os.path.realpath(relto)) | |
| path = os.path.abspath(os.path.realpath(path)) | |
| rpath = os.path.relpath(path, relto) | |
| return formatPath(rpath) | |
| def findFile(relPath, searchPaths=[getDataPath(), getSysDataPath()], strict=False): | |
| """ | |
| Inverse of getRelativePath: find an absolute path from specified relative | |
| path in one of the search paths. | |
| First occurence is returned, so order in which search paths are given matters. | |
| Note: does NOT treat the path as relative to the current working dir, unless | |
| you explicitly specify '.' as one of the searchpaths. | |
| """ | |
| if not isinstance(searchPaths, list): | |
| searchPaths = [searchPaths] | |
| for dataPath in searchPaths: | |
| path = os.path.join(dataPath, relPath) | |
| if os.path.isfile(path): | |
| return formatPath(path) | |
| if strict: | |
| return None | |
| else: | |
| return relPath | |
| def thoroughFindFile(filename, searchPaths=[], searchDefaultPaths=True): | |
| """ | |
| Extensively search the data paths to find a file with matching filename in | |
| as much cases as possible. If file is found, returns absolute filename. | |
| If nothing is found return the most probable filename. | |
| """ | |
| # Ensure unix style path | |
| filename.replace("\\", "/") | |
| if not isinstance(searchPaths, list): | |
| searchPaths = [searchPaths] | |
| if searchDefaultPaths: | |
| # Search in user / sys data, and user / sys root folders | |
| searchPaths = list(searchPaths) | |
| searchPaths.extend([getDataPath(), getSysDataPath(), getPath(), getSysPath()]) | |
| path = findFile(filename, searchPaths, strict=True) | |
| if path: | |
| return canonicalPath(path) | |
| # Treat as absolute path or search relative to application path | |
| if os.path.isfile(filename): | |
| return canonicalPath(filename) | |
| # Strip leading data/ folder if present (for the scenario where sysDataPath is not in sysPath) | |
| if filename.startswith("data/"): | |
| result = thoroughFindFile(filename[5:], searchPaths, False) | |
| if os.path.isfile(result): | |
| return result | |
| # Nothing found | |
| return formatPath(filename) | |
| def search(paths, extensions, recursive=True, mutexExtensions=False): | |
| """ | |
| Search for files with specified extensions in specified paths. | |
| If mutexExtensions is True, no duplicate files with only differing extension | |
| will be returned. Instead, only the file with highest extension precedence | |
| (extensions occurs earlier in the extensions list) is kept. | |
| """ | |
| if isinstance(paths, str): | |
| paths = [paths] | |
| if isinstance(extensions, str): | |
| extensions = [extensions] | |
| extensions = [e[1:].lower() if e.startswith(".") else e.lower() for e in extensions] | |
| if mutexExtensions: | |
| discovered = dict() | |
| def _aggregate_files_mutexExt(filepath): | |
| basep, ext = os.path.splitext(filepath) | |
| ext = ext[1:] | |
| if basep in discovered: | |
| if extensions.index(ext) < extensions.index(discovered[basep]): | |
| discovered[basep] = ext | |
| else: | |
| discovered[basep] = ext | |
| if recursive: | |
| for path in paths: | |
| for root, dirs, files in os.walk(path): | |
| for f in files: | |
| ext = os.path.splitext(f)[1][1:].lower() | |
| if ext in extensions: | |
| if mutexExtensions: | |
| _aggregate_files_mutexExt(os.path.join(root, f)) | |
| else: | |
| yield pathToUnicode(os.path.join(root, f)) | |
| else: | |
| for path in paths: | |
| if not os.path.isdir(path): | |
| continue | |
| for f in os.listdir(path): | |
| f = os.path.join(path, f) | |
| if os.path.isfile(f): | |
| ext = os.path.splitext(f)[1][1:].lower() | |
| if ext in extensions: | |
| if mutexExtensions: | |
| _aggregate_files_mutexExt(f) | |
| else: | |
| yield pathToUnicode(f) | |
| if mutexExtensions: | |
| for f in ["%s.%s" % (p, e) for p, e in list(discovered.items())]: | |
| yield pathToUnicode(f) | |
| def getJailedPath(filepath, relativeTo, jailLimits=[getDataPath(), getSysDataPath()]): | |
| """ | |
| Get a path to filepath, relative to relativeTo path, confined within the | |
| jailLimits folders. Returns None if the path would fall outside of the jail. | |
| This is a portable path which can be used for distributing eg. materials | |
| (texture paths are portable). | |
| Returns None if the filepath falls outside of the jail folders. Returns | |
| a path to filename relative to relativeTo path if it is a subpath of it, | |
| else returns a path relative to the jailLimits. | |
| """ | |
| def _withinJail(path): | |
| for j in jailLimits: | |
| if isSubPath(path, j): | |
| return True | |
| return False | |
| # These paths may become messed up when using symlinks for user home. | |
| # Make sure we use the same paths when calculating relative paths. | |
| filepath = os.path.realpath(filepath) | |
| if relativeTo is str: | |
| relativeTo = os.path.realpath(relativeTo) | |
| output = None | |
| if _withinJail(filepath): | |
| relPath = getRelativePath(filepath, relativeTo, strict=True) | |
| if relPath: | |
| output = relPath | |
| else: | |
| output = getRelativePath(filepath, jailLimits) | |
| return output | |