1 """
2 Support code for the freedesktop.org basedir spec.
3
4 This module provides functions for locating configuration files.
5
6 @see: U{http://freedesktop.org/wiki/Standards/basedir-spec}
7
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 """
12
13
14
15
16 from zeroinstall import _, logger
17 import os
18
19 home = os.environ.get('HOME', '/')
20
21 try:
22 _euid = os.geteuid()
23 except AttributeError:
24 pass
25 else:
26 if _euid == 0:
27
28
29
30 home_owner = os.stat(home).st_uid
31 if home_owner != 0:
32 import pwd
33 old_home = home
34 home = pwd.getpwuid(0).pw_dir or '/'
35 logger.info(_("$HOME (%(home)s) is owned by user %(user)d, but we are root (0). Using %(root_home)s instead."), {'home': old_home, 'user': home_owner, 'root_home': home})
36 del old_home
37 del home_owner
38
39 portable_base = os.environ.get('ZEROINSTALL_PORTABLE_BASE')
40 if portable_base:
41 xdg_data_dirs = [os.path.join(portable_base, "data")]
42 xdg_cache_dirs = [os.path.join(portable_base, "cache")]
43 xdg_config_dirs = [os.path.join(portable_base, "config")]
44 else:
45 if os.name == "nt":
46 from win32com.shell import shell, shellcon
47 appData = shell.SHGetFolderPath(0, shellcon.CSIDL_APPDATA, 0, 0)
48 localAppData = shell.SHGetFolderPath(0, shellcon.CSIDL_LOCAL_APPDATA, 0, 0)
49 commonAppData = shell.SHGetFolderPath(0, shellcon.CSIDL_COMMON_APPDATA, 0, 0)
50
51 _default_paths = {
52 'DATA' : [appData, commonAppData],
53 'CACHE' : [localAppData, commonAppData],
54 'CONFIG' : [appData, commonAppData],
55 }
56 else:
57 _default_paths = {
58 'DATA' : [os.path.join(home, '.local', 'share'), '/usr/local/share', '/usr/share'],
59 'CACHE' : [os.path.join(home, '.cache'), '/var/cache'],
60 'CONFIG' : [os.path.join(home, '.config'), '/etc/xdg'],
61 }
62
63 - def _get_path(home_var, dirs_var, default_paths):
64 """@type home_var: str
65 @type dirs_var: str
66 @type default_paths: [str]
67 @rtype: [str]"""
68 paths = default_paths
69
70 x = os.environ.get(home_var, None)
71 if x is not None:
72 paths[0] = x
73
74 x = os.environ.get(dirs_var, None)
75 if x is not None:
76 paths[1:] = filter(None, x.split(os.path.pathsep))
77
78 return paths
79
80 xdg_data_dirs = _get_path('XDG_DATA_HOME', 'XDG_DATA_DIRS', _default_paths['DATA'])
81 xdg_cache_dirs = _get_path('XDG_CACHE_HOME', 'XDG_CACHE_DIRS', _default_paths['CACHE'])
82 xdg_config_dirs = _get_path('XDG_CONFIG_HOME', 'XDG_CONFIG_DIRS', _default_paths['CONFIG'])
83
84
85 xdg_data_home = xdg_data_dirs[0]
86 xdg_cache_home = xdg_cache_dirs[0]
87 xdg_config_home = xdg_config_dirs[0]
88
90 """Ensure $XDG_CONFIG_HOME/<resource>/ exists, and return its path.
91 'resource' should normally be the name of your application. Use this
92 when SAVING configuration settings. Use the xdg_config_dirs variable
93 for loading.
94 @rtype: str"""
95 resource = os.path.join(*resource)
96 assert not os.path.isabs(resource)
97 path = os.path.join(xdg_config_home, resource)
98 if not os.path.isdir(path):
99 os.makedirs(path, 0o700)
100 return path
101
103 """Returns an iterator which gives each directory named 'resource' in the
104 configuration search path. Information provided by earlier directories should
105 take precedence over later ones (ie, the user's config dir comes first)."""
106 resource = os.path.join(*resource)
107 for config_dir in xdg_config_dirs:
108 path = os.path.join(config_dir, resource)
109 if os.path.exists(path): yield path
110
112 """Returns the first result from load_config_paths, or None if there is nothing
113 to load.
114 @rtype: str | None"""
115 for x in load_config_paths(*resource):
116 return x
117 return None
118
120 """Ensure $XDG_CACHE_HOME/<resource>/ exists, and return its path.
121 'resource' should normally be the name of your application.
122 @rtype: str"""
123 resource = os.path.join(*resource)
124 assert not os.path.isabs(resource)
125 path = os.path.join(xdg_cache_home, resource)
126 if not os.path.isdir(path):
127 os.makedirs(path, 0o700)
128 return path
129
131 """Returns an iterator which gives each directory named 'resource' in the
132 cache search path. Information provided by earlier directories should
133 take precedence over later ones (ie, the user's cache dir comes first)."""
134 resource = os.path.join(*resource)
135 for cache_dir in xdg_cache_dirs:
136 path = os.path.join(cache_dir, resource)
137 if os.path.exists(path): yield path
138
140 """Returns the first result from load_cache_paths, or None if there is nothing
141 to load.
142 @rtype: str | None"""
143 for x in load_cache_paths(*resource):
144 return x
145 return None
146
148 """Returns an iterator which gives each directory named 'resource' in the
149 shared data search path. Information provided by earlier directories should
150 take precedence over later ones.
151 @since: 0.28"""
152 resource = os.path.join(*resource)
153 for data_dir in xdg_data_dirs:
154 path = os.path.join(data_dir, resource)
155 if os.path.exists(path): yield path
156
158 """Returns the first result from load_data_paths, or None if there is nothing
159 to load.
160 @rtype: str | None
161 @since: 0.28"""
162 for x in load_data_paths(*resource):
163 return x
164 return None
165
167 """Ensure $XDG_DATA_HOME/<resource>/ exists, and return its path.
168 'resource' should normally be the name of your application.
169 @rtype: str"""
170 resource = os.path.join(*resource)
171 assert not os.path.isabs(resource)
172 path = os.path.join(xdg_data_home, resource)
173 if not os.path.isdir(path):
174 os.makedirs(path, 0o700)
175 return path
176