blob: 6c34f8b81acd736cd0de3b637475d0571fe93dd0 [file] [log] [blame]
Georg Brandle8f24432005-10-03 14:16:44 +00001#! /usr/bin/env python
Ka-Ping Yee0a8c29b2001-03-02 02:01:40 +00002"""Interfaces for launching and remotely controlling Web browsers."""
Fred Drakec70b4482000-07-09 16:45:56 +00003
4import os
5import sys
Georg Brandle8f24432005-10-03 14:16:44 +00006import stat
Fred Drakec70b4482000-07-09 16:45:56 +00007
Georg Brandle8f24432005-10-03 14:16:44 +00008__all__ = ["Error", "open", "open_new", "open_new_tab", "get", "register"]
Skip Montanaro40fc1602001-03-01 04:27:19 +00009
Fred Drakec70b4482000-07-09 16:45:56 +000010class Error(Exception):
11 pass
12
Tim Peters658cba62001-02-09 20:06:00 +000013_browsers = {} # Dictionary of available browser controllers
14_tryorder = [] # Preference order of available browsers
Fred Drakec70b4482000-07-09 16:45:56 +000015
Georg Brandle8f24432005-10-03 14:16:44 +000016def register(name, klass, instance=None, update_tryorder=1):
Fred Drakec70b4482000-07-09 16:45:56 +000017 """Register a browser connector and, optionally, connection."""
18 _browsers[name.lower()] = [klass, instance]
Georg Brandle8f24432005-10-03 14:16:44 +000019 if update_tryorder > 0:
20 _tryorder.append(name)
21 elif update_tryorder < 0:
22 _tryorder.insert(0, name)
Fred Drakec70b4482000-07-09 16:45:56 +000023
Eric S. Raymondf7f18512001-01-23 13:16:32 +000024def get(using=None):
25 """Return a browser launcher instance appropriate for the environment."""
Raymond Hettinger10ff7062002-06-02 03:04:52 +000026 if using is not None:
Eric S. Raymondf7f18512001-01-23 13:16:32 +000027 alternatives = [using]
28 else:
29 alternatives = _tryorder
30 for browser in alternatives:
Raymond Hettingerbac788a2004-05-04 09:21:43 +000031 if '%s' in browser:
Eric S. Raymondf7f18512001-01-23 13:16:32 +000032 # User gave us a command line, don't mess with it.
Eric S. Raymondf7eb4fa2001-03-31 01:50:52 +000033 return GenericBrowser(browser)
Eric S. Raymondf7f18512001-01-23 13:16:32 +000034 else:
Georg Brandle8f24432005-10-03 14:16:44 +000035 # User gave us a browser name or path.
Fred Drakef4e5bd92001-04-12 22:07:27 +000036 try:
37 command = _browsers[browser.lower()]
38 except KeyError:
39 command = _synthesize(browser)
Georg Brandle8f24432005-10-03 14:16:44 +000040 if command[1] is not None:
Eric S. Raymondf7f18512001-01-23 13:16:32 +000041 return command[1]
Georg Brandle8f24432005-10-03 14:16:44 +000042 elif command[0] is not None:
43 return command[0]()
Eric S. Raymondf7f18512001-01-23 13:16:32 +000044 raise Error("could not locate runnable browser")
Fred Drakec70b4482000-07-09 16:45:56 +000045
46# Please note: the following definition hides a builtin function.
Georg Brandle8f24432005-10-03 14:16:44 +000047# It is recommended one does "import webbrowser" and uses webbrowser.open(url)
48# instead of "from webbrowser import *".
Fred Drakec70b4482000-07-09 16:45:56 +000049
Eric S. Raymondf79cb2d2001-01-23 13:49:44 +000050def open(url, new=0, autoraise=1):
Georg Brandle8f24432005-10-03 14:16:44 +000051 for name in _tryorder:
52 browser = get(name)
53 if browser.open(url, new, autoraise):
54 return True
55 return False
Fred Drakec70b4482000-07-09 16:45:56 +000056
Fred Drake3f8f1642001-07-19 03:46:26 +000057def open_new(url):
Georg Brandle8f24432005-10-03 14:16:44 +000058 return open(url, 1)
59
60def open_new_tab(url):
61 return open(url, 2)
Fred Drakec70b4482000-07-09 16:45:56 +000062
Fred Drakef4e5bd92001-04-12 22:07:27 +000063
Georg Brandle8f24432005-10-03 14:16:44 +000064def _synthesize(browser, update_tryorder=1):
Fred Drakef4e5bd92001-04-12 22:07:27 +000065 """Attempt to synthesize a controller base on existing controllers.
66
67 This is useful to create a controller when a user specifies a path to
68 an entry in the BROWSER environment variable -- we can copy a general
69 controller to operate using a specific installation of the desired
70 browser in this way.
71
72 If we can't create a controller in this way, or if there is no
73 executable for the requested browser, return [None, None].
74
75 """
Georg Brandle8f24432005-10-03 14:16:44 +000076 cmd = browser.split()[0]
77 if not _iscommand(cmd):
Fred Drakef4e5bd92001-04-12 22:07:27 +000078 return [None, None]
Georg Brandle8f24432005-10-03 14:16:44 +000079 name = os.path.basename(cmd)
Fred Drakef4e5bd92001-04-12 22:07:27 +000080 try:
81 command = _browsers[name.lower()]
82 except KeyError:
83 return [None, None]
84 # now attempt to clone to fit the new name:
85 controller = command[1]
86 if controller and name.lower() == controller.basename:
87 import copy
88 controller = copy.copy(controller)
89 controller.name = browser
90 controller.basename = os.path.basename(browser)
Georg Brandle8f24432005-10-03 14:16:44 +000091 register(browser, None, controller, update_tryorder)
Fred Drakef4e5bd92001-04-12 22:07:27 +000092 return [None, controller]
Andrew M. Kuchling118aa532001-08-13 14:37:23 +000093 return [None, None]
Fred Drakef4e5bd92001-04-12 22:07:27 +000094
Fred Drake3f8f1642001-07-19 03:46:26 +000095
Georg Brandle8f24432005-10-03 14:16:44 +000096if sys.platform[:3] == "win":
97 def _isexecutable(cmd):
98 cmd = cmd.lower()
99 if os.path.isfile(cmd) and (cmd.endswith(".exe") or
100 cmd.endswith(".bat")):
101 return True
102 for ext in ".exe", ".bat":
103 if os.path.isfile(cmd + ext):
104 return True
105 return False
106else:
107 def _isexecutable(cmd):
108 if os.path.isfile(cmd):
109 mode = os.stat(cmd)[stat.ST_MODE]
110 if mode & stat.S_IXUSR or mode & stat.S_IXGRP or mode & stat.S_IXOTH:
111 return True
112 return False
113
Fred Drake3f8f1642001-07-19 03:46:26 +0000114def _iscommand(cmd):
Georg Brandle8f24432005-10-03 14:16:44 +0000115 """Return True if cmd is executable or can be found on the executable
116 search path."""
117 if _isexecutable(cmd):
118 return True
Fred Drake3f8f1642001-07-19 03:46:26 +0000119 path = os.environ.get("PATH")
120 if not path:
Tim Petersbc0e9102002-04-04 22:55:58 +0000121 return False
Fred Drake3f8f1642001-07-19 03:46:26 +0000122 for d in path.split(os.pathsep):
123 exe = os.path.join(d, cmd)
Georg Brandle8f24432005-10-03 14:16:44 +0000124 if _isexecutable(exe):
Tim Petersbc0e9102002-04-04 22:55:58 +0000125 return True
126 return False
Fred Drake3f8f1642001-07-19 03:46:26 +0000127
128
Georg Brandle8f24432005-10-03 14:16:44 +0000129# General parent classes
130
131class BaseBrowser(object):
132 """Parent class for all browsers."""
133
134 def __init__(self, name=""):
135 self.name = name
136
137 def open_new(self, url):
138 return self.open(url, 1)
139
140 def open_new_tab(self, url):
141 return self.open(url, 2)
Fred Drake3f8f1642001-07-19 03:46:26 +0000142
143
Georg Brandle8f24432005-10-03 14:16:44 +0000144class GenericBrowser(BaseBrowser):
145 """Class for all browsers started with a command
146 and without remote functionality."""
147
Fred Drake3f8f1642001-07-19 03:46:26 +0000148 def __init__(self, cmd):
149 self.name, self.args = cmd.split(None, 1)
Fred Drake3f8f1642001-07-19 03:46:26 +0000150
151 def open(self, url, new=0, autoraise=1):
Fred Drake925f1442002-01-07 15:29:01 +0000152 assert "'" not in url
Fred Drake3f8f1642001-07-19 03:46:26 +0000153 command = "%s %s" % (self.name, self.args)
Georg Brandle8f24432005-10-03 14:16:44 +0000154 rc = os.system(command % url)
155 return not rc
Fred Drake3f8f1642001-07-19 03:46:26 +0000156
157
Georg Brandle8f24432005-10-03 14:16:44 +0000158class UnixBrowser(BaseBrowser):
159 """Parent class for all Unix browsers with remote functionality."""
Fred Drake3f8f1642001-07-19 03:46:26 +0000160
Georg Brandle8f24432005-10-03 14:16:44 +0000161 raise_opts = None
162
163 remote_cmd = ''
164 remote_action = None
165 remote_action_newwin = None
166 remote_action_newtab = None
167 remote_background = False
168
169 def _remote(self, url, action, autoraise):
170 autoraise = int(bool(autoraise)) # always 0/1
171 raise_opt = self.raise_opts and self.raise_opts[autoraise] or ''
172 cmd = "%s %s %s '%s' >/dev/null 2>&1" % (self.name, raise_opt,
173 self.remote_cmd, action)
174 if remote_background:
175 cmd += ' &'
Fred Drake3f8f1642001-07-19 03:46:26 +0000176 rc = os.system(cmd)
177 if rc:
Georg Brandle8f24432005-10-03 14:16:44 +0000178 # bad return status, try again with simpler command
179 rc = os.system("%s %s" % (self.name, url))
Fred Drake3f8f1642001-07-19 03:46:26 +0000180 return not rc
181
182 def open(self, url, new=0, autoraise=1):
Georg Brandle8f24432005-10-03 14:16:44 +0000183 assert "'" not in url
184 if new == 0:
185 action = self.remote_action
186 elif new == 1:
187 action = self.remote_action_newwin
188 elif new == 2:
189 if self.remote_action_newtab is None:
190 action = self.remote_action_newwin
191 else:
192 action = self.remote_action_newtab
Fred Drake3f8f1642001-07-19 03:46:26 +0000193 else:
Georg Brandle8f24432005-10-03 14:16:44 +0000194 raise Error("Bad 'new' parameter to open(); expected 0, 1, or 2, got %s" % new)
195 return self._remote(url, action % url, autoraise)
Fred Drake3f8f1642001-07-19 03:46:26 +0000196
197
Georg Brandle8f24432005-10-03 14:16:44 +0000198class Mozilla(UnixBrowser):
199 """Launcher class for Mozilla/Netscape browsers."""
Neal Norwitz8dd28eb2002-10-10 22:49:29 +0000200
Georg Brandle8f24432005-10-03 14:16:44 +0000201 raise_opts = ("-noraise", "-raise")
Neal Norwitz8dd28eb2002-10-10 22:49:29 +0000202
Georg Brandle8f24432005-10-03 14:16:44 +0000203 remote_cmd = '-remote'
204 remote_action = "openURL(%s)"
205 remote_action_newwin = "openURL(%s,new-window)"
206 remote_action_newtab = "openURL(%s,new-tab)"
Neal Norwitz8dd28eb2002-10-10 22:49:29 +0000207
Georg Brandle8f24432005-10-03 14:16:44 +0000208Netscape = Mozilla
Neal Norwitz8dd28eb2002-10-10 22:49:29 +0000209
210
Georg Brandle8f24432005-10-03 14:16:44 +0000211class Galeon(UnixBrowser):
212 """Launcher class for Galeon/Epiphany browsers."""
213
214 raise_opts = ("-noraise", "")
215 remote_action = "-n '%s'"
216 remote_action_newwin = "-w '%s'"
217
218 remote_background = True
219
220
221class Konqueror(BaseBrowser):
Fred Drake3f8f1642001-07-19 03:46:26 +0000222 """Controller for the KDE File Manager (kfm, or Konqueror).
223
224 See http://developer.kde.org/documentation/other/kfmclient.html
225 for more information on the Konqueror remote-control interface.
226
227 """
Fred Drake3f8f1642001-07-19 03:46:26 +0000228
Georg Brandle8f24432005-10-03 14:16:44 +0000229 def _remote(self, url, action):
230 # kfmclient is the new KDE way of opening URLs.
Neal Norwitz520cdf72002-10-11 22:04:22 +0000231 cmd = "kfmclient %s >/dev/null 2>&1" % action
Fred Drake3f8f1642001-07-19 03:46:26 +0000232 rc = os.system(cmd)
Georg Brandle8f24432005-10-03 14:16:44 +0000233 # Fall back to other variants.
Fred Drake3f8f1642001-07-19 03:46:26 +0000234 if rc:
Georg Brandle8f24432005-10-03 14:16:44 +0000235 if _iscommand("konqueror"):
236 rc = os.system(self.name + " --silent '%s' &" % url)
237 elif _iscommand("kfm"):
238 rc = os.system(self.name + " -d '%s'" % url)
Fred Drake3f8f1642001-07-19 03:46:26 +0000239 return not rc
240
Georg Brandle8f24432005-10-03 14:16:44 +0000241 def open(self, url, new=0, autoraise=1):
Fred Drake3f8f1642001-07-19 03:46:26 +0000242 # XXX Currently I know no way to prevent KFM from
243 # opening a new win.
Neal Norwitz520cdf72002-10-11 22:04:22 +0000244 assert "'" not in url
Georg Brandle8f24432005-10-03 14:16:44 +0000245 if new == 2:
246 action = "newTab '%s'" % url
247 else:
248 action = "openURL '%s'" % url
249 ok = self._remote(url, action)
250 return ok
Fred Drake3f8f1642001-07-19 03:46:26 +0000251
252
Georg Brandle8f24432005-10-03 14:16:44 +0000253class Opera(UnixBrowser):
254 "Launcher class for Opera browser."
255
256 raise_opts = ("", "-raise")
257
258 remote_cmd = '-remote'
259 remote_action = "openURL(%s)"
260 remote_action_newwin = "openURL(%s,new-window)"
261 remote_action_newtab = "openURL(%s,new-page)"
262
263
264class Elinks(UnixBrowser):
265 "Launcher class for Elinks browsers."
266
267 remote_cmd = '-remote'
268 remote_action = "openURL(%s)"
269 remote_action_newwin = "openURL(%s,new-window)"
270 remote_action_newtab = "openURL(%s,new-tab)"
271
272 def _remote(self, url, action, autoraise):
273 # elinks doesn't like its stdout to be redirected -
274 # it uses redirected stdout as a signal to do -dump
275 cmd = "%s %s '%s' 2>/dev/null" % (self.name,
276 self.remote_cmd, action)
277 rc = os.system(cmd)
278 if rc:
279 rc = os.system("%s %s" % (self.name, url))
280 return not rc
281
282
283class Grail(BaseBrowser):
Fred Drake3f8f1642001-07-19 03:46:26 +0000284 # There should be a way to maintain a connection to Grail, but the
285 # Grail remote control protocol doesn't really allow that at this
286 # point. It probably neverwill!
287 def _find_grail_rc(self):
288 import glob
289 import pwd
290 import socket
291 import tempfile
292 tempdir = os.path.join(tempfile.gettempdir(),
293 ".grail-unix")
Fred Drake16623fe2001-10-13 16:00:52 +0000294 user = pwd.getpwuid(os.getuid())[0]
Fred Drake3f8f1642001-07-19 03:46:26 +0000295 filename = os.path.join(tempdir, user + "-*")
296 maybes = glob.glob(filename)
297 if not maybes:
298 return None
299 s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
300 for fn in maybes:
301 # need to PING each one until we find one that's live
302 try:
303 s.connect(fn)
304 except socket.error:
305 # no good; attempt to clean it out, but don't fail:
306 try:
307 os.unlink(fn)
308 except IOError:
309 pass
310 else:
311 return s
312
313 def _remote(self, action):
314 s = self._find_grail_rc()
315 if not s:
316 return 0
317 s.send(action)
318 s.close()
319 return 1
320
321 def open(self, url, new=0, autoraise=1):
322 if new:
Georg Brandle8f24432005-10-03 14:16:44 +0000323 ok = self._remote("LOADNEW " + url)
Fred Drake3f8f1642001-07-19 03:46:26 +0000324 else:
Georg Brandle8f24432005-10-03 14:16:44 +0000325 ok = self._remote("LOAD " + url)
326 return ok
Fred Drake3f8f1642001-07-19 03:46:26 +0000327
Fred Drakec70b4482000-07-09 16:45:56 +0000328
Tim Peters658cba62001-02-09 20:06:00 +0000329#
Eric S. Raymondf7f18512001-01-23 13:16:32 +0000330# Platform support for Unix
331#
Fred Drakec70b4482000-07-09 16:45:56 +0000332
Georg Brandle8f24432005-10-03 14:16:44 +0000333# These are the right tests because all these Unix browsers require either
334# a console terminal or an X display to run.
Fred Drakec70b4482000-07-09 16:45:56 +0000335
Georg Brandle8f24432005-10-03 14:16:44 +0000336# Prefer X browsers if present
337if os.environ.get("DISPLAY"):
Fred Drakec70b4482000-07-09 16:45:56 +0000338
Georg Brandle8f24432005-10-03 14:16:44 +0000339 # First, the Mozilla/Netscape browsers
340 for browser in ("mozilla-firefox", "firefox",
341 "mozilla-firebird", "firebird",
342 "mozilla", "netscape"):
343 if _iscommand(browser):
344 register(browser, None, Mozilla(browser))
Gustavo Niemeyer1456fde2002-11-25 17:25:04 +0000345
Georg Brandle8f24432005-10-03 14:16:44 +0000346 # The default Gnome browser
347 if _iscommand("gconftool-2"):
348 # get the web browser string from gconftool
349 gc = 'gconftool-2 -g /desktop/gnome/url-handlers/http/command'
350 out = os.popen(gc)
351 commd = out.read().strip()
352 retncode = out.close()
Eric S. Raymondf7f18512001-01-23 13:16:32 +0000353
Georg Brandle8f24432005-10-03 14:16:44 +0000354 # if successful, register it
355 if retncode == None and len(commd) != 0:
356 register("gnome", None, GenericBrowser(
357 commd + " '%s' >/dev/null &"))
Eric S. Raymondf7f18512001-01-23 13:16:32 +0000358
Georg Brandle8f24432005-10-03 14:16:44 +0000359 # Konqueror/kfm, the KDE browser.
360 if _iscommand("kfm") or _iscommand("konqueror"):
361 register("kfm", Konqueror, Konqueror())
Neal Norwitz8dd28eb2002-10-10 22:49:29 +0000362
Georg Brandle8f24432005-10-03 14:16:44 +0000363 # Gnome's Galeon and Epiphany
364 for browser in ("galeon", "epiphany"):
365 if _iscommand(browser):
366 register(browser, None, Galeon(browser))
Gustavo Niemeyer1456fde2002-11-25 17:25:04 +0000367
Georg Brandle8f24432005-10-03 14:16:44 +0000368 # Skipstone, another Gtk/Mozilla based browser
369 if _iscommand("skipstone"):
370 register("skipstone", None, GenericBrowser("skipstone '%s' &"))
Eric S. Raymondf7f18512001-01-23 13:16:32 +0000371
Georg Brandle8f24432005-10-03 14:16:44 +0000372 # Opera, quite popular
373 if _iscommand("opera"):
374 register("opera", None, Opera("opera"))
Eric S. Raymondf7f18512001-01-23 13:16:32 +0000375
Georg Brandle8f24432005-10-03 14:16:44 +0000376 # Next, Mosaic -- old but still in use.
377 if _iscommand("mosaic"):
378 register("mosaic", None, GenericBrowser("mosaic '%s' &"))
Fred Drake3f8f1642001-07-19 03:46:26 +0000379
Georg Brandle8f24432005-10-03 14:16:44 +0000380 # Grail, the Python browser. Does anybody still use it?
381 if _iscommand("grail"):
382 register("grail", Grail, None)
Fred Drake3f8f1642001-07-19 03:46:26 +0000383
Georg Brandle8f24432005-10-03 14:16:44 +0000384# Also try console browsers
385if os.environ.get("TERM"):
386 # The Links/elinks browsers <http://artax.karlin.mff.cuni.cz/~mikulas/links/>
387 if _iscommand("links"):
388 register("links", None, GenericBrowser("links '%s'"))
389 if _iscommand("elinks"):
390 register("elinks", None, Elinks("elinks"))
391 # The Lynx browser <http://lynx.isc.org/>, <http://lynx.browser.org/>
392 if _iscommand("lynx"):
393 register("lynx", None, GenericBrowser("lynx '%s'"))
394 # The w3m browser <http://w3m.sourceforge.net/>
395 if _iscommand("w3m"):
396 register("w3m", None, GenericBrowser("w3m '%s'"))
Fred Drake3f8f1642001-07-19 03:46:26 +0000397
Eric S. Raymondf7f18512001-01-23 13:16:32 +0000398#
399# Platform support for Windows
400#
Fred Drakec70b4482000-07-09 16:45:56 +0000401
402if sys.platform[:3] == "win":
Georg Brandle8f24432005-10-03 14:16:44 +0000403 class WindowsDefault(BaseBrowser):
404 def open(self, url, new=0, autoraise=1):
405 os.startfile(url)
406 return True # Oh, my...
407
408 _tryorder = []
409 _browsers = {}
410 # Prefer mozilla/netscape/opera if present
411 for browser in ("firefox", "firebird", "mozilla", "netscape", "opera"):
412 if _iscommand(browser):
413 register(browser, None, GenericBrowser(browser + ' %s'))
Fred Drakec70b4482000-07-09 16:45:56 +0000414 register("windows-default", WindowsDefault)
Fred Drakec70b4482000-07-09 16:45:56 +0000415
Fred Drakec70b4482000-07-09 16:45:56 +0000416#
Eric S. Raymondf7f18512001-01-23 13:16:32 +0000417# Platform support for MacOS
418#
Fred Drakec70b4482000-07-09 16:45:56 +0000419
420try:
421 import ic
422except ImportError:
423 pass
424else:
Georg Brandle8f24432005-10-03 14:16:44 +0000425 class InternetConfig(BaseBrowser):
426 def open(self, url, new=0, autoraise=1):
427 ic.launchurl(url)
428 return True # Any way to get status?
429
430 register("internet-config", InternetConfig, update_tryorder=-1)
431
432if sys.platform == 'darwin':
433 # Adapted from patch submitted to SourceForge by Steven J. Burr
434 class MacOSX(BaseBrowser):
435 """Launcher class for Aqua browsers on Mac OS X
436
437 Optionally specify a browser name on instantiation. Note that this
438 will not work for Aqua browsers if the user has moved the application
439 package after installation.
440
441 If no browser is specified, the default browser, as specified in the
442 Internet System Preferences panel, will be used.
443 """
444 def __init__(self, name):
445 self.name = name
446
447 def open(self, url, new=0, autoraise=1):
448 assert "'" not in url
449 # new must be 0 or 1
450 new = int(bool(new))
451 if self.name == "default":
452 # User called open, open_new or get without a browser parameter
453 script = _safequote('open location "%s"', url) # opens in default browser
454 else:
455 # User called get and chose a browser
456 if self.name == "OmniWeb":
457 toWindow = ""
458 else:
459 # Include toWindow parameter of OpenURL command for browsers
460 # that support it. 0 == new window; -1 == existing
461 toWindow = "toWindow %d" % (new - 1)
462 cmd = _safequote('OpenURL "%s"', url)
463 script = '''tell application "%s"
464 activate
465 %s %s
466 end tell''' % (self.name, cmd, toWindow)
467 # Open pipe to AppleScript through osascript command
468 osapipe = os.popen("osascript", "w")
469 if osapipe is None:
470 return False
471 # Write script to osascript's stdin
472 osapipe.write(script)
473 rc = osapipe.close()
474 return not rc
475
476 # Don't clear _tryorder or _browsers since OS X can use above Unix support
477 # (but we prefer using the OS X specific stuff)
478 register("MacOSX", None, MacOSX('default'), -1)
479
Eric S. Raymondf7f18512001-01-23 13:16:32 +0000480
Martin v. Löwis3a89b2b2001-11-25 14:35:58 +0000481#
482# Platform support for OS/2
483#
484
Georg Brandle8f24432005-10-03 14:16:44 +0000485if sys.platform[:3] == "os2" and _iscommand("netscape"):
486 _tryorder = []
487 _browsers = {}
Martin v. Löwis3a89b2b2001-11-25 14:35:58 +0000488 register("os2netscape", None,
Georg Brandle8f24432005-10-03 14:16:44 +0000489 GenericBrowser("start netscape %s"), -1)
490
Martin v. Löwis3a89b2b2001-11-25 14:35:58 +0000491
Eric S. Raymondf7f18512001-01-23 13:16:32 +0000492# OK, now that we know what the default preference orders for each
493# platform are, allow user to override them with the BROWSER variable.
Raymond Hettinger54f02222002-06-01 14:18:47 +0000494if "BROWSER" in os.environ:
Georg Brandle8f24432005-10-03 14:16:44 +0000495 _userchoices = os.environ["BROWSER"].split(os.pathsep)
496 _userchoices.reverse()
Skip Montanarocdab3bf2001-07-18 20:03:32 +0000497
Georg Brandle8f24432005-10-03 14:16:44 +0000498 # Treat choices in same way as if passed into get() but do register
499 # and prepend to _tryorder
500 for cmdline in _userchoices:
501 if cmdline != '':
502 _synthesize(cmdline, -1)
503 cmdline = None # to make del work if _userchoices was empty
504 del cmdline
505 del _userchoices
Skip Montanarocdab3bf2001-07-18 20:03:32 +0000506
Skip Montanarocdab3bf2001-07-18 20:03:32 +0000507# what to do if _tryorder is now empty?
Georg Brandle8f24432005-10-03 14:16:44 +0000508
509
510def main():
511 import getopt
512 usage = """Usage: %s [-n | -t] url
513 -n: open new window
514 -t: open new tab""" % sys.argv[0]
515 try:
516 opts, args = getopt.getopt(sys.argv[1:], 'ntd')
517 except getopt.error, msg:
518 print >>sys.stderr, msg
519 print >>sys.stderr, usage
520 sys.exit(1)
521 new_win = 0
522 for o, a in opts:
523 if o == '-n': new_win = 1
524 elif o == '-t': new_win = 2
525 if len(args) <> 1:
526 print >>sys.stderr, usage
527 sys.exit(1)
528
529 url = args[0]
530 open(url, new_win)
531
532if __name__ == "__main__":
533 main()