00001
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
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
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
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
00086
00087
00088
00089
00090
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
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
00137
00138
00139 if os.path.isfile(fn):
00140 return outputFile(self.context, fn)
00141
00142
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
00148
00149 handlerPath = ''
00150
00151
00152
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
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
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)