]> Dogcows Code - chaz/openbox/blob - data/autostart/openbox-xdg-autostart
Print error message to stderr (Fix bug 5731)
[chaz/openbox] / data / autostart / openbox-xdg-autostart
1 #!/usr/bin/env python
2
3 # openbox-xdg-autostart runs things based on the XDG autostart specification
4 # Copyright (C) 2008 Dana Jansens
5 #
6 # XDG autostart specification can be found here:
7 # http://standards.freedesktop.org/autostart-spec/
8 #
9 #
10 #
11 # LICENSE:
12 # This program is free software; you can redistribute it and/or modify
13 # it under the terms of the GNU General Public License as published by
14 # the Free Software Foundation; either version 2 of the License, or
15 # (at your option) any later version.
16 #
17 # This program is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # GNU General Public License for more details.
21
22 ME="openbox-xdg-autostart"
23 VERSION="1.1"
24
25 import os, glob, sys
26 try:
27 from xdg import BaseDirectory
28 from xdg.DesktopEntry import DesktopEntry
29 from xdg.Exceptions import ParsingError
30 except ImportError:
31 print
32 print >>sys.stderr, "ERROR:", ME, "requires PyXDG to be installed"
33 print
34 sys.exit(1)
35
36 def main(argv=sys.argv):
37 if "--help" in argv[1:]:
38 show_help()
39 return 0
40 if "--version" in argv[1:]:
41 show_version()
42 return 0
43
44 # get the autostart directories
45 autodirs = BaseDirectory.load_config_paths("autostart")
46
47 # find all the autostart files
48 files = []
49 for dir in autodirs:
50 for path in glob.glob(os.path.join(dir, '*.desktop')):
51 try:
52 autofile = AutostartFile(path)
53 except ParsingError:
54 print "Invalid .desktop file: " + path
55 else:
56 if not autofile in files:
57 files.append(autofile)
58
59 list = False
60 if "--list" in argv[1:]:
61 list = True
62 argv.remove("--list")
63
64 # run them !
65 environments = argv[1:]
66 for autofile in files:
67 if list: autofile.display(environments)
68 else: autofile.run(environments)
69
70 class AutostartFile:
71 def __init__(self, path):
72 self.path = path
73 self.filename = os.path.basename(path)
74 self.dirname = os.path.dirname(path)
75 self.de = DesktopEntry(path)
76
77 def __eq__(self, other):
78 return self.filename == other.filename
79
80 def __str__(self):
81 return self.path + " : " + self.de.getName()
82
83 def _isexecfile(self, path):
84 return os.access(path, os.X_OK)
85
86 def _findFile(self, path, search, match_func):
87 # check empty path
88 if not path: return None
89 # check absolute path
90 if path[0] == '/':
91 if match_func(path): return path
92 else: return None
93 else:
94 # check relative path
95 for dirname in search.split(os.pathsep):
96 if dirname != "":
97 candidate = os.path.join(dirname, path)
98 if (match_func(candidate)): return candidate
99
100 def _alert(self, str, info=False):
101 if info:
102 print "\t ", str
103 else:
104 print "\t*", str
105
106 def _showInEnvironment(self, envs, verbose=False):
107 default = not self.de.getOnlyShowIn()
108 noshow = False
109 force = False
110 for i in self.de.getOnlyShowIn():
111 if i in envs: force = True
112 for i in self.de.getNotShowIn():
113 if i in envs: noshow = True
114
115 if verbose:
116 if not default and not force:
117 s = ""
118 for i in self.de.getOnlyShowIn():
119 if s: s += ", "
120 s += i
121 self._alert("Excluded by: OnlyShowIn (" + s + ")")
122 if default and noshow and not force:
123 s = ""
124 for i in self.de.getNotShowIn():
125 if s: s += ", "
126 s += i
127 self._alert("Excluded by: NotShowIn (" + s + ")")
128 return (default and not noshow) or force
129
130 def _shouldRun(self, envs, verbose=False):
131 if not self.de.getExec():
132 if verbose: self._alert("Excluded by: Missing Exec field")
133 return False
134 if self.de.getHidden():
135 if verbose: self._alert("Excluded by: Hidden")
136 return False
137 if self.de.getTryExec():
138 if not self._findFile(self.de.getTryExec(), os.getenv("PATH"),
139 self._isexecfile):
140 if verbose: self._alert("Excluded by: TryExec (" +
141 self.de.getTryExec() + ")")
142 return False
143 if not self._showInEnvironment(envs, verbose):
144 return False
145 return True
146
147 def display(self, envs):
148 if self._shouldRun(envs):
149 print "[*] " + self.de.getName()
150 else:
151 print "[ ] " + self.de.getName()
152 self._alert("File: " + self.path, info=True)
153 if self.de.getExec():
154 self._alert("Executes: " + self.de.getExec(), info=True)
155 self._shouldRun(envs, True)
156 print
157
158 def run(self, envs):
159 here = os.getcwd()
160 if self.de.getPath():
161 os.chdir(self.de.getPath())
162 if self._shouldRun(envs):
163 args = ["/bin/sh", "-c", "exec " + self.de.getExec()]
164 os.spawnv(os.P_NOWAIT, args[0], args);
165 os.chdir(here)
166
167 def show_help():
168 print "Usage:", ME, "[OPTION]... [ENVIRONMENT]..."
169 print
170 print "This tool will run xdg autostart .desktop files"
171 print
172 print "OPTIONS"
173 print " --list Show a list of the files which would be run"
174 print " Files which would be run are marked with an asterix"
175 print " symbol [*]. For files which would not be run,"
176 print " information is given for why they are excluded"
177 print " --help Show this help and exit"
178 print " --version Show version and copyright information"
179 print
180 print "ENVIRONMENT specifies a list of environments for which to run autostart"
181 print "applications. If none are specified, only applications which do not "
182 print "limit themselves to certain environments will be run."
183 print
184 print "ENVIRONMENT can be one or more of:"
185 print " GNOME Gnome Desktop"
186 print " KDE KDE Desktop"
187 print " ROX ROX Desktop"
188 print " XFCE XFCE Desktop"
189 print " Old Legacy systems"
190 print
191
192 def show_version():
193 print ME, VERSION
194 print "Copyright (c) 2008 Dana Jansens"
195 print
196
197 if __name__ == "__main__":
198 sys.exit(main())
This page took 0.048207 seconds and 4 git commands to generate.