blob: 1cef7243d4e6332d6c43c33b3233afb2f9d7df99 [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
Neal Norwitz196f7332005-10-04 03:17:49 +0000137 def open(self, url, new=0, autoraise=1):
138 raise NotImplementedError
139
Georg Brandle8f24432005-10-03 14:16:44 +0000140 def open_new(self, url):
141 return self.open(url, 1)
142
143 def open_new_tab(self, url):
144 return self.open(url, 2)
Fred Drake3f8f1642001-07-19 03:46:26 +0000145
146
Georg Brandle8f24432005-10-03 14:16:44 +0000147class GenericBrowser(BaseBrowser):
148 """Class for all browsers started with a command
149 and without remote functionality."""
150
Fred Drake3f8f1642001-07-19 03:46:26 +0000151 def __init__(self, cmd):
152 self.name, self.args = cmd.split(None, 1)
Fred Drake3f8f1642001-07-19 03:46:26 +0000153
154 def open(self, url, new=0, autoraise=1):
Fred Drake925f1442002-01-07 15:29:01 +0000155 assert "'" not in url
Fred Drake3f8f1642001-07-19 03:46:26 +0000156 command = "%s %s" % (self.name, self.args)
Georg Brandle8f24432005-10-03 14:16:44 +0000157 rc = os.system(command % url)
158 return not rc
Fred Drake3f8f1642001-07-19 03:46:26 +0000159
160
Georg Brandle8f24432005-10-03 14:16:44 +0000161class UnixBrowser(BaseBrowser):
162 """Parent class for all Unix browsers with remote functionality."""
Fred Drake3f8f1642001-07-19 03:46:26 +0000163
Georg Brandle8f24432005-10-03 14:16:44 +0000164 raise_opts = None
165
166 remote_cmd = ''
167 remote_action = None
168 remote_action_newwin = None
169 remote_action_newtab = None
170 remote_background = False
171
172 def _remote(self, url, action, autoraise):
173 autoraise = int(bool(autoraise)) # always 0/1
174 raise_opt = self.raise_opts and self.raise_opts[autoraise] or ''
175 cmd = "%s %s %s '%s' >/dev/null 2>&1" % (self.name, raise_opt,
176 self.remote_cmd, action)
Neal Norwitz196f7332005-10-04 03:17:49 +0000177 if self.remote_background:
Georg Brandle8f24432005-10-03 14:16:44 +0000178 cmd += ' &'
Fred Drake3f8f1642001-07-19 03:46:26 +0000179 rc = os.system(cmd)
180 if rc:
Georg Brandle8f24432005-10-03 14:16:44 +0000181 # bad return status, try again with simpler command
182 rc = os.system("%s %s" % (self.name, url))
Fred Drake3f8f1642001-07-19 03:46:26 +0000183 return not rc
184
185 def open(self, url, new=0, autoraise=1):
Georg Brandle8f24432005-10-03 14:16:44 +0000186 assert "'" not in url
187 if new == 0:
188 action = self.remote_action
189 elif new == 1:
190 action = self.remote_action_newwin
191 elif new == 2:
192 if self.remote_action_newtab is None:
193 action = self.remote_action_newwin
194 else:
195 action = self.remote_action_newtab
Fred Drake3f8f1642001-07-19 03:46:26 +0000196 else:
Georg Brandle8f24432005-10-03 14:16:44 +0000197 raise Error("Bad 'new' parameter to open(); expected 0, 1, or 2, got %s" % new)
198 return self._remote(url, action % url, autoraise)
Fred Drake3f8f1642001-07-19 03:46:26 +0000199
200
Georg Brandle8f24432005-10-03 14:16:44 +0000201class Mozilla(UnixBrowser):
202 """Launcher class for Mozilla/Netscape browsers."""
Neal Norwitz8dd28eb2002-10-10 22:49:29 +0000203
Georg Brandle8f24432005-10-03 14:16:44 +0000204 raise_opts = ("-noraise", "-raise")
Neal Norwitz8dd28eb2002-10-10 22:49:29 +0000205
Georg Brandle8f24432005-10-03 14:16:44 +0000206 remote_cmd = '-remote'
207 remote_action = "openURL(%s)"
208 remote_action_newwin = "openURL(%s,new-window)"
209 remote_action_newtab = "openURL(%s,new-tab)"
Neal Norwitz8dd28eb2002-10-10 22:49:29 +0000210
Georg Brandle8f24432005-10-03 14:16:44 +0000211Netscape = Mozilla
Neal Norwitz8dd28eb2002-10-10 22:49:29 +0000212
213
Georg Brandle8f24432005-10-03 14:16:44 +0000214class Galeon(UnixBrowser):
215 """Launcher class for Galeon/Epiphany browsers."""
216
217 raise_opts = ("-noraise", "")
218 remote_action = "-n '%s'"
219 remote_action_newwin = "-w '%s'"
220
221 remote_background = True
222
223
224class Konqueror(BaseBrowser):
Fred Drake3f8f1642001-07-19 03:46:26 +0000225 """Controller for the KDE File Manager (kfm, or Konqueror).
226
227 See http://developer.kde.org/documentation/other/kfmclient.html
228 for more information on the Konqueror remote-control interface.
229
230 """
Fred Drake3f8f1642001-07-19 03:46:26 +0000231
Georg Brandle8f24432005-10-03 14:16:44 +0000232 def _remote(self, url, action):
233 # kfmclient is the new KDE way of opening URLs.
Neal Norwitz520cdf72002-10-11 22:04:22 +0000234 cmd = "kfmclient %s >/dev/null 2>&1" % action
Fred Drake3f8f1642001-07-19 03:46:26 +0000235 rc = os.system(cmd)
Georg Brandle8f24432005-10-03 14:16:44 +0000236 # Fall back to other variants.
Fred Drake3f8f1642001-07-19 03:46:26 +0000237 if rc:
Georg Brandle8f24432005-10-03 14:16:44 +0000238 if _iscommand("konqueror"):
239 rc = os.system(self.name + " --silent '%s' &" % url)
240 elif _iscommand("kfm"):
241 rc = os.system(self.name + " -d '%s'" % url)
Fred Drake3f8f1642001-07-19 03:46:26 +0000242 return not rc
243
Georg Brandle8f24432005-10-03 14:16:44 +0000244 def open(self, url, new=0, autoraise=1):
Fred Drake3f8f1642001-07-19 03:46:26 +0000245 # XXX Currently I know no way to prevent KFM from
246 # opening a new win.
Neal Norwitz520cdf72002-10-11 22:04:22 +0000247 assert "'" not in url
Georg Brandle8f24432005-10-03 14:16:44 +0000248 if new == 2:
249 action = "newTab '%s'" % url
250 else:
251 action = "openURL '%s'" % url
252 ok = self._remote(url, action)
253 return ok
Fred Drake3f8f1642001-07-19 03:46:26 +0000254
255
Georg Brandle8f24432005-10-03 14:16:44 +0000256class Opera(UnixBrowser):
257 "Launcher class for Opera browser."
258
259 raise_opts = ("", "-raise")
260
261 remote_cmd = '-remote'
262 remote_action = "openURL(%s)"
263 remote_action_newwin = "openURL(%s,new-window)"
264 remote_action_newtab = "openURL(%s,new-page)"
265
266
267class Elinks(UnixBrowser):
268 "Launcher class for Elinks browsers."
269
270 remote_cmd = '-remote'
271 remote_action = "openURL(%s)"
272 remote_action_newwin = "openURL(%s,new-window)"
273 remote_action_newtab = "openURL(%s,new-tab)"
274
275 def _remote(self, url, action, autoraise):
276 # elinks doesn't like its stdout to be redirected -
277 # it uses redirected stdout as a signal to do -dump
278 cmd = "%s %s '%s' 2>/dev/null" % (self.name,
279 self.remote_cmd, action)
280 rc = os.system(cmd)
281 if rc:
282 rc = os.system("%s %s" % (self.name, url))
283 return not rc
284
285
286class Grail(BaseBrowser):
Fred Drake3f8f1642001-07-19 03:46:26 +0000287 # There should be a way to maintain a connection to Grail, but the
288 # Grail remote control protocol doesn't really allow that at this
289 # point. It probably neverwill!
290 def _find_grail_rc(self):
291 import glob
292 import pwd
293 import socket
294 import tempfile
295 tempdir = os.path.join(tempfile.gettempdir(),
296 ".grail-unix")
Fred Drake16623fe2001-10-13 16:00:52 +0000297 user = pwd.getpwuid(os.getuid())[0]
Fred Drake3f8f1642001-07-19 03:46:26 +0000298 filename = os.path.join(tempdir, user + "-*")
299 maybes = glob.glob(filename)
300 if not maybes:
301 return None
302 s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
303 for fn in maybes:
304 # need to PING each one until we find one that's live
305 try:
306 s.connect(fn)
307 except socket.error:
308 # no good; attempt to clean it out, but don't fail:
309 try:
310 os.unlink(fn)
311 except IOError:
312 pass
313 else:
314 return s
315
316 def _remote(self, action):
317 s = self._find_grail_rc()
318 if not s:
319 return 0
320 s.send(action)
321 s.close()
322 return 1
323
324 def open(self, url, new=0, autoraise=1):
325 if new:
Georg Brandle8f24432005-10-03 14:16:44 +0000326 ok = self._remote("LOADNEW " + url)
Fred Drake3f8f1642001-07-19 03:46:26 +0000327 else:
Georg Brandle8f24432005-10-03 14:16:44 +0000328 ok = self._remote("LOAD " + url)
329 return ok
Fred Drake3f8f1642001-07-19 03:46:26 +0000330
Fred Drakec70b4482000-07-09 16:45:56 +0000331
Tim Peters658cba62001-02-09 20:06:00 +0000332#
Eric S. Raymondf7f18512001-01-23 13:16:32 +0000333# Platform support for Unix
334#
Fred Drakec70b4482000-07-09 16:45:56 +0000335
Georg Brandle8f24432005-10-03 14:16:44 +0000336# These are the right tests because all these Unix browsers require either
337# a console terminal or an X display to run.
Fred Drakec70b4482000-07-09 16:45:56 +0000338
Neal Norwitz196f7332005-10-04 03:17:49 +0000339def register_X_browsers():
Georg Brandle8f24432005-10-03 14:16:44 +0000340 # First, the Mozilla/Netscape browsers
341 for browser in ("mozilla-firefox", "firefox",
342 "mozilla-firebird", "firebird",
343 "mozilla", "netscape"):
344 if _iscommand(browser):
345 register(browser, None, Mozilla(browser))
Gustavo Niemeyer1456fde2002-11-25 17:25:04 +0000346
Georg Brandle8f24432005-10-03 14:16:44 +0000347 # The default Gnome browser
348 if _iscommand("gconftool-2"):
349 # get the web browser string from gconftool
350 gc = 'gconftool-2 -g /desktop/gnome/url-handlers/http/command'
351 out = os.popen(gc)
352 commd = out.read().strip()
353 retncode = out.close()
Eric S. Raymondf7f18512001-01-23 13:16:32 +0000354
Georg Brandle8f24432005-10-03 14:16:44 +0000355 # if successful, register it
356 if retncode == None and len(commd) != 0:
357 register("gnome", None, GenericBrowser(
358 commd + " '%s' >/dev/null &"))
Eric S. Raymondf7f18512001-01-23 13:16:32 +0000359
Georg Brandle8f24432005-10-03 14:16:44 +0000360 # Konqueror/kfm, the KDE browser.
361 if _iscommand("kfm") or _iscommand("konqueror"):
362 register("kfm", Konqueror, Konqueror())
Neal Norwitz8dd28eb2002-10-10 22:49:29 +0000363
Georg Brandle8f24432005-10-03 14:16:44 +0000364 # Gnome's Galeon and Epiphany
365 for browser in ("galeon", "epiphany"):
366 if _iscommand(browser):
367 register(browser, None, Galeon(browser))
Gustavo Niemeyer1456fde2002-11-25 17:25:04 +0000368
Georg Brandle8f24432005-10-03 14:16:44 +0000369 # Skipstone, another Gtk/Mozilla based browser
370 if _iscommand("skipstone"):
371 register("skipstone", None, GenericBrowser("skipstone '%s' &"))
Eric S. Raymondf7f18512001-01-23 13:16:32 +0000372
Georg Brandle8f24432005-10-03 14:16:44 +0000373 # Opera, quite popular
374 if _iscommand("opera"):
375 register("opera", None, Opera("opera"))
Eric S. Raymondf7f18512001-01-23 13:16:32 +0000376
Georg Brandle8f24432005-10-03 14:16:44 +0000377 # Next, Mosaic -- old but still in use.
378 if _iscommand("mosaic"):
379 register("mosaic", None, GenericBrowser("mosaic '%s' &"))
Fred Drake3f8f1642001-07-19 03:46:26 +0000380
Georg Brandle8f24432005-10-03 14:16:44 +0000381 # Grail, the Python browser. Does anybody still use it?
382 if _iscommand("grail"):
383 register("grail", Grail, None)
Fred Drake3f8f1642001-07-19 03:46:26 +0000384
Neal Norwitz196f7332005-10-04 03:17:49 +0000385# Prefer X browsers if present
386if os.environ.get("DISPLAY"):
387 register_X_browsers()
388
Georg Brandle8f24432005-10-03 14:16:44 +0000389# Also try console browsers
390if os.environ.get("TERM"):
391 # The Links/elinks browsers <http://artax.karlin.mff.cuni.cz/~mikulas/links/>
392 if _iscommand("links"):
393 register("links", None, GenericBrowser("links '%s'"))
394 if _iscommand("elinks"):
395 register("elinks", None, Elinks("elinks"))
396 # The Lynx browser <http://lynx.isc.org/>, <http://lynx.browser.org/>
397 if _iscommand("lynx"):
398 register("lynx", None, GenericBrowser("lynx '%s'"))
399 # The w3m browser <http://w3m.sourceforge.net/>
400 if _iscommand("w3m"):
401 register("w3m", None, GenericBrowser("w3m '%s'"))
Fred Drake3f8f1642001-07-19 03:46:26 +0000402
Eric S. Raymondf7f18512001-01-23 13:16:32 +0000403#
404# Platform support for Windows
405#
Fred Drakec70b4482000-07-09 16:45:56 +0000406
407if sys.platform[:3] == "win":
Georg Brandle8f24432005-10-03 14:16:44 +0000408 class WindowsDefault(BaseBrowser):
409 def open(self, url, new=0, autoraise=1):
410 os.startfile(url)
411 return True # Oh, my...
412
413 _tryorder = []
414 _browsers = {}
415 # Prefer mozilla/netscape/opera if present
416 for browser in ("firefox", "firebird", "mozilla", "netscape", "opera"):
417 if _iscommand(browser):
418 register(browser, None, GenericBrowser(browser + ' %s'))
Fred Drakec70b4482000-07-09 16:45:56 +0000419 register("windows-default", WindowsDefault)
Fred Drakec70b4482000-07-09 16:45:56 +0000420
Fred Drakec70b4482000-07-09 16:45:56 +0000421#
Eric S. Raymondf7f18512001-01-23 13:16:32 +0000422# Platform support for MacOS
423#
Fred Drakec70b4482000-07-09 16:45:56 +0000424
425try:
426 import ic
427except ImportError:
428 pass
429else:
Georg Brandle8f24432005-10-03 14:16:44 +0000430 class InternetConfig(BaseBrowser):
431 def open(self, url, new=0, autoraise=1):
432 ic.launchurl(url)
433 return True # Any way to get status?
434
435 register("internet-config", InternetConfig, update_tryorder=-1)
436
437if sys.platform == 'darwin':
438 # Adapted from patch submitted to SourceForge by Steven J. Burr
439 class MacOSX(BaseBrowser):
440 """Launcher class for Aqua browsers on Mac OS X
441
442 Optionally specify a browser name on instantiation. Note that this
443 will not work for Aqua browsers if the user has moved the application
444 package after installation.
445
446 If no browser is specified, the default browser, as specified in the
447 Internet System Preferences panel, will be used.
448 """
449 def __init__(self, name):
450 self.name = name
451
452 def open(self, url, new=0, autoraise=1):
453 assert "'" not in url
454 # new must be 0 or 1
455 new = int(bool(new))
456 if self.name == "default":
457 # User called open, open_new or get without a browser parameter
458 script = _safequote('open location "%s"', url) # opens in default browser
459 else:
460 # User called get and chose a browser
461 if self.name == "OmniWeb":
462 toWindow = ""
463 else:
464 # Include toWindow parameter of OpenURL command for browsers
465 # that support it. 0 == new window; -1 == existing
466 toWindow = "toWindow %d" % (new - 1)
467 cmd = _safequote('OpenURL "%s"', url)
468 script = '''tell application "%s"
469 activate
470 %s %s
471 end tell''' % (self.name, cmd, toWindow)
472 # Open pipe to AppleScript through osascript command
473 osapipe = os.popen("osascript", "w")
474 if osapipe is None:
475 return False
476 # Write script to osascript's stdin
477 osapipe.write(script)
478 rc = osapipe.close()
479 return not rc
480
481 # Don't clear _tryorder or _browsers since OS X can use above Unix support
482 # (but we prefer using the OS X specific stuff)
483 register("MacOSX", None, MacOSX('default'), -1)
484
Eric S. Raymondf7f18512001-01-23 13:16:32 +0000485
Martin v. Löwis3a89b2b2001-11-25 14:35:58 +0000486#
487# Platform support for OS/2
488#
489
Georg Brandle8f24432005-10-03 14:16:44 +0000490if sys.platform[:3] == "os2" and _iscommand("netscape"):
491 _tryorder = []
492 _browsers = {}
Martin v. Löwis3a89b2b2001-11-25 14:35:58 +0000493 register("os2netscape", None,
Georg Brandle8f24432005-10-03 14:16:44 +0000494 GenericBrowser("start netscape %s"), -1)
495
Martin v. Löwis3a89b2b2001-11-25 14:35:58 +0000496
Eric S. Raymondf7f18512001-01-23 13:16:32 +0000497# OK, now that we know what the default preference orders for each
498# platform are, allow user to override them with the BROWSER variable.
Raymond Hettinger54f02222002-06-01 14:18:47 +0000499if "BROWSER" in os.environ:
Georg Brandle8f24432005-10-03 14:16:44 +0000500 _userchoices = os.environ["BROWSER"].split(os.pathsep)
501 _userchoices.reverse()
Skip Montanarocdab3bf2001-07-18 20:03:32 +0000502
Georg Brandle8f24432005-10-03 14:16:44 +0000503 # Treat choices in same way as if passed into get() but do register
504 # and prepend to _tryorder
505 for cmdline in _userchoices:
506 if cmdline != '':
507 _synthesize(cmdline, -1)
508 cmdline = None # to make del work if _userchoices was empty
509 del cmdline
510 del _userchoices
Skip Montanarocdab3bf2001-07-18 20:03:32 +0000511
Skip Montanarocdab3bf2001-07-18 20:03:32 +0000512# what to do if _tryorder is now empty?
Georg Brandle8f24432005-10-03 14:16:44 +0000513
514
515def main():
516 import getopt
517 usage = """Usage: %s [-n | -t] url
518 -n: open new window
519 -t: open new tab""" % sys.argv[0]
520 try:
521 opts, args = getopt.getopt(sys.argv[1:], 'ntd')
522 except getopt.error, msg:
523 print >>sys.stderr, msg
524 print >>sys.stderr, usage
525 sys.exit(1)
526 new_win = 0
527 for o, a in opts:
528 if o == '-n': new_win = 1
529 elif o == '-t': new_win = 2
530 if len(args) <> 1:
531 print >>sys.stderr, usage
532 sys.exit(1)
533
534 url = args[0]
535 open(url, new_win)
536
537if __name__ == "__main__":
538 main()