widgets.remote: retain focus when showing remote messages
[git-cola.git] / cola / resources.py
blobbd72d50ab540664ba0cf6567c24824a8331331c0
1 """Functions for finding cola resources"""
2 import os
3 from os.path import dirname
4 import webbrowser
6 from . import core
7 from . import compat
10 # Default git-cola icon theme
11 _default_icon_theme = 'light'
13 _resources = core.abspath(core.realpath(__file__))
14 _package = os.path.dirname(_resources)
16 if _package.endswith(os.path.join('site-packages', 'cola')):
17 # Unix release tree
18 # __file__ = '$prefix/lib/pythonX.Y/site-packages/cola/__file__.py'
19 # _package = '$prefix/lib/pythonX.Y/site-packages/cola'
20 _prefix = dirname(dirname(dirname(dirname(_package))))
21 elif _package.endswith(os.path.join('pkgs', 'cola')):
22 # Windows release tree
23 # __file__ = $installdir/pkgs/cola
24 _prefix = dirname(dirname(_package))
25 else:
26 # this is the source tree
27 # __file__ = '$prefix/cola/__file__.py'
28 _prefix = dirname(_package)
31 def get_prefix():
32 """Return the installation prefix"""
33 return _prefix
36 def prefix(*args):
37 """Return a path relative to cola's installation prefix"""
38 return os.path.join(get_prefix(), *args)
41 def command(name):
42 """Return a command from the bin/ directory"""
43 if compat.WIN32:
44 # Check for "${name}.exe" on Windows.
45 exe_path = prefix('bin', '%s.exe' % name)
46 scripts_exe_path = prefix('Scripts', '%s.exe' % name)
47 scripts_path = prefix('Scripts', name)
48 path = prefix('bin', name)
50 if core.exists(exe_path):
51 result = exe_path
52 elif core.exists(scripts_exe_path):
53 result = scripts_exe_path
54 elif core.exists(scripts_path):
55 result = scripts_path
56 else:
57 result = path
58 else:
59 result = prefix('bin', name)
60 return result
63 def doc(*args):
64 """Return a path relative to cola's /usr/share/doc/ directory"""
65 return share('doc', 'git-cola', *args)
68 def i18n(*args):
69 """Return a path relative to cola's i18n locale directory, eg. cola/i18n"""
70 return package_data('i18n', *args)
73 def html_docs():
74 """Return the path to the cola html documentation."""
75 # html/index.html only exists after the install-docs target is run.
76 # Fallback to the source tree and lastly git-cola.rst.
77 paths_to_try = (('html', 'index.html'), ('_build', 'html', 'index.html'))
78 for paths in paths_to_try:
79 docdir = doc(*paths)
80 if core.exists(docdir):
81 return docdir
82 return doc('git-cola.rst')
85 def show_html_docs():
86 """Open the HTML documentation in a browser"""
87 url = html_docs()
88 webbrowser.open_new_tab('file://' + url)
91 def share(*args):
92 """Return a path relative to cola's /usr/share/ directory"""
93 return prefix('share', *args)
96 def package_data(*args):
97 """Return a path relative to cola's Python modules"""
98 return os.path.join(_package, *args)
101 def package_command(*args):
102 """Return a path relative to cola's private bin/ directory"""
103 return package_data('bin', *args)
106 def icon_dir(theme):
107 """Return the icons directory for the specified theme
109 This returns the ``icons`` directory inside the ``cola`` Python package.
110 When theme is defined then it will return a subdirectory of the icons/
111 directory, e.g. "dark" for the dark icon theme.
113 When theme is set to an absolute directory path, that directory will be
114 returned, which effectively makes git-cola use those icons.
116 if not theme or theme == _default_icon_theme:
117 icons = package_data('icons')
118 else:
119 theme_dir = package_data('icons', theme)
120 if os.path.isabs(theme) and os.path.isdir(theme):
121 icons = theme
122 elif os.path.isdir(theme_dir):
123 icons = theme_dir
124 else:
125 icons = package_data('icons')
127 return icons
130 def xdg_config_home(*args):
131 """Return the XDG_CONFIG_HOME configuration directory, eg. ~/.config"""
132 config = core.getenv(
133 'XDG_CONFIG_HOME', os.path.join(core.expanduser('~'), '.config')
135 return os.path.join(config, *args)
138 def xdg_data_home(*args):
139 """Return the XDG_DATA_HOME configuration directory, eg. ~/.local/share"""
140 config = core.getenv(
141 'XDG_DATA_HOME', os.path.join(core.expanduser('~'), '.local', 'share')
143 return os.path.join(config, *args)
146 def xdg_data_dirs():
147 """Return the current set of XDG data directories
149 Returns the values from $XDG_DATA_DIRS when defined in the environment.
150 If $XDG_DATA_DIRS is either not set or empty, a value equal to
151 /usr/local/share:/usr/share is used.
153 paths = []
154 xdg_data_home_dir = xdg_data_home()
155 if os.path.isdir(xdg_data_home_dir):
156 paths.append(xdg_data_home_dir)
158 xdg_data_dirs_env = core.getenv('XDG_DATA_DIRS', '')
159 if not xdg_data_dirs_env:
160 xdg_data_dirs_env = '/usr/local/share:/usr/share'
161 paths.extend(path for path in xdg_data_dirs_env.split(':') if os.path.isdir(path))
162 return paths
165 def find_first(subpath, paths, validate=os.path.isfile):
166 """Return the first `subpath` found in the specified directory paths"""
167 if os.path.isabs(subpath):
168 return subpath
169 for path in paths:
170 candidate = os.path.join(path, subpath)
171 if validate(candidate):
172 return candidate
173 # Nothing was found so return None.
174 return None
177 def config_home(*args):
178 """Return git-cola's configuration directory, eg. ~/.config/git-cola"""
179 return xdg_config_home('git-cola', *args)