/opt/imh-python/lib/python3.9/site-packages
NameSizeModeActions
amqp/-0755rm
amqp-5.3.1.dist-info/-0755rm
apache_libcloud-3.1.0.dist-info/-0755rm
appdirs-1.4.4.dist-info/-0755rm
apscheduler/-0755rm
APScheduler-3.11.0.dist-info/-0755rm
arrow/-0755rm
arrow-1.2.3.dist-info/-0755rm
astroid/-0755rm
astroid-3.3.9.dist-info/-0755rm
asttokens/-0755rm
asttokens-3.0.0.dist-info/-0755rm
attr/-0755rm
attrs/-0755rm
attrs-25.3.0.dist-info/-0755rm
autocommand/-0755rm
autocommand-2.2.2.dist-info/-0755rm
automat/-0755rm
automat-25.4.16.dist-info/-0755rm
backports/-0755rm
backports.tarfile-1.2.0.dist-info/-0755rm
bakauth/-0755rm
bakauth-1.6.2.dist-info/-0755rm
bcrypt/-0755rm
bcrypt-3.2.2.dist-info/-0755rm
billiard/-0755rm
billiard-4.2.1.dist-info/-0755rm
blessings/-0755rm
blessings-1.7.dist-info/-0755rm
boto3/-0755rm
boto3-1.16.63.dist-info/-0755rm
botocore/-0755rm
botocore-1.19.63.dist-info/-0755rm
celery/-0755rm
celery-5.4.0.dist-info/-0755rm
certifi/-0755rm
certifi-2025.4.26.dist-info/-0755rm
cffi/-0755rm
cffi-1.17.1.dist-info/-0755rm
chardet/-0755rm
chardet-3.0.4.dist-info/-0755rm
cheroot/-0755rm
cheroot-10.0.1.dist-info/-0755rm
cherrypy/-0755rm
CherryPy-18.6.1.dist-info/-0755rm
cinderclient/-0755rm
click/-0755rm
click-8.1.8.dist-info/-0755rm
click_didyoumean/-0755rm
click_didyoumean-0.3.1.dist-info/-0755rm
click_plugins/-0755rm
click_plugins-1.1.1.dist-info/-0755rm
click_repl/-0755rm
click_repl-0.3.0.dist-info/-0755rm
constantly/-0755rm
constantly-23.10.4.dist-info/-0755rm
construct/-0755rm
construct-2.10.70.dist-info/-0755rm
cpapis/-0755rm
cpapis-1.0.dist-info/-0755rm
cproc/-0755rm
cproc-1.0.dist-info/-0755rm
croniter/-0755rm
croniter-2.0.1.dist-info/-0755rm
crossplane/-0755rm
crossplane-0.5.8.dist-info/-0755rm
Crypto/-0755rm
Cryptodome/-0755rm
cryptography/-0755rm
cryptography-36.0.2.dist-info/-0755rm
cwp/-0755rm
cwp-0.1.2.dist-info/-0755rm
dateutil/-0755rm
debtcollector/-0755rm
debtcollector-3.0.0.dist-info/-0755rm
decorator-5.2.1.dist-info/-0755rm
dill/-0755rm
dill-0.4.0.dist-info/-0755rm
distro/-0755rm
distro-1.9.0.dist-info/-0755rm
dns/-0755rm
dnspython-2.7.0.dist-info/-0755rm
dogpile/-0755rm
dogpile_cache-1.4.0.dist-info/-0755rm
exceptiongroup/-0755rm
exceptiongroup-1.2.2.dist-info/-0755rm
executing/-0755rm
executing-2.2.0.dist-info/-0755rm
fabric/-0755rm
fab_classic-1.19.1.dist-info/-0755rm
flask/-0755rm
Flask-1.1.2.dist-info/-0755rm
flask_apscheduler/-0755rm
Flask_APScheduler-1.11.0.dist-info/-0755rm
flask_redis/-0755rm
flask_redis-0.4.0.dist-info/-0755rm
flask_sqlalchemy/-0755rm
Flask_SQLAlchemy-2.4.4.dist-info/-0755rm
future/-0755rm
future-1.0.0.dist-info/-0755rm
gunicorn/-0755rm
gunicorn-20.0.4.dist-info/-0755rm
hyperlink/-0755rm
hyperlink-21.0.0.dist-info/-0755rm
idna/-0755rm
idna-2.10.dist-info/-0755rm
importlib_metadata/-0755rm
importlib_metadata-4.13.0.dist-info/-0755rm
incremental/-0755rm
incremental-22.10.0.dist-info/-0755rm
influxdb/-0755rm
influxdb-5.3.2.dist-info/-0755rm
IPython/-0755rm
ipython-8.18.1.dist-info/-0755rm
iso8601/-0755rm
iso8601-2.1.0.dist-info/-0755rm
isort/-0755rm
isort-6.0.1.dist-info/-0755rm
itsdangerous/-0755rm
itsdangerous-1.1.0.dist-info/-0755rm
jaraco/-0755rm
jaraco.collections-5.1.0.dist-info/-0755rm
jaraco.context-6.0.1.dist-info/-0755rm
jaraco.functools-4.1.0.dist-info/-0755rm
jaraco.text-4.0.0.dist-info/-0755rm
jedi/-0755rm
jedi-0.19.2.dist-info/-0755rm
jinja2/-0755rm
Jinja2-2.11.3.dist-info/-0755rm
jmespath/-0755rm
jmespath-0.10.0.dist-info/-0755rm
jsonpatch-1.33.dist-info/-0755rm
jsonpointer-3.0.0.dist-info/-0755rm
keystoneauth1/-0755rm
keystoneauth1-5.10.0.dist-info/-0755rm
kombu/-0755rm
kombu-5.5.3.dist-info/-0755rm
ldap/-0755rm
libcloud/-0755rm
libfuturize/-0755rm
libpasteurize/-0755rm
markupsafe/-0755rm
MarkupSafe-1.1.1.dist-info/-0755rm
matplotlib_inline/-0755rm
matplotlib_inline-0.1.7.dist-info/-0755rm
mccabe-0.7.0.dist-info/-0755rm
mdstat/-0755rm
mdstat-1.0.4.dist-info/-0755rm
meld3/-0755rm
meld3-2.0.1.dist-info/-0755rm
more_itertools/-0755rm
more_itertools-10.7.0.dist-info/-0755rm
msgpack/-0755rm
msgpack-0.6.1.dist-info/-0755rm
mtrlib/-0755rm
mtrlib-1.2.0.dist-info/-0755rm
munch/-0755rm
munch-4.0.0.dist-info/-0755rm
nacl/-0755rm
netaddr/-0755rm
netaddr-0.8.0.dist-info/-0755rm
netifaces-0.10.9.dist-info/-0755rm
netmiko/-0755rm
netmiko-3.4.0.dist-info/-0755rm
ntc_templates/-0755rm
ntc_templates-7.8.0.dist-info/-0755rm
numpy/-0755rm
numpy-1.26.0.dist-info/-0755rm
numpy.libs/-0755rm
OpenSSL/-0755rm
openstack/-0755rm
openstacksdk-0.49.0.dist-info/-0755rm
oslo.i18n-6.5.1.dist-info/-0755rm
oslo.utils-7.1.0.dist-info/-0755rm
oslo_i18n/-0755rm
oslo_utils/-0755rm
os_client_config/-0755rm
os_client_config-2.1.0.dist-info/-0755rm
os_service_types/-0755rm
os_service_types-1.7.0.dist-info/-0755rm
packaging/-0755rm
packaging-25.0.dist-info/-0755rm
paramiko/-0755rm
paramiko-3.5.1.dist-info/-0755rm
parso/-0755rm
parso-0.8.4.dist-info/-0755rm
past/-0755rm
pbr/-0755rm
pbr-6.1.1.dist-info/-0755rm
pem/-0755rm
pem-20.1.0.dist-info/-0755rm
pexpect/-0755rm
pexpect-4.9.0.dist-info/-0755rm
picotui/-0755rm
picotui-1.2.dist-info/-0755rm
pip/-0755rm
pip-25.1.1.dist-info/-0755rm
pkg_resources/-0755rm
platformdirs/-0755rm
platformdirs-4.3.7.dist-info/-0755rm
portend-3.2.0.dist-info/-0755rm
pp_api/-0755rm
pp_api-1.3.1.dist-info/-0755rm
pr2modules/-0755rm
prettytable-0.7.2.dist-info/-0755rm
prometheus_client/-0755rm
prometheus_client-0.14.1.dist-info/-0755rm
prompt_toolkit/-0755rm
prompt_toolkit-3.0.51.dist-info/-0755rm
psutil/-0755rm
psutil-5.7.3.dist-info/-0755rm
psycopg2/-0755rm
psycopg2-2.8.6.dist-info/-0755rm
ptyprocess/-0755rm
ptyprocess-0.7.0.dist-info/-0755rm
pure_eval/-0755rm
pure_eval-0.2.3.dist-info/-0755rm
pyasn1/-0755rm
pyasn1-0.6.1.dist-info/-0755rm
pyasn1_modules/-0755rm
pyasn1_modules-0.4.2.dist-info/-0755rm
pycparser/-0755rm
pycparser-2.22.dist-info/-0755rm
pycryptodome-3.9.9.dist-info/-0755rm
pycryptodomex-3.9.9.dist-info/-0755rm
pyeapi/-0755rm
pyeapi-0.8.4.dist-info/-0755rm
pygit2/-0755rm
pygit2-1.6.1.dist-info/-0755rm
pygit2.libs/-0755rm
pygments/-0755rm
pygments-2.19.1.dist-info/-0755rm
pygraph/-0755rm
PyGraph-0.3.0.dist-info/-0755rm
pyipmi/-0755rm
pylint/-0755rm
pylint-3.3.7.dist-info/-0755rm
pymysql/-0755rm
PyMySQL-1.0.3.dist-info/-0755rm
PyNaCl-1.5.0.dist-info/-0755rm
pynetbox/-0755rm
pynetbox-6.5.0.dist-info/-0755rm
pyOpenSSL-19.1.0.dist-info/-0755rm
pyparsing/-0755rm
pyparsing-3.2.3.dist-info/-0755rm
pyroute2/-0755rm
pyroute2-0.7.12.dist-info/-0755rm
pyserial-3.5.dist-info/-0755rm
pysparklines-1.4.dist-info/-0755rm
python_cinderclient-7.1.0.dist-info/-0755rm
python_crontab-2.7.1.dist-info/-0755rm
python_dateutil-2.9.0.post0.dist-info/-0755rm
python_ipmi-0.5.7.dist-info/-0755rm
python_ldap-3.3.1.dist-info/-0755rm
python_whois-0.7.3.dist-info/-0755rm
pytz/-0755rm
pytz-2025.2.dist-info/-0755rm
pyudev/-0755rm
pyudev-0.23.2.dist-info/-0755rm
PyYAML-5.4.1.dist-info/-0755rm
pyzmq-19.0.2.dist-info/-0755rm
pyzmq.libs/-0755rm
rads/-0755rm
rads-4.1.0.dist-info/-0755rm
redis/-0755rm
redis-3.5.3.dist-info/-0755rm
requests/-0755rm
requests-2.24.0.dist-info/-0755rm
requestsexceptions/-0755rm
requestsexceptions-1.4.0.dist-info/-0755rm
restic/-0755rm
restic-1.3.5.dist-info/-0755rm
s3transfer/-0755rm
s3transfer-0.3.7.dist-info/-0755rm
scp-0.15.0.dist-info/-0755rm
serial/-0755rm
service_identity/-0755rm
service_identity-23.1.0.dist-info/-0755rm
setproctitle-1.1.10.dist-info/-0755rm
setuptools/-0755rm
setuptools-57.0.0.dist-info/-0755rm
simplejson/-0755rm
simplejson-3.20.1.dist-info/-0755rm
six-1.17.0.dist-info/-0755rm
slapdtest/-0755rm
sparkline/-0755rm
sqlalchemy/-0755rm
SQLAlchemy-1.3.24.dist-info/-0755rm
stack_data/-0755rm
stack_data-0.6.3.dist-info/-0755rm
stevedore/-0755rm
stevedore-5.4.1.dist-info/-0755rm
tabulate-0.8.10.dist-info/-0755rm
tailer/-0755rm
tailer-0.4.1.dist-info/-0755rm
tempora/-0755rm
tempora-5.8.0.dist-info/-0755rm
tenacity/-0755rm
tenacity-9.1.2.dist-info/-0755rm
test/-0755rm
testdata/-0755rm
tests/-0755rm
textfsm/-0755rm
textfsm-1.1.3.dist-info/-0755rm
toml/-0755rm
toml-0.10.2.dist-info/-0755rm
tomli/-0755rm
tomli-2.2.1.dist-info/-0755rm
tomlkit/-0755rm
tomlkit-0.13.2.dist-info/-0755rm
tornado/-0755rm
tornado-6.0.4.dist-info/-0755rm
traitlets/-0755rm
traitlets-5.14.3.dist-info/-0755rm
twisted/-0755rm
Twisted-22.4.0.dist-info/-0755rm
typing_extensions-4.13.2.dist-info/-0755rm
tzdata/-0755rm
tzdata-2025.2.dist-info/-0755rm
tzlocal/-0755rm
tzlocal-5.3.1.dist-info/-0755rm
untangle-1.1.1.dist-info/-0755rm
urllib3/-0755rm
urllib3-1.25.11.dist-info/-0755rm
uWSGI-2.0.19.1.dist-info/-0755rm
version_utils/-0755rm
version_utils-0.3.2.dist-info/-0755rm
vine/-0755rm
vine-5.1.0.dist-info/-0755rm
wcwidth/-0755rm
wcwidth-0.2.13.dist-info/-0755rm
werkzeug/-0755rm
Werkzeug-2.0.3.dist-info/-0755rm
wheel/-0755rm
wheel-0.45.1.dist-info/-0755rm
whois/-0755rm
wrapt/-0755rm
wrapt-1.17.2.dist-info/-0755rm
yaml/-0755rm
zc/-0755rm
zc.lockfile-3.0.post1.dist-info/-0755rm
zipp/-0755rm
zipp-3.21.0.dist-info/-0755rm
zmq/-0755rm
zope/-0755rm
zope.interface-7.2.dist-info/-0755rm
_distutils_hack/-0755rm
_yaml/-0755rm
__pycache__/-0755rm
appdirs.py247200644editdlrm
cronlog.py37730644editdlrm
crontab.py468620644editdlrm
crontabs.py44380644editdlrm
decorator.py170670644editdlrm
distutils-precedence.pth1520644editdlrm
jsonpatch.py297780644editdlrm
jsonpointer.py106010644editdlrm
ldapurl.py125250644editdlrm
ldif.py202780644editdlrm
LICENSE6010644editdlrm
mccabe.py106540644editdlrm
netifaces.cpython-39-x86_64-linux-gnu.so245840755editdlrm
portend.py64880644editdlrm
prettytable.py542040644editdlrm
README.md31800644editdlrm
README.txt1190644editdlrm
scp.py223930644editdlrm
setproctitle.cpython-39-x86_64-linux-gnu.so239520755editdlrm
six.py347030644editdlrm
tabulate.py738890644editdlrm
typing_extensions.py1726540644editdlrm
untangle.py55350644editdlrm
uwsgidecorators.py103920644editdlrm
zc.lockfile-3.0.post1-py3.9-nspkg.pth5190644editdlrm
zope.interface-7.2-py3.9-nspkg.pth4570644editdlrm
_cffi_backend.cpython-39-x86_64-linux-gnu.so2740960755editdlrm
_ldap.cpython-39-x86_64-linux-gnu.so956320755editdlrm
Edit: /opt/imh-python/lib/python3.9/site-packages/appdirs.py (24720B)
#!/usr/bin/env python # -*- coding: utf-8 -*- # Copyright (c) 2005-2010 ActiveState Software Inc. # Copyright (c) 2013 Eddy Petrișor """Utilities for determining application-specific dirs. See for details and usage. """ # Dev Notes: # - MSDN on where to store app data files: # http://support.microsoft.com/default.aspx?scid=kb;en-us;310294#XSLTH3194121123120121120120 # - 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 __version__ = "1.4.4" __version_info__ = tuple(int(segment) for segment in __version__.split(".")) import sys import os PY3 = sys.version_info[0] == 3 if PY3: unicode = str if sys.platform.startswith('java'): import platform os_name = platform.java_ver()[3][0] if os_name.startswith('Windows'): # "Windows XP", "Windows 7", etc. system = 'win32' elif os_name.startswith('Mac'): # "Mac OS X", etc. system = 'darwin' else: # "Linux", "SunOS", "FreeBSD", etc. # Setting this to "linux2" is not ideal, but only Windows or Mac # are actually checked for and the rest of the module expects # *sys.platform* style strings. system = 'linux2' else: system = sys.platform 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. "appname" is the name of application. If None, just the system directory is returned. "appauthor" (only used on Windows) is the name of the appauthor or distributing body for this application. Typically it is the owning company name. This falls back to appname. You may pass False to disable it. "version" is an optional version path element to append to the path. You might want to use this if you want multiple versions of your app to be able to run independently. If used, this would typically be ".". Only applied when appname is present. "roaming" (boolean, default False) can be set True to use the Windows roaming appdata directory. That means that for users on a Windows network setup for roaming profiles, this user data will be sync'd on login. See for a discussion of issues. Typical user data directories are: Mac OS X: ~/Library/Application Support/ Unix: ~/.local/share/ # or in $XDG_DATA_HOME, if defined Win XP (not roaming): C:\Documents and Settings\\Application Data\\ Win XP (roaming): C:\Documents and Settings\\Local Settings\Application Data\\ Win 7 (not roaming): C:\Users\\AppData\Local\\ Win 7 (roaming): C:\Users\\AppData\Roaming\\ For Unix, we follow the XDG spec and support $XDG_DATA_HOME. That means, by default "~/.local/share/". """ if system == "win32": if appauthor is None: appauthor = appname const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA" path = os.path.normpath(_get_win_folder(const)) if appname: if appauthor is not False: path = os.path.join(path, appauthor, appname) else: path = os.path.join(path, appname) elif system == 'darwin': path = os.path.expanduser('~/Library/Application Support/') if appname: path = os.path.join(path, appname) else: path = os.getenv('XDG_DATA_HOME', os.path.expanduser("~/.local/share")) if appname: path = os.path.join(path, appname) if appname and version: path = os.path.join(path, version) return path def site_data_dir(appname=None, appauthor=None, version=None, multipath=False): r"""Return full path to the user-shared data dir for this application. "appname" is the name of application. If None, just the system directory is returned. "appauthor" (only used on Windows) is the name of the appauthor or distributing body for this application. Typically it is the owning company name. This falls back to appname. You may pass False to disable it. "version" is an optional version path element to append to the path. You might want to use this if you want multiple versions of your app to be able to run independently. If used, this would typically be ".". Only applied when appname is present. "multipath" is an optional parameter only applicable to *nix which indicates that the entire list of data dirs should be returned. By default, the first item from XDG_DATA_DIRS is returned, or '/usr/local/share/', if XDG_DATA_DIRS is not set Typical site data directories are: Mac OS X: /Library/Application Support/ Unix: /usr/local/share/ or /usr/share/ Win XP: C:\Documents and Settings\All Users\Application Data\\ Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) Win 7: C:\ProgramData\\ # Hidden, but writeable on Win 7. For Unix, this is using the $XDG_DATA_DIRS[0] default. WARNING: Do not use this on Windows. See the Vista-Fail note above for why. """ if system == "win32": if appauthor is None: appauthor = appname path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA")) if appname: if appauthor is not False: path = os.path.join(path, appauthor, appname) else: path = os.path.join(path, appname) elif system == 'darwin': path = os.path.expanduser('/Library/Application Support') if appname: path = os.path.join(path, appname) else: # XDG default for $XDG_DATA_DIRS # only first, if multipath is False path = os.getenv('XDG_DATA_DIRS', os.pathsep.join(['/usr/local/share', '/usr/share'])) pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)] if appname: if version: appname = os.path.join(appname, version) pathlist = [os.sep.join([x, appname]) for x in pathlist] if multipath: path = os.pathsep.join(pathlist) else: path = pathlist[0] return path if appname and version: path = os.path.join(path, version) return path def user_config_dir(appname=None, appauthor=None, version=None, roaming=False): r"""Return full path to the user-specific config dir for this application. "appname" is the name of application. If None, just the system directory is returned. "appauthor" (only used on Windows) is the name of the appauthor or distributing body for this application. Typically it is the owning company name. This falls back to appname. You may pass False to disable it. "version" is an optional version path element to append to the path. You might want to use this if you want multiple versions of your app to be able to run independently. If used, this would typically be ".". Only applied when appname is present. "roaming" (boolean, default False) can be set True to use the Windows roaming appdata directory. That means that for users on a Windows network setup for roaming profiles, this user data will be sync'd on login. See for a discussion of issues. Typical user config directories are: Mac OS X: same as user_data_dir Unix: ~/.config/ # or in $XDG_CONFIG_HOME, if defined Win *: same as user_data_dir For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME. That means, by default "~/.config/". """ if system in ["win32", "darwin"]: path = user_data_dir(appname, appauthor, None, roaming) else: path = os.getenv('XDG_CONFIG_HOME', os.path.expanduser("~/.config")) if appname: path = os.path.join(path, appname) if appname and version: path = os.path.join(path, version) return path def site_config_dir(appname=None, appauthor=None, version=None, multipath=False): r"""Return full path to the user-shared data dir for this application. "appname" is the name of application. If None, just the system directory is returned. "appauthor" (only used on Windows) is the name of the appauthor or distributing body for this application. Typically it is the owning company name. This falls back to appname. You may pass False to disable it. "version" is an optional version path element to append to the path. You might want to use this if you want multiple versions of your app to be able to run independently. If used, this would typically be ".". Only applied when appname is present. "multipath" is an optional parameter only applicable to *nix which indicates that the entire list of config dirs should be returned. By default, the first item from XDG_CONFIG_DIRS is returned, or '/etc/xdg/', if XDG_CONFIG_DIRS is not set Typical site config directories are: Mac OS X: same as site_data_dir Unix: /etc/xdg/ or $XDG_CONFIG_DIRS[i]/ for each value in $XDG_CONFIG_DIRS Win *: same as site_data_dir Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) For Unix, this is using the $XDG_CONFIG_DIRS[0] default, if multipath=False WARNING: Do not use this on Windows. See the Vista-Fail note above for why. """ if system in ["win32", "darwin"]: path = site_data_dir(appname, appauthor) if appname and version: path = os.path.join(path, version) else: # XDG default for $XDG_CONFIG_DIRS # only first, if multipath is False path = os.getenv('XDG_CONFIG_DIRS', '/etc/xdg') pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)] if appname: if version: appname = os.path.join(appname, version) pathlist = [os.sep.join([x, appname]) for x in pathlist] if multipath: path = os.pathsep.join(pathlist) else: path = pathlist[0] return path 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. "appname" is the name of application. If None, just the system directory is returned. "appauthor" (only used on Windows) is the name of the appauthor or distributing body for this application. Typically it is the owning company name. This falls back to appname. You may pass False to disable it. "version" is an optional version path element to append to the path. You might want to use this if you want multiple versions of your app to be able to run independently. If used, this would typically be ".". Only applied when appname is present. "opinion" (boolean) can be False to disable the appending of "Cache" to the base app data dir for Windows. See discussion below. Typical user cache directories are: Mac OS X: ~/Library/Caches/ Unix: ~/.cache/ (XDG default) Win XP: C:\Documents and Settings\\Local Settings\Application Data\\\Cache Vista: C:\Users\\AppData\Local\\\Cache On Windows the only suggestion in the MSDN docs is that local settings go in the `CSIDL_LOCAL_APPDATA` directory. This is identical to the non-roaming app data dir (the default returned by `user_data_dir` above). Apps typically put cache data somewhere *under* the given dir here. Some examples: ...\Mozilla\Firefox\Profiles\\Cache ...\Acme\SuperApp\Cache\1.0 OPINION: This function appends "Cache" to the `CSIDL_LOCAL_APPDATA` value. This can be disabled with the `opinion=False` option. """ if system == "win32": if appauthor is None: appauthor = appname path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA")) if appname: if appauthor is not False: path = os.path.join(path, appauthor, appname) else: path = os.path.join(path, appname) if opinion: path = os.path.join(path, "Cache") elif system == 'darwin': path = os.path.expanduser('~/Library/Caches') if appname: path = os.path.join(path, appname) else: path = os.getenv('XDG_CACHE_HOME', os.path.expanduser('~/.cache')) if appname: path = os.path.join(path, appname) if appname and version: path = os.path.join(path, version) return path def user_state_dir(appname=None, appauthor=None, version=None, roaming=False): r"""Return full path to the user-specific state dir for this application. "appname" is the name of application. If None, just the system directory is returned. "appauthor" (only used on Windows) is the name of the appauthor or distributing body for this application. Typically it is the owning company name. This falls back to appname. You may pass False to disable it. "version" is an optional version path element to append to the path. You might want to use this if you want multiple versions of your app to be able to run independently. If used, this would typically be ".". Only applied when appname is present. "roaming" (boolean, default False) can be set True to use the Windows roaming appdata directory. That means that for users on a Windows network setup for roaming profiles, this user data will be sync'd on login. See for a discussion of issues. Typical user state directories are: Mac OS X: same as user_data_dir Unix: ~/.local/state/ # or in $XDG_STATE_HOME, if defined Win *: same as user_data_dir For Unix, we follow this Debian proposal to extend the XDG spec and support $XDG_STATE_HOME. That means, by default "~/.local/state/". """ if system in ["win32", "darwin"]: path = user_data_dir(appname, appauthor, None, roaming) else: path = os.getenv('XDG_STATE_HOME', os.path.expanduser("~/.local/state")) if appname: path = os.path.join(path, appname) if appname and version: path = os.path.join(path, version) return path 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. "appname" is the name of application. If None, just the system directory is returned. "appauthor" (only used on Windows) is the name of the appauthor or distributing body for this application. Typically it is the owning company name. This falls back to appname. You may pass False to disable it. "version" is an optional version path element to append to the path. You might want to use this if you want multiple versions of your app to be able to run independently. If used, this would typically be ".". Only applied when appname is present. "opinion" (boolean) can be False to disable the appending of "Logs" to the base app data dir for Windows, and "log" to the base cache dir for Unix. See discussion below. Typical user log directories are: Mac OS X: ~/Library/Logs/ Unix: ~/.cache//log # or under $XDG_CACHE_HOME if defined Win XP: C:\Documents and Settings\\Local Settings\Application Data\\\Logs Vista: C:\Users\\AppData\Local\\\Logs On Windows the only suggestion in the MSDN docs is that local settings go in the `CSIDL_LOCAL_APPDATA` directory. (Note: I'm interested in examples of what some windows apps use for a logs dir.) OPINION: This function appends "Logs" to the `CSIDL_LOCAL_APPDATA` value for Windows and appends "log" to the user cache dir for Unix. This can be disabled with the `opinion=False` option. """ if system == "darwin": path = os.path.join( os.path.expanduser('~/Library/Logs'), appname) elif system == "win32": path = user_data_dir(appname, appauthor, version) version = False if opinion: path = os.path.join(path, "Logs") else: path = user_cache_dir(appname, appauthor, version) version = False if opinion: path = os.path.join(path, "log") if appname and version: path = os.path.join(path, version) return path class AppDirs(object): """Convenience wrapper for getting application dirs.""" def __init__(self, appname=None, appauthor=None, version=None, roaming=False, multipath=False): self.appname = appname self.appauthor = appauthor self.version = version self.roaming = roaming self.multipath = multipath @property def user_data_dir(self): return user_data_dir(self.appname, self.appauthor, version=self.version, roaming=self.roaming) @property def site_data_dir(self): return site_data_dir(self.appname, self.appauthor, version=self.version, multipath=self.multipath) @property def user_config_dir(self): return user_config_dir(self.appname, self.appauthor, version=self.version, roaming=self.roaming) @property def site_config_dir(self): return site_config_dir(self.appname, self.appauthor, version=self.version, multipath=self.multipath) @property def user_cache_dir(self): return user_cache_dir(self.appname, self.appauthor, version=self.version) @property def user_state_dir(self): return user_state_dir(self.appname, self.appauthor, version=self.version) @property def user_log_dir(self): return user_log_dir(self.appname, self.appauthor, version=self.version) #---- internal support stuff def _get_win_folder_from_registry(csidl_name): """This is a fallback technique at best. I'm not sure if using the registry for this guarantees us the correct answer for all CSIDL_* names. """ if PY3: import winreg as _winreg else: import _winreg shell_folder_name = { "CSIDL_APPDATA": "AppData", "CSIDL_COMMON_APPDATA": "Common AppData", "CSIDL_LOCAL_APPDATA": "Local AppData", }[csidl_name] key = _winreg.OpenKey( _winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" ) dir, type = _winreg.QueryValueEx(key, shell_folder_name) return dir def _get_win_folder_with_pywin32(csidl_name): from win32com.shell import shellcon, shell dir = shell.SHGetFolderPath(0, getattr(shellcon, csidl_name), 0, 0) # Try to make this a unicode path because SHGetFolderPath does # not return unicode strings when there is unicode data in the # path. try: dir = unicode(dir) # Downgrade to short path name if have highbit chars. See # . has_high_char = False for c in dir: if ord(c) > 255: has_high_char = True break if has_high_char: try: import win32api dir = win32api.GetShortPathName(dir) except ImportError: pass except UnicodeError: pass return dir def _get_win_folder_with_ctypes(csidl_name): import ctypes csidl_const = { "CSIDL_APPDATA": 26, "CSIDL_COMMON_APPDATA": 35, "CSIDL_LOCAL_APPDATA": 28, }[csidl_name] buf = ctypes.create_unicode_buffer(1024) ctypes.windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf) # Downgrade to short path name if have highbit chars. See # . has_high_char = False for c in buf: if ord(c) > 255: has_high_char = True break if has_high_char: buf2 = ctypes.create_unicode_buffer(1024) if ctypes.windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024): buf = buf2 return buf.value def _get_win_folder_with_jna(csidl_name): import array from com.sun import jna from com.sun.jna.platform import win32 buf_size = win32.WinDef.MAX_PATH * 2 buf = array.zeros('c', buf_size) shell = win32.Shell32.INSTANCE shell.SHGetFolderPath(None, getattr(win32.ShlObj, csidl_name), None, win32.ShlObj.SHGFP_TYPE_CURRENT, buf) dir = jna.Native.toString(buf.tostring()).rstrip("\0") # Downgrade to short path name if have highbit chars. See # . has_high_char = False for c in dir: if ord(c) > 255: has_high_char = True break if has_high_char: buf = array.zeros('c', buf_size) kernel = win32.Kernel32.INSTANCE if kernel.GetShortPathName(dir, buf, buf_size): dir = jna.Native.toString(buf.tostring()).rstrip("\0") return dir if system == "win32": try: import win32com.shell _get_win_folder = _get_win_folder_with_pywin32 except ImportError: try: from ctypes import windll _get_win_folder = _get_win_folder_with_ctypes except ImportError: try: import com.sun.jna _get_win_folder = _get_win_folder_with_jna except ImportError: _get_win_folder = _get_win_folder_from_registry #---- self test code if __name__ == "__main__": appname = "MyApp" appauthor = "MyCompany" props = ("user_data_dir", "user_config_dir", "user_cache_dir", "user_state_dir", "user_log_dir", "site_data_dir", "site_config_dir") print("-- app dirs %s --" % __version__) print("-- app dirs (with optional 'version')") dirs = AppDirs(appname, appauthor, version="1.0") for prop in props: print("%s: %s" % (prop, getattr(dirs, prop))) print("\n-- app dirs (without optional 'version')") dirs = AppDirs(appname, appauthor) for prop in props: print("%s: %s" % (prop, getattr(dirs, prop))) print("\n-- app dirs (without optional 'appauthor')") dirs = AppDirs(appname) for prop in props: print("%s: %s" % (prop, getattr(dirs, prop))) print("\n-- app dirs (with disabled 'appauthor')") dirs = AppDirs(appname, appauthor=False) for prop in props: print("%s: %s" % (prop, getattr(dirs, prop)))