m2m模型翻译
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

223 lines
8.6 KiB

6 months ago
  1. """Unix."""
  2. from __future__ import annotations
  3. import os
  4. import sys
  5. from configparser import ConfigParser
  6. from pathlib import Path
  7. from .api import PlatformDirsABC
  8. if sys.platform == "win32":
  9. def getuid() -> int:
  10. msg = "should only be used on Unix"
  11. raise RuntimeError(msg)
  12. else:
  13. from os import getuid
  14. class Unix(PlatformDirsABC):
  15. """
  16. On Unix/Linux, we follow the
  17. `XDG Basedir Spec <https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html>`_. The spec allows
  18. overriding directories with environment variables. The examples show are the default values, alongside the name of
  19. the environment variable that overrides them. Makes use of the
  20. `appname <platformdirs.api.PlatformDirsABC.appname>`,
  21. `version <platformdirs.api.PlatformDirsABC.version>`,
  22. `multipath <platformdirs.api.PlatformDirsABC.multipath>`,
  23. `opinion <platformdirs.api.PlatformDirsABC.opinion>`,
  24. `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
  25. """
  26. @property
  27. def user_data_dir(self) -> str:
  28. """
  29. :return: data directory tied to the user, e.g. ``~/.local/share/$appname/$version`` or
  30. ``$XDG_DATA_HOME/$appname/$version``
  31. """
  32. path = os.environ.get("XDG_DATA_HOME", "")
  33. if not path.strip():
  34. path = os.path.expanduser("~/.local/share") # noqa: PTH111
  35. return self._append_app_name_and_version(path)
  36. @property
  37. def site_data_dir(self) -> str:
  38. """
  39. :return: data directories shared by users (if `multipath <platformdirs.api.PlatformDirsABC.multipath>` is
  40. enabled and ``XDG_DATA_DIR`` is set and a multi path the response is also a multi path separated by the OS
  41. path separator), e.g. ``/usr/local/share/$appname/$version`` or ``/usr/share/$appname/$version``
  42. """
  43. # XDG default for $XDG_DATA_DIRS; only first, if multipath is False
  44. path = os.environ.get("XDG_DATA_DIRS", "")
  45. if not path.strip():
  46. path = f"/usr/local/share{os.pathsep}/usr/share"
  47. return self._with_multi_path(path)
  48. def _with_multi_path(self, path: str) -> str:
  49. path_list = path.split(os.pathsep)
  50. if not self.multipath:
  51. path_list = path_list[0:1]
  52. path_list = [self._append_app_name_and_version(os.path.expanduser(p)) for p in path_list] # noqa: PTH111
  53. return os.pathsep.join(path_list)
  54. @property
  55. def user_config_dir(self) -> str:
  56. """
  57. :return: config directory tied to the user, e.g. ``~/.config/$appname/$version`` or
  58. ``$XDG_CONFIG_HOME/$appname/$version``
  59. """
  60. path = os.environ.get("XDG_CONFIG_HOME", "")
  61. if not path.strip():
  62. path = os.path.expanduser("~/.config") # noqa: PTH111
  63. return self._append_app_name_and_version(path)
  64. @property
  65. def site_config_dir(self) -> str:
  66. """
  67. :return: config directories shared by users (if `multipath <platformdirs.api.PlatformDirsABC.multipath>`
  68. is enabled and ``XDG_DATA_DIR`` is set and a multi path the response is also a multi path separated by the OS
  69. path separator), e.g. ``/etc/xdg/$appname/$version``
  70. """
  71. # XDG default for $XDG_CONFIG_DIRS only first, if multipath is False
  72. path = os.environ.get("XDG_CONFIG_DIRS", "")
  73. if not path.strip():
  74. path = "/etc/xdg"
  75. return self._with_multi_path(path)
  76. @property
  77. def user_cache_dir(self) -> str:
  78. """
  79. :return: cache directory tied to the user, e.g. ``~/.cache/$appname/$version`` or
  80. ``~/$XDG_CACHE_HOME/$appname/$version``
  81. """
  82. path = os.environ.get("XDG_CACHE_HOME", "")
  83. if not path.strip():
  84. path = os.path.expanduser("~/.cache") # noqa: PTH111
  85. return self._append_app_name_and_version(path)
  86. @property
  87. def site_cache_dir(self) -> str:
  88. """:return: cache directory shared by users, e.g. ``/var/tmp/$appname/$version``"""
  89. return self._append_app_name_and_version("/var/tmp") # noqa: S108
  90. @property
  91. def user_state_dir(self) -> str:
  92. """
  93. :return: state directory tied to the user, e.g. ``~/.local/state/$appname/$version`` or
  94. ``$XDG_STATE_HOME/$appname/$version``
  95. """
  96. path = os.environ.get("XDG_STATE_HOME", "")
  97. if not path.strip():
  98. path = os.path.expanduser("~/.local/state") # noqa: PTH111
  99. return self._append_app_name_and_version(path)
  100. @property
  101. def user_log_dir(self) -> str:
  102. """:return: log directory tied to the user, same as `user_state_dir` if not opinionated else ``log`` in it"""
  103. path = self.user_state_dir
  104. if self.opinion:
  105. path = os.path.join(path, "log") # noqa: PTH118
  106. return path
  107. @property
  108. def user_documents_dir(self) -> str:
  109. """:return: documents directory tied to the user, e.g. ``~/Documents``"""
  110. return _get_user_media_dir("XDG_DOCUMENTS_DIR", "~/Documents")
  111. @property
  112. def user_downloads_dir(self) -> str:
  113. """:return: downloads directory tied to the user, e.g. ``~/Downloads``"""
  114. return _get_user_media_dir("XDG_DOWNLOAD_DIR", "~/Downloads")
  115. @property
  116. def user_pictures_dir(self) -> str:
  117. """:return: pictures directory tied to the user, e.g. ``~/Pictures``"""
  118. return _get_user_media_dir("XDG_PICTURES_DIR", "~/Pictures")
  119. @property
  120. def user_videos_dir(self) -> str:
  121. """:return: videos directory tied to the user, e.g. ``~/Videos``"""
  122. return _get_user_media_dir("XDG_VIDEOS_DIR", "~/Videos")
  123. @property
  124. def user_music_dir(self) -> str:
  125. """:return: music directory tied to the user, e.g. ``~/Music``"""
  126. return _get_user_media_dir("XDG_MUSIC_DIR", "~/Music")
  127. @property
  128. def user_runtime_dir(self) -> str:
  129. """
  130. :return: runtime directory tied to the user, e.g. ``/run/user/$(id -u)/$appname/$version`` or
  131. ``$XDG_RUNTIME_DIR/$appname/$version``.
  132. For FreeBSD/OpenBSD/NetBSD, it would return ``/var/run/user/$(id -u)/$appname/$version`` if
  133. exists, otherwise ``/tmp/runtime-$(id -u)/$appname/$version``, if``$XDG_RUNTIME_DIR``
  134. is not set.
  135. """
  136. path = os.environ.get("XDG_RUNTIME_DIR", "")
  137. if not path.strip():
  138. if sys.platform.startswith(("freebsd", "openbsd", "netbsd")):
  139. path = f"/var/run/user/{getuid()}"
  140. if not Path(path).exists():
  141. path = f"/tmp/runtime-{getuid()}" # noqa: S108
  142. else:
  143. path = f"/run/user/{getuid()}"
  144. return self._append_app_name_and_version(path)
  145. @property
  146. def site_data_path(self) -> Path:
  147. """:return: data path shared by users. Only return first item, even if ``multipath`` is set to ``True``"""
  148. return self._first_item_as_path_if_multipath(self.site_data_dir)
  149. @property
  150. def site_config_path(self) -> Path:
  151. """:return: config path shared by the users. Only return first item, even if ``multipath`` is set to ``True``"""
  152. return self._first_item_as_path_if_multipath(self.site_config_dir)
  153. @property
  154. def site_cache_path(self) -> Path:
  155. """:return: cache path shared by users. Only return first item, even if ``multipath`` is set to ``True``"""
  156. return self._first_item_as_path_if_multipath(self.site_cache_dir)
  157. def _first_item_as_path_if_multipath(self, directory: str) -> Path:
  158. if self.multipath:
  159. # If multipath is True, the first path is returned.
  160. directory = directory.split(os.pathsep)[0]
  161. return Path(directory)
  162. def _get_user_media_dir(env_var: str, fallback_tilde_path: str) -> str:
  163. media_dir = _get_user_dirs_folder(env_var)
  164. if media_dir is None:
  165. media_dir = os.environ.get(env_var, "").strip()
  166. if not media_dir:
  167. media_dir = os.path.expanduser(fallback_tilde_path) # noqa: PTH111
  168. return media_dir
  169. def _get_user_dirs_folder(key: str) -> str | None:
  170. """Return directory from user-dirs.dirs config file. See https://freedesktop.org/wiki/Software/xdg-user-dirs/."""
  171. user_dirs_config_path = Path(Unix().user_config_dir) / "user-dirs.dirs"
  172. if user_dirs_config_path.exists():
  173. parser = ConfigParser()
  174. with user_dirs_config_path.open() as stream:
  175. # Add fake section header, so ConfigParser doesn't complain
  176. parser.read_string(f"[top]\n{stream.read()}")
  177. if key not in parser["top"]:
  178. return None
  179. path = parser["top"][key].strip('"')
  180. # Handle relative home paths
  181. return path.replace("$HOME", os.path.expanduser("~")) # noqa: PTH111
  182. return None
  183. __all__ = [
  184. "Unix",
  185. ]