# template.py
# Copyright (C) 2006, 2007, 2008 Michael Bayer mike_mp@zzzcomputing.com
#
# This module is part of Mako and is released under
# the MIT License: http://www.opensource.org/licenses/mit-license.php

"""provides the Template class, a facade for parsing, generating and executing template strings,
as well as template runtime operations."""

from mako.lexer import Lexer
from mako import codegen
from mako import runtime, util, exceptions
import imp, os, re, shutil, stat, sys, tempfile, time, types, weakref

    
class Template(object):
    """a compiled template"""
    def __init__(self, text=None, filename=None, uri=None, format_exceptions=False, error_handler=None, 
        lookup=None, output_encoding=None, encoding_errors='strict', module_directory=None, cache_type=None, 
        cache_dir=None, cache_url=None, module_filename=None, input_encoding=None, disable_unicode=False, default_filters=None, 
        buffer_filters=[], imports=None, preprocessor=None, cache_enabled=True):
        """construct a new Template instance using either literal template text, or a previously loaded template module
        
        text - textual template source, or None if a module is to be provided
        
        uri - the uri of this template, or some identifying string. defaults to the 
        full filename given, or "memory:(hex id of this Template)" if no filename
        
        filename - filename of the source template, if any
        
        format_exceptions - catch exceptions and format them into an error display template
        """
        
        if uri:
            self.module_id = re.sub(r'\W', "_", uri)
            self.uri = uri
        elif filename:
            self.module_id = re.sub(r'\W', "_", filename)
            self.uri = filename
        else:
            self.module_id = "memory:" + hex(id(self))
            self.uri = self.module_id
        
        self.input_encoding = input_encoding
        self.output_encoding = output_encoding
        self.encoding_errors = encoding_errors
        self.disable_unicode = disable_unicode
        if default_filters is None:
            if self.disable_unicode:
                self.default_filters = ['str']
            else:
                self.default_filters = ['unicode']
        else:
            self.default_filters = default_filters
        self.buffer_filters = buffer_filters
            
        self.imports = imports
        self.preprocessor = preprocessor
        
        # if plain text, compile code in memory only
        if text is not None:
            (code, module) = _compile_text(self, text, filename)
            self._code = code
            self._source = text
            ModuleInfo(module, None, self, filename, code, text)
        elif filename is not None:
            # if template filename and a module directory, load
            # a filesystem-based module file, generating if needed
            if module_filename is not None:
                path = module_filename
            elif module_directory is not None:
                u = self.uri
                if u[0] == '/':
                    u = u[1:]
                path = os.path.abspath(os.path.join(module_directory.replace('/', os.path.sep), u + ".py"))
            else:
                path = None    
            if path is not None:
                util.verify_directory(os.path.dirname(path))
                filemtime = os.stat(filename)[stat.ST_MTIME]
                if not os.path.exists(path) or os.stat(path)[stat.ST_MTIME] < filemtime:
                    _compile_module_file(self, file(filename).read(), filename, path)
                module = imp.load_source(self.module_id, path, file(path))
                del sys.modules[self.module_id]
                if module._magic_number != codegen.MAGIC_NUMBER:
                    _compile_module_file(self, file(filename).read(), filename, path)
                    module = imp.load_source(self.module_id, path, file(path))
                    del sys.modules[self.module_id]
                ModuleInfo(module, path, self, filename, None, None)
            else:
                # template filename and no module directory, compile code
                # in memory
                (code, module) = _compile_text(self, file(filename).read(), filename)
                self._source = None
                self._code = code
                ModuleInfo(module, None, self, filename, code, None)
        else:
            raise exceptions.RuntimeException("Template requires text or filename")

        self.module = module
        self.filename = filename
        self.callable_ = self.module.render_body
        self.format_exceptions = format_exceptions
        self.error_handler = error_handler
        self.lookup = lookup
        self.cache_type = cache_type
        self.cache_dir = cache_dir
        self.cache_url = cache_url
        self.cache_enabled = cache_enabled

    def source(self):
        """return the template source code for this Template."""
        return _get_module_info_from_callable(self.callable_).source
    source = property(source)
    
    def code(self):
        """return the module source code for this Template"""
        return _get_module_info_from_callable(self.callable_).code
    code = property(code)
    
    def cache(self):
        return self.module._template_cache
    cache = property(cache)
    
    def render(self, *args, **data):
        """render the output of this template as a string.
        
        if the template specifies an output encoding, the string will be encoded accordingly, else the output
        is raw (raw output uses cStringIO and can't handle multibyte characters).
        a Context object is created corresponding to the given data.  Arguments that are explictly
        declared by this template's internal rendering method are also pulled from the given *args, **data 
        members."""
        return runtime._render(self, self.callable_, args, data)
    
    def render_unicode(self, *args, **data):
        """render the output of this template as a unicode object."""
        
        return runtime._render(self, self.callable_, args, data, as_unicode=True)
        
    def render_context(self, context, *args, **kwargs):
        """render this Template with the given context.  
        
        the data is written to the context's buffer."""
        if getattr(context, '_with_template', None) is None:
            context._with_template = self
        runtime._render_context(self, self.callable_, context, *args, **kwargs)
    
    def has_def(self, name):
        return hasattr(self.module, "render_%s" % name)
        
    def get_def(self, name):
        """return a def of this template as an individual Template of its own."""
        return DefTemplate(self, getattr(self.module, "render_%s" % name))
    

