Getting rid of support for MacOS9 and earlier. This is the first step,

and the biggest in size, but probably the easiest. Hunting through the
source code comes next.
This commit is contained in:
Jack Jansen 2003-11-19 14:34:18 +00:00
parent 6045b9c935
commit 28ecf70db5
181 changed files with 0 additions and 22664 deletions

View file

@ -1,76 +0,0 @@
"""BuildCGIApplet.py -- Create a CGI applet from a Python script.
Specilized version of BuildApplet, enabling Python CGI scripts to be
used under Mac web servers like WebStar. The __main__ program is
PythonCGISlave.py, which provides a compatibility layer, emulating
Unix-style CGI scripts. See CGI_README.txt for details.
"""
import sys
import os
import macfs
import MacOS
from Carbon import Res
import EasyDialogs
import buildtools
import py_resource
def main():
try:
buildcgiapplet()
except buildtools.BuildError, detail:
EasyDialogs.Message(detail)
def buildcgiapplet():
buildtools.DEBUG=1
# Find the template
# (there's no point in proceeding if we can't find it)
template = buildtools.findtemplate()
wrapper = "PythonCGISlave.py"
if not os.path.exists("PythonCGISlave.py"):
wrapper = os.path.join(sys.exec_prefix, ":Mac:Tools:CGI", wrapper)
# Ask for source text if not specified in sys.argv[1:]
if not sys.argv[1:]:
srcfss, ok = macfs.PromptGetFile('Select a CGI script:', 'TEXT', 'APPL')
if not ok:
return
filename = srcfss.as_pathname()
dstfilename = mkcgifilename(filename)
dstfss, ok = macfs.StandardPutFile('Save application as:',
os.path.basename(dstfilename))
if not ok:
return
dstfilename = dstfss.as_pathname()
buildone(template, wrapper, filename, dstfilename)
else:
# Loop over all files to be processed
for filename in sys.argv[1:]:
dstfilename = mkcgifilename(filename)
buildone(template, wrapper, filename, dstfilename)
def mkcgifilename(filename):
if filename[-3:] == '.py':
filename = filename[:-3]
filename = filename + ".cgi"
return filename
def buildone(template, wrapper, src, dst):
buildtools.process(template, wrapper, dst, 1)
# write source as a PYC resource into dst
ref = Res.FSpOpenResFile(dst, 2)
try:
Res.UseResFile(ref)
py_resource.frompyfile(src, "CGI_MAIN", preload=1)
finally:
Res.CloseResFile(ref)
if __name__ == '__main__':
main()

Binary file not shown.

View file

@ -1,66 +0,0 @@
Python CGI under MacOS
This folder contains two tools that enable Python CGI scripts under
Mac based web servers, like WebStar, Quid Quo Pro, NetPresentz or
Apple's Personal Webserver.
Both tools emulate Unix style CGI's, allowing for cross platform
CGI scripts. In short, this happens by converting an AppleEvent sent
by the web server into os.environ dictionary entries. See below for more
details.
Both tools serve slightly different purposes:
- PythonCGISlave enables execution of Python scripts as plain *.py
text files. The web server must be configured to handle .py requests
over to PythonCGISlave. Not all web servers support that. Eg. WebStar
does, but NetPresentz does not.
- BuildCGIApplet wraps a Python CGI script in a compatibility layer, and
creates a CGI Applet which can be executed by any web server.
The pros and cons of using PythonCGISlave are (+ is good, - is bad):
+ support plain .py files, no need to wrap each script
- not supported b all servers, requires more complicated configuration
The pros and cons of using BuildCGIApplet are:
+ supported by more servers
+ less configuration troubles
- must wrap each script
Using BuildCGIApplet
Drop your CGI script onto BuildCGIApplet. An applet called <script name>.cgi
will be created. Move it to the appropriate location in the HTTP document tree.
Make sure your web server is configured to handle .cgi applet files. Usually
it is configured correctly by default, since .cgi is a standard extension.
If your CGI applet starts up for the first time, a file <applet name>.errors
is created. If your CGI script causes an exception, debug info will be written
to that file.
Using PythonCGISlave
Place the PythonCGISlave applet somewhere in the HTTP document tree. Configure
your web server so it'll pass requests for .py files to PythonCGISlave. For
Webstar, this goes roughly like this:
- in the WebStar Admin app, create a new "action", call it PYTHON, click the
"Choose" button and select our applet. Save the settings.
- go to Suffix Mappings, create a new suffix .PY, type TEXT, creator *, and
choose PYTHON in the actions popup. Save the settings.
How it works
For each Python CGI request, the web server will send an AppleEvent to the
CGI applet. Most relevant CGI parameters are taken from the AppleEvent and
get stuffed into the os.environ dictionary. Then the script gets executed.
This emulates Unix-style CGI as much as possible, so CGI scripts that are
written portably should now also work under a Mac web server.
Since the applet does not quit after each request by default, there is hardly
any startup overhead except the first time it starts up. If an exception occurs
in the CGI script, the applet will write a traceback to a file called
<applet name>.errors, and then quit. The latter seems a good idea, just in case
we leak memory. The applet will be restarted upon the next request.
Please direct feedback to <just@letterror.com> and/or <pythonmac-sig@python.org>.

