Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3
 
4
"""Utility for opening a file using the default application in a cross-platform
5
manner. Modified from http://code.activestate.com/recipes/511443/.
6
"""
7
 
8
__version__ = '1.1x'
9
__all__ = ['open']
10
 
11
import os
12
import sys
13
import webbrowser
14
import subprocess
15
 
16
_controllers = {}
17
_open = None
18
 
19
 
20
class BaseController(object):
21
    '''Base class for open program controllers.'''
22
 
23
    def __init__(self, name):
24
        self.name = name
25
 
26
    def open(self, filename):
27
        raise NotImplementedError
28
 
29
 
30
class Controller(BaseController):
31
    '''Controller for a generic open program.'''
32
 
33
    def __init__(self, *args):
34
        super(Controller, self).__init__(os.path.basename(args[0]))
35
        self.args = list(args)
36
 
37
    def _invoke(self, cmdline):
38
        if sys.platform[:3] == 'win':
39
            closefds = False
40
            startupinfo = subprocess.STARTUPINFO()
41
            startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
42
        else:
43
            closefds = True
44
            startupinfo = None
45
 
46
        if (os.environ.get('DISPLAY') or sys.platform[:3] == 'win' or
47
                                                    sys.platform == 'darwin'):
48
            inout = file(os.devnull, 'r+')
49
        else:
50
            # for TTY programs, we need stdin/out
51
            inout = None
52
 
53
        # if possible, put the child precess in separate process group,
54
        # so keyboard interrupts don't affect child precess as well as
55
        # Python
56
        setsid = getattr(os, 'setsid', None)
57
        if not setsid:
58
            setsid = getattr(os, 'setpgrp', None)
59
 
60
        pipe = subprocess.Popen(cmdline, stdin=inout, stdout=inout,
61
                                stderr=inout, close_fds=closefds,
62
                                preexec_fn=setsid, startupinfo=startupinfo)
63
 
64
        # It is assumed that this kind of tools (gnome-open, kfmclient,
65
        # exo-open, xdg-open and open for OSX) immediately exit after launching
66
        # the specific application
67
        returncode = pipe.wait()
68
        if hasattr(self, 'fixreturncode'):
69
            returncode = self.fixreturncode(returncode)
70
        return not returncode
71
 
72
    def open(self, filename):
73
        if isinstance(filename, basestring):
74
            cmdline = self.args + [filename]
75
        else:
76
            # assume it is a sequence
77
            cmdline = self.args + filename
78
        try:
79
            return self._invoke(cmdline)
80
        except OSError:
81
            return False
82
 
83
 
84
# Platform support for Windows
85
if sys.platform[:3] == 'win':
86
 
87
    class Start(BaseController):
88
        '''Controller for the win32 start program through os.startfile.'''
89
 
90
        def open(self, filename):
91
            try:
92
                os.startfile(filename)
93
            except WindowsError:
94
                # [Error 22] No application is associated with the specified
95
                # file for this operation: '<URL>'
96
                return False
97
            else:
98
                return True
99
 
100
    _controllers['windows-default'] = Start('start')
101
    _open = _controllers['windows-default'].open
102
 
103
 
104
# Platform support for MacOS
105
elif sys.platform == 'darwin':
106
    _controllers['open']= Controller('open')
107
    _open = _controllers['open'].open
108
 
109
 
110
# Platform support for Unix
111
else:
112
 
113
    try:
114
        from commands import getoutput
115
    except ImportError:
116
        from subprocess import getoutput
117
 
118
    # @WARNING: use the private API of the webbrowser module
119
    from webbrowser import _iscommand
120
 
121
    class KfmClient(Controller):
122
        '''Controller for the KDE kfmclient program.'''
123
 
124
        def __init__(self, kfmclient='kfmclient'):
125
            super(KfmClient, self).__init__(kfmclient, 'exec')
126
            self.kde_version = self.detect_kde_version()
127
 
128
        def detect_kde_version(self):
129
            kde_version = None
130
            try:
131
                info = getoutput('kde-config --version')
132
 
133
                for line in info.splitlines():
134
                    if line.startswith('KDE'):
135
                        kde_version = line.split(':')[-1].strip()
136
                        break
137
            except (OSError, RuntimeError):
138
                pass
139
 
140
            return kde_version
141
 
142
        def fixreturncode(self, returncode):
143
            if returncode is not None and self.kde_version > '3.5.4':
144
                return returncode
145
            else:
146
                return os.EX_OK
147
 
148
    def detect_desktop_environment():
149
        '''Checks for known desktop environments
150
 
151
        Return the desktop environments name, lowercase (kde, gnome, xfce)
152
        or "generic"
153
 
154
        '''
155
 
156
        desktop_environment = 'generic'
157
 
158
        if os.environ.get('KDE_FULL_SESSION') == 'true':
159
            desktop_environment = 'kde'
160
        elif os.environ.get('GNOME_DESKTOP_SESSION_ID'):
161
            desktop_environment = 'gnome'
162
        else:
163
            try:
164
                info = getoutput('xprop -root _DT_SAVE_MODE')
165
                if ' = "xfce4"' in info:
166
                    desktop_environment = 'xfce'
167
            except (OSError, RuntimeError):
168
                pass
169
 
170
        return desktop_environment
171
 
172
 
173
    def register_X_controllers():
174
        if _iscommand('kfmclient'):
175
            _controllers['kde-open'] = KfmClient()
176
 
177
        for command in ('gnome-open', 'exo-open', 'xdg-open'):
178
            if _iscommand(command):
179
                _controllers[command] = Controller(command)
180
 
181
    def get():
182
        controllers_map = {
183
            'gnome': 'gnome-open',
184
            'kde': 'kde-open',
185
            'xfce': 'exo-open',
186
        }
187
 
188
        desktop_environment = detect_desktop_environment()
189
 
190
        try:
191
            controller_name = controllers_map[desktop_environment]
192
            return _controllers[controller_name].open
193
 
194
        except KeyError:
195
            if 'xdg-open' in _controllers:
196
                return _controllers['xdg-open'].open
197
            else:
198
                return webbrowser.open
199
 
200
 
201
    if os.environ.get("DISPLAY"):
202
        register_X_controllers()
203
    _open = get()
204
 
205
 
206
def open(filename):
207
    '''Open a file or a URL in the registered default application.'''
208
 
209
    return _open(filename)