home *** CD-ROM | disk | FTP | other *** search
/ PC World 2001 April / PCWorld_2001-04_cd.bin / Software / TemaCD / webclean / !!!python!!! / BeOpen-Python-2.0.exe / WEBBROWSER.PY < prev    next >
Encoding:
Python Source  |  2000-10-02  |  5.7 KB  |  226 lines

  1. """Remote-control interfaces to some browsers."""
  2.  
  3. import os
  4. import sys
  5.  
  6.  
  7. PROCESS_CREATION_DELAY = 4
  8.  
  9.  
  10. class Error(Exception):
  11.     pass
  12.  
  13.  
  14. _browsers = {}
  15.  
  16. def register(name, klass, instance=None):
  17.     """Register a browser connector and, optionally, connection."""
  18.     _browsers[name.lower()] = [klass, instance]
  19.  
  20.  
  21. def get(name=None):
  22.     """Retrieve a connection to a browser by type name, or the default
  23.     browser."""
  24.     name = name or DEFAULT_BROWSER
  25.     try:
  26.         L = _browsers[name.lower()]
  27.     except KeyError:
  28.         raise ValueError, "unknown browser type: " + `name`
  29.     if L[1] is None:
  30.         L[1] = L[0]()
  31.     return L[1]
  32.  
  33.  
  34. # Please note: the following definition hides a builtin function.
  35.  
  36. def open(url, new=0):
  37.     get().open(url, new)
  38.  
  39.  
  40. def open_new(url):
  41.     get().open_new(url)
  42.  
  43.  
  44. def _iscommand(cmd):
  45.     """Return true if cmd can be found on the executable search path."""
  46.     path = os.environ.get("PATH")
  47.     if not path:
  48.         return 0
  49.     for d in path.split(os.pathsep):
  50.         exe = os.path.join(d, cmd)
  51.         if os.path.isfile(exe):
  52.             return 1
  53.     return 0
  54.  
  55.  
  56. class CommandLineBrowser:
  57.     _browsers = []
  58.     if os.environ.get("DISPLAY"):
  59.         _browsers.extend([
  60.             ("netscape", "netscape %s >/dev/null &"),
  61.             ("mosaic", "mosaic %s >/dev/null &"),
  62.             ])
  63.     _browsers.extend([
  64.         ("lynx", "lynx %s"),
  65.         ("w3m", "w3m %s"),
  66.         ])
  67.  
  68.     def open(self, url, new=0):
  69.         for exe, cmd in self._browsers:
  70.             if _iscommand(exe):
  71.                 os.system(cmd % url)
  72.                 return
  73.         raise Error("could not locate runnable browser")
  74.  
  75.     def open_new(self, url):
  76.         self.open(url)
  77.  
  78. register("command-line", CommandLineBrowser)
  79.  
  80.  
  81. class Netscape:
  82.     autoRaise = 1
  83.  
  84.     def _remote(self, action):
  85.         raise_opt = ("-noraise", "-raise")[self.autoRaise]
  86.         cmd = "netscape %s -remote '%s' >/dev/null 2>&1" % (raise_opt, action)
  87.         rc = os.system(cmd)
  88.         if rc:
  89.             import time
  90.             os.system("netscape -no-about-splash &")
  91.             time.sleep(PROCESS_CREATION_DELAY)
  92.             rc = os.system(cmd)
  93.         return not rc
  94.  
  95.     def open(self, url, new=0):
  96.         if new:
  97.             self.open_new(url)
  98.         else:
  99.             self._remote("openURL(%s)" % url)
  100.  
  101.     def open_new(self, url):
  102.         self._remote("openURL(%s, new-window)" % url)
  103.  
  104. register("netscape", Netscape)
  105.  
  106.  
  107. class Konquerer:
  108.     """Controller for the KDE File Manager (kfm, or Konquerer).
  109.  
  110.     See http://developer.kde.org/documentation/other/kfmclient.html
  111.     for more information on the Konquerer remote-control interface.
  112.  
  113.     """
  114.     def _remote(self, action):
  115.         cmd = "kfmclient %s >/dev/null 2>&1" % action
  116.         rc = os.system(cmd)
  117.         if rc:
  118.             import time
  119.             os.system("kfm -d &")
  120.             time.sleep(PROCESS_CREATION_DELAY)
  121.             rc = os.system(cmd)
  122.         return not rc
  123.  
  124.     def open(self, url, new=1):
  125.     # XXX currently I know no way to prevent KFM from opening a new win.
  126.         self.open_new(url)
  127.  
  128.     def open_new(self, url):
  129.         self._remote("openURL %s" % url)
  130.  
  131. register("kfm", Konquerer)
  132.  
  133.  
  134. class Grail:
  135.     # There should be a way to maintain a connection to Grail, but the
  136.     # Grail remote control protocol doesn't really allow that at this
  137.     # point.  It probably never will!
  138.  
  139.     def _find_grail_rc(self):
  140.         import glob
  141.         import pwd
  142.         import socket
  143.         import tempfile
  144.         tempdir = os.path.join(tempfile.gettempdir(), ".grail-unix")
  145.         user = pwd.getpwuid(_os.getuid())[0]
  146.         filename = os.path.join(tempdir, user + "-*")
  147.         maybes = glob.glob(filename)
  148.         if not maybes:
  149.             return None
  150.         s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
  151.         for fn in maybes:
  152.             # need to PING each one until we find one that's live
  153.             try:
  154.                 s.connect(fn)
  155.             except socket.error:
  156.                 # no good; attempt to clean it out, but don't fail:
  157.                 try:
  158.                     os.unlink(fn)
  159.                 except IOError:
  160.                     pass
  161.             else:
  162.                 return s
  163.  
  164.     def _remote(self, action):
  165.         s = self._find_grail_rc()
  166.         if not s:
  167.             return 0
  168.         s.send(action)
  169.         s.close()
  170.         return 1
  171.  
  172.     def open(self, url, new=0):
  173.         if new:
  174.             self.open_new(url)
  175.         else:
  176.             self._remote("LOAD " + url)
  177.  
  178.     def open_new(self, url):
  179.         self._remote("LOADNEW " + url)
  180.  
  181. register("grail", Grail)
  182.  
  183.  
  184. class WindowsDefault:
  185.     def open(self, url, new=0):
  186.         os.startfile(url)
  187.  
  188.     def open_new(self, url):
  189.         self.open(url)
  190.  
  191.  
  192. DEFAULT_BROWSER = "command-line"
  193.  
  194. if sys.platform[:3] == "win":
  195.     del _browsers["kfm"]
  196.     register("windows-default", WindowsDefault)
  197.     DEFAULT_BROWSER = "windows-default"
  198. elif os.environ.get("DISPLAY"):
  199.     if _iscommand("netscape"):
  200.         DEFAULT_BROWSER = "netscape"
  201.  
  202. # If the $BROWSER environment variable is set and true, let that be
  203. # the name of the browser to use:
  204. #
  205. DEFAULT_BROWSER = os.environ.get("BROWSER") or DEFAULT_BROWSER
  206.  
  207.  
  208. # Now try to support the MacOS world.  This is the only supported
  209. # controller on that platform, so don't mess with the default!
  210.  
  211. try:
  212.     import ic
  213. except ImportError:
  214.     pass
  215. else:
  216.     class InternetConfig:
  217.         def open(self, url, new=0):
  218.             ic.launcurl(url)
  219.  
  220.         def open_new(self, url):
  221.             self.open(url)
  222.  
  223.     _browsers.clear()
  224.     register("internet-config", InternetConfig)
  225.     DEFAULT_BROWSER = "internet-config"
  226.