# HG changeset patch # User paulb # Date 1196642224 0 # Node ID 7cea22629e6b14795c6b7da2f6f417c16c99dda4 # Parent c181ebeec757742189a76e0b5eda398e1a49ba5e [project @ 2007-12-03 00:37:04 by paulb] Converted the desktop module into a package. diff -r c181ebeec757 -r 7cea22629e6b desktop.py --- a/desktop.py Wed Oct 15 23:18:30 2008 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,266 +0,0 @@ -#!/usr/bin/env python - -""" -Simple desktop integration for Python. This module provides desktop environment -detection and resource opening support for a selection of common and -standardised desktop environments. - -Copyright (C) 2005, 2006, 2007 Paul Boddie - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - --------- - -Desktop Detection ------------------ - -To detect a specific desktop environment, use the get_desktop function. -To detect whether the desktop environment is standardised (according to the -proposed DESKTOP_LAUNCH standard), use the is_standard function. - -Opening URLs ------------- - -To open a URL in the current desktop environment, relying on the automatic -detection of that environment, use the desktop.open function as follows: - -desktop.open("http://www.python.org") - -To override the detected desktop, specify the desktop parameter to the open -function as follows: - -desktop.open("http://www.python.org", "KDE") # Insists on KDE -desktop.open("http://www.python.org", "GNOME") # Insists on GNOME - -Without overriding using the desktop parameter, the open function will attempt -to use the "standard" desktop opening mechanism which is controlled by the -DESKTOP_LAUNCH environment variable as described below. - -The DESKTOP_LAUNCH Environment Variable ---------------------------------------- - -The DESKTOP_LAUNCH environment variable must be shell-quoted where appropriate, -as shown in some of the following examples: - -DESKTOP_LAUNCH="kdialog --msgbox" Should present any opened URLs in - their entirety in a KDE message box. - (Command "kdialog" plus parameter.) -DESKTOP_LAUNCH="my\ opener" Should run the "my opener" program to - open URLs. - (Command "my opener", no parameters.) -DESKTOP_LAUNCH="my\ opener --url" Should run the "my opener" program to - open URLs. - (Command "my opener" plus parameter.) - -Details of the DESKTOP_LAUNCH environment variable convention can be found here: -http://lists.freedesktop.org/archives/xdg/2004-August/004489.html -""" - -__version__ = "0.2.4" - -import os -import sys - -# Provide suitable process creation functions. - -try: - import subprocess - def _run(cmd, shell, wait): - opener = subprocess.Popen(cmd, shell=shell) - if wait: opener.wait() - return opener.pid - - def _readfrom(cmd, shell): - opener = subprocess.Popen(cmd, shell=shell, stdin=subprocess.PIPE, stdout=subprocess.PIPE) - opener.stdin.close() - return opener.stdout.read() - - def _status(cmd, shell): - opener = subprocess.Popen(cmd, shell=shell) - opener.wait() - return opener.returncode == 0 - -except ImportError: - import popen2 - def _run(cmd, shell, wait): - opener = popen2.Popen3(cmd) - if wait: opener.wait() - return opener.pid - - def _readfrom(cmd, shell): - opener = popen2.Popen3(cmd) - opener.tochild.close() - opener.childerr.close() - return opener.fromchild.read() - - def _status(cmd, shell): - opener = popen2.Popen3(cmd) - opener.wait() - return opener.poll() == 0 - -import commands - -# Private functions. - -def _is_xfce(): - - "Return whether XFCE is in use." - - # XFCE detection involves testing the output of a program. - - try: - if not os.environ.get("DISPLAY", "").strip(): - vars = "DISPLAY=:0.0 " - else: - vars = "" - return _readfrom(vars + "xprop -root _DT_SAVE_MODE", shell=1).strip().endswith(' = "xfce4"') - - except OSError: - return 0 - -# Introspection functions. - -def get_desktop(): - - """ - Detect the current desktop environment, returning the name of the - environment. If no environment could be detected, None is returned. - """ - - if os.environ.has_key("KDE_FULL_SESSION") or \ - os.environ.has_key("KDE_MULTIHEAD"): - return "KDE" - elif os.environ.has_key("GNOME_DESKTOP_SESSION_ID") or \ - os.environ.has_key("GNOME_KEYRING_SOCKET"): - return "GNOME" - elif sys.platform == "darwin": - return "Mac OS X" - elif hasattr(os, "startfile"): - return "Windows" - elif _is_xfce(): - return "XFCE" - - # XFCE runs on X11, so we have to test for X11 last. - - if os.environ.has_key("DISPLAY"): - return "X11" - else: - return None - -def use_desktop(desktop): - - """ - Decide which desktop should be used, based on the detected desktop and a - supplied 'desktop' argument (which may be None). Return an identifier - indicating the desktop type as being either "standard" or one of the results - from the 'get_desktop' function. - """ - - # Attempt to detect a desktop environment. - - detected = get_desktop() - - # Start with desktops whose existence can be easily tested. - - if (desktop is None or desktop == "standard") and is_standard(): - return "standard" - elif (desktop is None or desktop == "Windows") and detected == "Windows": - return "Windows" - - # Test for desktops where the overriding is not verified. - - elif (desktop or detected) == "KDE": - return "KDE" - elif (desktop or detected) == "GNOME": - return "GNOME" - elif (desktop or detected) == "XFCE": - return "XFCE" - elif (desktop or detected) == "Mac OS X": - return "Mac OS X" - elif (desktop or detected) == "X11": - return "X11" - else: - return None - -def is_standard(): - - """ - Return whether the current desktop supports standardised application - launching. - """ - - return os.environ.has_key("DESKTOP_LAUNCH") - -# Activity functions. - -def open(url, desktop=None, wait=0): - - """ - Open the 'url' in the current desktop's preferred file browser. If the - optional 'desktop' parameter is specified then attempt to use that - particular desktop environment's mechanisms to open the 'url' instead of - guessing or detecting which environment is being used. - - Suggested values for 'desktop' are "standard", "KDE", "GNOME", "XFCE", - "Mac OS X", "Windows" where "standard" employs a DESKTOP_LAUNCH environment - variable to open the specified 'url'. DESKTOP_LAUNCH should be a command, - possibly followed by arguments, and must have any special characters - shell-escaped. - - The process identifier of the "opener" (ie. viewer, editor, browser or - program) associated with the 'url' is returned by this function. If the - process identifier cannot be determined, None is returned. - - An optional 'wait' parameter is also available for advanced usage and, if - 'wait' is set to a true value, this function will wait for the launching - mechanism to complete before returning (as opposed to immediately returning - as is the default behaviour). - """ - - # Decide on the desktop environment in use. - - desktop_in_use = use_desktop(desktop) - - if desktop_in_use == "standard": - arg = "".join([os.environ["DESKTOP_LAUNCH"], commands.mkarg(url)]) - return _run(arg, 1, wait) - - elif desktop_in_use == "Windows": - # NOTE: This returns None in current implementations. - return os.startfile(url) - - elif desktop_in_use == "KDE": - cmd = ["kfmclient", "exec", url] - - elif desktop_in_use == "GNOME": - cmd = ["gnome-open", url] - - elif desktop_in_use == "XFCE": - cmd = ["exo-open", url] - - elif desktop_in_use == "Mac OS X": - cmd = ["open", url] - - elif desktop_in_use == "X11" and os.environ.has_key("BROWSER"): - cmd = [os.environ["BROWSER"], url] - - # Finish with an error where no suitable desktop was identified. - - else: - raise OSError, "Desktop '%s' not supported (neither DESKTOP_LAUNCH nor os.startfile could be used)" % desktop_in_use - - return _run(cmd, 0, wait) - -# vim: tabstop=4 expandtab shiftwidth=4