home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 December / CHIP_CD_2004-12.iso / bonus / oo / OOo_1.1.3_ru_RU_infra_WinIntel_install.exe / $PLUGINSDIR / f_0372 / python-core-2.2.2 / lib / webbrowser.py < prev    next >
Text File  |  2004-10-09  |  10KB  |  331 lines

  1. """Interfaces for launching and remotely controlling Web browsers."""
  2.  
  3. import os
  4. import sys
  5.  
  6. __all__ = ["Error", "open", "get", "register"]
  7.  
  8. class Error(Exception):
  9.     pass
  10.  
  11. _browsers = {}          # Dictionary of available browser controllers
  12. _tryorder = []          # Preference order of available browsers
  13.  
  14. def register(name, klass, instance=None):
  15.     """Register a browser connector and, optionally, connection."""
  16.     _browsers[name.lower()] = [klass, instance]
  17.  
  18. def get(using=None):
  19.     """Return a browser launcher instance appropriate for the environment."""
  20.     if using:
  21.         alternatives = [using]
  22.     else:
  23.         alternatives = _tryorder
  24.     for browser in alternatives:
  25.         if browser.find('%s') > -1:
  26.             # User gave us a command line, don't mess with it.
  27.             return GenericBrowser(browser)
  28.         else:
  29.             # User gave us a browser name.
  30.             try:
  31.                 command = _browsers[browser.lower()]
  32.             except KeyError:
  33.                 command = _synthesize(browser)
  34.             if command[1] is None:
  35.                 return command[0]()
  36.             else:
  37.                 return command[1]
  38.     raise Error("could not locate runnable browser")
  39.  
  40. # Please note: the following definition hides a builtin function.
  41.  
  42. def open(url, new=0, autoraise=1):
  43.     get().open(url, new, autoraise)
  44.  
  45. def open_new(url):
  46.     get().open(url, 1)
  47.  
  48.  
  49. def _synthesize(browser):
  50.     """Attempt to synthesize a controller base on existing controllers.
  51.  
  52.     This is useful to create a controller when a user specifies a path to
  53.     an entry in the BROWSER environment variable -- we can copy a general
  54.     controller to operate using a specific installation of the desired
  55.     browser in this way.
  56.  
  57.     If we can't create a controller in this way, or if there is no
  58.     executable for the requested browser, return [None, None].
  59.  
  60.     """
  61.     if not os.path.exists(browser):
  62.         return [None, None]
  63.     name = os.path.basename(browser)
  64.     try:
  65.         command = _browsers[name.lower()]
  66.     except KeyError:
  67.         return [None, None]
  68.     # now attempt to clone to fit the new name:
  69.     controller = command[1]
  70.     if controller and name.lower() == controller.basename:
  71.         import copy
  72.         controller = copy.copy(controller)
  73.         controller.name = browser
  74.         controller.basename = os.path.basename(browser)
  75.         register(browser, None, controller)
  76.         return [None, controller]
  77.     return [None, None]
  78.  
  79.  
  80. def _iscommand(cmd):
  81.     """Return true if cmd can be found on the executable search path."""
  82.     path = os.environ.get("PATH")
  83.     if not path:
  84.         return 0
  85.     for d in path.split(os.pathsep):
  86.         exe = os.path.join(d, cmd)
  87.         if os.path.isfile(exe):
  88.             return 1
  89.     return 0
  90.  
  91.  
  92. PROCESS_CREATION_DELAY = 4
  93.  
  94.  
  95. class GenericBrowser:
  96.     def __init__(self, cmd):
  97.         self.name, self.args = cmd.split(None, 1)
  98.         self.basename = os.path.basename(self.name)
  99.  
  100.     def open(self, url, new=0, autoraise=1):
  101.         assert "'" not in url
  102.         command = "%s %s" % (self.name, self.args)
  103.         os.system(command % url)
  104.  
  105.     def open_new(self, url):
  106.         self.open(url)
  107.  
  108.  
  109. class Netscape:
  110.     "Launcher class for Netscape browsers."
  111.     def __init__(self, name):
  112.         self.name = name
  113.         self.basename = os.path.basename(name)
  114.  
  115.     def _remote(self, action, autoraise):
  116.         raise_opt = ("-noraise", "-raise")[autoraise]
  117.         cmd = "%s %s -remote '%s' >/dev/null 2>&1" % (self.name,
  118.                                                       raise_opt,
  119.                                                       action)
  120.         rc = os.system(cmd)
  121.         if rc:
  122.             import time
  123.             os.system("%s &" % self.name)
  124.             time.sleep(PROCESS_CREATION_DELAY)
  125.             rc = os.system(cmd)
  126.         return not rc
  127.  
  128.     def open(self, url, new=0, autoraise=1):
  129.         if new:
  130.             self._remote("openURL(%s, new-window)"%url, autoraise)
  131.         else:
  132.             self._remote("openURL(%s)" % url, autoraise)
  133.  
  134.     def open_new(self, url):
  135.         self.open(url, 1)
  136.  
  137.  
  138. class Konqueror:
  139.     """Controller for the KDE File Manager (kfm, or Konqueror).
  140.  
  141.     See http://developer.kde.org/documentation/other/kfmclient.html
  142.     for more information on the Konqueror remote-control interface.
  143.  
  144.     """
  145.     def __init__(self):
  146.         if _iscommand("konqueror"):
  147.             self.name = self.basename = "konqueror"
  148.         else:
  149.             self.name = self.basename = "kfm"
  150.  
  151.     def _remote(self, action):
  152.         cmd = "kfmclient %s >/dev/null 2>&1" % action
  153.         rc = os.system(cmd)
  154.         if rc:
  155.             import time
  156.             if self.basename == "konqueror":
  157.                 os.system(self.name + " --silent &")
  158.             else:
  159.                 os.system(self.name + " -d &")
  160.             time.sleep(PROCESS_CREATION_DELAY)
  161.             rc = os.system(cmd)
  162.         return not rc
  163.  
  164.     def open(self, url, new=1, autoraise=1):
  165.         # XXX Currently I know no way to prevent KFM from
  166.         # opening a new win.
  167.         assert "'" not in url
  168.         self._remote("openURL '%s'" % url)
  169.  
  170.     open_new = open
  171.  
  172.  
  173. class Grail:
  174.     # There should be a way to maintain a connection to Grail, but the
  175.     # Grail remote control protocol doesn't really allow that at this
  176.     # point.  It probably neverwill!
  177.     def _find_grail_rc(self):
  178.         import glob
  179.         import pwd
  180.         import socket
  181.         import tempfile
  182.         tempdir = os.path.join(tempfile.gettempdir(),
  183.                                ".grail-unix")
  184.         user = pwd.getpwuid(os.getuid())[0]
  185.         filename = os.path.join(tempdir, user + "-*")
  186.         maybes = glob.glob(filename)
  187.         if not maybes:
  188.             return None
  189.         s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
  190.         for fn in maybes:
  191.             # need to PING each one until we find one that's live
  192.             try:
  193.                 s.connect(fn)
  194.             except socket.error:
  195.                 # no good; attempt to clean it out, but don't fail:
  196.                 try:
  197.                     os.unlink(fn)
  198.                 except IOError:
  199.                     pass
  200.             else:
  201.                 return s
  202.  
  203.     def _remote(self, action):
  204.         s = self._find_grail_rc()
  205.         if not s:
  206.             return 0
  207.         s.send(action)
  208.         s.close()
  209.         return 1
  210.  
  211.     def open(self, url, new=0, autoraise=1):
  212.         if new:
  213.             self._remote("LOADNEW " + url)
  214.         else:
  215.             self._remote("LOAD " + url)
  216.  
  217.     def open_new(self, url):
  218.         self.open(url, 1)
  219.  
  220.  
  221. class WindowsDefault:
  222.     def open(self, url, new=0, autoraise=1):
  223.         os.startfile(url)
  224.  
  225.     def open_new(self, url):
  226.         self.open(url)
  227.  
  228. #
  229. # Platform support for Unix
  230. #
  231.  
  232. # This is the right test because all these Unix browsers require either
  233. # a console terminal of an X display to run.  Note that we cannot split
  234. # the TERM and DISPLAY cases, because we might be running Python from inside
  235. # an xterm.
  236. if os.environ.get("TERM") or os.environ.get("DISPLAY"):
  237.     _tryorder = ["mozilla","netscape","kfm","grail","links","lynx","w3m"]
  238.  
  239.     # Easy cases first -- register console browsers if we have them.
  240.     if os.environ.get("TERM"):
  241.         # The Links browser <http://artax.karlin.mff.cuni.cz/~mikulas/links/>
  242.         if _iscommand("links"):
  243.             register("links", None, GenericBrowser("links '%s'"))
  244.         # The Lynx browser <http://lynx.browser.org/>
  245.         if _iscommand("lynx"):
  246.             register("lynx", None, GenericBrowser("lynx '%s'"))
  247.         # The w3m browser <http://ei5nazha.yz.yamagata-u.ac.jp/~aito/w3m/eng/>
  248.         if _iscommand("w3m"):
  249.             register("w3m", None, GenericBrowser("w3m '%s'"))
  250.  
  251.     # X browsers have more in the way of options
  252.     if os.environ.get("DISPLAY"):
  253.         # First, the Netscape series
  254.         if _iscommand("mozilla"):
  255.             register("mozilla", None, Netscape("mozilla"))
  256.         if _iscommand("netscape"):
  257.             register("netscape", None, Netscape("netscape"))
  258.  
  259.         # Next, Mosaic -- old but still in use.
  260.         if _iscommand("mosaic"):
  261.             register("mosaic", None, GenericBrowser(
  262.                 "mosaic '%s' >/dev/null &"))
  263.  
  264.         # Konqueror/kfm, the KDE browser.
  265.         if _iscommand("kfm") or _iscommand("konqueror"):
  266.             register("kfm", Konqueror, Konqueror())
  267.  
  268.         # Grail, the Python browser.
  269.         if _iscommand("grail"):
  270.             register("grail", Grail, None)
  271.  
  272.  
  273. class InternetConfig:
  274.     def open(self, url, new=0, autoraise=1):
  275.         ic.launchurl(url)
  276.  
  277.     def open_new(self, url):
  278.         self.open(url)
  279.  
  280.  
  281. #
  282. # Platform support for Windows
  283. #
  284.  
  285. if sys.platform[:3] == "win":
  286.     _tryorder = ["netscape", "windows-default"]
  287.     register("windows-default", WindowsDefault)
  288.  
  289. #
  290. # Platform support for MacOS
  291. #
  292.  
  293. try:
  294.     import ic
  295. except ImportError:
  296.     pass
  297. else:
  298.     # internet-config is the only supported controller on MacOS,
  299.     # so don't mess with the default!
  300.     _tryorder = ["internet-config"]
  301.     register("internet-config", InternetConfig)
  302.  
  303. #
  304. # Platform support for OS/2
  305. #
  306.  
  307. if sys.platform[:3] == "os2" and _iscommand("netscape.exe"):
  308.     _tryorder = ["os2netscape"]
  309.     register("os2netscape", None,
  310.              GenericBrowser("start netscape.exe %s"))
  311.  
  312. # OK, now that we know what the default preference orders for each
  313. # platform are, allow user to override them with the BROWSER variable.
  314. #
  315. if os.environ.has_key("BROWSER"):
  316.     # It's the user's responsibility to register handlers for any unknown
  317.     # browser referenced by this value, before calling open().
  318.     _tryorder = os.environ["BROWSER"].split(os.pathsep)
  319.  
  320. for cmd in _tryorder:
  321.     if not _browsers.has_key(cmd.lower()):
  322.         if _iscommand(cmd.lower()):
  323.             register(cmd.lower(), None, GenericBrowser(
  324.                 "%s '%%s'" % cmd.lower()))
  325. cmd = None # to make del work if _tryorder was empty
  326. del cmd
  327.  
  328. _tryorder = filter(lambda x: _browsers.has_key(x.lower())
  329.                    or x.find("%s") > -1, _tryorder)
  330. # what to do if _tryorder is now empty?
  331.