DT.py :  » Web-Server » SkunkWEB » skunkweb-3.4.4 » pylibs » DT » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Web Server » SkunkWEB 
SkunkWEB » skunkweb 3.4.4 » pylibs » DT » DT.py
#  
#  Copyright (C) 2001 Andrew T. Csillag <drew_csillag@geocities.com>
#  
#      You may distribute under the terms of either the GNU General
#      Public License or the SkunkWeb License, as specified in the
#      README file.
#   
"""The main place to be if you want to use the DT library
"""
import sys
import types
import string
import copy

import DTParser
import DTLexer
import DTTags
import DTTagRegistry
import DTC
import DTExcept
import DTCompilerUtil
from SkunkExcept import *

class dummy:
    """not user servicable"""
    pass

# Types of template execution 
DT_REGULAR, DT_DATA, DT_INCLUDE = 0, 1, 2

class _current_tag_thingy:
    """no user servicable parts inside"""
    def __init__(self, tag, lineno):
        self.tag = tag
        self._name, self._lineno = tuple ( string.split ( lineno, ':' ))
    def lineno(self): return int(self._lineno)
    def name(self): return self._name
    def __str__(self): return self.tag
    def __repr__(self): return self.tag

def compileTemplate ( text, path, tag_registry = None ):
    """create a compiled STML template.

    parameters:
    
    text -- the text of the template
    path -- a name for the template (seen in tracebacks and
            the like)

    tag_registry -- a tag registry object -- if None
                    the default tag registry is used

    After the thing is built, call the produced DT object like a function
    whose arguments are:
    
    local_ns  -- the local namespace dictionary
    global_ns -- the global namespace dictionary
    hidden_ns -- the "hidden" namespace dictionary
    call_type -- one of:
        DT_REGULAR -- the default, a regular template
        DT_INCLUDE -- use parent namespace games
        DT_DATA    -- a data template, enable <:return:> tag
    """

    # Check that valid tag registry is passed
    if not isinstance ( tag_registry, DTTagRegistry.DTTagRegistry ):
        raise SkunkRuntimeError, 'valid tag registry needs to be supplied'

    # Meta data is a dictionary to keep it marshallable
    meta = {} 

    # Generate the python code
    progtext = DTC.compileTemplate ( text, path, tag_registry, meta )

    # Compile python code
    cobj = DTC.compileText ( progtext, path )

    return DT ( path, progtext, cobj, meta )

class DT:
    """
    class representing a template. Can be pickled up and used at a later
    date
    """
    def __init__ ( self, path, text, compiled, meta ):
        """
        Create the template object
        """

        self.path = path

        self._text, self._compiled, self._meta = text, compiled, meta

    def meta ( self ):
        """
        Get a handle on our meta-data
        """
        return self._meta

    def source(self):
        """Get the source for self"""
        return self._text

    def setError ( self, err ): 
        """These are to propagate error, if the real template failed to 
        compile and we're using a cached one to avoid blowing up the site
        """
        self._error_text = err

    def getError ( self ):
        return getattr ( self, '_error_text', None )

    def errorTag ( self ):
        """
        Returns the error tag, should be called in 'except...' clause
        """
        return getattr ( self, '_error_tag', None )

    def __store_ns(self, ns, env):
        for v in ('__t', '__h', '__d'):
            if ns.has_key(v):
                env[v]=ns[v]
                
    def __unstore_ns(self, ns, env):
        self.__store_ns(env, ns)

    def __call__(self, local_ns, global_ns, hidden_ns, 
                       call_type = DT_REGULAR ):
        """
        This function is called to actually evaluate the template
        """

        ns = local_ns
        temp_ns={}
        if call_type == DT_INCLUDE:
            # Store somewhere parent's stuff
            # this failed when trying to do an include call
            # from a top-level python document; now be a little
            # more careful
            #__t, __h, __d = ns['__t'], ns['__h'], ns['__d']
            self.__store_ns(ns, temp_ns)

        # 
        # Add our stuff to local namespace
        #
        ns['__t'] = dummy()                     # temporary var space
        _h = ns['__h'] = copy.copy(hidden_ns)   # hidden ns

        #ATC
        #_d = ns['__d'] = DTCompilerUtil.get_d() # debug info ns
        #/ATC
        
        _d = ns['__d'] = DTCompilerUtil.dummy()
        
        # Add our own stuff to global_ns
        DTCompilerUtil.setup_h ( _h )

        # Clear out current tag
        self._error_tag = None

        if call_type == DT_DATA:
            # We are called as data component, prepare return value
            ns['__return'] = None
            ns['__return_set'] = None

        # Does the finally: clause need to setup the current tag?
        _needs_tag = 1
        try:
            try:
                exec self._compiled in global_ns, ns
            except DTExcept.DTHaltError:
                # Set the error tag, just in case error occurs
                pass
            else:
                _needs_tag = 0
        finally:
            if _needs_tag:
                self._error_tag = _current_tag_thingy ( _d.CURRENT_TAG,
                                                        _d.CURRENT_LINENO )
            # Cleanup the local namespace
            for k in ( '__t', '__h', '__d' ):
                 del ns[k]
        
            if call_type == DT_INCLUDE:
                # Restore parent's stuff
                #ns['__t'], ns['__h'], ns['__d'] = __t, __h, __d
                self.__unstore_ns(ns, temp_ns)

        # Check the return value
        if call_type == DT_DATA:
             if not ns['__return_set']:
                 raise SkunkStandardError, \
                       'no <:return:> tag was found in a data component'

        if call_type == DT_DATA:
            return ns['__return']
        else:
            return _h.OUTPUT.getvalue()
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.