Exemplo n.º 1
0
class Root:
    def __init__(self):
        self._applist = {}  # all apps
        self._index = None  # index app
        self._error = None
        self.environ = None
        self.start_response = None
        self.sessionman = SessionManager()
        self.debug = False

    def register_app(self, name, cpath):
        if name not in self._applist:
            self._applist[name] = ApplicationInfo(name, cpath=cpath)

    def register_index(self, name, cpath):
        self._index = ApplicationInfo(name, cpath=cpath)

    def register_error(self, name, cpath):
        self._error = ApplicationInfo(name, cpath=cpath)

    def _default_index(self):
        page = TextContent(_(u"Index method is left out."))
        return self._prepare_response(Response(200, page))

    def _default_error(self, code, message):
        page = TextContent(message)
        return self._prepare_response(Response(code, page))

    def __call__(self, environ, start_response):
        return self.run(environ, start_response)

    def run(self, environ, start_response):
        def tuplize(x):
            l = x.split("=")[:2]
            if len(l) == 1:
                l.append(True)
            return tuple(l)

        self.environ = environ
        self.start_response = start_response

        try:
            path_info = urllib.unquote_plus(environ["PATH_INFO"])
        except KeyError:
            raise WSGIKeyNotPresentError("PATH_INFO")

        path = [p for p in path_info.split("/") if p] or [""]
        if "QUERY_STRING" in environ:
            query_string = urllib.unquote_plus(environ["QUERY_STRING"])
            params = dict([tuplize(x) for x in query_string.split("&") if x])
        else:
            params = {}

            # a dirty little trick to deny FieldStorage to use QUERY_STRING
        self.environ["QUERY_STRING"] = ""

        xenviron = Struct()
        xenviron.args = path
        xenviron.kwargs = params
        try:
            xenviron.fields = FieldStorage(environ=self.environ, fp=self.environ["wsgi.input"])
        except KeyError:
            raise WSGIKeyNotPresentError("wsgi.input")
        xenviron.cookies = SimpleCookie(environ.get("HTTP_COOKIE", ""))

        try:
            xenviron.cookies, xenviron.session = self.sessionman.get_session(xenviron.cookies)
        except SessionError:
            xenviron.session = self.sessionman.new_session()

        if not path[0]:
            if not self._index:
                return self._default_index()

            app = self._index(xenviron)
        else:
            try:
                name = path[0]
                app = self._applist[name](xenviron)
            except KeyError:
                xenviron.error_code = 404
                xenviron.error_message = _(u"Method not found")

                if self._error:
                    app = self._error(xenviron)
                else:
                    return self._default_error(xenviron.error_code, xenviron.error_message)

        app.body.refresh(xenviron)
        app.body.run()
        app_xenviron, response = app.body.get()

        # further process the app_xenviron
        self.sessionman.update(app_xenviron.session)

        # return preparations
        cookies = SimpleCookie()
        cookies.update(app_xenviron.cookies)
        cookies.update(app_xenviron.session.sidcookie)
        cookies = str(cookies).split()[1]
        response.heads.set_cookie = cookies
        return self._prepare_response(response)

    def _prepare_response(self, response):
        rc, rh, ct = response.get_forwsgi()
        self.start_response(rc, rh)

        return ct

    @staticmethod
    def configure(cfgfilename, update=False):
        root = Root()
        cfg = ConfigParser()
        cfg.read(cfgfilename)

        apps = "applications"

        for app, cpath in cfg.items(apps):
            if not app in root._applist:
                root.register_app(app, cpath)

        index = "index"
        if cfg.has_section(index):
            app, cpath = cfg.items(index)[0]
            root.register_index(app, cpath)

        error = "error"
        if cfg.has_section(error):
            app, cpath = cfg.items(error)[0]
            root.register_error(app, cpath)

        try:
            timeout = cfg.getint("root", "timeout")
        except (NoSectionError, NoOptionError):
            timeout = 0

        root.sessionman.timeout = timeout

        try:
            expiretime = cfg.getint("root", "expiretime")
        except (NoSectionError, NoOptionError):
            expiretime = 0

        root.sessionman.expiretime = expiretime

        try:
            debug = cfg.getboolean("root", "debug")
        except (NoSectionError, NoOptionError):
            debug = False

        root.debug = debug

        return root
Exemplo n.º 2
0
class FunRoot(object):
	__slots__ = ["sessionman", "meltscriptname", "r"]
	r = threading.local()
	
	def __init__(self, **kwargs):
		self.sessionman = SessionManager()
		self.meltscriptname = kwargs.get("meltscriptname", False)
		
	def __call__(self, environ, start_response):
		return self.run(environ, start_response)
		
	def run(self, environ, start_response):
		try:	
			path_info = urllib.unquote_plus(environ["PATH_INFO"])
		except KeyError:
			path_info = ""
		
