2from __future__
import annotations
7from functools
import lru_cache
8from typing
import TYPE_CHECKING
10from .api
import PlatformDirsABC
18 `MSDN on where to store app data files
19 <http://support.microsoft.com/default.aspx?scid=kb;en-us;310294#XSLTH3194121123120121120120>`_.
21 `appname <platformdirs.api.PlatformDirsABC.appname>`,
22 `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`,
23 `version <platformdirs.api.PlatformDirsABC.version>`,
24 `roaming <platformdirs.api.PlatformDirsABC.roaming>`,
25 `opinion <platformdirs.api.PlatformDirsABC.opinion>`,
26 `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
32 :return: data directory tied to the user, e.g.
33 ``%USERPROFILE%\\AppData\\Local\\$appauthor\\$appname`` (not roaming) or
34 ``%USERPROFILE%\\AppData\\Roaming\\$appauthor\\$appname`` (roaming)
36 const =
"CSIDL_APPDATA" if self.
roaming else "CSIDL_LOCAL_APPDATA"
40 def _append_parts(self, path: str, *, opinion_value: str |
None =
None) -> str:
47 if opinion_value
is not None and self.
opinion:
57 """:return: data directory shared by users, e.g. ``C:\\ProgramData\\$appauthor\\$appname``"""
63 """:return: config directory tied to the user, same as `user_data_dir`"""
68 """:return: config directory shared by the users, same as `site_data_dir`"""
74 :return: cache directory tied to the user (if opinionated with ``Cache`` folder within ``$appname``) e.g.
75 ``%USERPROFILE%\\AppData\\Local\\$appauthor\\$appname\\Cache\\$version``
82 """:return: cache directory shared by users, e.g. ``C:\\ProgramData\\$appauthor\\$appname\\Cache\\$version``"""
88 """:return: state directory tied to the user, same as `user_data_dir`"""
93 """:return: log directory tied to the user, same as `user_data_dir` if not opinionated else ``Logs`` in it"""
102 """:return: documents directory tied to the user e.g. ``%USERPROFILE%\\Documents``"""
107 """:return: downloads directory tied to the user e.g. ``%USERPROFILE%\\Downloads``"""
112 """:return: pictures directory tied to the user e.g. ``%USERPROFILE%\\Pictures``"""
117 """:return: videos directory tied to the user e.g. ``%USERPROFILE%\\Videos``"""
122 """:return: music directory tied to the user e.g. ``%USERPROFILE%\\Music``"""
128 :return: runtime directory tied to the user, e.g.
129 ``%USERPROFILE%\\AppData\\Local\\Temp\\$appauthor\\$appname``
136 """Get folder from environment variables."""
138 if result
is not None:
142 "CSIDL_APPDATA":
"APPDATA",
143 "CSIDL_COMMON_APPDATA":
"ALLUSERSPROFILE",
144 "CSIDL_LOCAL_APPDATA":
"LOCALAPPDATA",
146 if env_var_name
is None:
147 msg = f
"Unknown CSIDL name: {csidl_name}"
148 raise ValueError(msg)
151 msg = f
"Unset environment variable: {env_var_name}"
152 raise ValueError(msg)
157 """Get folder for a CSIDL name that does not exist as an environment variable."""
158 if csidl_name ==
"CSIDL_PERSONAL":
161 if csidl_name ==
"CSIDL_DOWNLOADS":
164 if csidl_name ==
"CSIDL_MYPICTURES":
167 if csidl_name ==
"CSIDL_MYVIDEO":
170 if csidl_name ==
"CSIDL_MYMUSIC":
177 Get folder from the registry.
179 This is a fallback technique at best. I'm not sure if using the registry for these guarantees us the correct answer
180 for all CSIDL_* names.
182 shell_folder_name = {
183 "CSIDL_APPDATA":
"AppData",
184 "CSIDL_COMMON_APPDATA":
"Common AppData",
185 "CSIDL_LOCAL_APPDATA":
"Local AppData",
186 "CSIDL_PERSONAL":
"Personal",
187 "CSIDL_DOWNLOADS":
"{374DE290-123F-4565-9164-39C4925E467B}",
188 "CSIDL_MYPICTURES":
"My Pictures",
189 "CSIDL_MYVIDEO":
"My Video",
190 "CSIDL_MYMUSIC":
"My Music",
192 if shell_folder_name
is None:
193 msg = f
"Unknown CSIDL name: {csidl_name}"
194 raise ValueError(msg)
196 raise NotImplementedError
201 return str(directory)
205 """Get folder with ctypes."""
212 "CSIDL_COMMON_APPDATA": 35,
213 "CSIDL_LOCAL_APPDATA": 28,
215 "CSIDL_MYPICTURES": 39,
218 "CSIDL_DOWNLOADS": 40,
220 if csidl_const
is None:
221 msg = f
"Unknown CSIDL name: {csidl_name}"
222 raise ValueError(msg)
225 windll =
getattr(ctypes,
"windll")
229 if any(
ord(c) > 255
for c
in buf):
234 if csidl_name ==
"CSIDL_DOWNLOADS":
242 return get_win_folder_via_ctypes
246 return get_win_folder_from_env_vars
248 return get_win_folder_from_registry