'
__version__ = "0.1.0"
__date__ = "$Date: 2004/12/11 07:33:43 $"
__revision__ = "$Revision: 1.1 $"
__copyright__ = "Copyright (c) 2004 Steven Armstrong"
__license__ = "GPL 2+"
DEBUG = False
# Python imports
from mod_python import apache, util, Session
import sys
# Pyblosxom imports
from Pyblosxom.pyblosxom import PyBlosxom, Request
from config import py as cfg
class ModPythonRequest(Request):
"""
Subclass of Pyblosxoms Request class.
Provides a "run" method so it can be called directly from within mod_python.
This allowes for a site wide install without reduntant request handler scripts
in each blog's directory.
"""
def __init__(self, req):
"""
Saves mod_pythons request and creates/restores the session for it.
Sets basic variables by calling the _configure method.
@param req: the mod_python request instance
"""
Request.__init__(self)
self._mp_request = req
self.contentTypeSet = False
self._configure()
def getMPRequest(self):
"""
Returns the mod_python request instance.
@returns: mod_python request instance
"""
return self._mp_request
def getSession(self):
"""
Returns the session associated with this request.
@returns: mod_python session instance
"""
if not self._session:
self._session = Session.Session(self.getMPRequest())
return self._session
def _configure(self):
"""
Sets basic variables using the req.subprocess_env dict.
Sets the mod_python request instance as PyBlosxoms stdout.
Sets the request.content_type to a default of 'text/html'.
Sets PyBlosxoms renderer to 'modpython' and tells it to use
mod_python.util.FieldStorage instead of cgi.FieldStorage.
Note: for this to work the pyblosxom.py pyblosxom_handler has
to be hacked so it doesn't reset the FieldStorage handling
back to cgi. Use the patch below to accomplish this.
%<--------------------------------------------------
Index: pyblosxom.py
===================================================================
RCS file: /cvsroot/pyblosxom/pyblosxom/Pyblosxom/pyblosxom.py,v
retrieving revision 1.51
diff -u -r1.51 pyblosxom.py
--- pyblosxom.py 19 Nov 2004 18:11:15 -0000 1.51
+++ pyblosxom.py 26 Nov 2004 12:22:19 -0000
@@ -415,7 +415,10 @@
data['renderer'] = r
- request.addHttp( {"form": cgi.FieldStorage() } )
+ # hack to make pyblosxom play nicely with mod_python
+ if not request.getHttp().has_key("form"):
+ request.addHttp( {"form": cgi.FieldStorage() } )
+
# process the path info to determine what kind of blog entry(ies)
# this is
tools.run_callback("pathinfo",
%<--------------------------------------------------
"""
req = self.getMPRequest()
req.content_type = 'text/html' # default
req.add_common_vars()
d = {}
for k, v in req.subprocess_env.items():
d[k] = v
d['form'] = util.FieldStorage(req)
if not d.has_key('PATH_INFO'):
d['PATH_INFO'] = ""
cfg['stdoutput'] = self
cfg['renderer'] = 'modpython'
cfg['base_url'] = "http://www.c-area.lan/weblog"
self.addConfiguration(cfg)
self.addHttp(d)
def flush(self):
req = self.getMPRequest()
req.flush()
def write(self, data, flush=1):
req = self.getMPRequest()
# fix the mod_python content-type handling
# XXX: this is a really ugly hack
if not self.contentTypeSet:
ct = data[:12]
if ct and ct.lower() == "content-type":
if not "\n" in data:
ctvalue = data[13:]
data = None
else:
i = data.index("\n")
ctvalue = data[13:i]
data = data[i+1:]
if data.startswith("\n"):
data = data[1:]
ctvalue = ctvalue.strip()
req.content_type = ctvalue
self.contentTypeSet = True
# write the data
if data:
req.write(data, flush)
def debug(self):
"""
Adds some debug info to the response stream.
"""
req = self.getMPRequest()
if not req.content_type:
req.content_type = 'text/html'
req.writeln = lambda s: req.write(s +"
\n")
req.writeln("toggle debug")
req.write("")
req.writeln("path_info: "+ req.path_info)
req.writeln("uri: "+ req.uri)
req.writeln("filename: "+ req.filename)
req.writeln("canonical_filename: "+ req.canonical_filename)
req.write("
\n")
for k, v in req.subprocess_env.items():
req.writeln("%s = %s" % (k, v))
req.write("
\n")
req.write("")
def run(self, req):
"""
mod_python calls this with its request object. We ignore it here
cause we allready have it from the __init__ method.
Just create a PyBlosxom instance, run it and return a apache.OK to keep
mod_python happy.
"""
if DEBUG: self.debug()
try:
p = PyBlosxom(self)
p.run()
return apache.OK
except:
import utils
utils.log_exception()
return apache.HTTP_INTERNAL_SERVER_ERROR
def handler(req):
"""
Handler executed when mod_python is configured to use this file as a
script instead of directly calling ModPythonRequest.run.
"""
pyblosxomreq = ModPythonRequest(req)
return pyblosxomreq.run(req)