| """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" |