class ModuleTemplate(Template):
    """A Template which is constructed given an existing Python module.
    
        e.g.::
        
        t = Template("this is a template")
        f = file("mymodule.py", "w")
        f.write(t.code)
        f.close()
        
        import mymodule
        
        t = ModuleTemplate(mymodule)
        print t.render()
    
    """
    
    def __init__(self, module, 
        module_filename=None, 
        template=None, template_filename=None, 
        module_source=None, template_source=None,
        output_encoding=None, encoding_errors='strict', disable_unicode=False, format_exceptions=False,
        error_handler=None, lookup=None, cache_type=None, cache_dir=None, cache_url=None, cache_enabled=True
    ):
        self.module_id = re.sub(r'\W', "_", module._template_uri)
        self.uri = module._template_uri
        self.input_encoding = module._source_encoding
        self.output_encoding = output_encoding
        self.encoding_errors = encoding_errors
        self.disable_unicode = disable_unicode
        self.module = module
        self.filename = template_filename
        ModuleInfo(module, module_filename, self, template_filename, module_source, template_source)
        
        self.callable_ = self.module.render_body
        self.format_exceptions = format_exceptions
        self.error_handler = error_handler
        self.lookup = lookup
        self.cache_type = cache_type
        self.cache_dir = cache_dir
        self.cache_url = cache_url
        self.cache_enabled = cache_enabled
        
class DefTemplate(Template):
    """a Template which represents a callable def in a parent template."""
    def __init__(self, parent, callable_):
        self.parent = parent
        self.callable_ = callable_
        self.output_encoding = parent.output_encoding
        self.encoding_errors = parent.encoding_errors
        self.format_exceptions = parent.format_exceptions
        self.error_handler = parent.error_handler
        self.lookup = parent.lookup

    def get_def(self, name):
        return self.parent.get_def(name)

class ModuleInfo(object):
    """stores information about a module currently loaded into memory,
    provides reverse lookups of template source, module source code based on
    a module's identifier."""
    _modules = weakref.WeakValueDictionary()

    def __init__(self, module, module_filename, template, template_filename, module_source, template_source):
        self.module = module
        self.module_filename = module_filename
        self.template_filename = template_filename
        self.module_source = module_source
        self.template_source = template_source
        self._modules[module.__name__] = template._mmarker = self
        if module_filename:
            self._modules[module_filename] = self
    def _get_code(self):
        if self.module_source is not None:
            return self.module_source
        else:
            return file(self.module_filename).read()
    code = property(_get_code)
    def _get_source(self):
        if self.template_source is not None:
            if self.module._source_encoding and not isinstance(self.template_source, unicode):
                return self.template_source.decode(self.module._source_encoding)
            else:
                return self.template_source
        else:
            if self.module._source_encoding:
                return file(self.template_filename).read().decode(self.module._source_encoding)
            else:
                return file(self.template_filename).read()
    source = property(_get_source)
        
def _compile_text(template, text, filename):
    identifier = template.module_id
    lexer = Lexer(text, filename, disable_unicode=template.disable_unicode, input_encoding=template.input_encoding, preprocessor=template.preprocessor)
    node = lexer.parse()
    source = codegen.compile(node, template.uri, filename, default_filters=template.default_filters, buffer_filters=template.buffer_filters, imports=template.imports, source_encoding=lexer.encoding, generate_unicode=not template.disable_unicode)
    #print source
    cid = identifier
    if isinstance(cid, unicode):
        cid = cid.encode()
    module = types.ModuleType(cid)
    code = compile(source, cid, 'exec')
    exec code in module.__dict__, module.__dict__
    return (source, module)

def _compile_module_file(template, text, filename, outputpath):
    identifier = template.module_id
    lexer = Lexer(text, filename, disable_unicode=template.disable_unicode, input_encoding=template.input_encoding, preprocessor=template.preprocessor)
    node = lexer.parse()
    source = codegen.compile(node, template.uri, filename, default_filters=template.default_filters, buffer_filters=template.buffer_filters, imports=template.imports, source_encoding=lexer.encoding, generate_unicode=not template.disable_unicode)
    (dest, name) = tempfile.mkstemp()
    os.write(dest, source)
    os.close(dest)
    shutil.move(name, outputpath)

def _get_module_info_from_callable(callable_):
    return _get_module_info(callable_.func_globals['__name__'])
    
def _get_module_info(filename):
    return ModuleInfo._modules[filename]
        
