diff options
Diffstat (limited to 'venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/appdirs.py')
-rw-r--r-- | venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/appdirs.py | 604 |
1 files changed, 604 insertions, 0 deletions
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/appdirs.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/appdirs.py new file mode 100644 index 0000000..7ff6a07 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/appdirs.py | |||
@@ -0,0 +1,604 @@ | |||
1 | #!/usr/bin/env python | ||
2 | # -*- coding: utf-8 -*- | ||
3 | # Copyright (c) 2005-2010 ActiveState Software Inc. | ||
4 | # Copyright (c) 2013 Eddy Petrișor | ||
5 | |||
6 | """Utilities for determining application-specific dirs. | ||
7 | |||
8 | See <http://github.com/ActiveState/appdirs> for details and usage. | ||
9 | """ | ||
10 | # Dev Notes: | ||
11 | # - MSDN on where to store app data files: | ||
12 | # http://support.microsoft.com/default.aspx?scid=kb;en-us;310294#XSLTH3194121123120121120120 | ||
13 | # - Mac OS X: http://developer.apple.com/documentation/MacOSX/Conceptual/BPFileSystem/index.html | ||
14 | # - XDG spec for Un*x: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html | ||
15 | |||
16 | __version_info__ = (1, 4, 3) | ||
17 | __version__ = '.'.join(map(str, __version_info__)) | ||
18 | |||
19 | |||
20 | import sys | ||
21 | import os | ||
22 | |||
23 | PY3 = sys.version_info[0] == 3 | ||
24 | |||
25 | if PY3: | ||
26 | unicode = str | ||
27 | |||
28 | if sys.platform.startswith('java'): | ||
29 | import platform | ||
30 | os_name = platform.java_ver()[3][0] | ||
31 | if os_name.startswith('Windows'): # "Windows XP", "Windows 7", etc. | ||
32 | system = 'win32' | ||
33 | elif os_name.startswith('Mac'): # "Mac OS X", etc. | ||
34 | system = 'darwin' | ||
35 | else: # "Linux", "SunOS", "FreeBSD", etc. | ||
36 | # Setting this to "linux2" is not ideal, but only Windows or Mac | ||
37 | # are actually checked for and the rest of the module expects | ||
38 | # *sys.platform* style strings. | ||
39 | system = 'linux2' | ||
40 | else: | ||
41 | system = sys.platform | ||
42 | |||
43 | |||
44 | |||
45 | def user_data_dir(appname=None, appauthor=None, version=None, roaming=False): | ||
46 | r"""Return full path to the user-specific data dir for this application. | ||
47 | |||
48 | "appname" is the name of application. | ||
49 | If None, just the system directory is returned. | ||
50 | "appauthor" (only used on Windows) is the name of the | ||
51 | appauthor or distributing body for this application. Typically | ||
52 | it is the owning company name. This falls back to appname. You may | ||
53 | pass False to disable it. | ||
54 | "version" is an optional version path element to append to the | ||
55 | path. You might want to use this if you want multiple versions | ||
56 | of your app to be able to run independently. If used, this | ||
57 | would typically be "<major>.<minor>". | ||
58 | Only applied when appname is present. | ||
59 | "roaming" (boolean, default False) can be set True to use the Windows | ||
60 | roaming appdata directory. That means that for users on a Windows | ||
61 | network setup for roaming profiles, this user data will be | ||
62 | sync'd on login. See | ||
63 | <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> | ||
64 | for a discussion of issues. | ||
65 | |||
66 | Typical user data directories are: | ||
67 | Mac OS X: ~/Library/Application Support/<AppName> | ||
68 | Unix: ~/.local/share/<AppName> # or in $XDG_DATA_HOME, if defined | ||
69 | Win XP (not roaming): C:\Documents and Settings\<username>\Application Data\<AppAuthor>\<AppName> | ||
70 | Win XP (roaming): C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName> | ||
71 | Win 7 (not roaming): C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName> | ||
72 | Win 7 (roaming): C:\Users\<username>\AppData\Roaming\<AppAuthor>\<AppName> | ||
73 | |||
74 | For Unix, we follow the XDG spec and support $XDG_DATA_HOME. | ||
75 | That means, by default "~/.local/share/<AppName>". | ||
76 | """ | ||
77 | if system == "win32": | ||
78 | if appauthor is None: | ||
79 | appauthor = appname | ||
80 | const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA" | ||
81 | path = os.path.normpath(_get_win_folder(const)) | ||
82 | if appname: | ||
83 | if appauthor is not False: | ||
84 | path = os.path.join(path, appauthor, appname) | ||
85 | else: | ||
86 | path = os.path.join(path, appname) | ||
87 | elif system == 'darwin': | ||
88 | path = os.path.expanduser('~/Library/Application Support/') | ||
89 | if appname: | ||
90 | path = os.path.join(path, appname) | ||
91 | else: | ||
92 | path = os.getenv('XDG_DATA_HOME', os.path.expanduser("~/.local/share")) | ||
93 | if appname: | ||
94 | path = os.path.join(path, appname) | ||
95 | if appname and version: | ||
96 | path = os.path.join(path, version) | ||
97 | return path | ||
98 | |||
99 | |||
100 | def site_data_dir(appname=None, appauthor=None, version=None, multipath=False): | ||
101 | r"""Return full path to the user-shared data dir for this application. | ||
102 | |||
103 | "appname" is the name of application. | ||
104 | If None, just the system directory is returned. | ||
105 | "appauthor" (only used on Windows) is the name of the | ||
106 | appauthor or distributing body for this application. Typically | ||
107 | it is the owning company name. This falls back to appname. You may | ||
108 | pass False to disable it. | ||
109 | "version" is an optional version path element to append to the | ||
110 | path. You might want to use this if you want multiple versions | ||
111 | of your app to be able to run independently. If used, this | ||
112 | would typically be "<major>.<minor>". | ||
113 | Only applied when appname is present. | ||
114 | "multipath" is an optional parameter only applicable to *nix | ||
115 | which indicates that the entire list of data dirs should be | ||
116 | returned. By default, the first item from XDG_DATA_DIRS is | ||
117 | returned, or '/usr/local/share/<AppName>', | ||
118 | if XDG_DATA_DIRS is not set | ||
119 | |||
120 | Typical site data directories are: | ||
121 | Mac OS X: /Library/Application Support/<AppName> | ||
122 | Unix: /usr/local/share/<AppName> or /usr/share/<AppName> | ||
123 | Win XP: C:\Documents and Settings\All Users\Application Data\<AppAuthor>\<AppName> | ||
124 | Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) | ||
125 | Win 7: C:\ProgramData\<AppAuthor>\<AppName> # Hidden, but writeable on Win 7. | ||
126 | |||
127 | For Unix, this is using the $XDG_DATA_DIRS[0] default. | ||
128 | |||
129 | WARNING: Do not use this on Windows. See the Vista-Fail note above for why. | ||
130 | """ | ||
131 | if system == "win32": | ||
132 | if appauthor is None: | ||
133 | appauthor = appname | ||
134 | path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA")) | ||
135 | if appname: | ||
136 | if appauthor is not False: | ||
137 | path = os.path.join(path, appauthor, appname) | ||
138 | else: | ||
139 | path = os.path.join(path, appname) | ||
140 | elif system == 'darwin': | ||
141 | path = os.path.expanduser('/Library/Application Support') | ||
142 | if appname: | ||
143 | path = os.path.join(path, appname) | ||
144 | else: | ||
145 | # XDG default for $XDG_DATA_DIRS | ||
146 | # only first, if multipath is False | ||
147 | path = os.getenv('XDG_DATA_DIRS', | ||
148 | os.pathsep.join(['/usr/local/share', '/usr/share'])) | ||
149 | pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)] | ||
150 | if appname: | ||
151 | if version: | ||
152 | appname = os.path.join(appname, version) | ||
153 | pathlist = [os.sep.join([x, appname]) for x in pathlist] | ||
154 | |||
155 | if multipath: | ||
156 | path = os.pathsep.join(pathlist) | ||
157 | else: | ||
158 | path = pathlist[0] | ||
159 | return path | ||
160 | |||
161 | if appname and version: | ||
162 | path = os.path.join(path, version) | ||
163 | return path | ||
164 | |||
165 | |||
166 | def user_config_dir(appname=None, appauthor=None, version=None, roaming=False): | ||
167 | r"""Return full path to the user-specific config dir for this application. | ||
168 | |||
169 | "appname" is the name of application. | ||
170 | If None, just the system directory is returned. | ||
171 | "appauthor" (only used on Windows) is the name of the | ||
172 | appauthor or distributing body for this application. Typically | ||
173 | it is the owning company name. This falls back to appname. You may | ||
174 | pass False to disable it. | ||
175 | "version" is an optional version path element to append to the | ||
176 | path. You might want to use this if you want multiple versions | ||
177 | of your app to be able to run independently. If used, this | ||
178 | would typically be "<major>.<minor>". | ||
179 | Only applied when appname is present. | ||
180 | "roaming" (boolean, default False) can be set True to use the Windows | ||
181 | roaming appdata directory. That means that for users on a Windows | ||
182 | network setup for roaming profiles, this user data will be | ||
183 | sync'd on login. See | ||
184 | <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> | ||
185 | for a discussion of issues. | ||
186 | |||
187 | Typical user config directories are: | ||
188 | Mac OS X: same as user_data_dir | ||
189 | Unix: ~/.config/<AppName> # or in $XDG_CONFIG_HOME, if defined | ||
190 | Win *: same as user_data_dir | ||
191 | |||
192 | For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME. | ||
193 | That means, by default "~/.config/<AppName>". | ||
194 | """ | ||
195 | if system in ["win32", "darwin"]: | ||
196 | path = user_data_dir(appname, appauthor, None, roaming) | ||
197 | else: | ||
198 | path = os.getenv('XDG_CONFIG_HOME', os.path.expanduser("~/.config")) | ||
199 | if appname: | ||
200 | path = os.path.join(path, appname) | ||
201 | if appname and version: | ||
202 | path = os.path.join(path, version) | ||
203 | return path | ||
204 | |||
205 | |||
206 | def site_config_dir(appname=None, appauthor=None, version=None, multipath=False): | ||
207 | r"""Return full path to the user-shared data dir for this application. | ||
208 | |||
209 | "appname" is the name of application. | ||
210 | If None, just the system directory is returned. | ||
211 | "appauthor" (only used on Windows) is the name of the | ||
212 | appauthor or distributing body for this application. Typically | ||
213 | it is the owning company name. This falls back to appname. You may | ||
214 | pass False to disable it. | ||
215 | "version" is an optional version path element to append to the | ||
216 | path. You might want to use this if you want multiple versions | ||
217 | of your app to be able to run independently. If used, this | ||
218 | would typically be "<major>.<minor>". | ||
219 | Only applied when appname is present. | ||
220 | "multipath" is an optional parameter only applicable to *nix | ||
221 | which indicates that the entire list of config dirs should be | ||
222 | returned. By default, the first item from XDG_CONFIG_DIRS is | ||
223 | returned, or '/etc/xdg/<AppName>', if XDG_CONFIG_DIRS is not set | ||
224 | |||
225 | Typical site config directories are: | ||
226 | Mac OS X: same as site_data_dir | ||
227 | Unix: /etc/xdg/<AppName> or $XDG_CONFIG_DIRS[i]/<AppName> for each value in | ||
228 | $XDG_CONFIG_DIRS | ||
229 | Win *: same as site_data_dir | ||
230 | Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) | ||
231 | |||
232 | For Unix, this is using the $XDG_CONFIG_DIRS[0] default, if multipath=False | ||
233 | |||
234 | WARNING: Do not use this on Windows. See the Vista-Fail note above for why. | ||
235 | """ | ||
236 | if system in ["win32", "darwin"]: | ||
237 | path = site_data_dir(appname, appauthor) | ||
238 | if appname and version: | ||
239 | path = os.path.join(path, version) | ||
240 | else: | ||
241 | # XDG default for $XDG_CONFIG_DIRS | ||
242 | # only first, if multipath is False | ||
243 | path = os.getenv('XDG_CONFIG_DIRS', '/etc/xdg') | ||
244 | pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)] | ||
245 | if appname: | ||
246 | if version: | ||
247 | appname = os.path.join(appname, version) | ||
248 | pathlist = [os.sep.join([x, appname]) for x in pathlist] | ||
249 | |||
250 | if multipath: | ||
251 | path = os.pathsep.join(pathlist) | ||
252 | else: | ||
253 | path = pathlist[0] | ||
254 | return path | ||
255 | |||
256 | |||
257 | def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True): | ||
258 | r"""Return full path to the user-specific cache dir for this application. | ||
259 | |||
260 | "appname" is the name of application. | ||
261 | If None, just the system directory is returned. | ||
262 | "appauthor" (only used on Windows) is the name of the | ||
263 | appauthor or distributing body for this application. Typically | ||
264 | it is the owning company name. This falls back to appname. You may | ||
265 | pass False to disable it. | ||
266 | "version" is an optional version path element to append to the | ||
267 | path. You might want to use this if you want multiple versions | ||
268 | of your app to be able to run independently. If used, this | ||
269 | would typically be "<major>.<minor>". | ||
270 | Only applied when appname is present. | ||
271 | "opinion" (boolean) can be False to disable the appending of | ||
272 | "Cache" to the base app data dir for Windows. See | ||
273 | discussion below. | ||
274 | |||
275 | Typical user cache directories are: | ||
276 | Mac OS X: ~/Library/Caches/<AppName> | ||
277 | Unix: ~/.cache/<AppName> (XDG default) | ||
278 | Win XP: C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>\Cache | ||
279 | Vista: C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>\Cache | ||
280 | |||
281 | On Windows the only suggestion in the MSDN docs is that local settings go in | ||
282 | the `CSIDL_LOCAL_APPDATA` directory. This is identical to the non-roaming | ||
283 | app data dir (the default returned by `user_data_dir` above). Apps typically | ||
284 | put cache data somewhere *under* the given dir here. Some examples: | ||
285 | ...\Mozilla\Firefox\Profiles\<ProfileName>\Cache | ||
286 | ...\Acme\SuperApp\Cache\1.0 | ||
287 | OPINION: This function appends "Cache" to the `CSIDL_LOCAL_APPDATA` value. | ||
288 | This can be disabled with the `opinion=False` option. | ||
289 | """ | ||
290 | if system == "win32": | ||
291 | if appauthor is None: | ||
292 | appauthor = appname | ||
293 | path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA")) | ||
294 | if appname: | ||
295 | if appauthor is not False: | ||
296 | path = os.path.join(path, appauthor, appname) | ||
297 | else: | ||
298 | path = os.path.join(path, appname) | ||
299 | if opinion: | ||
300 | path = os.path.join(path, "Cache") | ||
301 | elif system == 'darwin': | ||
302 | path = os.path.expanduser('~/Library/Caches') | ||
303 | if appname: | ||
304 | path = os.path.join(path, appname) | ||
305 | else: | ||
306 | path = os.getenv('XDG_CACHE_HOME', os.path.expanduser('~/.cache')) | ||
307 | if appname: | ||
308 | path = os.path.join(path, appname) | ||
309 | if appname and version: | ||
310 | path = os.path.join(path, version) | ||
311 | return path | ||
312 | |||
313 | |||
314 | def user_state_dir(appname=None, appauthor=None, version=None, roaming=False): | ||
315 | r"""Return full path to the user-specific state dir for this application. | ||
316 | |||
317 | "appname" is the name of application. | ||
318 | If None, just the system directory is returned. | ||
319 | "appauthor" (only used on Windows) is the name of the | ||
320 | appauthor or distributing body for this application. Typically | ||
321 | it is the owning company name. This falls back to appname. You may | ||
322 | pass False to disable it. | ||
323 | "version" is an optional version path element to append to the | ||
324 | path. You might want to use this if you want multiple versions | ||
325 | of your app to be able to run independently. If used, this | ||
326 | would typically be "<major>.<minor>". | ||
327 | Only applied when appname is present. | ||
328 | "roaming" (boolean, default False) can be set True to use the Windows | ||
329 | roaming appdata directory. That means that for users on a Windows | ||
330 | network setup for roaming profiles, this user data will be | ||
331 | sync'd on login. See | ||
332 | <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> | ||
333 | for a discussion of issues. | ||
334 | |||
335 | Typical user state directories are: | ||
336 | Mac OS X: same as user_data_dir | ||
337 | Unix: ~/.local/state/<AppName> # or in $XDG_STATE_HOME, if defined | ||
338 | Win *: same as user_data_dir | ||
339 | |||
340 | For Unix, we follow this Debian proposal <https://wiki.debian.org/XDGBaseDirectorySpecification#state> | ||
341 | to extend the XDG spec and support $XDG_STATE_HOME. | ||
342 | |||
343 | That means, by default "~/.local/state/<AppName>". | ||
344 | """ | ||
345 | if system in ["win32", "darwin"]: | ||
346 | path = user_data_dir(appname, appauthor, None, roaming) | ||
347 | else: | ||
348 | path = os.getenv('XDG_STATE_HOME', os.path.expanduser("~/.local/state")) | ||
349 | if appname: | ||
350 | path = os.path.join(path, appname) | ||
351 | if appname and version: | ||
352 | path = os.path.join(path, version) | ||
353 | return path | ||
354 | |||
355 | |||
356 | def user_log_dir(appname=None, appauthor=None, version=None, opinion=True): | ||
357 | r"""Return full path to the user-specific log dir for this application. | ||
358 | |||
359 | "appname" is the name of application. | ||
360 | If None, just the system directory is returned. | ||
361 | "appauthor" (only used on Windows) is the name of the | ||
362 | appauthor or distributing body for this application. Typically | ||
363 | it is the owning company name. This falls back to appname. You may | ||
364 | pass False to disable it. | ||
365 | "version" is an optional version path element to append to the | ||
366 | path. You might want to use this if you want multiple versions | ||
367 | of your app to be able to run independently. If used, this | ||
368 | would typically be "<major>.<minor>". | ||
369 | Only applied when appname is present. | ||
370 | "opinion" (boolean) can be False to disable the appending of | ||
371 | "Logs" to the base app data dir for Windows, and "log" to the | ||
372 | base cache dir for Unix. See discussion below. | ||
373 | |||
374 | Typical user log directories are: | ||
375 | Mac OS X: ~/Library/Logs/<AppName> | ||
376 | Unix: ~/.cache/<AppName>/log # or under $XDG_CACHE_HOME if defined | ||
377 | Win XP: C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>\Logs | ||
378 | Vista: C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>\Logs | ||
379 | |||
380 | On Windows the only suggestion in the MSDN docs is that local settings | ||
381 | go in the `CSIDL_LOCAL_APPDATA` directory. (Note: I'm interested in | ||
382 | examples of what some windows apps use for a logs dir.) | ||
383 | |||
384 | OPINION: This function appends "Logs" to the `CSIDL_LOCAL_APPDATA` | ||
385 | value for Windows and appends "log" to the user cache dir for Unix. | ||
386 | This can be disabled with the `opinion=False` option. | ||
387 | """ | ||
388 | if system == "darwin": | ||
389 | path = os.path.join( | ||
390 | os.path.expanduser('~/Library/Logs'), | ||
391 | appname) | ||
392 | elif system == "win32": | ||
393 | path = user_data_dir(appname, appauthor, version) | ||
394 | version = False | ||
395 | if opinion: | ||
396 | path = os.path.join(path, "Logs") | ||
397 | else: | ||
398 | path = user_cache_dir(appname, appauthor, version) | ||
399 | version = False | ||
400 | if opinion: | ||
401 | path = os.path.join(path, "log") | ||
402 | if appname and version: | ||
403 | path = os.path.join(path, version) | ||
404 | return path | ||
405 | |||
406 | |||
407 | class AppDirs(object): | ||
408 | """Convenience wrapper for getting application dirs.""" | ||
409 | def __init__(self, appname=None, appauthor=None, version=None, | ||
410 | roaming=False, multipath=False): | ||
411 | self.appname = appname | ||
412 | self.appauthor = appauthor | ||
413 | self.version = version | ||
414 | self.roaming = roaming | ||
415 | self.multipath = multipath | ||
416 | |||
417 | @property | ||
418 | def user_data_dir(self): | ||
419 | return user_data_dir(self.appname, self.appauthor, | ||
420 | version=self.version, roaming=self.roaming) | ||
421 | |||
422 | @property | ||
423 | def site_data_dir(self): | ||
424 | return site_data_dir(self.appname, self.appauthor, | ||
425 | version=self.version, multipath=self.multipath) | ||
426 | |||
427 | @property | ||
428 | def user_config_dir(self): | ||
429 | return user_config_dir(self.appname, self.appauthor, | ||
430 | version=self.version, roaming=self.roaming) | ||
431 | |||
432 | @property | ||
433 | def site_config_dir(self): | ||
434 | return site_config_dir(self.appname, self.appauthor, | ||
435 | version=self.version, multipath=self.multipath) | ||
436 | |||
437 | @property | ||
438 | def user_cache_dir(self): | ||
439 | return user_cache_dir(self.appname, self.appauthor, | ||
440 | version=self.version) | ||
441 | |||
442 | @property | ||
443 | def user_state_dir(self): | ||
444 | return user_state_dir(self.appname, self.appauthor, | ||
445 | version=self.version) | ||
446 | |||
447 | @property | ||
448 | def user_log_dir(self): | ||
449 | return user_log_dir(self.appname, self.appauthor, | ||
450 | version=self.version) | ||
451 | |||
452 | |||
453 | #---- internal support stuff | ||
454 | |||
455 | def _get_win_folder_from_registry(csidl_name): | ||
456 | """This is a fallback technique at best. I'm not sure if using the | ||
457 | registry for this guarantees us the correct answer for all CSIDL_* | ||
458 | names. | ||
459 | """ | ||
460 | if PY3: | ||
461 | import winreg as _winreg | ||
462 | else: | ||
463 | import _winreg | ||
464 | |||
465 | shell_folder_name = { | ||
466 | "CSIDL_APPDATA": "AppData", | ||
467 | "CSIDL_COMMON_APPDATA": "Common AppData", | ||
468 | "CSIDL_LOCAL_APPDATA": "Local AppData", | ||
469 | }[csidl_name] | ||
470 | |||
471 | key = _winreg.OpenKey( | ||
472 | _winreg.HKEY_CURRENT_USER, | ||
473 | r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" | ||
474 | ) | ||
475 | dir, type = _winreg.QueryValueEx(key, shell_folder_name) | ||
476 | return dir | ||
477 | |||
478 | |||
479 | def _get_win_folder_with_pywin32(csidl_name): | ||
480 | from win32com.shell import shellcon, shell | ||
481 | dir = shell.SHGetFolderPath(0, getattr(shellcon, csidl_name), 0, 0) | ||
482 | # Try to make this a unicode path because SHGetFolderPath does | ||
483 | # not return unicode strings when there is unicode data in the | ||
484 | # path. | ||
485 | try: | ||
486 | dir = unicode(dir) | ||
487 | |||
488 | # Downgrade to short path name if have highbit chars. See | ||
489 | # <http://bugs.activestate.com/show_bug.cgi?id=85099>. | ||
490 | has_high_char = False | ||
491 | for c in dir: | ||
492 | if ord(c) > 255: | ||
493 | has_high_char = True | ||
494 | break | ||
495 | if has_high_char: | ||
496 | try: | ||
497 | import win32api | ||
498 | dir = win32api.GetShortPathName(dir) | ||
499 | except ImportError: | ||
500 | pass | ||
501 | except UnicodeError: | ||
502 | pass | ||
503 | return dir | ||
504 | |||
505 | |||
506 | def _get_win_folder_with_ctypes(csidl_name): | ||
507 | import ctypes | ||
508 | |||
509 | csidl_const = { | ||
510 | "CSIDL_APPDATA": 26, | ||
511 | "CSIDL_COMMON_APPDATA": 35, | ||
512 | "CSIDL_LOCAL_APPDATA": 28, | ||
513 | }[csidl_name] | ||
514 | |||
515 | buf = ctypes.create_unicode_buffer(1024) | ||
516 | ctypes.windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf) | ||
517 | |||
518 | # Downgrade to short path name if have highbit chars. See | ||
519 | # <http://bugs.activestate.com/show_bug.cgi?id=85099>. | ||
520 | has_high_char = False | ||
521 | for c in buf: | ||
522 | if ord(c) > 255: | ||
523 | has_high_char = True | ||
524 | break | ||
525 | if has_high_char: | ||
526 | buf2 = ctypes.create_unicode_buffer(1024) | ||
527 | if ctypes.windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024): | ||
528 | buf = buf2 | ||
529 | |||
530 | return buf.value | ||
531 | |||
532 | def _get_win_folder_with_jna(csidl_name): | ||
533 | import array | ||
534 | from com.sun import jna | ||
535 | from com.sun.jna.platform import win32 | ||
536 | |||
537 | buf_size = win32.WinDef.MAX_PATH * 2 | ||
538 | buf = array.zeros('c', buf_size) | ||
539 | shell = win32.Shell32.INSTANCE | ||
540 | shell.SHGetFolderPath(None, getattr(win32.ShlObj, csidl_name), None, win32.ShlObj.SHGFP_TYPE_CURRENT, buf) | ||
541 | dir = jna.Native.toString(buf.tostring()).rstrip("\0") | ||
542 | |||
543 | # Downgrade to short path name if have highbit chars. See | ||
544 | # <http://bugs.activestate.com/show_bug.cgi?id=85099>. | ||
545 | has_high_char = False | ||
546 | for c in dir: | ||
547 | if ord(c) > 255: | ||
548 | has_high_char = True | ||
549 | break | ||
550 | if has_high_char: | ||
551 | buf = array.zeros('c', buf_size) | ||
552 | kernel = win32.Kernel32.INSTANCE | ||
553 | if kernel.GetShortPathName(dir, buf, buf_size): | ||
554 | dir = jna.Native.toString(buf.tostring()).rstrip("\0") | ||
555 | |||
556 | return dir | ||
557 | |||
558 | if system == "win32": | ||
559 | try: | ||
560 | from ctypes import windll | ||
561 | _get_win_folder = _get_win_folder_with_ctypes | ||
562 | except ImportError: | ||
563 | try: | ||
564 | import com.sun.jna | ||
565 | _get_win_folder = _get_win_folder_with_jna | ||
566 | except ImportError: | ||
567 | _get_win_folder = _get_win_folder_from_registry | ||
568 | |||
569 | |||
570 | #---- self test code | ||
571 | |||
572 | if __name__ == "__main__": | ||
573 | appname = "MyApp" | ||
574 | appauthor = "MyCompany" | ||
575 | |||
576 | props = ("user_data_dir", | ||
577 | "user_config_dir", | ||
578 | "user_cache_dir", | ||
579 | "user_state_dir", | ||
580 | "user_log_dir", | ||
581 | "site_data_dir", | ||
582 | "site_config_dir") | ||
583 | |||
584 | print("-- app dirs %s --" % __version__) | ||
585 | |||
586 | print("-- app dirs (with optional 'version')") | ||
587 | dirs = AppDirs(appname, appauthor, version="1.0") | ||
588 | for prop in props: | ||
589 | print("%s: %s" % (prop, getattr(dirs, prop))) | ||
590 | |||
591 | print("\n-- app dirs (without optional 'version')") | ||
592 | dirs = AppDirs(appname, appauthor) | ||
593 | for prop in props: | ||
594 | print("%s: %s" % (prop, getattr(dirs, prop))) | ||
595 | |||
596 | print("\n-- app dirs (without optional 'appauthor')") | ||
597 | dirs = AppDirs(appname) | ||
598 | for prop in props: | ||
599 | print("%s: %s" % (prop, getattr(dirs, prop))) | ||
600 | |||
601 | print("\n-- app dirs (with disabled 'appauthor')") | ||
602 | dirs = AppDirs(appname, appauthor=False) | ||
603 | for prop in props: | ||
604 | print("%s: %s" % (prop, getattr(dirs, prop))) | ||