00001
00002
00003 import os, sys, string, time, string
00004 from pyclearsilver.log import *
00005
00006
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
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
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
00076
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
00110 if os.path.isfile(fn):
00111 return outputFile(self.context, fn)
00112
00113
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
00122
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
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
00147
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
00158 module = __import__("mod.%s.cgibin.%s" % (module, moduleName), {}, {}, (None,))
00159
00160 os.chdir(modulePath)
00161
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
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)