mirror of
https://github.com/python/cpython.git
synced 2024-12-04 15:25:13 +08:00
f58a7aafea
subset of Win32 ShellExecute's functionality. Guido wants this because IDLE's Help -> Docs function currently crashes his machine because of a conflict between his version of Norton AntiVirus (6.10.20) and MS's _popen. Docs for startfile are being mailed to Fred (or just read the docstring -- it tells the whole story). Changed webbrowser.py to use os.startfile instead of os.popen on Windows. Changed IDLE's EditorWindow.py to pass an absolute path for the docs (hardcoding ShellExecute's "directory" arg to "." as used to be done let IDLE work, but made the startfile command exceedingly obscure for other uses -- the MS docs are terrible, of course, & still not sure I understand it). Note that Windows Python must link with shell32.lib now! That's where ShellExecute lives.
228 lines
5.5 KiB
Python
228 lines
5.5 KiB
Python
"""Remote-control interfaces to some browsers."""
|
|
|
|
import os
|
|
import sys
|
|
|
|
|
|
PROCESS_CREATION_DELAY = 4
|
|
|
|
|
|
class Error(Exception):
|
|
pass
|
|
|
|
|
|
_browsers = {}
|
|
|
|
def register(name, klass, instance=None):
|
|
"""Register a browser connector and, optionally, connection."""
|
|
_browsers[name.lower()] = [klass, instance]
|
|
|
|
|
|
def get(name=None):
|
|
"""Retrieve a connection to a browser by type name, or the default
|
|
browser."""
|
|
name = name or DEFAULT_BROWSER
|
|
try:
|
|
L = _browsers[name.lower()]
|
|
except KeyError:
|
|
raise ValueError, "unknown browser type: " + `name`
|
|
if L[1] is None:
|
|
L[1] = L[0]()
|
|
return L[1]
|
|
|
|
|
|
# Please note: the following definition hides a builtin function.
|
|
|
|
def open(url, new=0):
|
|
get().open(url, new)
|
|
|
|
|
|
def open_new(url):
|
|
get().open_new(url)
|
|
|
|
|
|
def _iscommand(cmd):
|
|
"""Return true if cmd can be found on the executable search path."""
|
|
path = os.environ.get("PATH")
|
|
if not path:
|
|
return 0
|
|
for d in path.split(os.pathsep):
|
|
exe = os.path.join(d, cmd)
|
|
if os.path.isfile(exe):
|
|
return 1
|
|
return 0
|
|
|
|
|
|
class CommandLineBrowser:
|
|
_browsers = []
|
|
if os.environ.get("DISPLAY"):
|
|
_browsers.extend([
|
|
("netscape", "netscape %s >/dev/null &"),
|
|
("mosaic", "mosaic %s >/dev/null &"),
|
|
])
|
|
_browsers.extend([
|
|
("lynx", "lynx %s"),
|
|
("w3m", "w3m %s"),
|
|
])
|
|
|
|
def open(self, url, new=0):
|
|
for exe, cmd in self._browsers:
|
|
if _iscommand(exe):
|
|
os.system(cmd % url)
|
|
return
|
|
raise Error("could not locate runnable browser")
|
|
|
|
def open_new(self, url):
|
|
self.open(url)
|
|
|
|
register("command-line", CommandLineBrowser)
|
|
|
|
|
|
class Netscape:
|
|
autoRaise = 1
|
|
|
|
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 Konquerer:
|
|
"""Controller for the KDE File Manager (kfm, or Konquerer).
|
|
|
|
See http://developer.kde.org/documentation/other/kfmclient.html
|
|
for more information on the Konquerer remote-control interface.
|
|
|
|
"""
|
|
def _remote(self, action):
|
|
cmd = "kfmclient %s >/dev/null 2>&1" % action
|
|
rc = os.system(cmd)
|
|
if rc:
|
|
import time
|
|
os.system("kfm -d &")
|
|
time.sleep(PROCESS_CREATION_DELAY)
|
|
rc = os.system(cmd)
|
|
return not rc
|
|
|
|
def open(self, url, new=1):
|
|
# XXX currently I know no way to prevent KFM from opening a new win.
|
|
self.open_new(url)
|
|
|
|
def open_new(self, url):
|
|
self._remote("openURL %s" % url)
|
|
|
|
register("kfm", Konquerer)
|
|
|
|
|
|
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):
|
|
os.startfile(url)
|
|
|
|
def open_new(self, url):
|
|
self.open(url)
|
|
|
|
|
|
DEFAULT_BROWSER = "command-line"
|
|
|
|
if sys.platform[:3] == "win":
|
|
del _browsers["kfm"]
|
|
register("windows-default", WindowsDefault)
|
|
DEFAULT_BROWSER = "windows-default"
|
|
elif os.environ.get("DISPLAY"):
|
|
if os.environ.get("KDEDIR"):
|
|
DEFAULT_BROWSER = "kfm"
|
|
elif _iscommand("netscape"):
|
|
DEFAULT_BROWSER = "netscape"
|
|
|
|
# If the $BROWSER environment variable is set and true, let that be
|
|
# the name of the browser to use:
|
|
#
|
|
DEFAULT_BROWSER = os.environ.get("BROWSER") or DEFAULT_BROWSER
|
|
|
|
|
|
# Now try to support the MacOS world. This is the only supported
|
|
# controller on that platform, so don't mess with the default!
|
|
|
|
try:
|
|
import ic
|
|
except ImportError:
|
|
pass
|
|
else:
|
|
class InternetConfig:
|
|
def open(self, url, new=0):
|
|
ic.launcurl(url)
|
|
|
|
def open_new(self, url):
|
|
self.open(url)
|
|
|
|
_browsers.clear()
|
|
register("internet-config", InternetConfig)
|
|
DEFAULT_BROWSER = "internet-config"
|