NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

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()