[Python-Dev] urllib.browse() issues
Fred L. Drake, Jr.
fdrake@beopen.com
Thu, 6 Jul 2000 21:09:35 -0400 (EDT)
--wbCaznGdGX
Content-Type: text/plain; charset=us-ascii
Content-Description: message body and .signature
Content-Transfer-Encoding: 7bit
Eric S. Raymond writes:
> there's a functionally similar name/value pair facility available
> through system resource forks on the Mac. I really think a profile
> file is excessively heavyweight here. Environment variables or X
I still haven't heard from any MacOS users what the "right" way to
do this sort of thing is. Jack, Sjoerd, Just... are you listening?
> I've actually been seriously thinking, once this is in the Python
> library, of going to the Perl and Tcl people and giving them code that
> would make *their* standard libraries do the right thing with the
> BROWSER variable. It shouldn't only be portable across Python
> applications, but across scripting languages as well -- something that
> would be much harder to do with an .ini file.
I don't buy that using a config file is harder for those languages,
but I think providing similar functionality for all is a great idea.
Ok, here's a version that keeps the idea of a register() function,
but simplifies the machinery quite a bit. Instead of using a config
file, the BROWSER environment variable is used. If not set, the
default on Windows is to use the Windows default setting. On Unix,
the default is Netscape if $DISPLAY is set, otherwise it's the
"command line browser", which tries, in order: netscape, mosaic(!),
lync, and w3m. I left out Mozilla since I couldn't get it to work at
all last time I tried it (though I've had better results previously).
-Fred
--
Fred L. Drake, Jr. <fdrake at beopen.com>
BeOpen PythonLabs Team Member
--wbCaznGdGX
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-browser", 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
--wbCaznGdGX--