1 #!/usr/bin/env python 2 3 """ 4 Simple desktop integration for Python. This module provides desktop environment 5 detection and resource opening support for a selection of common and 6 standardised desktop environments. 7 8 Copyright (C) 2005, 2006 Paul Boddie <paul@boddie.org.uk> 9 10 This library is free software; you can redistribute it and/or 11 modify it under the terms of the GNU Lesser General Public 12 License as published by the Free Software Foundation; either 13 version 2.1 of the License, or (at your option) any later version. 14 15 This library is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 Lesser General Public License for more details. 19 20 You should have received a copy of the GNU Lesser General Public 21 License along with this library; if not, write to the Free Software 22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 23 24 -------- 25 26 Desktop Detection 27 ----------------- 28 29 To detect a specific desktop environment, use the get_desktop function. 30 To detect whether the desktop environment is standardised (according to the 31 proposed DESKTOP_LAUNCH standard), use the is_standard function. 32 33 Opening URLs 34 ------------ 35 36 To open a URL in the current desktop environment, relying on the automatic 37 detection of that environment, use the desktop.open function as follows: 38 39 desktop.open("http://www.python.org") 40 41 To override the detected desktop, specify the desktop parameter to the open 42 function as follows: 43 44 desktop.open("http://www.python.org", "KDE") # Insists on KDE 45 desktop.open("http://www.python.org", "GNOME") # Insists on GNOME 46 47 Without overriding using the desktop parameter, the open function will attempt 48 to use the "standard" desktop opening mechanism which is controlled by the 49 DESKTOP_LAUNCH environment variable as described below. 50 51 The DESKTOP_LAUNCH Environment Variable 52 --------------------------------------- 53 54 The DESKTOP_LAUNCH environment variable must be shell-quoted where appropriate, 55 as shown in some of the following examples: 56 57 DESKTOP_LAUNCH="kdialog --msgbox" Should present any opened URLs in 58 their entirety in a KDE message box. 59 (Command "kdialog" plus parameter.) 60 DESKTOP_LAUNCH="my\ opener" Should run the "my opener" program to 61 open URLs. 62 (Command "my opener", no parameters.) 63 DESKTOP_LAUNCH="my\ opener --url" Should run the "my opener" program to 64 open URLs. 65 (Command "my opener" plus parameter.) 66 67 Details of the DESKTOP_LAUNCH environment variable convention can be found here: 68 http://lists.freedesktop.org/archives/xdg/2004-August/004489.html 69 """ 70 71 __version__ = "0.2.3" 72 73 import os 74 import sys 75 76 try: 77 import subprocess 78 def _run(cmd, shell, wait): 79 opener = subprocess.Popen(cmd, shell=shell) 80 if wait: opener.wait() 81 return opener.pid 82 83 except ImportError: 84 import popen2 85 def _run(cmd, shell, wait): 86 opener = popen2.Popen3(cmd) 87 if wait: opener.wait() 88 return opener.pid 89 90 import commands 91 92 def get_desktop(): 93 94 """ 95 Detect the current desktop environment, returning the name of the 96 environment. If no environment could be detected, None is returned. 97 """ 98 99 if os.environ.has_key("KDE_FULL_SESSION") or \ 100 os.environ.has_key("KDE_MULTIHEAD"): 101 return "KDE" 102 elif os.environ.has_key("GNOME_DESKTOP_SESSION_ID") or \ 103 os.environ.has_key("GNOME_KEYRING_SOCKET"): 104 return "GNOME" 105 elif sys.platform == "darwin": 106 return "Mac OS X" 107 elif hasattr(os, "startfile"): 108 return "Windows" 109 else: 110 return None 111 112 def is_standard(): 113 114 """ 115 Return whether the current desktop supports standardised application 116 launching. 117 """ 118 119 return os.environ.has_key("DESKTOP_LAUNCH") 120 121 def open(url, desktop=None, wait=0): 122 123 """ 124 Open the 'url' in the current desktop's preferred file browser. If the 125 optional 'desktop' parameter is specified then attempt to use that 126 particular desktop environment's mechanisms to open the 'url' instead of 127 guessing or detecting which environment is being used. 128 129 Suggested values for 'desktop' are "standard", "KDE", "GNOME", "Mac OS X", 130 "Windows" where "standard" employs a DESKTOP_LAUNCH environment variable to 131 open the specified 'url'. DESKTOP_LAUNCH should be a command, possibly 132 followed by arguments, and must have any special characters shell-escaped. 133 134 The process identifier of the "opener" (ie. viewer, editor, browser or 135 program) associated with the 'url' is returned by this function. If the 136 process identifier cannot be determined, None is returned. 137 138 An optional 'wait' parameter is also available for advanced usage and, if 139 'wait' is set to a true value, this function will wait for the launching 140 mechanism to complete before returning (as opposed to immediately returning 141 as is the default behaviour). 142 """ 143 144 # Attempt to detect a desktop environment. 145 146 detected = get_desktop() 147 148 # Start with desktops whose existence can be easily tested. 149 150 if (desktop is None or desktop == "standard") and is_standard(): 151 arg = "".join([os.environ["DESKTOP_LAUNCH"], commands.mkarg(url)]) 152 return _run(arg, 1, wait) 153 154 elif (desktop is None or desktop == "Windows") and detected == "Windows": 155 # NOTE: This returns None in current implementations. 156 return os.startfile(url) 157 158 # Test for desktops where the overriding is not verified. 159 160 elif (desktop or detected) == "KDE": 161 cmd = ["kfmclient", "exec", url] 162 163 elif (desktop or detected) == "GNOME": 164 cmd = ["gnome-open", url] 165 166 elif (desktop or detected) == "Mac OS X": 167 cmd = ["open", url] 168 169 # Finish with an error where no suitable desktop was identified. 170 171 else: 172 raise OSError, "Desktop not supported (neither DESKTOP_LAUNCH nor os.startfile could be used)" 173 174 return _run(cmd, 0, wait) 175 176 # vim: tabstop=4 expandtab shiftwidth=4