""" The mako """

import logging
import os
import projex

logger = logging.getLogger(__name__)

try:
    import mako
    import mako.template
    import mako.lookup

except ImportError:
    logger.warning('The projex.makotext package requires mako to be installed.')
    mako = None

# import useful modules for the template
from datetime import datetime, date
import projex.text

_macros = {}


def register(macro):
    """
    Registers a macro method for the mako text rendering system.
    
    :param      macro | <method>
    """
    _macros[macro.__name__] = macro


def renderfile(filename,
               options=None,
               templatePaths=None,
               default='',
               silent=False):
    """
    Renders a file to text using the mako template system.
    
    To learn more about mako and its usage, see [[www.makotemplates.org]]
    
    :return     <str> formatted text
    """
    if not mako:
        logger.debug('mako is not installed')
        return default

    if not mako:
        logger.debug('mako is not installed.')
        return default

    if templatePaths is None:
        templatePaths = []

    # use the default mako templates
    basepath = os.environ.get('MAKO_TEMPLATEPATH', '')
    if basepath:
        basetempls = basepath.split(os.path.pathsep)
    else:
        basetempls = []

    templatePaths += basetempls

    # include the root path
    templatePaths.insert(0, os.path.dirname(filename))
    templatePaths = map(lambda x: x.replace('\\', '/'), templatePaths)

    # update the default options
    scope = dict(os.environ)

    scope['projex_text'] = projex.text
    scope['date'] = date
    scope['datetime'] = datetime
    scope.update(_macros)
    scope.update(os.environ)

    if options is not None:
        scope.update(options)

    old_env_path = os.environ.get('MAKO_TEMPLATEPATH', '')
    os.environ['MAKO_TEMPLATEPATH'] = os.path.pathsep.join(templatePaths)

    logger.debug('rendering mako file: %s', filename)
    if templatePaths:
        lookup = mako.lookup.TemplateLookup(directories=templatePaths)
        templ = mako.template.Template(filename=filename, lookup=lookup)
    else:
        templ = mako.template.Template(filename=filename)

    try:
        output = templ.render(**scope)
    except StandardError:
        output = default
        if not silent:
            logger.exception('Error rendering mako text')

    os.environ['MAKO_TEMPLATEPATH'] = old_env_path

    return output


def render(text,
           options=None,
           templatePaths=None,
           default=None,
           silent=False,
           raiseErrors=False):
    """
    Renders a template text to a resolved text value using the mako template
    system.
    
    Provides a much more robust template option to the projex.text system.  
    While the projex.text method can handle many simple cases with no
    dependencies, the makotext module makes use of the powerful mako template
    language.  This module provides a simple wrapper to the mako code.
    
    To learn more about mako and its usage, see [[www.makotemplates.org]]
    
    :param      text        <str>
    :param      options     <dict> { <str> key: <variant> value, .. }
    
    :return     <str> formatted text
    
    :usage      |import projex.makotext
                |options = { 'key': 10, 'name': 'eric' }
                |template = '${name.lower()}_${key}_${date.today()}.txt'
                |projex.makotext.render( template, options )
    """
    if not mako:
        logger.debug('mako is not installed.')
        return text if default is None else default

    if templatePaths is None:
        templatePaths = []

    # use the default mako templates
    basepath = os.environ.get('MAKO_TEMPLATEPATH', '')
    if basepath:
        basetempls = basepath.split(os.path.pathsep)
    else:
        basetempls = []

    templatePaths += basetempls

    # update the default options
    scope = dict(os.environ)

    scope['projex_text'] = projex.text
    scope['date'] = date
    scope['datetime'] = datetime
    scope.update(_macros)

    if options is not None:
        scope.update(options)

    if templatePaths:
        lookup = mako.lookup.TemplateLookup(directories=templatePaths)
        try:
            templ = mako.template.Template(text, lookup=lookup)
        except StandardError:
            output = text if default is None else default
            if not silent:
                logger.exception('Error compiling mako text')
            return output
    else:
        try:
            templ = mako.template.Template(text)
        except StandardError:
            output = text if default is None else default
            if not silent:
                logger.exception('Error compiling mako text')
            return output

    try:
        output = templ.render(**scope)
    except StandardError:
        if raiseErrors:
            raise
        output = text if default is None else default
        if not silent:
            logger.exception('Error rendering mako text')
        return output

    return output


def unregister(method):
    """
    Unregisters the given macro from the system.
    
    :param      name | <str>
    """
    _macros.pop(method.__name__, None)


# ----------------------------------------------------------------------
# register some macros
# ----------------------------------------------------------------------

def collectfiles(path, filt=None):
    """
    Collects some files based on the given filename.
    
    :param      path | <str>
                filt | <method>
        
    :return     [(<str> name, <str> filepath), ..]
    """
    if not os.path.isdir(path):
        path = os.path.dirname(path)

    output = []
    for name in sorted(os.listdir(path)):
        filepath = os.path.join(path, name)
        if os.path.isfile(filepath):
            if not filt or filt(name):
                output.append((name, filepath))
    return output


register(collectfiles)
""" The mako """

import logging
import os
import projex

logger = logging.getLogger(__name__)

try:
    import mako
    import mako.template
    import mako.lookup

except ImportError:
    logger.warning('The projex.makotext package requires mako to be installed.')
    mako = None

# import useful modules for the template
from datetime import datetime, date
import projex.text

_macros = {}


def register(macro):
    """
    Registers a macro method for the mako text rendering system.
    
    :param      macro | <method>
    """
    _macros[macro.__name__] = macro


