diff options
author | Carlo Zancanaro <carlo@pc-4w14-0.cs.usyd.edu.au> | 2012-10-15 17:10:06 +1100 |
---|---|---|
committer | Carlo Zancanaro <carlo@pc-4w14-0.cs.usyd.edu.au> | 2012-10-15 17:10:06 +1100 |
commit | be1de4be954c80875ad4108e0a33e8e131b2f2c0 (patch) | |
tree | 1fbbecf276bf7c7bdcbb4dd446099d6d90eaa516 /clang/tools/scan-view/startfile.py | |
parent | c4626a62754862d20b41e8a46a3574264ea80e6d (diff) | |
parent | f1bd2e48c5324d3f7cda4090c87f8a5b6f463ce2 (diff) |
Merge branch 'master' of ssh://bitbucket.org/czan/honours
Diffstat (limited to 'clang/tools/scan-view/startfile.py')
-rw-r--r-- | clang/tools/scan-view/startfile.py | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/clang/tools/scan-view/startfile.py b/clang/tools/scan-view/startfile.py new file mode 100644 index 0000000..e8fbe2d --- /dev/null +++ b/clang/tools/scan-view/startfile.py @@ -0,0 +1,203 @@ +"""Utility for opening a file using the default application in a cross-platform +manner. Modified from http://code.activestate.com/recipes/511443/. +""" + +__version__ = '1.1x' +__all__ = ['open'] + +import os +import sys +import webbrowser +import subprocess + +_controllers = {} +_open = None + + +class BaseController(object): + '''Base class for open program controllers.''' + + def __init__(self, name): + self.name = name + + def open(self, filename): + raise NotImplementedError + + +class Controller(BaseController): + '''Controller for a generic open program.''' + + def __init__(self, *args): + super(Controller, self).__init__(os.path.basename(args[0])) + self.args = list(args) + + def _invoke(self, cmdline): + if sys.platform[:3] == 'win': + closefds = False + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + else: + closefds = True + startupinfo = None + + if (os.environ.get('DISPLAY') or sys.platform[:3] == 'win' or + sys.platform == 'darwin'): + inout = file(os.devnull, 'r+') + else: + # for TTY programs, we need stdin/out + inout = None + + # if possible, put the child precess in separate process group, + # so keyboard interrupts don't affect child precess as well as + # Python + setsid = getattr(os, 'setsid', None) + if not setsid: + setsid = getattr(os, 'setpgrp', None) + + pipe = subprocess.Popen(cmdline, stdin=inout, stdout=inout, + stderr=inout, close_fds=closefds, + preexec_fn=setsid, startupinfo=startupinfo) + + # It is assumed that this kind of tools (gnome-open, kfmclient, + # exo-open, xdg-open and open for OSX) immediately exit after lauching + # the specific application + returncode = pipe.wait() + if hasattr(self, 'fixreturncode'): + returncode = self.fixreturncode(returncode) + return not returncode + + def open(self, filename): + if isinstance(filename, basestring): + cmdline = self.args + [filename] + else: + # assume it is a sequence + cmdline = self.args + filename + try: + return self._invoke(cmdline) + except OSError: + return False + + +# Platform support for Windows +if sys.platform[:3] == 'win': + + class Start(BaseController): + '''Controller for the win32 start progam through os.startfile.''' + + def open(self, filename): + try: + os.startfile(filename) + except WindowsError: + # [Error 22] No application is associated with the specified + # file for this operation: '<URL>' + return False + else: + return True + + _controllers['windows-default'] = Start('start') + _open = _controllers['windows-default'].open + + +# Platform support for MacOS +elif sys.platform == 'darwin': + _controllers['open']= Controller('open') + _open = _controllers['open'].open + + +# Platform support for Unix +else: + + import commands + + # @WARNING: use the private API of the webbrowser module + from webbrowser import _iscommand + + class KfmClient(Controller): + '''Controller for the KDE kfmclient program.''' + + def __init__(self, kfmclient='kfmclient'): + super(KfmClient, self).__init__(kfmclient, 'exec') + self.kde_version = self.detect_kde_version() + + def detect_kde_version(self): + kde_version = None + try: + info = commands.getoutput('kde-config --version') + + for line in info.splitlines(): + if line.startswith('KDE'): + kde_version = line.split(':')[-1].strip() + break + except (OSError, RuntimeError): + pass + + return kde_version + + def fixreturncode(self, returncode): + if returncode is not None and self.kde_version > '3.5.4': + return returncode + else: + return os.EX_OK + + def detect_desktop_environment(): + '''Checks for known desktop environments + + Return the desktop environments name, lowercase (kde, gnome, xfce) + or "generic" + + ''' + + desktop_environment = 'generic' + + if os.environ.get('KDE_FULL_SESSION') == 'true': + desktop_environment = 'kde' + elif os.environ.get('GNOME_DESKTOP_SESSION_ID'): + desktop_environment = 'gnome' + else: + try: + info = commands.getoutput('xprop -root _DT_SAVE_MODE') + if ' = "xfce4"' in info: + desktop_environment = 'xfce' + except (OSError, RuntimeError): + pass + + return desktop_environment + + + def register_X_controllers(): + if _iscommand('kfmclient'): + _controllers['kde-open'] = KfmClient() + + for command in ('gnome-open', 'exo-open', 'xdg-open'): + if _iscommand(command): + _controllers[command] = Controller(command) + + def get(): + controllers_map = { + 'gnome': 'gnome-open', + 'kde': 'kde-open', + 'xfce': 'exo-open', + } + + desktop_environment = detect_desktop_environment() + + try: + controller_name = controllers_map[desktop_environment] + return _controllers[controller_name].open + + except KeyError: + if _controllers.has_key('xdg-open'): + return _controllers['xdg-open'].open + else: + return webbrowser.open + + + if os.environ.get("DISPLAY"): + register_X_controllers() + _open = get() + + +def open(filename): + '''Open a file or an URL in the registered default application.''' + + return _open(filename) |