0001import inspect
0002
0003def capture_params(method, after=None):
0004
0005    def f(params):
0006        return params
0007    if after == None:
0008        after = f
0009
0010    def getValue(*k, **p):
0011        args, ks, ps, defaults = inspect.getargspec(method.im_func)
0012        final = {}
0013        # Which have no defaults
0014        nodefaults = []
0015        if defaults:
0016            nodefaults = args[1:-len(defaults)]
0017
0018        # Out of these which are specified by params
0019        for key, value in p.items():
0020            if key in nodefaults:
0021                nodefaults.pop(nodefaults.index(key))
0022        # We are left with words with no defaults and no params, these should correspond to the keywords:
0023        if len(k) < len(nodefaults):
0024            raise TypeError('Required parameter %s not specified.'%(repr(nodefaults[len(k):len(k)+1][0])))
0025        elif len(k) > len(nodefaults):
0026            overridedefaults = defaults[:len(k)]
0027            names = args[-len(defaults):][:len(k)-len(nodefaults)]
0028            counter = 0
0029            for name in names:
0030                if name in p.keys():
0031                    raise TypeError('Keyword and named parameter specified for %s'%repr(name))
0032                else:
0033                    final[name] = k[len(k)-len(nodefaults):][counter]
0034            for i in range(len(nodefaults)):
0035                final[args[i+1]] = k[i]
0036        else:
0037            # Assuming all is well we now know the parameters, defaults and keywords
0038            for i in range(len(k)):
0039                final[args[i+1]] = k[i]
0040        # That's the keywords sorted, now for the params
0041        for key, value in p.items():
0042            final[key] = value
0043        return after(final)
0044    return getValue
0045
0046class ModifierBase:
0047    pass
0048
0049class Build(ModifierBase):
0050    """Just returns the params entered"""
0051    def __init__(self, *objects):
0052        self._fields = Combine(*objects)
0053
0054    def __call__(self, form):
0055        self._fields(form)
0056
0057    def __getattr__(self, name):
0058        method = getattr(self._fields, name)
0059        return capture_params(method)
0060
0061class Capture(ModifierBase):
0062    def __init__(self, *objects):
0063        self._fields = None
0064        self._fields = Combine(*objects)
0065        self.captured = []
0066
0067    def __call__(self, form):
0068        self._fields(form)
0069
0070    def __getattr__(self, name):
0071        method = getattr(self._fields, name)
0072        def func(params):
0073            self.captured.append([method.im_class.type+'.'+name, params])
0074            return None #method(**params)
0075        return capture_params(getattr(self._fields, name), func)
0076
0077class CaptureAndReturn(Capture):
0078    """
0079    Capture the parameters and return them
0080    """
0081    def __getattr__(self, name):
0082        method = getattr(self._fields, name)
0083        def func(params):
0084            self.captured.append([method.im_class.type+'.'+name, params])
0085            return method(**params)
0086        return capture_params(getattr(self._fields, name), func)
0087
0088class Combine(ModifierBase):
0089    def __init__(self, *objects):
0090        self._objects = objects
0091        self.names = ''
0092        for object in self.__dict__['_objects']:
0093            self.names += object.__class__.__name__ + ', '
0094        if self.names:
0095            self.names = self.names[:-2]
0096
0097    def __call__(self, form):
0098        self.form = form
0099        in_objects = []
0100        for object in self.__dict__['_objects']:
0101            in_objects.append(object(form))
0102        #self.__dict__['_objects'] = in_objects
0103
0104    def __getattr__(self, name):
0105        for object in self.__dict__['_objects']:
0106            if hasattr(object, name):
0107                return getattr(object, name)
0108        raise AttributeError('Method %s could not be found in any of the combined classes %s'%(repr(name), self.names))
0109
0110class Frozen(ModifierBase):
0111    def __init__(self, *objects):
0112        self._fields = Combine(*objects)
0113
0114    def __call__(self, form):
0115        self._fields(form)
0116
0117    def __getattr__(self, name):
0118        # We only want the value from the method, not the rest
0119        def func(params):
0120            value = None
0121            if params.has_key('value'):
0122                value = params['value']
0123            else:
0124                value = self._fields.form.get_default(params['name'])
0125            if value == None:
0126                return ''
0127            else:
0128                return str(value)
0129        return capture_params(getattr(self._fields, name), func)