def renderfile(filename,
               options=None,
               templatePaths=None,
               default='',
               silent=False):
    """
    Renders a file to text using the mako template system.
    
    To learn more about mako and its usage, see [[www.makotemplates.org]]
    
    :return     <str> formatted text
    """
    if not mako:
        logger.debug('mako is not installed')
        return default

    if not mako:
        logger.debug('mako is not installed.')
        return default

    if templatePaths is None:
        templatePaths = []

    # use the default mako templates
    basepath = os.environ.get('MAKO_TEMPLATEPATH', '')
    if basepath:
        basetempls = basepath.split(os.path.pathsep)
    else:
        basetempls = []

    templatePaths += basetempls

    # include the root path
    templatePaths.insert(0, os.path.dirname(filename))
    templatePaths = map(lambda x: x.replace('\\', '/'), templatePaths)

    # update the default options
    scope = dict(os.environ)

    scope['projex_text'] = projex.text
    scope['date'] = date
    scope['datetime'] = datetime
    scope.update(_macros)
    scope.update(os.environ)

    if options is not None:
        scope.update(options)

    old_env_path = os.environ.get('MAKO_TEMPLATEPATH', '')
    os.environ['MAKO_TEMPLATEPATH'] = os.path.pathsep.join(templatePaths)

    logger.debug('rendering mako file: %s', filename)
    if templatePaths:
        lookup = mako.lookup.TemplateLookup(directories=templatePaths)
        templ = mako.template.Template(filename=filename, lookup=lookup)
    else:
        templ = mako.template.Template(filename=filename)

    try:
        output = templ.render(**scope)
    except StandardError:
        output = default
        if not silent:
            logger.exception('Error rendering mako text')

    os.environ['MAKO_TEMPLATEPATH'] = old_env_path

    return output


def render(text,
           options=None,
           templatePaths=None,
           default=None,
           silent=False,
           raiseErrors=False):
    """
    Renders a template text to a resolved text value using the mako template
    system.
    
    Provides a much more robust template option to the projex.text system.  
    While the projex.text method can handle many simple cases with no
    dependencies, the makotext module makes use of the powerful mako template
    language.  This module provides a simple wrapper to the mako code.
    
    To learn more about mako and its usage, see [[www.makotemplates.org]]
    
    :param      text        <str>
    :param      options     <dict> { <str> key: <variant> value, .. }
    
    :return     <str> formatted text
    
    :usage      |import projex.makotext
                |options = { 'key': 10, 'name': 'eric' }
                |template = '${name.lower()}_${key}_${date.today()}.txt'
                |projex.makotext.render( template, options )
    """
    if not mako:
        logger.debug('mako is not installed.')
        return text if default is None else default

    if templatePaths is None:
        templatePaths = []

    # use the default mako templates
    basepath = os.environ.get('MAKO_TEMPLATEPATH', '')
    if basepath:
        basetempls = basepath.split(os.path.pathsep)
    else:
        basetempls = []

    templatePaths += basetempls

    # update the default options
    scope = dict(os.environ)

    scope['projex_text'] = projex.text
    scope['date'] = date
    scope['datetime'] = datetime
    scope.update(_macros)

    if options is not None:
        scope.update(options)

    if templatePaths:
        lookup = mako.lookup.TemplateLookup(directories=templatePaths)
        try:
            templ = mako.template.Template(text, lookup=lookup)
        except StandardError:
            output = text if default is None else default
            if not silent:
                logger.exception('Error compiling mako text')
            return output
    else:
        try:
            templ = mako.template.Template(text)
        except StandardError:
            output = text if default is None else default
            if not silent:
                logger.exception('Error compiling mako text')
            return output

    try:
        output = templ.render(**scope)
    except StandardError:
        if raiseErrors:
            raise
        output = text if default is None else default
        if not silent:
            logger.exception('Error rendering mako text')
        return output

    return output


def unregister(method):
    """
    Unregisters the given macro from the system.
    
    :param      name | <str>
    """
    _macros.pop(method.__name__, None)


# ----------------------------------------------------------------------
# register some macros
# ----------------------------------------------------------------------

def collectfiles(path, filt=None):
    """
    Collects some files based on the given filename.
    
    :param      path | <str>
                filt | <method>
        
    :return     [(<str> name, <str> filepath), ..]
    """
    if not os.path.isdir(path):
        path = os.path.dirname(path)

    output = []
    for name in sorted(os.listdir(path)):
        filepath = os.path.join(path, name)
        if os.path.isfile(filepath):
            if not filt or filt(name):
                output.append((name, filepath))
    return output


register(collectfiles)
The mako # import useful modules for the template Registers a macro method for the mako text rendering system.          :param      macro | <method> Renders a file to text using the mako template system.          To learn more about mako and its usage, see [[www.makotemplates.org]]          :return     <str> formatted text # use the default mako templates # include the root path # update the default options Renders a template text to a resolved text value using the mako template     system.          Provides a much more robust template option to the projex.text system.       While the projex.text method can handle many simple cases with no     dependencies, the makotext module makes use of the powerful mako template     language.  This module provides a simple wrapper to the mako code.          To learn more about mako and its usage, see [[www.makotemplates.org]]          :param      text        <str>     :param      options     <dict> { <str> key: <variant> value, .. }          :return     <str> formatted text          :usage      |import projex.makotext                 |options = { 'key': 10, 'name': 'eric' }                 |template = '${name.lower()}_${key}_${date.today()}.txt'                 |projex.makotext.render( template, options ) # use the default mako templates # update the default options Unregisters the given macro from the system.          :param      name | <str> # ---------------------------------------------------------------------- # register some macros # ---------------------------------------------------------------------- Collects some files based on the given filename.          :param      path | <str>                 filt | <method>              :return     [(<str> name, <str> filepath), ..]