##		self.r = r
##		r = Struct()
		r = self.r
		r.path = Struct()
		r.path.endswithslash = path_info.endswith("/")
		
		if not self.meltscriptname:
			try:
				path_info = "%s%s" % (environ["SCRIPT_NAME"],path_info)
			except KeyError:
				pass
			
		path = [p for p in path_info.split("/") if p] or [""]
		
		if self.meltscriptname:
			try:
				r.path.scriptname = environ["SCRIPT_NAME"]
			except KeyError:
				pass
		else:
			r.path.scriptname = ""
			
		kwargs = dict([(x[0],x[1])
			for x in parse_qsl(environ["QUERY_STRING"], keep_blank_values=True)])
		
		r.cookies = CookieJar(environ.get("HTTP_COOKIE", ""))
		r.env = environ

		# TODO: Find a way to figure out whether the client browser can use cookies
		try:
			sessionman_lock.acquire()
			try:
				r.cookies, r.session = self.sessionman.get_session(r.cookies)
			except SessionError:
				r.session = self.sessionman.new_session()
		finally:
			sessionman_lock.release()
			
		appname = path[0]
		args = path[1:]
		
		if not (appname and hasattr(self, appname)):
			appname = "__index__"
			
		r.heads = Heads()
		r.code = 200
		
		try:
##			response = getattr(self, appname)(r, *args, **kwargs)
			getattr(self, appname)(*args, **kwargs)
		except TypeError, e:
			response = getattr(self, "__error__")(r, e)
		
		try:
			sessionman_lock.acquire()
			# further process the app_xenviron
##			self.sessionman.update(response.session)
			self.sessionman.update(r.session)
		finally:
			sessionman_lock.release()

##		return self._prepare_response(start_response, Response(response))
		return self._prepare_response(start_response, Response(r))
Exemplo n.º 3
0
class Root:
    def __init__(self, meltscriptname=False, debug=False):  # XXX: meltscriptname is too cryptic
        """Create the root WSGI application.
		
		* Usually, this constructor is not called by the programmer directly.
		* It is called by ``configure``.
		* Set ``meltscript=True`` when using by another WSGI server.
		* Set ``debug=True`` for debug mode.
		
		"""

        self._applist = {}  # all apps
        self._index = None  # index app
        self._error = None
        self._login = None  # login app
        self.sessionman = SessionManager()
        self.debug = debug
        self.meltscriptname = meltscriptname  # XXX: meltscriptname is too cryptic
        self.cacheall = False

    def register_app(self, name, appoptions):
        """Register the application if it is not already registered.
		
		* This method is called by ``configure``.		
		* ``appoptions`` is the application options.
		
			- If the config. files are in cfg/ cpath could be
			``cfg/example.ini``.
		
		"""

        if name not in self._applist:
            self._applist[name] = ApplicationInfo(name, appoptions)
            # XXX: maybe we should raise an exception if name is in applist

            # TODO: This is pretty ugly, make it more useful

    def _default_index(self, start_response):
        response = Struct()
        response.content = TextContent(_(u"Index method is left out"))
        response.code = 404
        response.heads = Heads()

        return self._prepare_response(start_response, Response(response))

        # TODO: This is pretty ugly, make it more useful

    def _default_error(self, start_response, code, message):
        response = Struct()
        response.content = TextContent(message)
        response.code = code
        response.heads = Heads()

        return self._prepare_response(start_response, Response(response))

    def __call__(self, environ, start_response):
        # TODO: The error handler must be put here
        return self.run(environ, start_response)

    def run(self, environ, start_response):
        try:
            path_info = urllib.unquote_plus(environ["PATH_INFO"])
        except KeyError:
            path_info = ""

        if not self.meltscriptname:
            try:
                path_info = "%s%s" % (environ["SCRIPT_NAME"], path_info)
            except KeyError:
                raise WSGIKeyNotPresentError("SCRIPT_NAME", source="root.py")

        xenviron = Struct()
        xenviron.path = Struct()
        xenviron.path.endswithslash = path_info.endswith("/")

        path = [p for p in path_info.split("/") if p] or [""]
        params = dict([(x[0], x[1] or True) for x in parse_qsl(environ["QUERY_STRING"], keep_blank_values=True)])

        # a dirty little trick to deny FieldStorage to use QUERY_STRING
        environ["QUERY_STRING"] = ""

        xenviron.path.args = path
        xenviron.path.scriptname = environ["SCRIPT_NAME"]
        xenviron.path.kwargs = params

        # use Python's ``cgi`` module to parse contents of POST
        try:
            xenviron.fields = BizFieldStorage(environ=environ, fp=environ["wsgi.input"])
        except KeyError:
            raise WSGIKeyNotPresentError("wsgi.input")

        xenviron.cookies = CookieJar(environ.get("HTTP_COOKIE", ""))
        xenviron.env = environ

        # TODO: Find a way to check whether the client browser can use cookies
        try:
            sessionman_lock.acquire()
            try:
                xenviron.cookies, xenviron.session = self.sessionman.get_session(xenviron.cookies)
            except SessionError:
                xenviron.session = self.sessionman.new_session()
        finally:
            sessionman_lock.release()

        appname = path[0]

        # if no application name given in the URL (i.e., it is ``/``),
        # ... call the index/default index application
        if not appname:
            if not self._index:
                return self._default_index(start_response)

            appname = self._index

        try:
            app = self._applist[appname](xenviron)
        except KeyError, e:
            xenviron.error_code = 404
            if self.debug:
                xenviron.error_message = unicode(e)
            else:
                xenviron.error_message = _(u"Method not found")

            return self._default_error(start_response, xenviron.error_code, xenviron.error_message)

        try:
            response = app(xenviron)
        except KeyboardInterrupt:
            pass  # sys.exit()

        try:
            sessionman_lock.acquire()
            # further process the app_xenviron
            self.sessionman.update(response.session)
        finally:
            sessionman_lock.release()

        return self._prepare_response(start_response, Response(response))