desktop

Change of desktop.py

45:7cea22629e6b
desktop.py
     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