1.1 --- a/desktop.py Wed Oct 15 23:18:30 2008 +0200
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,266 +0,0 @@
1.4 -#!/usr/bin/env python
1.5 -
1.6 -"""
1.7 -Simple desktop integration for Python. This module provides desktop environment
1.8 -detection and resource opening support for a selection of common and
1.9 -standardised desktop environments.
1.10 -
1.11 -Copyright (C) 2005, 2006, 2007 Paul Boddie <paul@boddie.org.uk>
1.12 -
1.13 -This library is free software; you can redistribute it and/or
1.14 -modify it under the terms of the GNU Lesser General Public
1.15 -License as published by the Free Software Foundation; either
1.16 -version 2.1 of the License, or (at your option) any later version.
1.17 -
1.18 -This library is distributed in the hope that it will be useful,
1.19 -but WITHOUT ANY WARRANTY; without even the implied warranty of
1.20 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1.21 -Lesser General Public License for more details.
1.22 -
1.23 -You should have received a copy of the GNU Lesser General Public
1.24 -License along with this library; if not, write to the Free Software
1.25 -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
1.26 -
1.27 ---------
1.28 -
1.29 -Desktop Detection
1.30 ------------------
1.31 -
1.32 -To detect a specific desktop environment, use the get_desktop function.
1.33 -To detect whether the desktop environment is standardised (according to the
1.34 -proposed DESKTOP_LAUNCH standard), use the is_standard function.
1.35 -
1.36 -Opening URLs
1.37 -------------
1.38 -
1.39 -To open a URL in the current desktop environment, relying on the automatic
1.40 -detection of that environment, use the desktop.open function as follows:
1.41 -
1.42 -desktop.open("http://www.python.org")
1.43 -
1.44 -To override the detected desktop, specify the desktop parameter to the open
1.45 -function as follows:
1.46 -
1.47 -desktop.open("http://www.python.org", "KDE") # Insists on KDE
1.48 -desktop.open("http://www.python.org", "GNOME") # Insists on GNOME
1.49 -
1.50 -Without overriding using the desktop parameter, the open function will attempt
1.51 -to use the "standard" desktop opening mechanism which is controlled by the
1.52 -DESKTOP_LAUNCH environment variable as described below.
1.53 -
1.54 -The DESKTOP_LAUNCH Environment Variable
1.55 ----------------------------------------
1.56 -
1.57 -The DESKTOP_LAUNCH environment variable must be shell-quoted where appropriate,
1.58 -as shown in some of the following examples:
1.59 -
1.60 -DESKTOP_LAUNCH="kdialog --msgbox" Should present any opened URLs in
1.61 - their entirety in a KDE message box.
1.62 - (Command "kdialog" plus parameter.)
1.63 -DESKTOP_LAUNCH="my\ opener" Should run the "my opener" program to
1.64 - open URLs.
1.65 - (Command "my opener", no parameters.)
1.66 -DESKTOP_LAUNCH="my\ opener --url" Should run the "my opener" program to
1.67 - open URLs.
1.68 - (Command "my opener" plus parameter.)
1.69 -
1.70 -Details of the DESKTOP_LAUNCH environment variable convention can be found here:
1.71 -http://lists.freedesktop.org/archives/xdg/2004-August/004489.html
1.72 -"""
1.73 -
1.74 -__version__ = "0.2.4"
1.75 -
1.76 -import os
1.77 -import sys
1.78 -
1.79 -# Provide suitable process creation functions.
1.80 -
1.81 -try:
1.82 - import subprocess
1.83 - def _run(cmd, shell, wait):
1.84 - opener = subprocess.Popen(cmd, shell=shell)
1.85 - if wait: opener.wait()
1.86 - return opener.pid
1.87 -
1.88 - def _readfrom(cmd, shell):
1.89 - opener = subprocess.Popen(cmd, shell=shell, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
1.90 - opener.stdin.close()
1.91 - return opener.stdout.read()
1.92 -
1.93 - def _status(cmd, shell):
1.94 - opener = subprocess.Popen(cmd, shell=shell)
1.95 - opener.wait()
1.96 - return opener.returncode == 0
1.97 -
1.98 -except ImportError:
1.99 - import popen2
1.100 - def _run(cmd, shell, wait):
1.101 - opener = popen2.Popen3(cmd)
1.102 - if wait: opener.wait()
1.103 - return opener.pid
1.104 -
1.105 - def _readfrom(cmd, shell):
1.106 - opener = popen2.Popen3(cmd)
1.107 - opener.tochild.close()
1.108 - opener.childerr.close()
1.109 - return opener.fromchild.read()
1.110 -
1.111 - def _status(cmd, shell):
1.112 - opener = popen2.Popen3(cmd)
1.113 - opener.wait()
1.114 - return opener.poll() == 0
1.115 -
1.116 -import commands
1.117 -
1.118 -# Private functions.
1.119 -
1.120 -def _is_xfce():
1.121 -
1.122 - "Return whether XFCE is in use."
1.123 -
1.124 - # XFCE detection involves testing the output of a program.
1.125 -
1.126 - try:
1.127 - if not os.environ.get("DISPLAY", "").strip():
1.128 - vars = "DISPLAY=:0.0 "
1.129 - else:
1.130 - vars = ""
1.131 - return _readfrom(vars + "xprop -root _DT_SAVE_MODE", shell=1).strip().endswith(' = "xfce4"')
1.132 -
1.133 - except OSError:
1.134 - return 0
1.135 -
1.136 -# Introspection functions.
1.137 -
1.138 -def get_desktop():
1.139 -
1.140 - """
1.141 - Detect the current desktop environment, returning the name of the
1.142 - environment. If no environment could be detected, None is returned.
1.143 - """
1.144 -
1.145 - if os.environ.has_key("KDE_FULL_SESSION") or \
1.146 - os.environ.has_key("KDE_MULTIHEAD"):
1.147 - return "KDE"
1.148 - elif os.environ.has_key("GNOME_DESKTOP_SESSION_ID") or \
1.149 - os.environ.has_key("GNOME_KEYRING_SOCKET"):
1.150 - return "GNOME"
1.151 - elif sys.platform == "darwin":
1.152 - return "Mac OS X"
1.153 - elif hasattr(os, "startfile"):
1.154 - return "Windows"
1.155 - elif _is_xfce():
1.156 - return "XFCE"
1.157 -
1.158 - # XFCE runs on X11, so we have to test for X11 last.
1.159 -
1.160 - if os.environ.has_key("DISPLAY"):
1.161 - return "X11"
1.162 - else:
1.163 - return None
1.164 -
1.165 -def use_desktop(desktop):
1.166 -
1.167 - """
1.168 - Decide which desktop should be used, based on the detected desktop and a
1.169 - supplied 'desktop' argument (which may be None). Return an identifier
1.170 - indicating the desktop type as being either "standard" or one of the results
1.171 - from the 'get_desktop' function.
1.172 - """
1.173 -
1.174 - # Attempt to detect a desktop environment.
1.175 -
1.176 - detected = get_desktop()
1.177 -
1.178 - # Start with desktops whose existence can be easily tested.
1.179 -
1.180 - if (desktop is None or desktop == "standard") and is_standard():
1.181 - return "standard"
1.182 - elif (desktop is None or desktop == "Windows") and detected == "Windows":
1.183 - return "Windows"
1.184 -
1.185 - # Test for desktops where the overriding is not verified.
1.186 -
1.187 - elif (desktop or detected) == "KDE":
1.188 - return "KDE"
1.189 - elif (desktop or detected) == "GNOME":
1.190 - return "GNOME"
1.191 - elif (desktop or detected) == "XFCE":
1.192 - return "XFCE"
1.193 - elif (desktop or detected) == "Mac OS X":
1.194 - return "Mac OS X"
1.195 - elif (desktop or detected) == "X11":
1.196 - return "X11"
1.197 - else:
1.198 - return None
1.199 -
1.200 -def is_standard():
1.201 -
1.202 - """
1.203 - Return whether the current desktop supports standardised application
1.204 - launching.
1.205 - """
1.206 -
1.207 - return os.environ.has_key("DESKTOP_LAUNCH")
1.208 -
1.209 -# Activity functions.
1.210 -
1.211 -def open(url, desktop=None, wait=0):
1.212 -
1.213 - """
1.214 - Open the 'url' in the current desktop's preferred file browser. If the
1.215 - optional 'desktop' parameter is specified then attempt to use that
1.216 - particular desktop environment's mechanisms to open the 'url' instead of
1.217 - guessing or detecting which environment is being used.
1.218 -
1.219 - Suggested values for 'desktop' are "standard", "KDE", "GNOME", "XFCE",
1.220 - "Mac OS X", "Windows" where "standard" employs a DESKTOP_LAUNCH environment
1.221 - variable to open the specified 'url'. DESKTOP_LAUNCH should be a command,
1.222 - possibly followed by arguments, and must have any special characters
1.223 - shell-escaped.
1.224 -
1.225 - The process identifier of the "opener" (ie. viewer, editor, browser or
1.226 - program) associated with the 'url' is returned by this function. If the
1.227 - process identifier cannot be determined, None is returned.
1.228 -
1.229 - An optional 'wait' parameter is also available for advanced usage and, if
1.230 - 'wait' is set to a true value, this function will wait for the launching
1.231 - mechanism to complete before returning (as opposed to immediately returning
1.232 - as is the default behaviour).
1.233 - """
1.234 -
1.235 - # Decide on the desktop environment in use.
1.236 -
1.237 - desktop_in_use = use_desktop(desktop)
1.238 -
1.239 - if desktop_in_use == "standard":
1.240 - arg = "".join([os.environ["DESKTOP_LAUNCH"], commands.mkarg(url)])
1.241 - return _run(arg, 1, wait)
1.242 -
1.243 - elif desktop_in_use == "Windows":
1.244 - # NOTE: This returns None in current implementations.
1.245 - return os.startfile(url)
1.246 -
1.247 - elif desktop_in_use == "KDE":
1.248 - cmd = ["kfmclient", "exec", url]
1.249 -
1.250 - elif desktop_in_use == "GNOME":
1.251 - cmd = ["gnome-open", url]
1.252 -
1.253 - elif desktop_in_use == "XFCE":
1.254 - cmd = ["exo-open", url]
1.255 -
1.256 - elif desktop_in_use == "Mac OS X":
1.257 - cmd = ["open", url]
1.258 -
1.259 - elif desktop_in_use == "X11" and os.environ.has_key("BROWSER"):
1.260 - cmd = [os.environ["BROWSER"], url]
1.261 -
1.262 - # Finish with an error where no suitable desktop was identified.
1.263 -
1.264 - else:
1.265 - raise OSError, "Desktop '%s' not supported (neither DESKTOP_LAUNCH nor os.startfile could be used)" % desktop_in_use
1.266 -
1.267 - return _run(cmd, 0, wait)
1.268 -
1.269 -# vim: tabstop=4 expandtab shiftwidth=4