1# Copyright (c) 2004 Divmod. 2# See LICENSE for details. 3 4from __future__ import generators 5 6from zope.interface import implements 7 8from twisted.python import components 9 10from nevow import inevow 11from nevow import tags 12 13from formless import iformless 14 15 16try: 17 enumerate = enumerate 18except: 19 def enumerate(collection): 20 i = 0 21 it = iter(collection) 22 while 1: 23 yield (i, it.next()) 24 i += 1 25 26 27class PrefixerDict(dict): 28 def __init__(self, prefix, errors): 29 if prefix is None: prefix = '' 30 self.prefix = prefix 31 self.errors = errors 32 dict.__init__(self) 33 34 def __setitem__(self, key, value): 35 if key is None: 36 key = '' 37 if key == '': 38 pfxkey = self.prefix 39 else: 40 pfxkey = '.'.join((self.prefix, key)) 41 self.errors[pfxkey] = value 42 43 def __getitem__(self, key): 44 if key == '': 45 pfxkey = self.prefix 46 else: 47 pfxkey = '.'.join((self.prefix, key)) 48 return self.errors[pfxkey] 49 50 def update(self, other): 51 for key, value in other.items(): 52 self[key] = value 53 54 55class FormDefaults(components.Adapter): 56 def __init__(self): 57 self.defaults = {} 58 59 def setDefault(self, key, value, context=None): 60 self.defaults[key] = value 61 62 def getDefault(self, key, context=None): 63 #print "getting default for key", key, self.defaults 64 # 1) Check on the request 65 current = self.defaults.get(key, None) 66 if current is None: 67 # 2) Check on the session 68 if context is not None: 69 sessionDefaults = context.locate(iformless.IFormDefaults) 70 if sessionDefaults is not self: 71 current = sessionDefaults.getDefault(key) 72 if current is not None: 73 return current 74 # 3) Ask the Binding instance for the default values 75 try: 76 configurable = context.locate(iformless.IConfigurable) 77 except KeyError: 78 return '' 79 return configurable.getDefault(context.locate(inevow.IData)) 80 return current 81 82 def getAllDefaults(self, key): 83 return PrefixerDict(key, self.defaults) 84 85 def clearAll(self): 86 self.defaults = {} 87 88 89class FormErrors(components.Adapter): 90 """An object which keeps track of which forms have which errors 91 """ 92 implements(iformless.IFormErrors) 93 def __init__(self): 94 self.errors = {} 95 96 def setError(self, errorKey, error): 97 self.errors[errorKey] = error 98 99 def getError(self, errorKey): 100 #print "get error", errorKey, self.__dict__ 101 return self.errors.get(errorKey) 102 103 def getAllErrors(self, formName): 104 return PrefixerDict(formName, self.errors) 105 106 def updateErrors(self, formName, errors): 107 PrefixerDict(formName, self.errors).update(errors) 108 109 def clearErrors(self, formName): 110 for key in self.errors.keys(): 111 if key.startswith(formName): 112 del self.errors[key] 113 114 def clearAll(self): 115 self.errors = {} 116 117def calculatePostURL(context, data): 118 postLocation = inevow.ICurrentSegments(context)[-1] 119 if postLocation == '': 120 postLocation = '.' 121 try: 122 configurableKey = context.locate(iformless.IConfigurableKey) 123 except KeyError: 124 #print "IConfigurableKey was not remembered when calculating full binding name for %s in node %s" % (configurable, context.key) 125 configurableKey = '' 126 bindingName = context.key 127 return "%s/freeform_post!%s!%s" % (postLocation, configurableKey, bindingName) 128 129 130def keyToXMLID(key): 131 """Convert a key into an XML-styleinevow.ID """ 132 if not key: 133 #print 'keyToXMLID: no key, but why?' 134 return '***Error: Unset***' 135 return '-'.join(key.split('.')) 136 137 138def getError(context): 139 errors = context.locate(iformless.IFormErrors) 140 err = errors.getError(context.key) 141 if err is not None: 142 return err 143 return tags.comment["\nNo error for error key: %s\n" % context.key] 144