from params import Params from session import Session, SessionContainer import BaseHTTPServer import Cheetah.Template import Cookie import SocketServer import StringIO import cgi import sys import uuid import os import threading from logger import Logger TEMPLATE_DIR='./templates' class YaDynWebApp(object): @classmethod def setSessionContainer(cls, sessionContainer): cls.sessionContainer = sessionContainer def __init__(self, sid): self.buf = StringIO.StringIO() self.params = None self.session = YaDynWebApp.sessionContainer.get(sid) self.error_msg = None self.msg = None self.sid = sid def finish(self): pass def log(self, msg): Logger.log(msg) def setParams(self, p): self.params = p def showPage(self, forcePage=''): if self.session: if forcePage != '': page = forcePage else: page = self.session.redirectTarget else: page = 'login' if page == 'logout': YaDynWebApp.sessionContainer.delete(self.sid) self.session = None page = 'login' templateFile = page + '.tmpl' try: if self.session: self.log("showPage, session: %s" % str(self.session)) self.log("showPage, params: %s" % str(self.session.params)) self.session.setShownPage(page) try: loaderObjectClass = eval("loader_" + page) loaderObject = loaderObjectClass(self.session) loaderObject.mergeAdditionalData() except NameError, e: self.log("loader class for %s not found: %s" % (page, str(e))) except HscException, e: s = "HSC Failure loading data: %s" % str(e) self.log(s) raise Exception(s) tmpl = Cheetah.Template.Template(file=TEMPLATE_DIR + '/' + templateFile, searchList=[self]) #self.log("OUTPUT: %s" % str(tmpl)) self.buf.write(str(tmpl)) if self.session: self.session.clearMsgs() except Exception, e: YaDynWebApp.sessionContainer.delete(self.sid) self.buf.write("Problems to show this page: %s %s" % (e.__class__.__name__, str(e))) finally: pass def processAction(self): if self.params.action == "Login": authTuple = getAuthTuple(self.params.username, self.params.password) if authTuple: self.params = Params({}) self.sid = str(uuid.uuid1()) session = Session(self.sid, self.params) session.setAuthTuple(authTuple) session.setGoodMsg("Welcome") session.setRedirectTarget("menu") YaDynWebApp.sessionContainer.add(session) else: self.sid = 0 else: if self.session == None: self.sid = 0 else: shownPage = self.session.getShownPage() self.session.setParams(self.params) self.log("shownPage: %s" % shownPage) try: dataObjectClass = eval(shownPage) dataObject = dataObjectClass(self.session) dataObject.process() self.session.setGoodMsg("Action on %s performed successfully" % shownPage) self.session.setRedirectTarget(dataObject.getNextPage()) except NameError, e: self.log("processAction, NameError PARAMS: %s" % str(self.session.params)) s = "Internal program error: %s" % str(e) self.session.setBadMsg(s) self.log(s) self.session.setRedirectTarget("menu") except HscException, e: self.log("processAction, HscException PARAMS: %s" % str(self.session.params)) s = "HSC Failure: %s" % str(e) self.session.setBadMsg(s) self.log(s) self.session.setRedirectTarget(shownPage) def __str__(self): return self.buf.getvalue() class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler): server_version = "YaDynWebAppHTTP/1.0" @classmethod def setParams(cls, entries): cls.entries = entries def log_message(self, format, *args): Logger.log(format%args) def getSidFromCookie(self): try: cookie = Cookie.SimpleCookie(self.headers.get('Cookie')) sid = cookie['sid'].value except KeyError: sid = None return sid def setSidInCookie(self, sid): cookie = Cookie.SimpleCookie() cookie['sid'] = sid cookie['sid']['Max-Age'] = 10*60 self.wfile.write(str(cookie) + '\r\n') def do_POST(self): self.log_message("Request: %s", self.path) sid = self.getSidFromCookie() self.log_message("Cookie: %s" % self.headers.get('Cookie')) d = YaDynWebApp(sid) l = int(self.headers.get('Content-Length', '0')) q = self.rfile.read(l) e = cgi.parse_qs(q) self.log_message("QUERY: %s" % str(e)) d.setParams(Params(e)) d.processAction() self.send_response(303, "See Other") self.setSidInCookie(d.sid) self.send_header("Location", "/") self.end_headers() d.finish() def do_GET(self): self.log_message("Request: %s", self.path) sid = self.getSidFromCookie() self.log_message("SID: %s" % sid) d = YaDynWebApp(sid) d.showPage(self.path.split('/')[1]) self.send_response(200, "OK") self.send_header("Content-Type", "text/html") self.end_headers() self.wfile.write(str(d)) d.finish() class MyServer(SocketServer.ThreadingTCPServer): def __init__(self, server_address, RequestHandlerClass): self.allow_reuse_address = True SocketServer.ThreadingTCPServer.__init__(self, server_address, RequestHandlerClass) class WebReceiver(threading.Thread): def __init__(self, webAddr, entries): threading.Thread.__init__(self) self.webAddr = webAddr MyHandler.setParams(entries) self.setDaemon(True) def run(self): self.sessionContainer = SessionContainer(60, 600) self.sessionContainer.setDaemon(True) self.sessionContainer.start() YaDynWebApp.setSessionContainer(self.sessionContainer) MyServer(self.webAddr, MyHandler).serve_forever()