1#!/usr/bin/env python 2# Copyright 2009 Google Inc. All Rights Reserved. 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16"""Wrapper for webbrowser library, to invoke the http handler on win32.""" 17 18__author__ = 'tstromberg@google.com (Thomas Stromberg)' 19 20import os.path 21import subprocess 22import sys 23import traceback 24import webbrowser 25 26import util 27 28 29def output(string): 30 print string 31 32 33def create_win32_http_cmd(url): 34 """Create a command-line tuple to launch a web browser for a given URL. 35 36 Args: 37 url: string 38 39 Returns: 40 tuple of: (executable, arg1, arg2, ...) 41 42 At the moment, this ignores all default arguments to the browser. 43 TODO(tstromberg): Properly parse the command-line arguments. 44 """ 45 browser_type = None 46 try: 47 key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, 48 'Software\Classes\http\shell\open\command') 49 browser_type = 'user' 50 except WindowsError: 51 key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, 52 'Software\Classes\http\shell\open\command') 53 browser_type = 'machine' 54 except: 55 return False 56 57 cmd = _winreg.EnumValue(key, 0)[1] 58 # "C:\blah blah\iexplore.exe" -nohome 59 # "C:\blah blah\firefox.exe" -requestPending -osint -url "%1" 60 if '"' in cmd: 61 executable = cmd.split('"')[1] 62 else: 63 executable = cmd.split(' ')[0] 64 65 if not os.path.exists(executable): 66 output('$ Default HTTP browser does not exist: %s' % executable) 67 return False 68 else: 69 output('$ %s HTTP handler: %s' % (browser_type, executable)) 70 return (executable, url) 71 72 73def open(url): 74 """Opens a URL, overriding the normal webbrowser.open methods for sanity.""" 75 76 try: 77 webbrowser.open(url, new=1, autoraise=True) 78 # If the user is missing the osascript binary - see 79 # http://code.google.com/p/namebench/issues/detail?id=88 80 except: 81 output('Failed to open: [%s]: %s' % (url, util.GetLastExceptionString())) 82 if os.path.exists('/usr/bin/open'): 83 try: 84 output('trying open: %s' % url) 85 p = subprocess.Popen(('open', url)) 86 p.wait() 87 except: 88 output('open did not seem to work: %s' % util.GetLastExceptionString()) 89 elif sys.platform[:3] == 'win': 90 try: 91 output('trying default Windows controller: %s' % url) 92 controller = webbrowser.get('windows-default') 93 controller.open_new(url) 94 except: 95 output('WindowsController did not work: %s' % util.GetLastExceptionString()) 96 97 98# *NOTE*: EVIL IMPORT SIDE EFFECTS AHEAD! 99# 100# If we are running on Windows, register the WindowsHttpDefault class. 101if sys.platform[:3] == 'win': 102 import _winreg 103 104 # We don't want to load this class by default, because Python 2.4 doesn't have BaseBrowser. 105 106 class WindowsHttpDefault(webbrowser.BaseBrowser): 107 """Provide an alternate open class for Windows user, using the http handler.""" 108 109 def open(self, url, new=0, autoraise=1): 110 command_args = create_win32_http_cmd(url) 111 if not command_args: 112 output('$ Could not find HTTP handler') 113 return False 114 115 output('command_args:') 116 output(command_args) 117 # Avoid some unicode path issues by moving our current directory 118 old_pwd = os.getcwd() 119 os.chdir('C:\\') 120 try: 121 _unused = subprocess.Popen(command_args) 122 os.chdir(old_pwd) 123 return True 124 except: 125 traceback.print_exc() 126 output('$ Failed to run HTTP handler, trying next browser.') 127 os.chdir(old_pwd) 128 return False 129 130 webbrowser.register('windows-http', WindowsHttpDefault, update_tryorder=-1) 131