from pyhouse.tools import getPackageLocation from pyhouse.config import loadConfig import cherrypy from simpletal import simpleTAL, simpleTALES, simpleTALUtils import os import sys def getParams(): params = cherrypy.request.path.split("/") #@UndefinedVariable params.reverse() retVal = [] path = "" for param in params: if len( param ) == 0: continue path += "../" retVal.append( { "url" : path + param + "/", "name" : param }) retVal.append({ "url" : path, "name" : "main" }) retVal.reverse() return retVal class InterfaceView(object): def __init__(self, filename, viewObjectFactory, macros, dir): templateFile = open (dir + "/" + filename, 'r') template = simpleTAL.compileHTMLTemplate(templateFile) templateFile.close() self.template = template self.viewObjectFactory = viewObjectFactory self.macros = macros self.dir = dir def expand(self, obj, params): # Create the context that is used by the template context = simpleTALES.Context(allowPythonPath=1) viewObject = None if self.viewObjectFactory: viewObject = self.viewObjectFactory( context=obj, request=cherrypy.request ) cherrypy.request.__setattr__("paramsMap", getParams) # A list that contains a dictionary context.addGlobal ("context", obj) context.addGlobal ("view", viewObject ) context.addGlobal ("request", cherrypy.request) context.addGlobal ( "params", params ) for name, macroFileName in self.macros.items(): macroFile = open (self.dir + "/" + macroFileName, 'r') macro = simpleTAL.compileHTMLTemplate(macroFile) macroFile.close() context.addGlobal( name, macro ) out = simpleTALUtils.FastStringOutput() self.template.expand (context, out) return out.getvalue() class Theme(object): def __init__(self, themedir, themename, views = {}, macros = {} ): self.views = views self.macros = { 'sitemacros' : 'macros.pt' } self.themedir = themedir self.themename = themename cherrypy.config.update( { '/static/' + themename : { 'staticFilter.on': True, 'staticFilter.dir': themedir + "/static" } } ) def getView(self, obj ): from pyhouse.interfaces import GetImplementedInterfaces for interface in GetImplementedInterfaces( obj ): if self.views.has_key( interface ): view = self.views[interface] return InterfaceView( view["template"], view["classfactory"], self.macros, self.themedir) class ThemeManager(object): def __init__(self, themeDir ): self.themes = {} for file in os.listdir( themeDir ): themePath = themeDir + os.sep + file themeFilePath = themePath + os.sep + "theme.conf" if not os.path.exists(themeFilePath): continue overrides = [ "theme/themedir=" + themePath, "theme/name=" + file ] import pyhouse config = loadConfig( themeFilePath, getPackageLocation( pyhouse ) + "/component.xml" , overrides=overrides ) self.themes = dict( self.themes.items() + config.themes ) def getTheme(self): return self.themes['default'] from threading import Thread import logging class PyHouseWebServer(Thread): """A thread that runs the cherrypy server""" def __init__(self, pyhouse, configFile="server.conf"): self.pyhouse= pyhouse #cherrypy.config.update({ '/static' : { 'staticFilter.on': True, 'staticFilter.dir': "/home/clehmann/src/pyhouse/servers/http/themes/default" + "/static" }}) cherrypy.root = self import pyhouse_themes #@UnresolvedImport templatesPath = getPackageLocation(pyhouse_themes) self.themeManager = ThemeManager( templatesPath ) cherrypy.config.update( { '/favicon.ico' : { 'staticFilter.on': True, 'staticFilter.file': templatesPath + "/static/favicon.ico" } } ) logging.info( "Pyhouse web server initalized...") Thread.__init__( self ) def run(self): logging.info( "Starting web server...") cherrypy.server.quickstart(None) def stop(self): cherrypy.server.interrupt = SystemExit() def default(self, *path, **kwds): from pyhouse.containers import TraversalError if len(path) == 1 and path[0] == 'index': path = path[:-1] try: context = self.pyhouse.objectFromPath( path ) #context = ProxiedClass( self.pyhouseURI + cherrypy.request.path ) except TraversalError: raise cherrypy.HTTPError( 404, "Resource " + cherrypy.request.path + " does not exist!" ) #@UndefinedVariable template = self.themeManager.getTheme().getView( context ) if template: return template.expand(context, kwds) else: raise cherrypy.HTTPError( 404, "Resource " + cherrypy.request.path + " contains no view!" ) #@UndefinedVariable default.exposed = True if __name__ == '__main__': pyhouse = sys.argv[ 1 ] # Start the CherryPy server. server = PyHouseWebServer(pyhouse) server.run()