Update year to 2009 in various places
[zeroinstall/zeroinstall-rsl.git] / zeroinstall / support / basedir.py
blob53481f41f7f9c926af4155fd78265bb8d0b3c1c9
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 import os
18 home = os.environ.get('HOME', '/')
20 try:
21 _euid = os.geteuid()
22 except AttributeError:
23 pass # Windows?
24 else:
25 if _euid == 0:
26 # We're running as root. Ensure that $HOME really is root's home,
27 # not the user's home, or we're likely to fill it will unreadable
28 # root-owned files.
29 home_owner = os.stat(home).st_uid
30 if home_owner != 0:
31 import pwd
32 from logging import info
33 old_home = home
34 home = pwd.getpwuid(0).pw_dir or '/'
35 info("$HOME (%s) is owned by user %d, but we are root (0). Using %s instead.", old_home, home_owner, home)
36 del old_home
37 del home_owner
39 xdg_data_home = os.environ.get('XDG_DATA_HOME',
40 os.path.join(home, '.local', 'share'))
42 xdg_data_dirs = [xdg_data_home] + \
43 os.environ.get('XDG_DATA_DIRS', '/usr/local/share:/usr/share').split(':')
45 xdg_cache_home = os.environ.get('XDG_CACHE_HOME',
46 os.path.join(home, '.cache'))
48 xdg_cache_dirs = [xdg_cache_home] + \
49 os.environ.get('XDG_CACHE_DIRS', '/var/cache').split(':')
51 xdg_config_home = os.environ.get('XDG_CONFIG_HOME',
52 os.path.join(home, '.config'))
54 xdg_config_dirs = [xdg_config_home] + \
55 os.environ.get('XDG_CONFIG_DIRS', '/etc/xdg').split(':')
57 xdg_data_dirs = filter(lambda x: x, xdg_data_dirs)
58 xdg_cache_dirs = filter(lambda x: x, xdg_cache_dirs)
59 xdg_config_dirs = filter(lambda x: x, xdg_config_dirs)
61 def save_config_path(*resource):
62 """Ensure $XDG_CONFIG_HOME/<resource>/ exists, and return its path.
63 'resource' should normally be the name of your application. Use this
64 when SAVING configuration settings. Use the xdg_config_dirs variable
65 for loading."""
66 resource = os.path.join(*resource)
67 assert not resource.startswith('/')
68 path = os.path.join(xdg_config_home, resource)
69 if not os.path.isdir(path):
70 os.makedirs(path, 0700)
71 return path
73 def load_config_paths(*resource):
74 """Returns an iterator which gives each directory named 'resource' in the
75 configuration search path. Information provided by earlier directories should
76 take precedence over later ones (ie, the user's config dir comes first)."""
77 resource = os.path.join(*resource)
78 for config_dir in xdg_config_dirs:
79 path = os.path.join(config_dir, resource)
80 if os.path.exists(path): yield path
82 def load_first_config(*resource):
83 """Returns the first result from load_config_paths, or None if there is nothing
84 to load."""
85 for x in load_config_paths(*resource):
86 return x
87 return None
89 def save_cache_path(*resource):
90 """Ensure $XDG_CACHE_HOME/<resource>/ exists, and return its path.
91 'resource' should normally be the name of your application."""
92 resource = os.path.join(*resource)
93 assert not resource.startswith('/')
94 path = os.path.join(xdg_cache_home, resource)
95 if not os.path.isdir(path):
96 os.makedirs(path, 0700)
97 return path
99 def load_cache_paths(*resource):
100 """Returns an iterator which gives each directory named 'resource' in the
101 cache search path. Information provided by earlier directories should
102 take precedence over later ones (ie, the user's cache dir comes first)."""
103 resource = os.path.join(*resource)
104 for cache_dir in xdg_cache_dirs:
105 path = os.path.join(cache_dir, resource)
106 if os.path.exists(path): yield path
108 def load_first_cache(*resource):
109 """Returns the first result from load_cache_paths, or None if there is nothing
110 to load."""
111 for x in load_cache_paths(*resource):
112 return x
113 return None
115 def load_data_paths(*resource):
116 """Returns an iterator which gives each directory named 'resource' in the
117 shared data search path. Information provided by earlier directories should
118 take precedence over later ones.
119 @since: 0.28"""
120 resource = os.path.join(*resource)
121 for data_dir in xdg_data_dirs:
122 path = os.path.join(data_dir, resource)
123 if os.path.exists(path): yield path
125 def load_first_data(*resource):
126 """Returns the first result from load_data_paths, or None if there is nothing
127 to load.
128 @since: 0.28"""
129 for x in load_data_paths(*resource):
130 return x
131 return None