mirror of
https://github.com/python/cpython.git
synced 2025-10-09 16:34:44 +00:00
New module to control Web browsers; see the documentation for
more information.
This commit is contained in:
parent
dbbf76bd5a
commit
c70b4483d2
1 changed files with 229 additions and 0 deletions
229
Lib/webbrowser.py
Normal file
229
Lib/webbrowser.py
Normal file
|
@ -0,0 +1,229 @@
|
|||
"""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]
|
||||
|
||||
|
||||
# Please note: the following definition hides a builtin function.
|
||||
|
||||
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 Konquerer:
|
||||
"""Controller for the KDE File Manager (kfm, or Konquerer).
|
||||
|
||||
See http://developer.kde.org/documentation/other/kfmclient.html
|
||||
for more information on the Konquerer remote-control interface.
|
||||
|
||||
"""
|
||||
def _remote(self, action):
|
||||
cmd = "kfmclient %s >/dev/null 2>&1" % action
|
||||
rc = os.system(cmd)
|
||||
if rc:
|
||||
import time
|
||||
os.system("kfm -d &")
|
||||
time.sleep(PROCESS_CREATION_DELAY)
|
||||
rc = os.system(cmd)
|
||||
return not rc
|
||||
|
||||
def open(self, url, new=1):
|
||||
# XXX currently I know no way to prevent KFM from opening a new win.
|
||||
self.open_new(url)
|
||||
|
||||
def open_new(self, url):
|
||||
self._remote("openURL %s" % url)
|
||||
|
||||
register("kfm", Konquerer)
|
||||
|
||||
|
||||
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)
|
||||
|
||||
|
||||
DEFAULT_BROWSER = "command-line"
|
||||
|
||||
if sys.platform[:3] == "win":
|
||||
del _browsers["kfm"]
|
||||
register("windows-default", WindowsDefault)
|
||||
DEFAULT_BROWSER = "windows-default"
|
||||
elif os.environ.get("DISPLAY"):
|
||||
if os.environ.get("KDEDIR"):
|
||||
DEFAULT_BROWSER = "kfm"
|
||||
elif _iscommand("netscape"):
|
||||
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"
|
Loading…
Add table
Add a link
Reference in a new issue