All pastes #397542 Raw Edit

Miscellany

public text v1 · immutable
·published 2007-03-16 15:48 UTC
rendered paste body
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()