$search
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)