#!/usr/bin/env python # Copyright 2009 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Wrapper for webbrowser library, to invoke the http handler on win32.""" __author__ = 'tstromberg@google.com (Thomas Stromberg)' import os.path import subprocess import sys import traceback import webbrowser import util def output(string): print string def create_win32_http_cmd(url): """Create a command-line tuple to launch a web browser for a given URL. Args: url: string Returns: tuple of: (executable, arg1, arg2, ...) At the moment, this ignores all default arguments to the browser. TODO(tstromberg): Properly parse the command-line arguments. """ browser_type = None try: key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, 'Software\Classes\http\shell\open\command') browser_type = 'user' except WindowsError: key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, 'Software\Classes\http\shell\open\command') browser_type = 'machine' except: return False cmd = _winreg.EnumValue(key, 0)[1] # "C:\blah blah\iexplore.exe" -nohome # "C:\blah blah\firefox.exe" -requestPending -osint -url "%1" if '"' in cmd: executable = cmd.split('"')[1] else: executable = cmd.split(' ')[0] if not os.path.exists(executable): output('$ Default HTTP browser does not exist: %s' % executable) return False else: output('$ %s HTTP handler: %s' % (browser_type, executable)) return (executable, url) def open(url): """Opens a URL, overriding the normal webbrowser.open methods for sanity.""" try: webbrowser.open(url, new=1, autoraise=True) # If the user is missing the osascript binary - see # http://code.google.com/p/namebench/issues/detail?id=88 except: output('Failed to open: [%s]: %s' % (url, util.GetLastExceptionString())) if os.path.exists('/usr/bin/open'): try: output('trying open: %s' % url) p = subprocess.Popen(('open', url)) p.wait() except: output('open did not seem to work: %s' % util.GetLastExceptionString()) elif sys.platform[:3] == 'win': try: output('trying default Windows controller: %s' % url) controller = webbrowser.get('windows-default') controller.open_new(url) except: output('WindowsController did not work: %s' % util.GetLastExceptionString()) # *NOTE*: EVIL IMPORT SIDE EFFECTS AHEAD! # # If we are running on Windows, register the WindowsHttpDefault class. if sys.platform[:3] == 'win': import _winreg # We don't want to load this class by default, because Python 2.4 doesn't have BaseBrowser. class WindowsHttpDefault(webbrowser.BaseBrowser): """Provide an alternate open class for Windows user, using the http handler.""" def open(self, url, new=0, autoraise=1): command_args = create_win32_http_cmd(url) if not command_args: output('$ Could not find HTTP handler') return False output('command_args:') output(command_args) # Avoid some unicode path issues by moving our current directory old_pwd = os.getcwd() os.chdir('C:\\') try: _unused = subprocess.Popen(command_args) os.chdir(old_pwd) return True except: traceback.print_exc() output('$ Failed to run HTTP handler, trying next browser.') os.chdir(old_pwd) return False webbrowser.register('windows-http', WindowsHttpDefault, update_tryorder=-1)