forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			204 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			204 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Python
		
	
	
	
| """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)
 |