PyXR

c:\python24\lib \ webbrowser.py



0001 """Interfaces for launching and remotely controlling Web browsers."""
0002 
0003 import os
0004 import sys
0005 
0006 __all__ = ["Error", "open", "get", "register"]
0007 
0008 class Error(Exception):
0009     pass
0010 
0011 _browsers = {}          # Dictionary of available browser controllers
0012 _tryorder = []          # Preference order of available browsers
0013 
0014 def register(name, klass, instance=None):
0015     """Register a browser connector and, optionally, connection."""
0016     _browsers[name.lower()] = [klass, instance]
0017 
0018 def get(using=None):
0019     """Return a browser launcher instance appropriate for the environment."""
0020     if using is not None:
0021         alternatives = [using]
0022     else:
0023         alternatives = _tryorder
0024     for browser in alternatives:
0025         if '%s' in browser:
0026             # User gave us a command line, don't mess with it.
0027             return GenericBrowser(browser)
0028         else:
0029             # User gave us a browser name.
0030             try:
0031                 command = _browsers[browser.lower()]
0032             except KeyError:
0033                 command = _synthesize(browser)
0034             if command[1] is None:
0035                 return command[0]()
0036             else:
0037                 return command[1]
0038     raise Error("could not locate runnable browser")
0039 
0040 # Please note: the following definition hides a builtin function.
0041 
0042 def open(url, new=0, autoraise=1):
0043     get().open(url, new, autoraise)
0044 
0045 def open_new(url):
0046     get().open(url, 1)
0047 
0048 
0049 def _synthesize(browser):
0050     """Attempt to synthesize a controller base on existing controllers.
0051 
0052     This is useful to create a controller when a user specifies a path to
0053     an entry in the BROWSER environment variable -- we can copy a general
0054     controller to operate using a specific installation of the desired
0055     browser in this way.
0056 
0057     If we can't create a controller in this way, or if there is no
0058     executable for the requested browser, return [None, None].
0059 
0060     """
0061     if not os.path.exists(browser):
0062         return [None, None]
0063     name = os.path.basename(browser)
0064     try:
0065         command = _browsers[name.lower()]
0066     except KeyError:
0067         return [None, None]
0068     # now attempt to clone to fit the new name:
0069     controller = command[1]
0070     if controller and name.lower() == controller.basename:
0071         import copy
0072         controller = copy.copy(controller)
0073         controller.name = browser
0074         controller.basename = os.path.basename(browser)
0075         register(browser, None, controller)
0076         return [None, controller]
0077     return [None, None]
0078 
0079 
0080 def _iscommand(cmd):
0081     """Return True if cmd can be found on the executable search path."""
0082     path = os.environ.get("PATH")
0083     if not path:
0084         return False
0085     for d in path.split(os.pathsep):
0086         exe = os.path.join(d, cmd)
0087         if os.path.isfile(exe):
0088             return True
0089     return False
0090 
0091 
0092 PROCESS_CREATION_DELAY = 4
0093 
0094 
0095 class GenericBrowser:
0096     def __init__(self, cmd):
0097         self.name, self.args = cmd.split(None, 1)
0098         self.basename = os.path.basename(self.name)
0099 
0100     def open(self, url, new=0, autoraise=1):
0101         assert "'" not in url
0102         command = "%s %s" % (self.name, self.args)
0103         os.system(command % url)
0104 
0105     def open_new(self, url):
0106         self.open(url)
0107 
0108 
0109 class Netscape:
0110     "Launcher class for Netscape browsers."
0111     def __init__(self, name):
0112         self.name = name
0113         self.basename = os.path.basename(name)
0114 
0115     def _remote(self, action, autoraise):
0116         raise_opt = ("-noraise", "-raise")[autoraise]
0117         cmd = "%s %s -remote '%s' >/dev/null 2>&1" % (self.name,
0118                                                       raise_opt,
0119                                                       action)
0120         rc = os.system(cmd)
0121         if rc:
0122             import time
0123             os.system("%s &" % self.name)
0124             time.sleep(PROCESS_CREATION_DELAY)
0125             rc = os.system(cmd)
0126         return not rc
0127 
0128     def open(self, url, new=0, autoraise=1):
0129         if new:
0130             self._remote("openURL(%s, new-window)"%url, autoraise)
0131         else:
0132             self._remote("openURL(%s)" % url, autoraise)
0133 
0134     def open_new(self, url):
0135         self.open(url, 1)
0136 
0137 
0138 class Galeon:
0139     """Launcher class for Galeon browsers."""
0140     def __init__(self, name):
0141         self.name = name
0142         self.basename = os.path.basename(name)
0143 
0144     def _remote(self, action, autoraise):
0145         raise_opt = ("--noraise", "")[autoraise]
0146         cmd = "%s %s %s >/dev/null 2>&1" % (self.name, raise_opt, action)
0147         rc = os.system(cmd)
0148         if rc:
0149             import time
0150             os.system("%s >/dev/null 2>&1 &" % self.name)
0151             time.sleep(PROCESS_CREATION_DELAY)
0152             rc = os.system(cmd)
0153         return not rc
0154 
0155     def open(self, url, new=0, autoraise=1):
0156         if new:
0157             self._remote("-w '%s'" % url, autoraise)
0158         else:
0159             self._remote("-n '%s'" % url, autoraise)
0160 
0161     def open_new(self, url):
0162         self.open(url, 1)
0163 
0164 
0165 class Konqueror:
0166     """Controller for the KDE File Manager (kfm, or Konqueror).
0167 
0168     See http://developer.kde.org/documentation/other/kfmclient.html
0169     for more information on the Konqueror remote-control interface.
0170 
0171     """
0172     def __init__(self):
0173         if _iscommand("konqueror"):
0174             self.name = self.basename = "konqueror"
0175         else:
0176             self.name = self.basename = "kfm"
0177 
0178     def _remote(self, action):
0179         cmd = "kfmclient %s >/dev/null 2>&1" % action
0180         rc = os.system(cmd)
0181         if rc:
0182             import time
0183             if self.basename == "konqueror":
0184                 os.system(self.name + " --silent &")
0185             else:
0186                 os.system(self.name + " -d &")
0187             time.sleep(PROCESS_CREATION_DELAY)
0188             rc = os.system(cmd)
0189         return not rc
0190 
0191     def open(self, url, new=1, autoraise=1):
0192         # XXX Currently I know no way to prevent KFM from
0193         # opening a new win.
0194         assert "'" not in url
0195         self._remote("openURL '%s'" % url)
0196 
0197     open_new = open
0198 
0199 
0200 class Grail:
0201     # There should be a way to maintain a connection to Grail, but the
0202     # Grail remote control protocol doesn't really allow that at this
0203     # point.  It probably neverwill!
0204     def _find_grail_rc(self):
0205         import glob
0206         import pwd
0207         import socket
0208         import tempfile
0209         tempdir = os.path.join(tempfile.gettempdir(),
0210                                ".grail-unix")
0211         user = pwd.getpwuid(os.getuid())[0]
0212         filename = os.path.join(tempdir, user + "-*")
0213         maybes = glob.glob(filename)
0214         if not maybes:
0215             return None
0216         s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
0217         for fn in maybes:
0218             # need to PING each one until we find one that's live
0219             try:
0220                 s.connect(fn)
0221             except socket.error:
0222                 # no good; attempt to clean it out, but don't fail:
0223                 try:
0224                     os.unlink(fn)
0225                 except IOError:
0226                     pass
0227             else:
0228                 return s
0229 
0230     def _remote(self, action):
0231         s = self._find_grail_rc()
0232         if not s:
0233             return 0
0234         s.send(action)
0235         s.close()
0236         return 1
0237 
0238     def open(self, url, new=0, autoraise=1):
0239         if new:
0240             self._remote("LOADNEW " + url)
0241         else:
0242             self._remote("LOAD " + url)
0243 
0244     def open_new(self, url):
0245         self.open(url, 1)
0246 
0247 
0248 class WindowsDefault:
0249     def open(self, url, new=0, autoraise=1):
0250         os.startfile(url)
0251 
0252     def open_new(self, url):
0253         self.open(url)
0254 
0255 #
0256 # Platform support for Unix
0257 #
0258 
0259 # This is the right test because all these Unix browsers require either
0260 # a console terminal of an X display to run.  Note that we cannot split
0261 # the TERM and DISPLAY cases, because we might be running Python from inside
0262 # an xterm.
0263 if os.environ.get("TERM") or os.environ.get("DISPLAY"):
0264     _tryorder = ["links", "lynx", "w3m"]
0265 
0266     # Easy cases first -- register console browsers if we have them.
0267     if os.environ.get("TERM"):
0268         # The Links browser <http://artax.karlin.mff.cuni.cz/~mikulas/links/>
0269         if _iscommand("links"):
0270             register("links", None, GenericBrowser("links '%s'"))
0271         # The Lynx browser <http://lynx.browser.org/>
0272         if _iscommand("lynx"):
0273             register("lynx", None, GenericBrowser("lynx '%s'"))
0274         # The w3m browser <http://ei5nazha.yz.yamagata-u.ac.jp/~aito/w3m/eng/>
0275         if _iscommand("w3m"):
0276             register("w3m", None, GenericBrowser("w3m '%s'"))
0277 
0278     # X browsers have more in the way of options
0279     if os.environ.get("DISPLAY"):
0280         _tryorder = ["galeon", "skipstone",
0281                      "mozilla-firefox", "mozilla-firebird", "mozilla", "netscape",
0282                      "kfm", "grail"] + _tryorder
0283 
0284         # First, the Netscape series
0285         for browser in ("mozilla-firefox", "mozilla-firebird",
0286                         "mozilla", "netscape"):
0287             if _iscommand(browser):
0288                 register(browser, None, Netscape(browser))
0289 
0290         # Next, Mosaic -- old but still in use.
0291         if _iscommand("mosaic"):
0292             register("mosaic", None, GenericBrowser(
0293                 "mosaic '%s' >/dev/null &"))
0294 
0295         # Gnome's Galeon
0296         if _iscommand("galeon"):
0297             register("galeon", None, Galeon("galeon"))
0298 
0299         # Skipstone, another Gtk/Mozilla based browser
0300         if _iscommand("skipstone"):
0301             register("skipstone", None, GenericBrowser(
0302                 "skipstone '%s' >/dev/null &"))
0303 
0304         # Konqueror/kfm, the KDE browser.
0305         if _iscommand("kfm") or _iscommand("konqueror"):
0306             register("kfm", Konqueror, Konqueror())
0307 
0308         # Grail, the Python browser.
0309         if _iscommand("grail"):
0310             register("grail", Grail, None)
0311 
0312 
0313 class InternetConfig:
0314     def open(self, url, new=0, autoraise=1):
0315         ic.launchurl(url)
0316 
0317     def open_new(self, url):
0318         self.open(url)
0319 
0320 
0321 #
0322 # Platform support for Windows
0323 #
0324 
0325 if sys.platform[:3] == "win":
0326     _tryorder = ["netscape", "windows-default"]
0327     register("windows-default", WindowsDefault)
0328 
0329 #
0330 # Platform support for MacOS
0331 #
0332 
0333 try:
0334     import ic
0335 except ImportError:
0336     pass
0337 else:
0338     # internet-config is the only supported controller on MacOS,
0339     # so don't mess with the default!
0340     _tryorder = ["internet-config"]
0341     register("internet-config", InternetConfig)
0342 
0343 #
0344 # Platform support for OS/2
0345 #
0346 
0347 if sys.platform[:3] == "os2" and _iscommand("netscape.exe"):
0348     _tryorder = ["os2netscape"]
0349     register("os2netscape", None,
0350              GenericBrowser("start netscape.exe %s"))
0351 
0352 # OK, now that we know what the default preference orders for each
0353 # platform are, allow user to override them with the BROWSER variable.
0354 #
0355 if "BROWSER" in os.environ:
0356     # It's the user's responsibility to register handlers for any unknown
0357     # browser referenced by this value, before calling open().
0358     _tryorder = os.environ["BROWSER"].split(os.pathsep)
0359 
0360 for cmd in _tryorder:
0361     if not cmd.lower() in _browsers:
0362         if _iscommand(cmd.lower()):
0363             register(cmd.lower(), None, GenericBrowser(
0364                 "%s '%%s'" % cmd.lower()))
0365 cmd = None # to make del work if _tryorder was empty
0366 del cmd
0367 
0368 _tryorder = filter(lambda x: x.lower() in _browsers
0369                    or x.find("%s") > -1, _tryorder)
0370 # what to do if _tryorder is now empty?
0371 

Generated by PyXR 0.9.4
SourceForge.net Logo