Bump version to 0.9.1.
[python/dscho.git] / Lib / webbrowser.py
blob5a4a80fa4e94f12614683f06e0799ea00ed945c2
1 """Remote-control interfaces to some browsers."""
3 import os
4 import sys
7 PROCESS_CREATION_DELAY = 4
10 class Error(Exception):
11 pass
14 _browsers = {}
16 def register(name, klass, instance=None):
17 """Register a browser connector and, optionally, connection."""
18 _browsers[name.lower()] = [klass, instance]
21 def get(name=None):
22 """Retrieve a connection to a browser by type name, or the default
23 browser."""
24 name = name or DEFAULT_BROWSER
25 try:
26 L = _browsers[name.lower()]
27 except KeyError:
28 raise ValueError, "unknown browser type: " + `name`
29 if L[1] is None:
30 L[1] = L[0]()
31 return L[1]
34 # Please note: the following definition hides a builtin function.
36 def open(url, new=0):
37 get().open(url, new)
40 def open_new(url):
41 get().open_new(url)
44 def _iscommand(cmd):
45 """Return true if cmd can be found on the executable search path."""
46 path = os.environ.get("PATH")
47 if not path:
48 return 0
49 for d in path.split(os.pathsep):
50 exe = os.path.join(d, cmd)
51 if os.path.isfile(exe):
52 return 1
53 return 0
56 class CommandLineBrowser:
57 _browsers = []
58 if os.environ.get("DISPLAY"):
59 _browsers.extend([
60 ("netscape", "netscape %s >/dev/null &"),
61 ("mosaic", "mosaic %s >/dev/null &"),
63 _browsers.extend([
64 ("lynx", "lynx %s"),
65 ("w3m", "w3m %s"),
68 def open(self, url, new=0):
69 for exe, cmd in self._browsers:
70 if _iscommand(exe):
71 os.system(cmd % url)
72 return
73 raise Error("could not locate runnable browser")
75 def open_new(self, url):
76 self.open(url)
78 register("command-line", CommandLineBrowser)
81 class Netscape:
82 autoRaise = 1
84 def _remote(self, action):
85 raise_opt = ("-noraise", "-raise")[self.autoRaise]
86 cmd = "netscape %s -remote '%s' >/dev/null 2>&1" % (raise_opt, action)
87 rc = os.system(cmd)
88 if rc:
89 import time
90 os.system("netscape -no-about-splash &")
91 time.sleep(PROCESS_CREATION_DELAY)
92 rc = os.system(cmd)
93 return not rc
95 def open(self, url, new=0):
96 if new:
97 self.open_new(url)
98 else:
99 self._remote("openURL(%s)" % url)
101 def open_new(self, url):
102 self._remote("openURL(%s, new-window)" % url)
104 register("netscape", Netscape)
107 class Konquerer:
108 """Controller for the KDE File Manager (kfm, or Konquerer).
110 See http://developer.kde.org/documentation/other/kfmclient.html
111 for more information on the Konquerer remote-control interface.
114 def _remote(self, action):
115 cmd = "kfmclient %s >/dev/null 2>&1" % action
116 rc = os.system(cmd)
117 if rc:
118 import time
119 os.system("kfm -d &")
120 time.sleep(PROCESS_CREATION_DELAY)
121 rc = os.system(cmd)
122 return not rc
124 def open(self, url, new=1):
125 # XXX currently I know no way to prevent KFM from opening a new win.
126 self.open_new(url)
128 def open_new(self, url):
129 self._remote("openURL %s" % url)
131 register("kfm", Konquerer)
134 class Grail:
135 # There should be a way to maintain a connection to Grail, but the
136 # Grail remote control protocol doesn't really allow that at this
137 # point. It probably never will!
139 def _find_grail_rc(self):
140 import glob
141 import pwd
142 import socket
143 import tempfile
144 tempdir = os.path.join(tempfile.gettempdir(), ".grail-unix")
145 user = pwd.getpwuid(_os.getuid())[0]
146 filename = os.path.join(tempdir, user + "-*")
147 maybes = glob.glob(filename)
148 if not maybes:
149 return None
150 s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
151 for fn in maybes:
152 # need to PING each one until we find one that's live
153 try:
154 s.connect(fn)
155 except socket.error:
156 # no good; attempt to clean it out, but don't fail:
157 try:
158 os.unlink(fn)
159 except IOError:
160 pass
161 else:
162 return s
164 def _remote(self, action):
165 s = self._find_grail_rc()
166 if not s:
167 return 0
168 s.send(action)
169 s.close()
170 return 1
172 def open(self, url, new=0):
173 if new:
174 self.open_new(url)
175 else:
176 self._remote("LOAD " + url)
178 def open_new(self, url):
179 self._remote("LOADNEW " + url)
181 register("grail", Grail)
184 class WindowsDefault:
185 def open(self, url, new=0):
186 import win32api, win32con
187 win32api.ShellExecute(0, "open", url, None, ".",
188 win32con.SW_SHOWNORMAL)
190 def open_new(self, url):
191 self.open(url)
194 DEFAULT_BROWSER = "command-line"
196 if sys.platform[:3] == "win":
197 del _browsers["kfm"]
198 register("windows-default", WindowsDefault)
199 DEFAULT_BROWSER = "windows-default"
200 elif os.environ.get("DISPLAY"):
201 if os.environ.get("KDEDIR"):
202 DEFAULT_BROWSER = "kfm"
203 elif _iscommand("netscape"):
204 DEFAULT_BROWSER = "netscape"
206 # If the $BROWSER environment variable is set and true, let that be
207 # the name of the browser to use:
209 DEFAULT_BROWSER = os.environ.get("BROWSER") or DEFAULT_BROWSER
212 # Now try to support the MacOS world. This is the only supported
213 # controller on that platform, so don't mess with the default!
215 try:
216 import ic
217 except ImportError:
218 pass
219 else:
220 class InternetConfig:
221 def open(self, url, new=0):
222 ic.launcurl(url)
224 def open_new(self, url):
225 self.open(url)
227 _browsers.clear()
228 register("internet-config", InternetConfig)
229 DEFAULT_BROWSER = "internet-config"