View file

@ -1,244 +0,0 @@
"""PythonCGISlave.py
This program can be used in two ways:
- As a Python CGI script server for web servers supporting "Actions", like WebStar.
- As a wrapper for a single Python CGI script, for any "compliant" Mac web server.
See CGI_README.txt for more details.
"""
#
# Written by Just van Rossum, but partly stolen from example code by Jack.
#
LONG_RUNNING = 1 # If true, don't quit after each request.
import MacOS
MacOS.SchedParams(0, 0)
from MiniAEFrame import AEServer, MiniApplication
import os
import string
import cStringIO
import sys
import traceback
import mimetools
__version__ = '3.2'
slave_dir = os.getcwd()
# log file for errors
sys.stderr = open(sys.argv[0] + ".errors", "a+")
def convertFSSpec(fss):
return fss.as_pathname()
# AE -> os.environ mappings
ae2environ = {
'kfor': 'QUERY_STRING',
'Kcip': 'REMOTE_ADDR',
'svnm': 'SERVER_NAME',
'svpt': 'SERVER_PORT',
'addr': 'REMOTE_HOST',
'scnm': 'SCRIPT_NAME',
'meth': 'REQUEST_METHOD',
'ctyp': 'CONTENT_TYPE',
}
ERROR_MESSAGE = """\
Content-type: text/html
<html>
<head>
<title>Error response</title>
</head>
<body>
<h1>Error response</h1>
<p>Error code %d.
<p>Message: %s.
</body>
</html>
"""
def get_cgi_code():
# If we're a CGI wrapper, the CGI code resides in a PYC resource.
from Carbon import Res
import marshal
try:
code = Res.GetNamedResource('PYC ', "CGI_MAIN")
except Res.Error:
return None
else:
return marshal.loads(code.data[8:])
class PythonCGISlave(AEServer, MiniApplication):
def __init__(self):
self.crumblezone = 100000 * "\0"
MiniApplication.__init__(self)
AEServer.__init__(self)
self.installaehandler('aevt', 'oapp', self.open_app)
self.installaehandler('aevt', 'quit', self.quit)
self.installaehandler('WWW\275', 'sdoc', self.cgihandler)
self.code = get_cgi_code()
self.long_running = LONG_RUNNING
if self.code is None:
print "%s version %s, ready to serve." % (self.__class__.__name__, __version__)
else:
print "%s, ready to serve." % os.path.basename(sys.argv[0])
try:
self.mainloop()
except:
self.crumblezone = None
sys.stderr.write("- " * 30 + '\n')
self.message("Unexpected exception")
self.dump_environ()
sys.stderr.write("%s: %s\n" % sys.exc_info()[:2])
def getabouttext(self):
if self.code is None:
return "PythonCGISlave %s, written by Just van Rossum." % __version__
else:
return "Python CGI script, wrapped by BuildCGIApplet and " \
"PythonCGISlave, version %s." % __version__
def getaboutmenutext(self):
return "About %s\311" % os.path.basename(sys.argv[0])
def message(self, msg):
import time
sys.stderr.write("%s (%s)\n" % (msg, time.asctime(time.localtime(time.time()))))
def dump_environ(self):
sys.stderr.write("os.environ = {\n")
keys = os.environ.keys()
keys.sort()
for key in keys:
sys.stderr.write(" %s: %s,\n" % (repr(key), repr(os.environ[key])))
sys.stderr.write("}\n")
def quit(self, **args):
self.quitting = 1
def open_app(self, **args):
pass
def cgihandler(self, pathargs, **args):
# We emulate the unix way of doing CGI: fill os.environ with stuff.
environ = os.environ
# First, find the document root. If we don't get a DIRE parameter,
# we take the directory of this program, which may be wrong if
# it doesn't live the actual http document root folder.
if args.has_key('DIRE'):
http_root = args['DIRE'].as_pathname()
del args['DIRE']
else:
http_root = slave_dir
environ['DOCUMENT_ROOT'] = http_root
if self.code is None:
# create a Mac pathname to the Python CGI script or applet
script = string.replace(args['scnm'], '/', ':')
script_path = os.path.join(http_root, script)
else:
script_path = sys.argv[0]
if not os.path.exists(script_path):
rv = "HTTP/1.0 404 Not found\n"
rv = rv + ERROR_MESSAGE % (404, "Not found")
return rv
# Kfrq is the complete http request.
infile = cStringIO.StringIO(args['Kfrq'])
firstline = infile.readline()
msg = mimetools.Message(infile, 0)
uri, protocol = string.split(firstline)[1:3]
environ['REQUEST_URI'] = uri
environ['SERVER_PROTOCOL'] = protocol
# Make all http headers available as HTTP_* fields.
for key in msg.keys():
environ['HTTP_' + string.upper(string.replace(key, "-", "_"))] = msg[key]
# Translate the AE parameters we know of to the appropriate os.environ
# entries. Make the ones we don't know available as AE_* fields.
items = args.items()
items.sort()
for key, value in items:
if key[0] == "_":
continue
if ae2environ.has_key(key):
envkey = ae2environ[key]
environ[envkey] = value
else:
environ['AE_' + string.upper(key)] = str(value)
# Redirect stdout and stdin.
saveout = sys.stdout
savein = sys.stdin
out = sys.stdout = cStringIO.StringIO()
postdata = args.get('post', "")
if postdata:
environ['CONTENT_LENGTH'] = str(len(postdata))
sys.stdin = cStringIO.StringIO(postdata)
# Set up the Python environment
script_dir = os.path.dirname(script_path)
os.chdir(script_dir)
sys.path.insert(0, script_dir)
sys.argv[:] = [script_path]
namespace = {"__name__": "__main__"}
rv = "HTTP/1.0 200 OK\n"
try:
if self.code is None:
# we're a Python script server
execfile(script_path, namespace)
else:
# we're a CGI wrapper, self.code is the CGI code
exec self.code in namespace
except SystemExit:
# We're not exiting dammit! ;-)
pass
except:
self.crumblezone = None
sys.stderr.write("- " * 30 + '\n')
self.message("CGI exception")
self.dump_environ()
traceback.print_exc()
sys.stderr.flush()
self.quitting = 1
# XXX we should return an error AE, but I don't know how to :-(
rv = "HTTP/1.0 500 Internal error\n"
# clean up
namespace.clear()
environ.clear()
sys.path.remove(script_dir)
sys.stdout = saveout
sys.stdin = savein
if not self.long_running:
# quit after each request
self.quitting = 1
return rv + out.getvalue()
PythonCGISlave()

