- #!/usr/bin/env python 
- # -*- coding: utf-8 -*- 
-   
- """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 launching 
-         # 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 program 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: 
-   
-     try: 
-         from commands import getoutput 
-     except ImportError: 
-         from subprocess import getoutput 
-   
-     # @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 = 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 = 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 'xdg-open' in _controllers: 
-                 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 a URL in the registered default application.''' 
-   
-     return _open(filename) 
-