[Python-Dev] webbrowser module

Fred L. Drake, Jr. fdrake@beopen.com
Thu, 6 Jul 2000 23:40:33 -0400 (EDT)


--av8WMY8/pQ
Content-Type: text/plain; charset=us-ascii
Content-Description: message body and .signature
Content-Transfer-Encoding: 7bit


  Ok, I've checked in the documentation for the webbrowser
documentation.  The implementation can go in as soon as SF clears a
bogus read lock (support request files 6.5 hours ago).
  Well, I said I knew about InternetConfig for MacOS, but I clearly
hadn't read the documentation!  Getting this module working on MacOS
is a trivial matter, if the docs are to be believed.  If someone with
a Mac could test it with a script like:

import webbrowser
webbrowser.open("http://www.python.org/")

and let me know what happens, I'd really appreciate it!
  I've attached the version with Mac support below.


  -Fred

-- 
Fred L. Drake, Jr.  <fdrake at beopen.com>
BeOpen PythonLabs Team Member


--av8WMY8/pQ
Content-Type: text/x-python
Content-Description: web browser controller module
Content-Disposition: inline;
	filename="webbrowser.py"
Content-Transfer-Encoding: 7bit

"""Remote-control interfaces to some browsers."""

import os
import sys


PROCESS_CREATION_DELAY = 4


class Error(Exception):
    pass


_browsers = {}

def register(name, klass, instance=None):
    """Register a browser connector and, optionally, connection."""
    _browsers[name.lower()] = [klass, instance]


def get(name=None):
    """Retrieve a connection to a browser by type name, or the default
    browser."""
    name = name or DEFAULT_BROWSER
    try:
        L = _browsers[name.lower()]
    except KeyError:
        raise ValueError, "unknown browser type: " + `name`
    if L[1] is None:
        L[1] = L[0]()
    return L[1]


def open(url, new=0):
    get().open(url, new)


def open_new(url):
    get().open_new(url)


def _iscommand(cmd):
    """Return true if cmd can be found on the executable search path."""
    path = os.environ.get("PATH")
    if not path:
        return 0
    for d in path.split(os.pathsep):
        exe = os.path.join(d, cmd)
        if os.path.isfile(exe):
            return 1
    return 0


class CommandLineBrowser:
    _browsers = []
    if os.environ.get("DISPLAY"):
        _browsers.extend([
            ("netscape", "netscape %s >/dev/null &"),
            ("mosaic", "mosaic %s >/dev/null &"),
            ])
    _browsers.extend([
        ("lynx", "lynx %s"),
        ("w3m", "w3m %s"),
        ])

    def open(self, url, new=0):
        for exe, cmd in self._browsers:
            if _iscommand(exe):
                os.system(cmd % url)
                return
        raise Error("could not locate runnable browser")

    def open_new(self, url):
        self.open(url)

register("command-line", CommandLineBrowser)


class Netscape:
    autoRaise = 1

    def _remote(self, action):
        raise_opt = ("-noraise", "-raise")[self.autoRaise]
        cmd = "netscape %s -remote '%s' >/dev/null 2>&1" % (raise_opt, action)
        rc = os.system(cmd)
        if rc:
            import time
            os.system("netscape -no-about-splash &")
            time.sleep(PROCESS_CREATION_DELAY)
            rc = os.system(cmd)
        return not rc

    def open(self, url, new=0):
        if new:
            self.open_new(url)
        else:
            self._remote("openURL(%s)" % url)

    def open_new(self, url):
        self._remote("openURL(%s, new-window)" % url)

register("netscape", Netscape)


class Grail:
    # There should be a way to maintain a connection to Grail, but the
    # Grail remote control protocol doesn't really allow that at this
    # point.  It probably never will!

    def _find_grail_rc(self):
        import glob
        import pwd
        import socket
        import tempfile
        tempdir = os.path.join(tempfile.gettempdir(), ".grail-unix")
        user = pwd.getpwuid(_os.getuid())[0]
        filename = os.path.join(tempdir, user + "-*")
        maybes = glob.glob(filename)
        if not maybes:
            return None
        s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        for fn in maybes:
            # need to PING each one until we find one that's live
            try:
                s.connect(fn)
            except socket.error:
                # no good; attempt to clean it out, but don't fail:
                try:
                    os.unlink(fn)
                except IOError:
                    pass
            else:
                return s

    def _remote(self, action):
        s = self._find_grail_rc()
        if not s:
            return 0
        s.send(action)
        s.close()
        return 1

    def open(self, url, new=0):
        if new:
            self.open_new(url)
        else:
            self._remote("LOAD " + url)

    def open_new(self, url):
        self._remote("LOADNEW " + url)

register("grail", Grail)


class WindowsDefault:
    def open(self, url, new=0):
        import win32api, win32con
        win32api.ShellExecute(0, "open", url, None, ".",
                              win32con.SW_SHOWNORMAL)

    def open_new(self, url):
        self.open(url)


if sys.platform[:3] == "win":
    register("windows-default", WindowsDefault)
    DEFAULT_BROWSER = "windows-default"
elif not os.environ.get("DISPLAY"):
    DEFAULT_BROWSER = "command-line-browser"
else:
    DEFAULT_BROWSER = "netscape"

# If the $BROWSER environment variable is set and true, let that be
# the name of the browser to use:
#
DEFAULT_BROWSER = os.environ.get("BROWSER") or DEFAULT_BROWSER


# Now try to support the MacOS world.  This is the only supported
# controller on that platform, so don't mess with the default!

try:
    import ic
except ImportError:
    pass
else:
    class InternetConfig:
        def open(self, url, new=0):
            ic.launcurl(url)

        def open_new(self, url):
            self.open(url)

    _browsers.clear()
    register("internet-config", InternetConfig)
    DEFAULT_BROWSER = "internet-config"

--av8WMY8/pQ--