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