#!/usr/bin/env python # openbox-xdg-autostart runs things based on the XDG autostart specification # Copyright (C) 2008 Dana Jansens # # XDG autostart specification can be found here: # http://standards.freedesktop.org/autostart-spec/ # # # # LICENSE: # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. ME="openbox-xdg-autostart" VERSION="1.1" import os, glob, sys try: from xdg import BaseDirectory from xdg.DesktopEntry import DesktopEntry from xdg.Exceptions import ParsingError except ImportError: print print >>sys.stderr, "ERROR:", ME, "requires PyXDG to be installed" print sys.exit(1) def main(argv=sys.argv): if "--help" in argv[1:]: show_help() return 0 if "--version" in argv[1:]: show_version() return 0 # get the autostart directories autodirs = BaseDirectory.load_config_paths("autostart") # find all the autostart files files = [] for dir in autodirs: for path in glob.glob(os.path.join(dir, '*.desktop')): try: autofile = AutostartFile(path) except ParsingError: print "Invalid .desktop file: " + path else: if not autofile in files: files.append(autofile) list = False if "--list" in argv[1:]: list = True argv.remove("--list") # run them ! environments = argv[1:] for autofile in files: if list: autofile.display(environments) else: autofile.run(environments) class AutostartFile: def __init__(self, path): self.path = path self.filename = os.path.basename(path) self.dirname = os.path.dirname(path) self.de = DesktopEntry(path) def __eq__(self, other): return self.filename == other.filename def __str__(self): return self.path + " : " + self.de.getName() def _isexecfile(self, path): return os.access(path, os.X_OK) def _findFile(self, path, search, match_func): # check empty path if not path: return None # check absolute path if path[0] == '/': if match_func(path): return path else: return None else: # check relative path for dirname in search.split(os.pathsep): if dirname != "": candidate = os.path.join(dirname, path) if (match_func(candidate)): return candidate def _alert(self, str, info=False): if info: print "\t ", str else: print "\t*", str def _showInEnvironment(self, envs, verbose=False): default = not self.de.getOnlyShowIn() noshow = False force = False for i in self.de.getOnlyShowIn(): if i in envs: force = True for i in self.de.getNotShowIn(): if i in envs: noshow = True if verbose: if not default and not force: s = "" for i in self.de.getOnlyShowIn(): if s: s += ", " s += i self._alert("Excluded by: OnlyShowIn (" + s + ")") if default and noshow and not force: s = "" for i in self.de.getNotShowIn(): if s: s += ", " s += i self._alert("Excluded by: NotShowIn (" + s + ")") return (default and not noshow) or force def _shouldRun(self, envs, verbose=False): if not self.de.getExec(): if verbose: self._alert("Excluded by: Missing Exec field") return False if self.de.getHidden(): if verbose: self._alert("Excluded by: Hidden") return False if self.de.getTryExec(): if not self._findFile(self.de.getTryExec(), os.getenv("PATH"), self._isexecfile): if verbose: self._alert("Excluded by: TryExec (" + self.de.getTryExec() + ")") return False if not self._showInEnvironment(envs, verbose): return False return True def display(self, envs): if self._shouldRun(envs): print "[*] " + self.de.getName() else: print "[ ] " + self.de.getName() self._alert("File: " + self.path, info=True) if self.de.getExec(): self._alert("Executes: " + self.de.getExec(), info=True) self._shouldRun(envs, True) print def run(self, envs): here = os.getcwd() if self.de.getPath(): os.chdir(self.de.getPath()) if self._shouldRun(envs): args = ["/bin/sh", "-c", "exec " + self.de.getExec()] os.spawnv(os.P_NOWAIT, args[0], args); os.chdir(here) def show_help(): print "Usage:", ME, "[OPTION]... [ENVIRONMENT]..." print print "This tool will run xdg autostart .desktop files" print print "OPTIONS" print " --list Show a list of the files which would be run" print " Files which would be run are marked with an asterix" print " symbol [*]. For files which would not be run," print " information is given for why they are excluded" print " --help Show this help and exit" print " --version Show version and copyright information" print print "ENVIRONMENT specifies a list of environments for which to run autostart" print "applications. If none are specified, only applications which do not " print "limit themselves to certain environments will be run." print print "ENVIRONMENT can be one or more of:" print " GNOME Gnome Desktop" print " KDE KDE Desktop" print " ROX ROX Desktop" print " XFCE XFCE Desktop" print " Old Legacy systems" print def show_version(): print ME, VERSION print "Copyright (c) 2008 Dana Jansens" print if __name__ == "__main__": sys.exit(main())