webbrowser.py revision 4a5a91838b7318cc89a2ff2018b26940a5960a29
1e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl#! /usr/bin/env python 20a8c29be4b5314d4bf72cb391ab078f7483cf3f7Ka-Ping Yee"""Interfaces for launching and remotely controlling Web browsers.""" 3c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drake 4c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drakeimport os 5c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drakeimport sys 6e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandlimport stat 7c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drake 8e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl__all__ = ["Error", "open", "open_new", "open_new_tab", "get", "register"] 940fc16059f04ee8fda0b5956cc4883eb21ca8f8cSkip Montanaro 10c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drakeclass Error(Exception): 11c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drake pass 12c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drake 13658cba6706eb4a2ad8b3e235cf0db9fe1c8e9e6bTim Peters_browsers = {} # Dictionary of available browser controllers 14658cba6706eb4a2ad8b3e235cf0db9fe1c8e9e6bTim Peters_tryorder = [] # Preference order of available browsers 15c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drake 16e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandldef register(name, klass, instance=None, update_tryorder=1): 17c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drake """Register a browser connector and, optionally, connection.""" 18c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drake _browsers[name.lower()] = [klass, instance] 19e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if update_tryorder > 0: 20e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl _tryorder.append(name) 21e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl elif update_tryorder < 0: 22e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl _tryorder.insert(0, name) 23c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drake 24f7f185116a8274b105edc1be64ffc9c8061c7f43Eric S. Raymonddef get(using=None): 25f7f185116a8274b105edc1be64ffc9c8061c7f43Eric S. Raymond """Return a browser launcher instance appropriate for the environment.""" 2610ff706e2788a7c7ef9f8ea0108a5ede625fedadRaymond Hettinger if using is not None: 27f7f185116a8274b105edc1be64ffc9c8061c7f43Eric S. Raymond alternatives = [using] 28f7f185116a8274b105edc1be64ffc9c8061c7f43Eric S. Raymond else: 29f7f185116a8274b105edc1be64ffc9c8061c7f43Eric S. Raymond alternatives = _tryorder 30f7f185116a8274b105edc1be64ffc9c8061c7f43Eric S. Raymond for browser in alternatives: 31bac788a3cd348203a5fdabba52e5faf65bf35c5eRaymond Hettinger if '%s' in browser: 32f7f185116a8274b105edc1be64ffc9c8061c7f43Eric S. Raymond # User gave us a command line, don't mess with it. 33f7eb4faf38fc9e4a215acae3323140b99cdce08fEric S. Raymond return GenericBrowser(browser) 34f7f185116a8274b105edc1be64ffc9c8061c7f43Eric S. Raymond else: 35e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # User gave us a browser name or path. 36f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake try: 37f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake command = _browsers[browser.lower()] 38f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake except KeyError: 39f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake command = _synthesize(browser) 40e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if command[1] is not None: 41f7f185116a8274b105edc1be64ffc9c8061c7f43Eric S. Raymond return command[1] 42e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl elif command[0] is not None: 43e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl return command[0]() 44f7f185116a8274b105edc1be64ffc9c8061c7f43Eric S. Raymond raise Error("could not locate runnable browser") 45c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drake 46c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drake# Please note: the following definition hides a builtin function. 47e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl# It is recommended one does "import webbrowser" and uses webbrowser.open(url) 48e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl# instead of "from webbrowser import *". 49c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drake 50f79cb2db3eae59f80e8031d45376dc5f48d2af04Eric S. Raymonddef open(url, new=0, autoraise=1): 51e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl for name in _tryorder: 52e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl browser = get(name) 53e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if browser.open(url, new, autoraise): 54e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl return True 55e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl return False 56c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drake 573f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drakedef open_new(url): 58e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl return open(url, 1) 59c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drake 60e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandldef open_new_tab(url): 61e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl return open(url, 2) 62f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake 63e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 64e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandldef _synthesize(browser, update_tryorder=1): 65f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake """Attempt to synthesize a controller base on existing controllers. 66f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake 67f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake This is useful to create a controller when a user specifies a path to 68f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake an entry in the BROWSER environment variable -- we can copy a general 69f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake controller to operate using a specific installation of the desired 70f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake browser in this way. 71f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake 72f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake If we can't create a controller in this way, or if there is no 73f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake executable for the requested browser, return [None, None]. 74f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake 75f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake """ 76e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl cmd = browser.split()[0] 77e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if not _iscommand(cmd): 78f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake return [None, None] 79e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl name = os.path.basename(cmd) 80f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake try: 81f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake command = _browsers[name.lower()] 82f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake except KeyError: 83f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake return [None, None] 84f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake # now attempt to clone to fit the new name: 85f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake controller = command[1] 86f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake if controller and name.lower() == controller.basename: 87f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake import copy 88f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake controller = copy.copy(controller) 89f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake controller.name = browser 90f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake controller.basename = os.path.basename(browser) 91e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl register(browser, None, controller, update_tryorder) 92f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake return [None, controller] 93118aa5337c745dece455f4782799c83b9e3a7d4fAndrew M. Kuchling return [None, None] 94f4e5bd9df540aa5b24e47d03dbb798ed277793f7Fred Drake 953f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake 96e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandlif sys.platform[:3] == "win": 97e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl def _isexecutable(cmd): 98e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl cmd = cmd.lower() 99e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if os.path.isfile(cmd) and (cmd.endswith(".exe") or 100e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl cmd.endswith(".bat")): 101e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl return True 102e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl for ext in ".exe", ".bat": 103e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if os.path.isfile(cmd + ext): 104e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl return True 105e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl return False 106e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandlelse: 107e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl def _isexecutable(cmd): 108e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if os.path.isfile(cmd): 109e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl mode = os.stat(cmd)[stat.ST_MODE] 110e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if mode & stat.S_IXUSR or mode & stat.S_IXGRP or mode & stat.S_IXOTH: 111e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl return True 112e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl return False 113e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 1143f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drakedef _iscommand(cmd): 115e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl """Return True if cmd is executable or can be found on the executable 116e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl search path.""" 117e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if _isexecutable(cmd): 118e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl return True 1193f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake path = os.environ.get("PATH") 1203f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake if not path: 121bc0e9108261693b6278687f4fb4709ff76c2e543Tim Peters return False 1223f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake for d in path.split(os.pathsep): 1233f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake exe = os.path.join(d, cmd) 124e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if _isexecutable(exe): 125bc0e9108261693b6278687f4fb4709ff76c2e543Tim Peters return True 126bc0e9108261693b6278687f4fb4709ff76c2e543Tim Peters return False 1273f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake 1283f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake 129e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl# General parent classes 130e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 131e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandlclass BaseBrowser(object): 132e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl """Parent class for all browsers.""" 133e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 134e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl def __init__(self, name=""): 135e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl self.name = name 136b980113a8df699797b837f103ac6d2049a214551Georg Brandl self.basename = name 137e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 138196f733d935bd51f8674c9761420ce990694f33aNeal Norwitz def open(self, url, new=0, autoraise=1): 139196f733d935bd51f8674c9761420ce990694f33aNeal Norwitz raise NotImplementedError 140196f733d935bd51f8674c9761420ce990694f33aNeal Norwitz 141e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl def open_new(self, url): 142e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl return self.open(url, 1) 143e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 144e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl def open_new_tab(self, url): 145e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl return self.open(url, 2) 146e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 1473f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake 148e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandlclass GenericBrowser(BaseBrowser): 149e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl """Class for all browsers started with a command 150e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl and without remote functionality.""" 1513f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake 1523f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake def __init__(self, cmd): 1533f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake self.name, self.args = cmd.split(None, 1) 154b980113a8df699797b837f103ac6d2049a214551Georg Brandl self.basename = os.path.basename(self.name) 1553f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake 1563f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake def open(self, url, new=0, autoraise=1): 157925f14427416c1c5a8c6e71d17daac20e248c7b0Fred Drake assert "'" not in url 1583f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake command = "%s %s" % (self.name, self.args) 159e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl rc = os.system(command % url) 160e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl return not rc 1613f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake 1623f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake 163e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandlclass UnixBrowser(BaseBrowser): 164e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl """Parent class for all Unix browsers with remote functionality.""" 1653f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake 166e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl raise_opts = None 1673f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake 168e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl remote_cmd = '' 169e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl remote_action = None 170e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl remote_action_newwin = None 171e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl remote_action_newtab = None 172e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl remote_background = False 173e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 174e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl def _remote(self, url, action, autoraise): 175e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl autoraise = int(bool(autoraise)) # always 0/1 176e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl raise_opt = self.raise_opts and self.raise_opts[autoraise] or '' 177e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl cmd = "%s %s %s '%s' >/dev/null 2>&1" % (self.name, raise_opt, 178e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl self.remote_cmd, action) 179196f733d935bd51f8674c9761420ce990694f33aNeal Norwitz if self.remote_background: 180e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl cmd += ' &' 1813f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake rc = os.system(cmd) 1823f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake if rc: 1831cb179e93fb0f698fdb5f215b3864c578d910d9aGeorg Brandl cmd = "%s %s" % (self.name, url) 1841cb179e93fb0f698fdb5f215b3864c578d910d9aGeorg Brandl if self.remote_background: 1851cb179e93fb0f698fdb5f215b3864c578d910d9aGeorg Brandl cmd += " &" 186e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # bad return status, try again with simpler command 1871cb179e93fb0f698fdb5f215b3864c578d910d9aGeorg Brandl rc = os.system(cmd) 1883f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake return not rc 1893f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake 1903f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake def open(self, url, new=0, autoraise=1): 191e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl assert "'" not in url 192e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if new == 0: 193e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl action = self.remote_action 194e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl elif new == 1: 195e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl action = self.remote_action_newwin 196e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl elif new == 2: 197e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if self.remote_action_newtab is None: 198e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl action = self.remote_action_newwin 199e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl else: 200e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl action = self.remote_action_newtab 2013f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake else: 202e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl raise Error("Bad 'new' parameter to open(); expected 0, 1, or 2, got %s" % new) 203e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl return self._remote(url, action % url, autoraise) 2043f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake 2053f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake 206e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandlclass Mozilla(UnixBrowser): 207e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl """Launcher class for Mozilla/Netscape browsers.""" 2083f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake 209e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl raise_opts = ("-noraise", "-raise") 2108dd28eb973a1c072448d961a6fb6a8a12cc3c950Neal Norwitz 211e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl remote_cmd = '-remote' 212e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl remote_action = "openURL(%s)" 213e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl remote_action_newwin = "openURL(%s,new-window)" 214e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl remote_action_newtab = "openURL(%s,new-tab)" 2151cb179e93fb0f698fdb5f215b3864c578d910d9aGeorg Brandl remote_background = True 2168dd28eb973a1c072448d961a6fb6a8a12cc3c950Neal Norwitz 217e8f244305ef4f257f6999b69601f4316b31faa5eGeorg BrandlNetscape = Mozilla 2188dd28eb973a1c072448d961a6fb6a8a12cc3c950Neal Norwitz 2198dd28eb973a1c072448d961a6fb6a8a12cc3c950Neal Norwitz 220e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandlclass Galeon(UnixBrowser): 221e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl """Launcher class for Galeon/Epiphany browsers.""" 222e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 223e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl raise_opts = ("-noraise", "") 224e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl remote_action = "-n '%s'" 225e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl remote_action_newwin = "-w '%s'" 2268dd28eb973a1c072448d961a6fb6a8a12cc3c950Neal Norwitz 227e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl remote_background = True 228e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 229e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 230e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandlclass Konqueror(BaseBrowser): 2313f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake """Controller for the KDE File Manager (kfm, or Konqueror). 2323f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake 2333f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake See http://developer.kde.org/documentation/other/kfmclient.html 2343f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake for more information on the Konqueror remote-control interface. 2353f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake 2363f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake """ 2373f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake 238e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl def _remote(self, url, action): 239e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # kfmclient is the new KDE way of opening URLs. 240520cdf733aa8bfff48369822802a2df913851fcbNeal Norwitz cmd = "kfmclient %s >/dev/null 2>&1" % action 2413f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake rc = os.system(cmd) 242e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # Fall back to other variants. 2433f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake if rc: 244e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if _iscommand("konqueror"): 245e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl rc = os.system(self.name + " --silent '%s' &" % url) 246e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl elif _iscommand("kfm"): 2471cb179e93fb0f698fdb5f215b3864c578d910d9aGeorg Brandl rc = os.system(self.name + " -d '%s' &" % url) 2483f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake return not rc 2493f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake 250e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl def open(self, url, new=0, autoraise=1): 2513f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake # XXX Currently I know no way to prevent KFM from 2523f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake # opening a new win. 253520cdf733aa8bfff48369822802a2df913851fcbNeal Norwitz assert "'" not in url 254e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if new == 2: 255e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl action = "newTab '%s'" % url 256e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl else: 257e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl action = "openURL '%s'" % url 258e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl ok = self._remote(url, action) 259e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl return ok 260e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 261e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 262e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandlclass Opera(UnixBrowser): 263e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl "Launcher class for Opera browser." 2643f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake 265e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl raise_opts = ("", "-raise") 2663f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake 267e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl remote_cmd = '-remote' 268e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl remote_action = "openURL(%s)" 269e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl remote_action_newwin = "openURL(%s,new-window)" 270e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl remote_action_newtab = "openURL(%s,new-page)" 2711cb179e93fb0f698fdb5f215b3864c578d910d9aGeorg Brandl remote_background = True 2723f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake 273e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 274e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandlclass Elinks(UnixBrowser): 275e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl "Launcher class for Elinks browsers." 276e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 277e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl remote_cmd = '-remote' 278e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl remote_action = "openURL(%s)" 279e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl remote_action_newwin = "openURL(%s,new-window)" 280e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl remote_action_newtab = "openURL(%s,new-tab)" 281e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 282e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl def _remote(self, url, action, autoraise): 283e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # elinks doesn't like its stdout to be redirected - 284e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # it uses redirected stdout as a signal to do -dump 285e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl cmd = "%s %s '%s' 2>/dev/null" % (self.name, 286e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl self.remote_cmd, action) 287e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl rc = os.system(cmd) 288e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if rc: 289e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl rc = os.system("%s %s" % (self.name, url)) 290e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl return not rc 291e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 292e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 293e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandlclass Grail(BaseBrowser): 2943f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake # There should be a way to maintain a connection to Grail, but the 2953f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake # Grail remote control protocol doesn't really allow that at this 2963f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake # point. It probably neverwill! 2973f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake def _find_grail_rc(self): 2983f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake import glob 2993f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake import pwd 3003f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake import socket 3013f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake import tempfile 3023f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake tempdir = os.path.join(tempfile.gettempdir(), 3033f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake ".grail-unix") 30416623fe3e606efdedead8ccccaf7ef583e1be97fFred Drake user = pwd.getpwuid(os.getuid())[0] 3053f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake filename = os.path.join(tempdir, user + "-*") 3063f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake maybes = glob.glob(filename) 3073f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake if not maybes: 3083f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake return None 3093f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) 3103f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake for fn in maybes: 3113f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake # need to PING each one until we find one that's live 3123f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake try: 3133f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake s.connect(fn) 3143f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake except socket.error: 3153f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake # no good; attempt to clean it out, but don't fail: 3163f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake try: 3173f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake os.unlink(fn) 3183f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake except IOError: 3193f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake pass 3203f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake else: 3213f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake return s 3223f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake 3233f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake def _remote(self, action): 3243f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake s = self._find_grail_rc() 3253f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake if not s: 3263f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake return 0 3273f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake s.send(action) 3283f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake s.close() 3293f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake return 1 3303f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake 3313f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake def open(self, url, new=0, autoraise=1): 3323f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake if new: 333e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl ok = self._remote("LOADNEW " + url) 3343f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake else: 335e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl ok = self._remote("LOAD " + url) 336e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl return ok 3373f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake 338c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drake 339658cba6706eb4a2ad8b3e235cf0db9fe1c8e9e6bTim Peters# 340f7f185116a8274b105edc1be64ffc9c8061c7f43Eric S. Raymond# Platform support for Unix 341f7f185116a8274b105edc1be64ffc9c8061c7f43Eric S. Raymond# 342c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drake 343e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl# These are the right tests because all these Unix browsers require either 344e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl# a console terminal or an X display to run. 345e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 346196f733d935bd51f8674c9761420ce990694f33aNeal Norwitzdef register_X_browsers(): 347e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # The default Gnome browser 348e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if _iscommand("gconftool-2"): 349e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # get the web browser string from gconftool 350e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl gc = 'gconftool-2 -g /desktop/gnome/url-handlers/http/command' 351e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl out = os.popen(gc) 352e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl commd = out.read().strip() 353e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl retncode = out.close() 354e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 355e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # if successful, register it 356e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if retncode == None and len(commd) != 0: 357e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl register("gnome", None, GenericBrowser( 358e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl commd + " '%s' >/dev/null &")) 359e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 3604a5a91838b7318cc89a2ff2018b26940a5960a29Georg Brandl # First, the Mozilla/Netscape browsers 3614a5a91838b7318cc89a2ff2018b26940a5960a29Georg Brandl for browser in ("mozilla-firefox", "firefox", 3624a5a91838b7318cc89a2ff2018b26940a5960a29Georg Brandl "mozilla-firebird", "firebird", 3634a5a91838b7318cc89a2ff2018b26940a5960a29Georg Brandl "mozilla", "netscape"): 3644a5a91838b7318cc89a2ff2018b26940a5960a29Georg Brandl if _iscommand(browser): 3654a5a91838b7318cc89a2ff2018b26940a5960a29Georg Brandl register(browser, None, Mozilla(browser)) 3664a5a91838b7318cc89a2ff2018b26940a5960a29Georg Brandl 367e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # Konqueror/kfm, the KDE browser. 368b980113a8df699797b837f103ac6d2049a214551Georg Brandl if _iscommand("kfm"): 369b980113a8df699797b837f103ac6d2049a214551Georg Brandl register("kfm", Konqueror, Konqueror("kfm")) 370b980113a8df699797b837f103ac6d2049a214551Georg Brandl elif _iscommand("konqueror"): 371b980113a8df699797b837f103ac6d2049a214551Georg Brandl register("konqueror", Konqueror, Konqueror("konqueror")) 372e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 373e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # Gnome's Galeon and Epiphany 374e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl for browser in ("galeon", "epiphany"): 375e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if _iscommand(browser): 376e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl register(browser, None, Galeon(browser)) 377e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 378e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # Skipstone, another Gtk/Mozilla based browser 379e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if _iscommand("skipstone"): 380e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl register("skipstone", None, GenericBrowser("skipstone '%s' &")) 381e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 382e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # Opera, quite popular 383e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if _iscommand("opera"): 384e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl register("opera", None, Opera("opera")) 385e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 386e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # Next, Mosaic -- old but still in use. 387e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if _iscommand("mosaic"): 388e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl register("mosaic", None, GenericBrowser("mosaic '%s' &")) 389e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 390e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # Grail, the Python browser. Does anybody still use it? 391e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if _iscommand("grail"): 392e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl register("grail", Grail, None) 393e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 394196f733d935bd51f8674c9761420ce990694f33aNeal Norwitz# Prefer X browsers if present 395196f733d935bd51f8674c9761420ce990694f33aNeal Norwitzif os.environ.get("DISPLAY"): 396196f733d935bd51f8674c9761420ce990694f33aNeal Norwitz register_X_browsers() 397196f733d935bd51f8674c9761420ce990694f33aNeal Norwitz 398e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl# Also try console browsers 399e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandlif os.environ.get("TERM"): 400e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # The Links/elinks browsers <http://artax.karlin.mff.cuni.cz/~mikulas/links/> 401e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if _iscommand("links"): 402e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl register("links", None, GenericBrowser("links '%s'")) 403e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if _iscommand("elinks"): 404e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl register("elinks", None, Elinks("elinks")) 405e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # The Lynx browser <http://lynx.isc.org/>, <http://lynx.browser.org/> 406e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if _iscommand("lynx"): 407e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl register("lynx", None, GenericBrowser("lynx '%s'")) 408e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # The w3m browser <http://w3m.sourceforge.net/> 409e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if _iscommand("w3m"): 410e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl register("w3m", None, GenericBrowser("w3m '%s'")) 4113f8f1643c8418a3e1980138c6fdb218e5be8c186Fred Drake 412f7f185116a8274b105edc1be64ffc9c8061c7f43Eric S. Raymond# 413f7f185116a8274b105edc1be64ffc9c8061c7f43Eric S. Raymond# Platform support for Windows 414f7f185116a8274b105edc1be64ffc9c8061c7f43Eric S. Raymond# 415c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drake 416f7f185116a8274b105edc1be64ffc9c8061c7f43Eric S. Raymondif sys.platform[:3] == "win": 417e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl class WindowsDefault(BaseBrowser): 418e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl def open(self, url, new=0, autoraise=1): 419e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl os.startfile(url) 420e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl return True # Oh, my... 421e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 422e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl _tryorder = [] 423e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl _browsers = {} 424e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # Prefer mozilla/netscape/opera if present 425e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl for browser in ("firefox", "firebird", "mozilla", "netscape", "opera"): 426e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if _iscommand(browser): 427e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl register(browser, None, GenericBrowser(browser + ' %s')) 428c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drake register("windows-default", WindowsDefault) 429c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drake 430c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drake# 431f7f185116a8274b105edc1be64ffc9c8061c7f43Eric S. Raymond# Platform support for MacOS 432f7f185116a8274b105edc1be64ffc9c8061c7f43Eric S. Raymond# 433c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drake 434c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Draketry: 435c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drake import ic 436c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drakeexcept ImportError: 437c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drake pass 438c70b4483d2c5042c68198dc7c4945ef3cfc95b27Fred Drakeelse: 439e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl class InternetConfig(BaseBrowser): 440e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl def open(self, url, new=0, autoraise=1): 441e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl ic.launchurl(url) 442e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl return True # Any way to get status? 443e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 444e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl register("internet-config", InternetConfig, update_tryorder=-1) 445e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 446e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandlif sys.platform == 'darwin': 447e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # Adapted from patch submitted to SourceForge by Steven J. Burr 448e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl class MacOSX(BaseBrowser): 449e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl """Launcher class for Aqua browsers on Mac OS X 450e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 451e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl Optionally specify a browser name on instantiation. Note that this 452e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl will not work for Aqua browsers if the user has moved the application 453e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl package after installation. 454e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 455e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl If no browser is specified, the default browser, as specified in the 456e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl Internet System Preferences panel, will be used. 457e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl """ 458e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl def __init__(self, name): 459e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl self.name = name 460e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 461e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl def open(self, url, new=0, autoraise=1): 462e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl assert "'" not in url 463e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # new must be 0 or 1 464e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl new = int(bool(new)) 465e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if self.name == "default": 466e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # User called open, open_new or get without a browser parameter 4671cb179e93fb0f698fdb5f215b3864c578d910d9aGeorg Brandl script = 'open location "%s"' % url.replace('"', '%22') # opens in default browser 468e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl else: 469e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # User called get and chose a browser 470e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if self.name == "OmniWeb": 471e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl toWindow = "" 472e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl else: 473e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # Include toWindow parameter of OpenURL command for browsers 474e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # that support it. 0 == new window; -1 == existing 475e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl toWindow = "toWindow %d" % (new - 1) 4761cb179e93fb0f698fdb5f215b3864c578d910d9aGeorg Brandl cmd = 'OpenURL "%s"' % url.replace('"', '%22') 477e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl script = '''tell application "%s" 478e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl activate 479e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl %s %s 480e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl end tell''' % (self.name, cmd, toWindow) 481e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # Open pipe to AppleScript through osascript command 482e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl osapipe = os.popen("osascript", "w") 483e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if osapipe is None: 484e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl return False 485e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # Write script to osascript's stdin 486e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl osapipe.write(script) 487e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl rc = osapipe.close() 488e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl return not rc 489e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 490e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # Don't clear _tryorder or _browsers since OS X can use above Unix support 491e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # (but we prefer using the OS X specific stuff) 492e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl register("MacOSX", None, MacOSX('default'), -1) 493e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 494f7f185116a8274b105edc1be64ffc9c8061c7f43Eric S. Raymond 4953a89b2b13134767475c8e0c14381c1a722d7b836Martin v. Löwis# 4963a89b2b13134767475c8e0c14381c1a722d7b836Martin v. Löwis# Platform support for OS/2 4973a89b2b13134767475c8e0c14381c1a722d7b836Martin v. Löwis# 4983a89b2b13134767475c8e0c14381c1a722d7b836Martin v. Löwis 499e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandlif sys.platform[:3] == "os2" and _iscommand("netscape"): 500e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl _tryorder = [] 501e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl _browsers = {} 5023a89b2b13134767475c8e0c14381c1a722d7b836Martin v. Löwis register("os2netscape", None, 503e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl GenericBrowser("start netscape %s"), -1) 504e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 5053a89b2b13134767475c8e0c14381c1a722d7b836Martin v. Löwis 506f7f185116a8274b105edc1be64ffc9c8061c7f43Eric S. Raymond# OK, now that we know what the default preference orders for each 507f7f185116a8274b105edc1be64ffc9c8061c7f43Eric S. Raymond# platform are, allow user to override them with the BROWSER variable. 50854f0222547b1e92cd018ef132307a6f793dc9505Raymond Hettingerif "BROWSER" in os.environ: 509e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl _userchoices = os.environ["BROWSER"].split(os.pathsep) 510e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl _userchoices.reverse() 511e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 512e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # Treat choices in same way as if passed into get() but do register 513e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl # and prepend to _tryorder 514e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl for cmdline in _userchoices: 515e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if cmdline != '': 516e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl _synthesize(cmdline, -1) 517e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl cmdline = None # to make del work if _userchoices was empty 518e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl del cmdline 519e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl del _userchoices 520e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 521cdab3bf7eb0810fcda21be065868f3da330779a1Skip Montanaro# what to do if _tryorder is now empty? 522e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 523e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 524e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandldef main(): 525e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl import getopt 526e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl usage = """Usage: %s [-n | -t] url 527e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl -n: open new window 528e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl -t: open new tab""" % sys.argv[0] 529e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl try: 530e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl opts, args = getopt.getopt(sys.argv[1:], 'ntd') 531e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl except getopt.error, msg: 532e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl print >>sys.stderr, msg 533e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl print >>sys.stderr, usage 534e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl sys.exit(1) 535e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl new_win = 0 536e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl for o, a in opts: 537e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if o == '-n': new_win = 1 538e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl elif o == '-t': new_win = 2 539e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl if len(args) <> 1: 540e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl print >>sys.stderr, usage 541e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl sys.exit(1) 542e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 543e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl url = args[0] 544e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl open(url, new_win) 545e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl 546e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandlif __name__ == "__main__": 547e8f244305ef4f257f6999b69601f4316b31faa5eGeorg Brandl main() 548