" % self.state
class PyLucidApp(BaseApplication):
"""
Klasse die die Programmlogik zusammenstellt
"""
# Angaben für colubrid:
charset = 'utf-8'
#~ slash_append = True
slash_append = False
def __init__(self, environ, start_response):
super(PyLucidApp, self).__init__(environ, start_response)
self.environ = environ
# Eigenes response-Objekt. Eigentlich genau wie das
# original von colubrid, nur mit einer kleinen Erweiterung
self.response = response.HttpResponse()
# Damit man von überall einen Debug einleiten kann
self.response.debug = self.request_debug
self.runlevel = self.request.runlevel = runlevel()
# Verwaltung für Einstellungen aus der DB (Objekt aus der Middleware)
self.preferences = self.request.preferences = preferences.Preferences(
environ['PyLucid.config']
)
# 'Speicher' für CSS/JS Daten, die erst am Ende in die CMS Seite
# eingefügt wird
self.response.addCode = environ["PyLucid.addCode"]
# Speichert Nachrichten die in der Seite angezeigt werden sollen
self.page_msg = self.response.page_msg = environ['PyLucid.page_msg']
#~ self.page_msg("page_msg - NORMAL")
#~ self.page_msg.red("page_msg - RED")
#~ self.page_msg.green("page_msg - GREEN")
#~ self.page_msg.debug("page_msg - DEBUG")
# Allgemeiner CGI Sessionhandler auf mySQL-Basis
self.session = self.request.session = sessionhandling.sessionhandler()
# Log-Ausgaben in SQL-DB
self.log = self.request.log = SQL_logging.log()
# Verwaltung von erweiterungs Modulen/Plugins
self.module_manager = self.request.module_manager = \
module_manager.module_manager()
self.render = self.request.render = page_parser.render()
self.staticTags = self.request.staticTags = response.staticTags()
# Passt die verwendeten Pfade an.
self.URLs = self.request.URLs = URLs.URLs(self.request, self.response)
# Tools an Request Objekt anhängen
tools.request = self.request # Objekt übergeben
tools.response = self.response # Objekt übergeben
self.tools = self.request.tools = tools
self.response.echo = tools.echo() # Echo Methode an response anhängen
# Jinja-Context anhängen
self.request.context = {}
# Anbindung an die SQL-Datenbank, mit speziellen PyLucid Methoden
self.db = self.request.db = environ['PyLucid.database']
# Einheitliche Schnittstelle zu den Templates Engines
self.request.templates = template_engines.TemplateEngines(
self.request, self.response
)
# FIXME: Übertragen von Objekten in den DBwrapper
self.db.page_msg = self.page_msg
self.db.tools = self.tools
self.db.URLs = self.URLs
self.db.preferences = self.preferences
def request_debug(self):
try:
import inspect
# Angaben zur Datei, Zeilennummer, aus dem die Nachricht stammt
stack = inspect.stack()[1]
filename = stack[1].split("/")[-1][-20:]
fileinfo = "%-20s line %3s: " % (filename, stack[2])
self.page_msg(fileinfo.replace(" "," "))
except Exception, e:
self.page_msg("(inspect Error: %s) " % e)
try:
from colubrid.debug import debug_info
self.page_msg(debug_info(self.request))
except Exception, e:
self.page_msg("Can't make debug info: %s" % e)
def setup_runlevel(self):
pathInfo = self.URLs["pathInfo"]
#~ self.page_msg(">>>", pathInfo)
if pathInfo.startswith(self.preferences["installURLprefix"]):
self.runlevel.set_install()
elif pathInfo.startswith(self.preferences["commandURLprefix"]):
self.runlevel.set_command()
else:
self.runlevel.set_normal()
# Pfade anhand des Runlevel anpassen.
self.URLs.setup_runlevel()
def init2(self):
"""
Getrennt vom normalen init, weil zwischenzeitlich evtl. nur ein CSS
ausgeliefert werden sollte oder PyLucid installieret werden soll...
Dazu sind die restilichen Objekte garnicht nötig.
"""
# Preferences aus der DB lesen
self.preferences.init2(self.request, self.response)
self.preferences.update_from_sql(self.db)
# Log-Ausgaben in SQL-DB
self.log.init2(self.request, self.response)
#~ self.request.log.debug_last()
self.session.init2(self.request, self.response)
self.staticTags.init2(self.request, self.response)
self.render.init2(self.request, self.response)
self.module_manager.init2(self.request, self.response)
#~ self.request.module_manager.debug()
# Aktuelle Seite ermitteln und festlegen
try:
detect_page.detect_page(self.request, self.response).detect_page()
except NoPageExists:
# Es existiert noch keine CMS Seite
self.create_first_page()
# Überprüfe Rechte der Seite
#~ self.verify_page()
# Übertragen von Objekten
self.db.render = self.render
self.db.session = self.session
self.response.module_manager = self.module_manager
self.response.staticTags = self.staticTags
# Statische-Tag-Informationen setzten:
self.staticTags.setup()
def create_first_page(self):
from PyLucid.modules.pageadmin import pageadmin
p = pageadmin.pageadmin(self.request, self.response)
p.create_first_page()
msg = (
'No Page exists.
\n'
'First page created now, please reload :)
\n'
)
raise NoPageExists(msg)
def process_request(self):
try:
self.db.connect(self.preferences)
except database.ConnectionError, e:
raise ConnectionError(e)
self.environ["request_start"] = time.time()
self.setup_runlevel()
if self.runlevel.is_install():
self.installPyLucid()
return self.response
# init der Objekte für einen normalen Request:
self.init2()
if self.runlevel.is_normal():
# Normale CMS Seite ausgeben
self.normalRequest()
elif self.runlevel.is_command():
# Ein Kommando soll ausgeführt werden
moduleOutput = self.module_manager.run_command()
if callable(moduleOutput):
# Wird wohl ein neues response-Objekt sein.
# z.B. bei einem Dateidownload!
return moduleOutput
# Ausgaben vom Modul speichern, dabei werden diese automatisch
# im response-Objekt gelöscht, denn ein "command"-Modul schreib
# auch, wie alle anderen Module ins response-Object ;)
content = self.response.get()
if "render follow" in self.session:
# Eintrag löschen, damit der nicht in die DB für den nächsten
# request gespeichert wird:
del(self.session["render follow"])
# Es soll nicht die Ausgaben den Modules angezeigt werden,
# sondern die normale CMS Seite. (z.B. nach dem Speichern
# einer editierten Seite!)
self.normalRequest()
else:
# Ausgaben vom Modul sollen in die Seite eingebaut werden:
self.staticTags["page_body"] = content
self.render.write_command_template()
else:
# Kann eigentlich nie passieren ;)
raise RuntimeError("unknown runlevel!!!")
# Evtl. vorhandene Sessiondaten in DB schreiben
self.session.commit()
if debug:
self.response.debug()
try:
self.db.close()
except Exception, e:
self.page_msg.red("WARNING: Can't disconnect from DB: %s" % e)
#~ else:
#~ self.page_msg.green("DB disconnect ok")
return self.response
def normalRequest(self):
# Normale Seite wird ausgegeben
# Schreib das Template mit dem page_body-Tag ins
# response Objekt.
self.render.write_page_template()
def debug(self, *txt):
#~ sys.stderr.write(
self.page_msg(
"%s\n" % " ".join([str(i) for i in txt])
)
def installPyLucid(self):
"""
Der aktuelle request ist im "_install"-Bereich
"""
from PyLucid.install.install import InstallApp
InstallApp.__info__ = __info__
InstallApp(self.request, self.response).process_request()
app = PyLucidApp
# database
#~ from PyLucid.middlewares.database import DatabaseMiddleware
from PyLucid.middlewares import database
app = database.DatabaseMiddleware(app)
# Configuration
from PyLucid.middlewares.configuration import configMiddleware
app = configMiddleware(app)
# Middleware Page-Message-Object
from PyLucid.middlewares.page_msg import page_msg
app = page_msg(app, debug=False)
#~ app = page_msg(app, debug=True)
# Middleware, die die Tags "script_duration" und "page_msg" ersetzt
from PyLucid.middlewares import replacer
app = replacer.AddCode(app) # Middleware, für addCode
app = replacer.Replacer(app)
if __name__ == '__main__':
# Eine Aufwendigere Variante, damit der Standalone-Entwicklungsserver
# auch funktioniert, s. http://trac.pocoo.org/ticket/87
def start():
host = "localhost"
port = 8080
print "\n", "="*79
print "Starting development server on: '%s:%s'...\n" % (host, port)
# with 'debugged application':
from colubrid.debug import DebuggedApplication
global app
app = DebuggedApplication(app)
# usind the new wsgiref (from Python 2.5)
from wsgiref.simple_server import WSGIServer, WSGIRequestHandler
server = WSGIServer((host, port), WSGIRequestHandler)
server.set_app(app)
server.serve_forever()
from colubrid import reloader
reloader.main(start, [])
#~ if __name__ == '__main__':
#~ print "\n", "="*79, "\nStarting local test server...\n"
#~ # with 'debugged application':
#~ from colubrid.debug import DebuggedApplication
#~ app = DebuggedApplication(app)
#~ from colubrid.server import execute
#~ execute(app, debug=True, reload=True)