summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFred Drake <fdrake@acm.org>2000-05-10 16:47:27 (GMT)
committerFred Drake <fdrake@acm.org>2000-05-10 16:47:27 (GMT)
commit95a40001e618a7f11ae7091b707459a01cd65af9 (patch)
treeb861684a1f0f007b7fd620c0eb4aaa76789494f2
parent9cfce18c4f73adb74f7a3eba16c8aa40f38770d7 (diff)
downloadcpython-95a40001e618a7f11ae7091b707459a01cd65af9.zip
cpython-95a40001e618a7f11ae7091b707459a01cd65af9.tar.gz
cpython-95a40001e618a7f11ae7091b707459a01cd65af9.tar.bz2
Collection of classes and convenience functions to control external
Web browsers.
-rwxr-xr-xTools/idle/browser.py157
1 files changed, 157 insertions, 0 deletions
diff --git a/Tools/idle/browser.py b/Tools/idle/browser.py
new file mode 100755
index 0000000..3829d49
--- /dev/null
+++ b/Tools/idle/browser.py
@@ -0,0 +1,157 @@
+"""Remote-control interfaces to some browsers."""
+
+import os
+import string
+import sys
+
+
+DEFAULT_CONFIG_FILE = "~/.browser.ini"
+PROCESS_CREATION_DELAY = 4
+
+DEFAULT_BROWSER = "netscape"
+
+_browsers = {}
+
+
+def get(name=None):
+ if name is None:
+ name = get_default_browser()
+ else:
+ name = string.lower(name)
+ L = _browsers[name]
+ if L[1] is None:
+ L[1] = L[0]()
+ return L[1]
+
+
+def get_default_browser(file=None):
+ if file is None:
+ files = [DEFAULT_CONFIG_FILE]
+ else:
+ files = [file, DEFAULT_CONFIG_FILE]
+ for file in files:
+ file = os.path.expandvars(os.path.expanduser(file))
+ if file and os.path.isfile(file):
+ import ConfigParser
+ cf = ConfigParser.ConfigParser()
+ cf.read([file])
+ try:
+ return string.lower(cf.get("Browser", "name"))
+ except ConfigParser.Error:
+ pass
+ return DEFAULT_BROWSER
+
+
+_default_browser = None
+
+def _get_browser():
+ global _default_browser
+ if _default_browser is None:
+ _default_browser = get()
+ return _default_browser
+
+
+def open(url, new=0):
+ _get_browser().open(url, new)
+
+
+def open_new(url):
+ _get_browser().open_new(url)
+
+
+def register(name, klass):
+ _browsers[string.lower(name)] = [klass, None]
+
+
+class Netscape:
+ autoRaise = 0
+
+ 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
+ try:
+ win32api.ShellExecute(0, "open", url, None, ".",
+ win32con.SW_SHOWNORMAL)
+ except:
+ traceback.print_exc()
+ raise
+
+ def open_new(self, url):
+ self.open(url)
+
+if sys.platform[:3] == "win":
+ register("windows-default", WindowsDefault)
+ DEFAULT_BROWSER = "windows-default"