diff options
Diffstat (limited to 'Lib/webbrowser.py')
-rw-r--r-- | Lib/webbrowser.py | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/Lib/webbrowser.py b/Lib/webbrowser.py new file mode 100644 index 0000000..5a4a80f --- /dev/null +++ b/Lib/webbrowser.py @@ -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" |