view makeitso/template.py @ 58:112bf081148c

make a full CLI class for a single API template
author Jeff Hammel <jhammel@mozilla.com>
date Thu, 06 Jan 2011 15:54:55 -0800
parents 728cae02a6ed
children 30100690ad3f
line wrap: on
line source

"""
basic API template class
"""

import os
import sys
from makeitso import ContentTemplate
from makeitso import PolyTemplate

class Undefined(object):
    """marker class for variables"""
Undefined = Undefined() # singleton

class Variable(object):
    """variable object for MakeItSo templates"""
    
    def __init__(self, name, description=None, default=Undefined,
                 cast=None):
        self.name = name
        self.default = default
        self.description = description

        # TODO (maybe): get cast from default variable type if not None
        self.cast = cast

        self._set = False

    def set(self, value):
        if self.cast:
            self.value = self.cast(value)
        else:
            self.value = value
        self._set = True

    def read(self, fd=sys.stdout):
        """prompt and read the variable from stdin"""
        fd.write(self.display())
        self.set(raw_input())

    def display(self):
        description = self.description or self.name
        if self.default:
            return 'Enter %s [DEFAULT: %s]:' % (description, repr(self.default))
        else:
            return 'Enter %s:' % description

class MakeItSoTemplate(ContentTemplate):
    """API template for MakeItSo"""

    # name of the template
    name = ''

    # description of the template
    description = ''

    # templates to interpolate
    # paths are relative to __file__ unless absolute or URIs
    templates = []

    # variables
    vars = []

    # inspect the templates for more variables
    look = False

    def __init__(self, output=None, interactive=True, usedefaults=True,
                 variables=None):
        """
        - output : output file or directory
        - interactive : whether tointeractively get variables
        - usedefaults : try to use the default values if not specified
        """
        
        assert self.templates
        self.output = output
        self.interactive = interactive
        self.location = os.path.dirname(os.path.abspath(__file__))
        self.defaults = variables.copy()

        # make a dictionary of the variables for lookup convenience
        self.vardict = {}
        for i in self.vars:
            self.vardict[i.name] = i

        # ensure all of these templates exist
        for template in self.templates:
            if template.startswith('http://') or template.startswith('https://'):
                continue
            if os.path.isabs(template):
                path = template
            else:
                path = os.path.join(self.location, template)
            assert os.path.exists(template)

    def missing(self, **variables):
        if self.look:
            pass
        else:
            if self.usedefaults:
                pass

    def pre(self, **variables):
        """do stuff before interpolation"""

    def substitute(self, **variables):
        """do the substitution"""
        vars = self.get_variables(**variables)
        self.pre(**variables)
        self.check_missing(vars)
        self.post(**variables)

    def post(self, **variables):
        """do stuff after interpolation"""
        
    def read_variables(self, variables):
        """read variables from stdin"""
        retval = {}
        for i in variables:
            if i in self.vardict:
                self.vardict[i].read()
            else:
                retval.update(ContentTemplate.read_variables(self, (i,)))
        return retval

class PasteScriptTemplate(MakeItSoTemplate):
    """template for backwards compatability with PasteScript"""