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