158 lines
3.8 KiB
Python
158 lines
3.8 KiB
Python
|
"""Remote-control interfaces to some browsers."""
|
||
|
|
||
|
import os
|
||
|
import string
|
||
|
import sys
|
||
|
|
||
|
|
||
|
DEFAULT_CONFIG_FILE = "~/.browser.ini"
|
||
|
PROCESS_CREATION_DELAY = 4
|
||
|
|
||
|
DEFAULT_BROWSER = "netscape"
|
||
|
|
||
|
_browsers = {}
|
||
|
|
||
|
|
||
|
def get(name=None):
|
||
|
if name is None:
|
||
|
name = get_default_browser()
|
||
|
else:
|
||
|
name = string.lower(name)
|
||
|
L = _browsers[name]
|
||
|
if L[1] is None:
|
||
|
L[1] = L[0]()
|
||
|
return L[1]
|
||
|
|
||
|
|
||
|
def get_default_browser(file=None):
|
||
|
if file is None:
|
||
|
files = [DEFAULT_CONFIG_FILE]
|
||
|
else:
|
||
|
files = [file, DEFAULT_CONFIG_FILE]
|
||
|
for file in files:
|
||
|
file = os.path.expandvars(os.path.expanduser(file))
|
||
|
if file and os.path.isfile(file):
|
||
|
import ConfigParser
|
||
|
cf = ConfigParser.ConfigParser()
|
||
|
cf.read([file])
|
||
|
try:
|
||
|
return string.lower(cf.get("Browser", "name"))
|
||
|
except ConfigParser.Error:
|
||
|
pass
|
||
|
return DEFAULT_BROWSER
|
||
|
|
||
|
|
||
|
_default_browser = None
|
||
|
|
||
|
def _get_browser():
|
||
|
global _default_browser
|
||
|
if _default_browser is None:
|
||
|
_default_browser = get()
|
||
|
return _default_browser
|
||
|
|
||
|
|
||
|
def open(url, new=0):
|
||
|
_get_browser().open(url, new)
|
||
|
|
||
|
|
||
|
def open_new(url):
|
||
|
_get_browser().open_new(url)
|
||
|
|
||
|
|
||
|
def register(name, klass):
|
||
|
_browsers[string.lower(name)] = [klass, None]
|
||
|
|
||
|
|
||
|
class Netscape:
|
||
|
autoRaise = 0
|
||
|
|
||
|
def _remote(self, action):
|
||
|
raise_opt = ("-noraise", "-raise")[self.autoRaise]
|
||
|
cmd = "netscape %s -remote '%s' >/dev/null 2>&1" % (raise_opt, action)
|
||
|
rc = os.system(cmd)
|
||
|
if rc:
|
||
|
import time
|
||
|
os.system("netscape -no-about-splash &")
|
||
|
time.sleep(PROCESS_CREATION_DELAY)
|
||
|
rc = os.system(cmd)
|
||
|
return not rc
|
||
|
|
||
|
def open(self, url, new=0):
|
||
|
if new:
|
||
|
self.open_new(url)
|
||
|
else:
|
||
|
self._remote("openURL(%s)" % url)
|
||
|
|
||
|
def open_new(self, url):
|
||
|
self._remote("openURL(%s, new-window)" % url)
|
||
|
|
||
|
register("netscape", Netscape)
|
||
|
|
||
|
|
||
|
class Grail:
|
||
|
# There should be a way to maintain a connection to Grail, but the
|
||
|
# Grail remote control protocol doesn't really allow that at this
|
||
|
# point. It probably never will!
|
||
|
|
||
|
def _find_grail_rc(self):
|
||
|
import glob
|
||
|
import pwd
|
||
|
import socket
|
||
|
import tempfile
|
||
|
tempdir = os.path.join(tempfile.gettempdir(), ".grail-unix")
|
||
|
user = pwd.getpwuid(_os.getuid())[0]
|
||
|
filename = os.path.join(tempdir, user + "-*")
|
||
|
maybes = glob.glob(filename)
|
||
|
if not maybes:
|
||
|
return None
|
||
|
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||
|
for fn in maybes:
|
||
|
# need to PING each one until we find one that's live
|
||
|
try:
|
||
|
s.connect(fn)
|
||
|
except socket.error:
|
||
|
# no good; attempt to clean it out, but don't fail:
|
||
|
try:
|
||
|
os.unlink(fn)
|
||
|
except IOError:
|
||
|
pass
|
||
|
else:
|
||
|
return s
|
||
|
|
||
|
def _remote(self, action):
|
||
|
s = self._find_grail_rc()
|
||
|
if not s:
|
||
|
return 0
|
||
|
s.send(action)
|
||
|
s.close()
|
||
|
return 1
|
||
|
|
||
|
def open(self, url, new=0):
|
||
|
if new:
|
||
|
self.open_new(url)
|
||
|
else:
|
||
|
self._remote("LOAD " + url)
|
||
|
|
||
|
def open_new(self, url):
|
||
|
self._remote("LOADNEW " + url)
|
||
|
|
||
|
register("grail", Grail)
|
||
|
|
||
|
|
||
|
class WindowsDefault:
|
||
|
def open(self, url, new=0):
|
||
|
import win32api, win32con
|
||
|
try:
|
||
|
win32api.ShellExecute(0, "open", url, None, ".",
|
||
|
win32con.SW_SHOWNORMAL)
|
||
|
except:
|
||
|
traceback.print_exc()
|
||
|
raise
|
||
|
|
||
|
def open_new(self, url):
|
||
|
self.open(url)
|
||
|
|
||
|
if sys.platform[:3] == "win":
|
||
|
register("windows-default", WindowsDefault)
|
||
|
DEFAULT_BROWSER = "windows-default"
|