cgistarter.py
Go to the documentation of this file.
00001 #! /usr/bin/env python
00002 
00003 import os, sys, string, time, string
00004 from pyclearsilver.log import *
00005 
00006 #debugfull()
00007 debugoff()
00008 
00009 import gc
00010 
00011 try:
00012   import warnings
00013   warnings.resetwarnings()
00014   warnings.filterwarnings("ignore")
00015 except ImportError:
00016   pass
00017 
00018 import neo_cgi, neo_cs, neo_util
00019 
00020 from pyclearsilver import CSPage
00021 
00022 import mimetypes
00023 mimetypes.init(["/etc/mime.types"])
00024 
00025 
00026 gConfig = None
00027 def setConfig(config):
00028   global gConfig
00029   gConfig = config
00030 
00031   if not hasattr(gConfig, "gRequireUsername"): gConfig.gRequireUsername = 0
00032   if not hasattr(gConfig, "gDataFilePaths"): gConfig.gDataFilePaths = []
00033 
00034 
00035 def split_path(path):
00036   # strip off leading slash, it's no fun!
00037   return string.split(path, '/')[1:]
00038 
00039 
00040 class Page:
00041   def __init__(self, context):
00042     self.context = context
00043 
00044   def setupvars(self):
00045 
00046     self.path = self.context.environ.get("PATH_INFO", '')
00047 
00048     script_name = self.context.environ.get("SCRIPT_NAME",'')
00049 
00050     ## handle the case where the site is located at '/'
00051     if not self.path:  
00052       self.path = script_name
00053       script_name = '/'
00054 
00055 
00056   def start(self):
00057     self.setupvars()
00058 
00059     self._path = self.path
00060 
00061     rpath = self._path
00062     if not rpath: rpath = '/'
00063 
00064     if rpath == "/": rpath = gConfig.gDefaultPage
00065 
00066     self.path = split_path(rpath)
00067 
00068     username = None
00069 
00070     if len(self.path) == 0:
00071       warn("no such path", self.path)
00072       self.error(404)
00073       return 404
00074 
00075     ## the url form should be:
00076     ##    /baseuri/username/module/script.py
00077 
00078     cwd = os.getcwd()
00079     debug("CWD", cwd)
00080 
00081     module = gConfig.gDefaultModule
00082 
00083     if hasattr(gConfig, "gDataFilePaths"):
00084       if self.path[0] in gConfig.gDataFilePaths:
00085         fn = apply(os.path.join, [cwd,] + self.path)
00086         return outputFile(self.context, fn)
00087 
00088     if gConfig.gRequireUsername:
00089       username = self.path[0]
00090       n = 1
00091     else:
00092       n = 0
00093 
00094     debug("self.path", self.path)
00095 
00096     if len(self.path) > 1:
00097       module = self.path[n]
00098       n = n + 1
00099 
00100     moduleRootPath = apply(os.path.join, ["mod", module])
00101     handlerRoot = apply(os.path.join, ["mod", module, "cgibin"])
00102     moduleTemplatePath = apply(os.path.join, [cwd, "mod", module, "templates"])
00103     systemTemplatePath = apply(os.path.join, [cwd, "templates"])
00104     systemJLIBPath = apply(os.path.join, [cwd, "jslib"])
00105 
00106     fn = apply(os.path.join, [cwd, moduleRootPath,] + self.path[n:])
00107     debug("fn", fn)
00108 
00109     ## if requesting a file, then just output it to the browser.
00110     if os.path.isfile(fn):
00111       return outputFile(self.context, fn)
00112 
00113     ## manage the Python module Path
00114     sys.path.insert(0, os.path.abspath(cwd))
00115     sys.path.insert(0, os.path.abspath(moduleRootPath))
00116 
00117     debug("sys.path", sys.path)
00118 
00119     handlerPath = ''
00120 
00121     ## find the first *real* file in the path
00122     ## the rest of the path becomes the pathinfo.
00123     m = n
00124     for m in range(len(self.path)-1, n-2, -1):
00125       handlerPath = apply(os.path.join, [handlerRoot, ] + self.path[n:m+1])
00126 #      warn(m, len(self.path), handlerPath)
00127 
00128       if os.path.isdir(handlerPath):
00129         sys.path.insert(0, handlerPath)
00130       if os.path.isfile(handlerPath): break
00131       if os.path.isdir(handlerPath): break
00132 
00133     if m+1 == len(self.path):
00134       pathinfo = ''
00135     else:
00136       pathinfo = apply(os.path.join, self.path[m+1:])
00137 
00138     if os.path.isdir(handlerPath): 
00139       modulePath = handlerPath
00140       moduleFilename = module + "_index.py"
00141       handlerPath = os.path.join(modulePath, moduleFilename)
00142     else:
00143       modulePath, moduleFilename = os.path.split(handlerPath)
00144 
00145     debug(handlerPath, pathinfo)
00146     #warn("PATH", handlerPath, pathinfo, modulePath, moduleFilename)
00147     #warn("PATH", self.path)
00148 
00149     if not os.path.isfile(handlerPath):
00150       self.error(404, handlerPath + " doesn't exist")
00151       return 404
00152 
00153     import imp
00154 
00155     moduleName, ext = os.path.splitext(moduleFilename)
00156 
00157     #module = __import__(moduleName)
00158     module = __import__("mod.%s.cgibin.%s" % (module, moduleName), {}, {}, (None,))
00159 
00160     os.chdir(modulePath)
00161 #    debug(mod)
00162     page = module.run(self.context)
00163     page.ncgi.hdf.setValue("CGI.BaseURI", gConfig.gBaseURL)
00164 
00165     if gConfig.gRequireUsername:
00166       page.ncgi.hdf.setValue("CGI.Username", username)
00167       page.username = username
00168 
00169     if hasattr(page, "checkLoginCookie"):
00170       if not page._pageparms.has_key("nologin"):
00171         try:
00172           page.checkLoginCookie()
00173         except CSPage.Redirected:
00174           return
00175 
00176     page.ncgi.hdf.setValue("CGI.PathInfo", pathinfo)
00177     page.clearPaths()
00178     page.setPaths([moduleTemplatePath, systemTemplatePath, systemJLIBPath])
00179     ret = page.start()
00180 
00181     try: 
00182       page.db.close()
00183     except AttributeError: pass
00184 
00185     page = None
00186 
00187     return ret
00188 
00189   def error(self, ecode, reason=None):
00190     import httpResponses
00191     message = httpResponses.gHTTPResponses[ecode]
00192 
00193     template = httpResponses.errorMessage_Default
00194     if ecode == 404:
00195       template = httpResponses.errorMessage_404
00196 
00197     hdf = neo_util.HDF()
00198     hdf.setValue("code", str(ecode))
00199     if message: hdf.setValue("message", message)
00200     if reason: hdf.setValue("reason", reason)
00201 
00202     for key,val in self.context.environ.items():
00203       hdf.setValue("environ." + key, str(val))
00204 
00205     self.context.stdout.write("Content-Type: text/html\r\n")
00206     self.context.setStatus(None, ecode)
00207     self.context.stdout.write("Status: %s\r\n" % ecode)
00208     self.context.stdout.write("\r\n")
00209     
00210     cs = neo_cs.CS(hdf)
00211     cs.parseStr(template)
00212     page = cs.render()
00213 
00214     self.context.stdout.write(page)
00215 
00216     warn("Error", message, reason)
00217 
00218 
00219 def outputFile(context, fn):
00220   fp = open(fn, "rb")
00221   data = fp.read()
00222   fp.close()
00223 
00224   context.setStatus(None, 200)
00225 
00226   imagetype, encoding = mimetypes.guess_type(fn)
00227   debug("imagetype = %s  fn = %s" % (imagetype,fn))
00228 
00229   lines = []
00230 
00231   if imagetype:
00232     lines.append("Content-Type: %s" % imagetype)
00233 
00234   lines.append("Content-Length: %d" % len(data))
00235   
00236   stat = os.stat(fn)
00237   mtime = stat.st_mtime
00238   mod_str = time.strftime("%a, %d %b %Y %H:%M:%S", time.gmtime(mtime))
00239   
00240   lines.append('Last-Modified: %s GMT' % mod_str)
00241 
00242   expire_time = time.gmtime(time.time() + (360*24*3600))
00243   expire_str = time.strftime("%a, %d %b %Y %H:%M:%S", expire_time)
00244   lines.append('Expires: %s GMT' % expire_str)
00245 
00246   lines.append("\r\n")
00247   
00248   headers = string.join(lines, "\r\n")
00249   context.stdout.write(headers)
00250   
00251   context.stdout.write(data)
00252 
00253   return 200
00254 
00255 
00256 class FakeError:
00257   def write(self, s):
00258     apache.log_error(s, apache.APLOG_STARTUP)
00259 
00260 class ModPythonContext:
00261   def __init__ (self, req):
00262 
00263     from mod_python import apache
00264 
00265     self.stdout = apache.CGIStdout(req)
00266     self.stdin = apache.CGIStdin(req)
00267 
00268     self.stderr = FakeError()
00269     env = apache.build_cgi_env(req)
00270 
00271     self.environ = env
00272 
00273     scriptFilename = self.environ.get("SCRIPT_FILENAME", "")
00274     if scriptFilename:
00275       path, fn = os.path.split(scriptFilename)
00276       os.chdir(path)
00277 
00278   def setStatus(self, request, status):
00279     if request:
00280       request['status'] = str(status)
00281 
00282 
00283 
00284 def handler(req):
00285   start = time.time()
00286 
00287   from mod_python import apache
00288 
00289   if 1:
00290     context = ModPythonContext(req)
00291     page = Page(context)
00292     page.mod_python_req = req
00293 
00294     gc.enable()
00295     ret = page.start()
00296     gc.collect()
00297 
00298   ret = apache.OK
00299 
00300   end = time.time()
00301   #sys.stderr.write("handler time %s\n" % int((end-start)*1000))
00302 
00303   return ret
00304 
00305 
00306 def main(argv, stdout, environ):
00307   context = CSPage.Context()
00308   page = Page(context)
00309   page.start()
00310 
00311 
00312 if __name__ == "__main__":
00313   main(sys.argv, sys.stdout, os.environ)


pyclearsilver
Author(s): Scott Hassan/hassan@willowgarage.com
autogenerated on Wed Apr 23 2014 10:35:42