webbrowser.py (16177B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\common\lib\webbrowser.py 2 import os 3 import shlex 4 import sys 5 import stat 6 import subprocess 7 import time 8 __all__ = ['Error', 9 'open', 10 'open_new', 11 'open_new_tab', 12 'get', 13 'register'] 14 15 class Error(Exception): 16 pass 17 18 19 _browsers = {} 20 _tryorder = [] 21 22 def register(name, klass, instance = None, update_tryorder = 1): 23 _browsers[name.lower()] = [klass, instance] 24 if update_tryorder > 0: 25 _tryorder.append(name) 26 elif update_tryorder < 0: 27 _tryorder.insert(0, name) 28 29 30 def get(using = None): 31 if using is not None: 32 alternatives = [using] 33 else: 34 alternatives = _tryorder 35 for browser in alternatives: 36 if '%s' in browser: 37 browser = shlex.split(browser) 38 if browser[-1] == '&': 39 return BackgroundBrowser(browser[:-1]) 40 else: 41 return GenericBrowser(browser) 42 else: 43 try: 44 command = _browsers[browser.lower()] 45 except KeyError: 46 command = _synthesize(browser) 47 48 if command[1] is not None: 49 return command[1] 50 if command[0] is not None: 51 return command[0]() 52 53 raise Error('could not locate runnable browser') 54 55 56 def open(url, new = 0, autoraise = True): 57 for name in _tryorder: 58 browser = get(name) 59 if browser.open(url, new, autoraise): 60 return True 61 62 return False 63 64 65 def open_new(url): 66 return open(url, 1) 67 68 69 def open_new_tab(url): 70 return open(url, 2) 71 72 73 def _synthesize(browser, update_tryorder = 1): 74 cmd = browser.split()[0] 75 if not _iscommand(cmd): 76 return [None, None] 77 name = os.path.basename(cmd) 78 try: 79 command = _browsers[name.lower()] 80 except KeyError: 81 return [None, None] 82 83 controller = command[1] 84 if controller and name.lower() == controller.basename: 85 import copy 86 controller = copy.copy(controller) 87 controller.name = browser 88 controller.basename = os.path.basename(browser) 89 register(browser, None, controller, update_tryorder) 90 return [None, controller] 91 return [None, None] 92 93 94 if sys.platform[:3] == 'win': 95 96 def _isexecutable(cmd): 97 cmd = cmd.lower() 98 if os.path.isfile(cmd) and cmd.endswith(('.exe', '.bat')): 99 return True 100 for ext in ('.exe', '.bat'): 101 if os.path.isfile(cmd + ext): 102 return True 103 104 return False 105 106 107 else: 108 109 def _isexecutable(cmd): 110 if os.path.isfile(cmd): 111 mode = os.stat(cmd)[stat.ST_MODE] 112 if mode & stat.S_IXUSR or mode & stat.S_IXGRP or mode & stat.S_IXOTH: 113 return True 114 return False 115 116 117 def _iscommand(cmd): 118 if _isexecutable(cmd): 119 return True 120 path = os.environ.get('PATH') 121 if not path: 122 return False 123 for d in path.split(os.pathsep): 124 exe = os.path.join(d, cmd) 125 if _isexecutable(exe): 126 return True 127 128 return False 129 130 131 class BaseBrowser(object): 132 args = ['%s'] 133 134 def __init__(self, name = ''): 135 self.name = name 136 self.basename = name 137 138 def open(self, url, new = 0, autoraise = True): 139 raise NotImplementedError 140 141 def open_new(self, url): 142 return self.open(url, 1) 143 144 def open_new_tab(self, url): 145 return self.open(url, 2) 146 147 148 class GenericBrowser(BaseBrowser): 149 150 def __init__(self, name): 151 if isinstance(name, basestring): 152 self.name = name 153 self.args = ['%s'] 154 else: 155 self.name = name[0] 156 self.args = name[1:] 157 self.basename = os.path.basename(self.name) 158 159 def open(self, url, new = 0, autoraise = True): 160 cmdline = [self.name] + [ arg.replace('%s', url) for arg in self.args ] 161 try: 162 if sys.platform[:3] == 'win': 163 p = subprocess.Popen(cmdline) 164 else: 165 p = subprocess.Popen(cmdline, close_fds=True) 166 return not p.wait() 167 except OSError: 168 return False 169 170 171 class BackgroundBrowser(GenericBrowser): 172 173 def open(self, url, new = 0, autoraise = True): 174 cmdline = [self.name] + [ arg.replace('%s', url) for arg in self.args ] 175 try: 176 if sys.platform[:3] == 'win': 177 p = subprocess.Popen(cmdline) 178 else: 179 setsid = getattr(os, 'setsid', None) 180 if not setsid: 181 setsid = getattr(os, 'setpgrp', None) 182 p = subprocess.Popen(cmdline, close_fds=True, preexec_fn=setsid) 183 return p.poll() is None 184 except OSError: 185 return False 186 187 188 class UnixBrowser(BaseBrowser): 189 raise_opts = None 190 remote_args = ['%action', '%s'] 191 remote_action = None 192 remote_action_newwin = None 193 remote_action_newtab = None 194 background = False 195 redirect_stdout = True 196 197 def _invoke(self, args, remote, autoraise): 198 raise_opt = [] 199 if remote and self.raise_opts: 200 autoraise = int(autoraise) 201 opt = self.raise_opts[autoraise] 202 if opt: 203 raise_opt = [opt] 204 cmdline = [self.name] + raise_opt + args 205 if remote or self.background: 206 inout = file(os.devnull, 'r+') 207 else: 208 inout = None 209 setsid = getattr(os, 'setsid', None) 210 if not setsid: 211 setsid = getattr(os, 'setpgrp', None) 212 p = subprocess.Popen(cmdline, close_fds=True, stdin=inout, stdout=self.redirect_stdout and inout or None, stderr=inout, preexec_fn=setsid) 213 if remote: 214 time.sleep(1) 215 rc = p.poll() 216 if rc is None: 217 time.sleep(4) 218 rc = p.poll() 219 if rc is None: 220 return True 221 return not rc 222 if self.background: 223 if p.poll() is None: 224 return True 225 else: 226 return False 227 else: 228 return not p.wait() 229 230 def open(self, url, new = 0, autoraise = True): 231 if new == 0: 232 action = self.remote_action 233 elif new == 1: 234 action = self.remote_action_newwin 235 elif new == 2: 236 if self.remote_action_newtab is None: 237 action = self.remote_action_newwin 238 else: 239 action = self.remote_action_newtab 240 else: 241 raise Error("Bad 'new' parameter to open(); " + 'expected 0, 1, or 2, got %s' % new) 242 args = [ arg.replace('%s', url).replace('%action', action) for arg in self.remote_args ] 243 success = self._invoke(args, True, autoraise) 244 if not success: 245 args = [ arg.replace('%s', url) for arg in self.args ] 246 return self._invoke(args, False, False) 247 else: 248 return True 249 250 251 class Mozilla(UnixBrowser): 252 raise_opts = ['-noraise', '-raise'] 253 remote_args = ['-remote', 'openURL(%s%action)'] 254 remote_action = '' 255 remote_action_newwin = ',new-window' 256 remote_action_newtab = ',new-tab' 257 background = True 258 259 260 Netscape = Mozilla 261 262 class Galeon(UnixBrowser): 263 raise_opts = ['-noraise', ''] 264 remote_args = ['%action', '%s'] 265 remote_action = '-n' 266 remote_action_newwin = '-w' 267 background = True 268 269 270 class Chrome(UnixBrowser): 271 remote_args = ['%action', '%s'] 272 remote_action = '' 273 remote_action_newwin = '--new-window' 274 remote_action_newtab = '' 275 background = True 276 277 278 Chromium = Chrome 279 280 class Opera(UnixBrowser): 281 raise_opts = ['-noraise', ''] 282 remote_args = ['-remote', 'openURL(%s%action)'] 283 remote_action = '' 284 remote_action_newwin = ',new-window' 285 remote_action_newtab = ',new-page' 286 background = True 287 288 289 class Elinks(UnixBrowser): 290 remote_args = ['-remote', 'openURL(%s%action)'] 291 remote_action = '' 292 remote_action_newwin = ',new-window' 293 remote_action_newtab = ',new-tab' 294 background = False 295 redirect_stdout = False 296 297 298 class Konqueror(BaseBrowser): 299 300 def open(self, url, new = 0, autoraise = True): 301 if new == 2: 302 action = 'newTab' 303 else: 304 action = 'openURL' 305 devnull = file(os.devnull, 'r+') 306 setsid = getattr(os, 'setsid', None) 307 if not setsid: 308 setsid = getattr(os, 'setpgrp', None) 309 try: 310 p = subprocess.Popen(['kfmclient', action, url], close_fds=True, stdin=devnull, stdout=devnull, stderr=devnull) 311 except OSError: 312 pass 313 else: 314 p.wait() 315 return True 316 317 try: 318 p = subprocess.Popen(['konqueror', '--silent', url], close_fds=True, stdin=devnull, stdout=devnull, stderr=devnull, preexec_fn=setsid) 319 except OSError: 320 pass 321 else: 322 if p.poll() is None: 323 return True 324 325 try: 326 p = subprocess.Popen(['kfm', '-d', url], close_fds=True, stdin=devnull, stdout=devnull, stderr=devnull, preexec_fn=setsid) 327 except OSError: 328 return False 329 330 return p.poll() is None 331 332 333 class Grail(BaseBrowser): 334 335 def _find_grail_rc(self): 336 import glob 337 import pwd 338 import socket 339 import tempfile 340 tempdir = os.path.join(tempfile.gettempdir(), '.grail-unix') 341 user = pwd.getpwuid(os.getuid())[0] 342 filename = os.path.join(tempdir, user + '-*') 343 maybes = glob.glob(filename) 344 if not maybes: 345 return 346 s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) 347 for fn in maybes: 348 try: 349 s.connect(fn) 350 except socket.error: 351 try: 352 os.unlink(fn) 353 except IOError: 354 pass 355 356 else: 357 return s 358 359 def _remote(self, action): 360 s = self._find_grail_rc() 361 if not s: 362 return 0 363 s.send(action) 364 s.close() 365 return 1 366 367 def open(self, url, new = 0, autoraise = True): 368 if new: 369 ok = self._remote('LOADNEW ' + url) 370 else: 371 ok = self._remote('LOAD ' + url) 372 return ok 373 374 375 def register_X_browsers(): 376 if _iscommand('xdg-open'): 377 register('xdg-open', None, BackgroundBrowser('xdg-open')) 378 if 'GNOME_DESKTOP_SESSION_ID' in os.environ and _iscommand('gvfs-open'): 379 register('gvfs-open', None, BackgroundBrowser('gvfs-open')) 380 if 'GNOME_DESKTOP_SESSION_ID' in os.environ and _iscommand('gnome-open'): 381 register('gnome-open', None, BackgroundBrowser('gnome-open')) 382 if 'KDE_FULL_SESSION' in os.environ and _iscommand('kfmclient'): 383 register('kfmclient', Konqueror, Konqueror('kfmclient')) 384 if _iscommand('x-www-browser'): 385 register('x-www-browser', None, BackgroundBrowser('x-www-browser')) 386 for browser in ('mozilla-firefox', 'firefox', 'mozilla-firebird', 'firebird', 'iceweasel', 'iceape', 'seamonkey', 'mozilla', 'netscape'): 387 if _iscommand(browser): 388 register(browser, None, Mozilla(browser)) 389 390 if _iscommand('kfm'): 391 register('kfm', Konqueror, Konqueror('kfm')) 392 elif _iscommand('konqueror'): 393 register('konqueror', Konqueror, Konqueror('konqueror')) 394 for browser in ('galeon', 'epiphany'): 395 if _iscommand(browser): 396 register(browser, None, Galeon(browser)) 397 398 if _iscommand('skipstone'): 399 register('skipstone', None, BackgroundBrowser('skipstone')) 400 for browser in ('google-chrome', 'chrome', 'chromium', 'chromium-browser'): 401 if _iscommand(browser): 402 register(browser, None, Chrome(browser)) 403 404 if _iscommand('opera'): 405 register('opera', None, Opera('opera')) 406 if _iscommand('mosaic'): 407 register('mosaic', None, BackgroundBrowser('mosaic')) 408 if _iscommand('grail'): 409 register('grail', Grail, None) 410 411 412 if os.environ.get('DISPLAY'): 413 register_X_browsers() 414 if os.environ.get('TERM'): 415 if _iscommand('www-browser'): 416 register('www-browser', None, GenericBrowser('www-browser')) 417 if _iscommand('links'): 418 register('links', None, GenericBrowser('links')) 419 if _iscommand('elinks'): 420 register('elinks', None, Elinks('elinks')) 421 if _iscommand('lynx'): 422 register('lynx', None, GenericBrowser('lynx')) 423 if _iscommand('w3m'): 424 register('w3m', None, GenericBrowser('w3m')) 425 if sys.platform[:3] == 'win': 426 427 class WindowsDefault(BaseBrowser): 428 429 def open(self, url, new = 0, autoraise = True): 430 try: 431 os.startfile(url) 432 except WindowsError: 433 return False 434 435 return True 436 437 438 _tryorder = [] 439 _browsers = {} 440 register('windows-default', WindowsDefault) 441 iexplore = os.path.join(os.environ.get('PROGRAMFILES', 'C:\\Program Files'), 'Internet Explorer\\IEXPLORE.EXE') 442 for browser in ('firefox', 443 'firebird', 444 'seamonkey', 445 'mozilla', 446 'netscape', 447 'opera', 448 iexplore): 449 if _iscommand(browser): 450 register(browser, None, BackgroundBrowser(browser)) 451 452 if sys.platform == 'darwin': 453 454 class MacOSX(BaseBrowser): 455 456 def __init__(self, name): 457 self.name = name 458 459 def open(self, url, new = 0, autoraise = True): 460 if ':' not in url: 461 url = 'file:' + url 462 new = int(bool(new)) 463 if self.name == 'default': 464 script = 'open location "%s"' % url.replace('"', '%22') 465 else: 466 if self.name == 'OmniWeb': 467 toWindow = '' 468 else: 469 toWindow = 'toWindow %d' % (new - 1) 470 cmd = 'OpenURL "%s"' % url.replace('"', '%22') 471 script = 'tell application "%s"\n activate\n %s %s\n end tell' % (self.name, cmd, toWindow) 472 osapipe = os.popen('osascript', 'w') 473 if osapipe is None: 474 return False 475 osapipe.write(script) 476 rc = osapipe.close() 477 return not rc 478 479 480 class MacOSXOSAScript(BaseBrowser): 481 482 def __init__(self, name): 483 self._name = name 484 485 def open(self, url, new = 0, autoraise = True): 486 if self._name == 'default': 487 script = 'open location "%s"' % url.replace('"', '%22') 488 else: 489 script = '\n tell application "%s"\n activate\n open location "%s"\n end\n ' % (self._name, url.replace('"', '%22')) 490 osapipe = os.popen('osascript', 'w') 491 if osapipe is None: 492 return False 493 osapipe.write(script) 494 rc = osapipe.close() 495 return not rc 496 497 498 register('safari', None, MacOSXOSAScript('safari'), -1) 499 register('firefox', None, MacOSXOSAScript('firefox'), -1) 500 register('MacOSX', None, MacOSXOSAScript('default'), -1) 501 if sys.platform[:3] == 'os2' and _iscommand('netscape'): 502 _tryorder = [] 503 _browsers = {} 504 register('os2netscape', None, GenericBrowser(['start', 'netscape', '%s']), -1) 505 if 'BROWSER' in os.environ: 506 _userchoices = os.environ['BROWSER'].split(os.pathsep) 507 _userchoices.reverse() 508 for cmdline in _userchoices: 509 if cmdline != '': 510 cmd = _synthesize(cmdline, -1) 511 if cmd[1] is None: 512 register(cmdline, None, GenericBrowser(cmdline), -1) 513 514 cmdline = None 515 del cmdline 516 del _userchoices 517 518 def main(): 519 import getopt 520 usage = 'Usage: %s [-n | -t] url\n -n: open new window\n -t: open new tab' % sys.argv[0] 521 try: 522 opts, args = getopt.getopt(sys.argv[1:], 'ntd') 523 except getopt.error as msg: 524 print >> sys.stderr, msg 525 print >> sys.stderr, usage 526 sys.exit(1) 527 528 new_win = 0 529 for o, a in opts: 530 if o == '-n': 531 new_win = 1 532 elif o == '-t': 533 new_win = 2 534 535 if len(args) != 1: 536 print >> sys.stderr, usage 537 sys.exit(1) 538 url = args[0] 539 open(url, new_win) 540 print '\x07' 541 542 543 if __name__ == '__main__': 544 main()