Update appdirs.py

This commit is contained in:
Florian Bruhin 2014-04-22 12:07:57 +02:00
parent ce274aa9c8
commit 9b5cf6ee7d

View File

@ -13,13 +13,19 @@ See <http://github.com/ActiveState/appdirs> for details and usage.
# - Mac OS X: http://developer.apple.com/documentation/MacOSX/Conceptual/BPFileSystem/index.html # - Mac OS X: http://developer.apple.com/documentation/MacOSX/Conceptual/BPFileSystem/index.html
# - XDG spec for Un*x: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html # - XDG spec for Un*x: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
__version_info__ = (1, 3, 0) __version_info__ = (1, 4, 0)
__version__ = '.'.join(map(str, __version_info__)) __version__ = '.'.join(map(str, __version_info__))
import sys import sys
import os import os
PY3 = sys.version_info[0] == 3
if PY3:
unicode = str
def user_data_dir(appname=None, appauthor=None, version=None, roaming=False): def user_data_dir(appname=None, appauthor=None, version=None, roaming=False):
r"""Return full path to the user-specific data dir for this application. r"""Return full path to the user-specific data dir for this application.
@ -115,12 +121,12 @@ def site_data_dir(appname=None, appauthor=None, version=None, multipath=False):
# XDG default for $XDG_DATA_DIRS # XDG default for $XDG_DATA_DIRS
# only first, if multipath is False # only first, if multipath is False
path = os.getenv('XDG_DATA_DIRS', path = os.getenv('XDG_DATA_DIRS',
os.pathsep.join(['/usr/local/share', '/usr/share'])) os.pathsep.join(['/usr/local/share', '/usr/share']))
pathlist = [ os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep) ] pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)]
if appname: if appname:
if version: if version:
appname = os.path.join(appname, version) appname = os.path.join(appname, version)
pathlist = [ os.sep.join([x, appname]) for x in pathlist ] pathlist = [os.sep.join([x, appname]) for x in pathlist]
if multipath: if multipath:
path = os.pathsep.join(pathlist) path = os.pathsep.join(pathlist)
@ -161,7 +167,7 @@ def user_config_dir(appname=None, appauthor=None, version=None, roaming=False):
For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME. For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME.
That means, by deafult "~/.config/<AppName>". That means, by deafult "~/.config/<AppName>".
""" """
if sys.platform in [ "win32", "darwin" ]: if sys.platform in ["win32", "darwin"]:
path = user_data_dir(appname, appauthor, None, roaming) path = user_data_dir(appname, appauthor, None, roaming)
else: else:
path = os.getenv('XDG_CONFIG_HOME', os.path.expanduser("~/.config")) path = os.getenv('XDG_CONFIG_HOME', os.path.expanduser("~/.config"))
@ -201,7 +207,7 @@ def site_config_dir(appname=None, appauthor=None, version=None, multipath=False)
WARNING: Do not use this on Windows. See the Vista-Fail note above for why. WARNING: Do not use this on Windows. See the Vista-Fail note above for why.
""" """
if sys.platform in [ "win32", "darwin" ]: if sys.platform in ["win32", "darwin"]:
path = site_data_dir(appname, appauthor) path = site_data_dir(appname, appauthor)
if appname and version: if appname and version:
path = os.path.join(path, version) path = os.path.join(path, version)
@ -209,11 +215,11 @@ def site_config_dir(appname=None, appauthor=None, version=None, multipath=False)
# XDG default for $XDG_CONFIG_DIRS # XDG default for $XDG_CONFIG_DIRS
# only first, if multipath is False # only first, if multipath is False
path = os.getenv('XDG_CONFIG_DIRS', '/etc/xdg') path = os.getenv('XDG_CONFIG_DIRS', '/etc/xdg')
pathlist = [ os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep) ] pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)]
if appname: if appname:
if version: if version:
appname = os.path.join(appname, version) appname = os.path.join(appname, version)
pathlist = [ os.sep.join([x, appname]) for x in pathlist ] pathlist = [os.sep.join([x, appname]) for x in pathlist]
if multipath: if multipath:
path = os.pathsep.join(pathlist) path = os.pathsep.join(pathlist)
@ -221,6 +227,7 @@ def site_config_dir(appname=None, appauthor=None, version=None, multipath=False)
path = pathlist[0] path = pathlist[0]
return path return path
def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True): def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True):
r"""Return full path to the user-specific cache dir for this application. r"""Return full path to the user-specific cache dir for this application.
@ -273,6 +280,7 @@ def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True):
path = os.path.join(path, version) path = os.path.join(path, version)
return path return path
def user_log_dir(appname=None, appauthor=None, version=None, opinion=True): def user_log_dir(appname=None, appauthor=None, version=None, opinion=True):
r"""Return full path to the user-specific log dir for this application. r"""Return full path to the user-specific log dir for this application.
@ -309,11 +317,13 @@ def user_log_dir(appname=None, appauthor=None, version=None, opinion=True):
os.path.expanduser('~/Library/Logs'), os.path.expanduser('~/Library/Logs'),
appname) appname)
elif sys.platform == "win32": elif sys.platform == "win32":
path = user_data_dir(appname, appauthor, version); version=False path = user_data_dir(appname, appauthor, version)
version = False
if opinion: if opinion:
path = os.path.join(path, "Logs") path = os.path.join(path, "Logs")
else: else:
path = user_cache_dir(appname, appauthor, version); version=False path = user_cache_dir(appname, appauthor, version)
version = False
if opinion: if opinion:
path = os.path.join(path, "log") path = os.path.join(path, "log")
if appname and version: if appname and version:
@ -323,39 +333,43 @@ def user_log_dir(appname=None, appauthor=None, version=None, opinion=True):
class AppDirs(object): class AppDirs(object):
"""Convenience wrapper for getting application dirs.""" """Convenience wrapper for getting application dirs."""
def __init__(self, appname, appauthor=None, version=None, def __init__(self, appname, appauthor=None, version=None, roaming=False,
roaming=False, multipath=False): multipath=False):
self.appname = appname self.appname = appname
self.appauthor = appauthor self.appauthor = appauthor
self.version = version self.version = version
self.roaming = roaming self.roaming = roaming
self.multipath = multipath self.multipath = multipath
@property @property
def user_data_dir(self): def user_data_dir(self):
return user_data_dir(self.appname, self.appauthor, return user_data_dir(self.appname, self.appauthor,
version=self.version, roaming=self.roaming) version=self.version, roaming=self.roaming)
@property @property
def site_data_dir(self): def site_data_dir(self):
return site_data_dir(self.appname, self.appauthor, return site_data_dir(self.appname, self.appauthor,
version=self.version, multipath=self.multipath) version=self.version, multipath=self.multipath)
@property @property
def user_config_dir(self): def user_config_dir(self):
return user_config_dir(self.appname, self.appauthor, return user_config_dir(self.appname, self.appauthor,
version=self.version, roaming=self.roaming) version=self.version, roaming=self.roaming)
@property @property
def site_config_dir(self): def site_config_dir(self):
return site_data_dir(self.appname, self.appauthor, return site_data_dir(self.appname, self.appauthor,
version=self.version, multipath=self.multipath) version=self.version, multipath=self.multipath)
@property @property
def user_cache_dir(self): def user_cache_dir(self):
return user_cache_dir(self.appname, self.appauthor, return user_cache_dir(self.appname, self.appauthor,
version=self.version) version=self.version)
@property @property
def user_log_dir(self): def user_log_dir(self):
return user_log_dir(self.appname, self.appauthor, return user_log_dir(self.appname, self.appauthor,
version=self.version) version=self.version)
#---- internal support stuff #---- internal support stuff
@ -365,7 +379,10 @@ def _get_win_folder_from_registry(csidl_name):
registry for this guarantees us the correct answer for all CSIDL_* registry for this guarantees us the correct answer for all CSIDL_*
names. names.
""" """
import winreg if PY3:
import winreg as _winreg
else:
import _winreg
shell_folder_name = { shell_folder_name = {
"CSIDL_APPDATA": "AppData", "CSIDL_APPDATA": "AppData",
@ -373,11 +390,14 @@ def _get_win_folder_from_registry(csidl_name):
"CSIDL_LOCAL_APPDATA": "Local AppData", "CSIDL_LOCAL_APPDATA": "Local AppData",
}[csidl_name] }[csidl_name]
key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, key = _winreg.OpenKey(
r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders") _winreg.HKEY_CURRENT_USER,
dir, type = winreg.QueryValueEx(key, shell_folder_name) r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
)
dir, type = _winreg.QueryValueEx(key, shell_folder_name)
return dir return dir
def _get_win_folder_with_pywin32(csidl_name): def _get_win_folder_with_pywin32(csidl_name):
from win32com.shell import shellcon, shell from win32com.shell import shellcon, shell
dir = shell.SHGetFolderPath(0, getattr(shellcon, csidl_name), 0, 0) dir = shell.SHGetFolderPath(0, getattr(shellcon, csidl_name), 0, 0)
@ -385,7 +405,7 @@ def _get_win_folder_with_pywin32(csidl_name):
# not return unicode strings when there is unicode data in the # not return unicode strings when there is unicode data in the
# path. # path.
try: try:
dir = str(dir) dir = unicode(dir)
# Downgrade to short path name if have highbit chars. See # Downgrade to short path name if have highbit chars. See
# <http://bugs.activestate.com/show_bug.cgi?id=85099>. # <http://bugs.activestate.com/show_bug.cgi?id=85099>.
@ -404,6 +424,7 @@ def _get_win_folder_with_pywin32(csidl_name):
pass pass
return dir return dir
def _get_win_folder_with_ctypes(csidl_name): def _get_win_folder_with_ctypes(csidl_name):
import ctypes import ctypes
@ -442,7 +463,6 @@ if sys.platform == "win32":
_get_win_folder = _get_win_folder_from_registry _get_win_folder = _get_win_folder_from_registry
#---- self test code #---- self test code
if __name__ == "__main__": if __name__ == "__main__":
@ -456,15 +476,14 @@ if __name__ == "__main__":
print("-- app dirs (with optional 'version')") print("-- app dirs (with optional 'version')")
dirs = AppDirs(appname, appauthor, version="1.0") dirs = AppDirs(appname, appauthor, version="1.0")
for prop in props: for prop in props:
print(("%s: %s" % (prop, getattr(dirs, prop)))) print("%s: %s" % (prop, getattr(dirs, prop)))
print("\n-- app dirs (without optional 'version')") print("\n-- app dirs (without optional 'version')")
dirs = AppDirs(appname, appauthor) dirs = AppDirs(appname, appauthor)
for prop in props: for prop in props:
print(("%s: %s" % (prop, getattr(dirs, prop)))) print("%s: %s" % (prop, getattr(dirs, prop)))
print("\n-- app dirs (without optional 'appauthor')") print("\n-- app dirs (without optional 'appauthor')")
dirs = AppDirs(appname) dirs = AppDirs(appname)
for prop in props: for prop in props:
print(("%s: %s" % (prop, getattr(dirs, prop)))) print("%s: %s" % (prop, getattr(dirs, prop)))