Import _ into each module rather than using a builtin
[zeroinstall/zeroinstall-rsl.git] / zeroinstall / support / basedir.py
blob38b5d718bf4e320f78c6dd791a9df05aae0c4f44
1 """
2 Support code for the freedesktop.org basedir spec.
4 This module provides functions for locating configuration files.
6 @see: U{http://freedesktop.org/wiki/Standards/basedir-spec}
8 @var home: The value of $HOME (or '/' if not set). If we're running as root and
9 $HOME isn't owned by root, then this will be root's home from /etc/passwd
10 instead.
11 """
13 # Copyright (C) 2009, Thomas Leonard
14 # See the README file for details, or visit http://0install.net.
16 from zeroinstall import _
17 import os
19 home = os.environ.get('HOME', '/')
21 try:
22 _euid = os.geteuid()
23 except AttributeError:
24 pass # Windows?
25 else:
26 if _euid == 0:
27 # We're running as root. Ensure that $HOME really is root's home,
28 # not the user's home, or we're likely to fill it will unreadable
29 # root-owned files.
30 home_owner = os.stat(home).st_uid
31 if home_owner != 0:
32 import pwd
33 from logging import info
34 old_home = home
35 home = pwd.getpwuid(0).pw_dir or '/'
36 info(_("$HOME (%(home)s) is owned by user %(user)d, but we are root (0). Using %(root_home)s instead."), {'old_home': old_home, 'user': home_owner, 'root_home': home})
37 del old_home
38 del home_owner
40 xdg_data_home = os.environ.get('XDG_DATA_HOME',
41 os.path.join(home, '.local', 'share'))
43 xdg_data_dirs = [xdg_data_home] + \
44 os.environ.get('XDG_DATA_DIRS', '/usr/local/share:/usr/share').split(':')
46 xdg_cache_home = os.environ.get('XDG_CACHE_HOME',
47 os.path.join(home, '.cache'))
49 xdg_cache_dirs = [xdg_cache_home] + \
50 os.environ.get('XDG_CACHE_DIRS', '/var/cache').split(':')
52 xdg_config_home = os.environ.get('XDG_CONFIG_HOME',
53 os.path.join(home, '.config'))
55 xdg_config_dirs = [xdg_config_home] + \
56 os.environ.get('XDG_CONFIG_DIRS', '/etc/xdg').split(':')
58 xdg_data_dirs = filter(lambda x: x, xdg_data_dirs)
59 xdg_cache_dirs = filter(lambda x: x, xdg_cache_dirs)
60 xdg_config_dirs = filter(lambda x: x, xdg_config_dirs)
62 def save_config_path(*resource):
63 """Ensure $XDG_CONFIG_HOME/<resource>/ exists, and return its path.
64 'resource' should normally be the name of your application. Use this
65 when SAVING configuration settings. Use the xdg_config_dirs variable
66 for loading."""
67 resource = os.path.join(*resource)
68 assert not resource.startswith('/')
69 path = os.path.join(xdg_config_home, resource)
70 if not os.path.isdir(path):
71 os.makedirs(path, 0700)
72 return path
74 def load_config_paths(*resource):
75 """Returns an iterator which gives each directory named 'resource' in the
76 configuration search path. Information provided by earlier directories should
77 take precedence over later ones (ie, the user's config dir comes first)."""
78 resource = os.path.join(*resource)
79 for config_dir in xdg_config_dirs:
80 path = os.path.join(config_dir, resource)
81 if os.path.exists(path): yield path
83 def load_first_config(*resource):
84 """Returns the first result from load_config_paths, or None if there is nothing
85 to load."""
86 for x in load_config_paths(*resource):
87 return x
88 return None
90 def save_cache_path(*resource):
91 """Ensure $XDG_CACHE_HOME/<resource>/ exists, and return its path.
92 'resource' should normally be the name of your application."""
93 resource = os.path.join(*resource)
94 assert not resource.startswith('/')
95 path = os.path.join(xdg_cache_home, resource)
96 if not os.path.isdir(path):
97 os.makedirs(path, 0700)
98 return path
100 def load_cache_paths(*resource):
101 """Returns an iterator which gives each directory named 'resource' in the
102 cache search path. Information provided by earlier directories should
103 take precedence over later ones (ie, the user's cache dir comes first)."""
104 resource = os.path.join(*resource)
105 for cache_dir in xdg_cache_dirs:
106 path = os.path.join(cache_dir, resource)
107 if os.path.exists(path): yield path
109 def load_first_cache(*resource):
110 """Returns the first result from load_cache_paths, or None if there is nothing
111 to load."""
112 for x in load_cache_paths(*resource):
113 return x
114 return None
116 def load_data_paths(*resource):
117 """Returns an iterator which gives each directory named 'resource' in the
118 shared data search path. Information provided by earlier directories should
119 take precedence over later ones.
120 @since: 0.28"""
121 resource = os.path.join(*resource)
122 for data_dir in xdg_data_dirs:
123 path = os.path.join(data_dir, resource)
124 if os.path.exists(path): yield path
126 def load_first_data(*resource):
127 """Returns the first result from load_data_paths, or None if there is nothing
128 to load.
129 @since: 0.28"""
130 for x in load_data_paths(*resource):
131 return x
132 return None