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 Paul Boddie <paul@boddie.org.uk> 9 10 Licensed under the Academic Free License version 2.1 - see docs/LICENCE.txt. 11 12 -------- 13 14 Desktop Detection 15 ----------------- 16 17 To detect a specific desktop environment, use the get_desktop function. 18 To detect whether the desktop environment is standardised (according to the 19 proposed DESKTOP_LAUNCH standard), use the is_standard function. 20 21 Opening URLs 22 ------------ 23 24 To open a URL in the current desktop environment, relying on the automatic 25 detection of that environment, use the desktop.open function as follows: 26 27 desktop.open("http://www.python.org") 28 29 To override the detected desktop, specify the desktop parameter to the open 30 function as follows: 31 32 desktop.open("http://www.python.org", "KDE") # Insists on KDE 33 desktop.open("http://www.python.org", "GNOME") # Insists on GNOME 34 35 Without overriding using the desktop parameter, the open function will attempt 36 to use the "standard" desktop opening mechanism which is controlled by the 37 DESKTOP_LAUNCH environment variable as described below. 38 39 The DESKTOP_LAUNCH Environment Variable 40 --------------------------------------- 41 42 The DESKTOP_LAUNCH environment variable must be shell-quoted where appropriate, 43 as shown in some of the following examples: 44 45 DESKTOP_LAUNCH="kdialog --msgbox" Should present any opened URLs in 46 their entirety in a KDE message box. 47 (Command "kdialog" plus parameter.) 48 DESKTOP_LAUNCH="my\ opener" Should run the "my opener" program to 49 open URLs. 50 (Command "my opener", no parameters.) 51 DESKTOP_LAUNCH="my\ opener --url" Should run the "my opener" program to 52 open URLs. 53 (Command "my opener" plus parameter.) 54 55 Details of the DESKTOP_LAUNCH environment variable convention can be found here: 56 http://lists.freedesktop.org/archives/xdg/2004-August/004489.html 57 """ 58 59 __version__ = "0.2" 60 61 import os 62 import sys 63 import subprocess 64 import commands 65 66 def get_desktop(): 67 68 """ 69 Detect the current desktop environment, returning the name of the 70 environment. If no environment could be detected, None is returned. 71 """ 72 73 if os.environ.has_key("KDE_FULL_SESSION") or \ 74 os.environ.has_key("KDE_MULTIHEAD"): 75 return "KDE" 76 elif os.environ.has_key("GNOME_DESKTOP_SESSION_ID") or \ 77 os.environ.has_key("GNOME_KEYRING_SOCKET"): 78 return "GNOME" 79 elif sys.platform == "darwin": 80 return "Mac OS X" 81 elif hasattr(os, "startfile"): 82 return "Windows" 83 else: 84 return None 85 86 def is_standard(): 87 88 """ 89 Return whether the current desktop supports standardised application 90 launching. 91 """ 92 93 return os.environ.has_key("DESKTOP_LAUNCH") 94 95 def _wait(pid, block): 96 97 """ 98 Perform a blocking Wait for the given process identifier, 'pid', if the 99 'block' flag is set to a true value. Return the process identifier. 100 """ 101 102 if block: 103 os.waitpid(pid, os.P_WAIT) 104 return pid 105 106 def open(url, desktop=None, wait=0): 107 108 """ 109 Open the 'url' in the current desktop's preferred file browser. If the 110 optional 'desktop' parameter is specified then attempt to use that 111 particular desktop environment's mechanisms to open the 'url' instead of 112 guessing or detecting which environment is being used. 113 114 Suggested values for 'desktop' are "standard", "KDE", "GNOME", "Mac OS X", 115 "Windows" where "standard" employs a DESKTOP_LAUNCH environment variable to 116 open the specified 'url'. DESKTOP_LAUNCH should be a command, possibly 117 followed by arguments, and must have any special characters shell-escaped. 118 119 The process identifier of the "opener" (ie. viewer, editor, browser or 120 program) associated with the 'url' is returned by this function. If the 121 process identifier cannot be determined, None is returned. 122 123 An optional 'wait' parameter is also available for advanced usage and, if 124 'wait' is set to a true value, this function will wait for the launching 125 mechanism to complete before returning (as opposed to immediately returning 126 as is the default behaviour). 127 """ 128 129 # Attempt to detect a desktop environment. 130 131 detected = get_desktop() 132 133 # Start with desktops whose existence can be easily tested. 134 135 if (desktop is None or desktop == "standard") and is_standard(): 136 arg = "".join([os.environ["DESKTOP_LAUNCH"], commands.mkarg(url)]) 137 return _wait(subprocess.Popen(arg, shell=1).pid, wait) 138 139 elif (desktop is None or desktop == "Windows") and detected == "Windows": 140 # NOTE: This returns None in current implementations. 141 return os.startfile(url) 142 143 # Test for desktops where the overriding is not verified. 144 145 elif (desktop or detected) == "KDE": 146 cmd = ["kfmclient", "exec", url] 147 148 elif (desktop or detected) == "GNOME": 149 cmd = ["gnome-open", url] 150 151 elif (desktop or detected) == "Mac OS X": 152 cmd = ["open", url] 153 154 # Finish with an error where no suitable desktop was identified. 155 156 else: 157 raise OSError, "Desktop not supported (neither DESKTOP_LAUNCH nor os.startfile could be used)" 158 159 return _wait(subprocess.Popen(cmd).pid, wait) 160 161 # vim: tabstop=4 expandtab shiftwidth=4