Binary file not shown.

View file

@ -1,53 +0,0 @@
<HTML>
<HEAD>
<META NAME="GENERATOR" CONTENT="Adobe PageMill 3.0 Mac">
<TITLE>Creating CGI scripts with MacPython</TITLE>
</HEAD>
<BODY>
<H3>Creating CGI scripts with MacPython</H3>
<BLOCKQUOTE>
Note: this document is work-in-progress, and not tested.
</BLOCKQUOTE>
<P>MacPython allows you to use Python as a CGI scripting language
for your webserver. Moreover, there are some helper applications
that allow you to write your CGI scripts in the same way as for
Unix and Windows, i.e. obtaining their arguments from <TT>os.environ</TT>
and sending their results to <TT>stdout</TT>. MacPython also has
all the facilities to program CGI scripts in the Macintosh way,
through AppleEvents, but that falls outside the scope of this
document (reading the source code for the helper scripts will
give you an idea about how to do this).</P>
<P>For the purpose of this document we will assume you are using
Apple's Personal Webserver 1.5, which comes standard with your
machine as of MacOS 9.</P>
<P>The first step is to start the webserver, you will find it
in your control panels. Give it a folder to serve documents from,
and check that it is working by pointing your browser at it.</P>
<P>The next step is to tell the webserver that documents with
a &quot;.<TT>py</TT>&quot; extension should be served through
the <TT>PythonCGISlave</TT> helper application. Open the webserver,
choose Preferences, tab Action, Add, Start on Extension, extension
&quot;.py&quot;, select application <TT>PythonCGISlave</TT> (which
lives in <TT>Python:Mac:Tools:CGI</TT>).</P>
<P>The last step is to try it. Put the following script in <TT>Macintosh
HD:Webpages:hello.py </TT>(assuming your webserver has the default
settings for its document folder):</P>
<BLOCKQUOTE>
<P><CODE>print &quot;Content-type: text/plain&quot;<BR>
print<BR>
print &quot;Hello world!&quot;<BR>
import time<BR>
print &quot;Local time is&quot;, time.ctime(time.time())</CODE></P></BLOCKQUOTE>
<P>Point your webbrowser at <A HREF="http://localhost/hello.py">http://localhost/hello.py</A><CODE>
</CODE>and check whether it works.
</BODY>
</HTML>