Changeset 308
- Timestamp:
- 03/14/08 16:26:40 (9 months ago)
- Files:
-
- trunk/bin/domainmodel-test (modified) (1 diff)
- trunk/setup.py (modified) (1 diff)
- trunk/src/dm/accesscontrol.py (modified) (12 diffs)
- trunk/src/dm/application.py (modified) (1 diff)
- trunk/src/dm/applicationtest.py (modified) (1 diff)
- trunk/src/dm/db.py (modified) (5 diffs)
- trunk/src/dm/dictionary.py (modified) (3 diffs)
- trunk/src/dm/dictionarywords.py (modified) (1 diff)
- trunk/src/dm/djangotest.py (modified) (1 diff)
- trunk/src/dm/dom/meta.py (modified) (1 diff)
- trunk/src/dm/dom/registry.py (modified) (3 diffs)
- trunk/src/dm/dom/session.py (modified) (2 diffs)
- trunk/src/dm/exceptions.py (modified) (1 diff)
- trunk/src/dm/logtest.py (modified) (1 diff)
- trunk/src/dm/migrate.py (modified) (9 diffs)
- trunk/src/dm/pylons (added)
- trunk/src/dm/pylons/__init__.py (added)
- trunk/src/dm/pylonstest.py (added)
- trunk/src/dm/test.py (modified) (2 diffs)
- trunk/src/dm/testunit.py (modified) (4 diffs)
- trunk/src/dm/util/datastructure.py (modified) (1 diff)
- trunk/src/dm/util/html.py (modified) (1 diff)
- trunk/src/dm/util/http.py (modified) (1 diff)
- trunk/src/dm/util/manipulator.py (modified) (1 diff)
- trunk/src/dm/util/template.py (modified) (1 diff)
- trunk/src/dm/view/base.py (modified) (6 diffs)
- trunk/src/dm/view/basetest.py (modified) (4 diffs)
- trunk/src/dm/view/manipulator.py (modified) (10 diffs)
- trunk/src/dm/view/registry.py (modified) (6 diffs)
- trunk/src/dm/view/registrytest.py (modified) (4 diffs)
- trunk/src/dm/webkit (added)
- trunk/src/dm/webkit/__init__.py (added)
- trunk/src/dm/webkit/context.py (added)
- trunk/src/dm/webkittest.py (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/bin/domainmodel-test
r228 r308 39 39 os.environ['DOMAINMODEL_SETTINGS'] = options.config 40 40 41 # import after SETTINGS is set 42 from dm.testunit import ApplicationTestSuite 43 ApplicationTestSuite.buildApplication() 41 import dm.testunit 42 dm.testunit.DevApplication() 44 43 45 44 (options, args) = parser.parse_args() trunk/setup.py
r246 r308 16 16 # no way to specify the dependency on django as we need a specific revision 17 17 install_requires = [ 18 'SQLObject>=0. 6,<=0.7.99',18 'SQLObject>=0.7.1,<=0.7.99', 19 19 'simplejson', 20 20 # 'Django>=0.95' # Django not served on cheese shop trunk/src/dm/accesscontrol.py
r246 r308 3 3 from dm.dictionarywords import VISITOR_NAME 4 4 from dm.strategy import FindProtectionObjects 5 6 moddebug = False 5 7 6 8 class BaseAccessController(object): … … 55 57 self.assertAccessAuthorised() 56 58 except AccessIsAuthorised, inst: 57 if self.debug:59 if moddebug and self.debug: 58 60 if self.person: 59 61 personName = self.person.name … … 69 71 return True 70 72 except AccessNotAuthorised, inst: 71 if self.debug:73 if moddebug and self.debug: 72 74 if self.person: 73 75 personName = self.person.name … … 85 87 86 88 def logAccessAttempt(self, person, actionName, protectedObject): 87 if self.debug:89 if moddebug and self.debug: 88 90 if person: 89 91 personName = person.name … … 130 132 def isRoleAuthorised(self, role): 131 133 if self.isPermissionGranted(role.grants): 132 if self.debug:134 if moddebug and self.debug: 133 135 msg = "Access authorised by '%s' associated role." % ( 134 136 role.name … … 137 139 return True 138 140 else: 139 if self.debug:141 if moddebug and self.debug: 140 142 msg = "Access not authorised by '%s' associated role." % ( 141 143 role.name … … 203 205 def isPersonBarred(self): 204 206 if self.isPermissionGranted(self.person.bars): 205 if self.debug:207 if moddebug and self.debug: 206 208 msg = "Access personally barred." 207 209 self.logger.debug(msg) 208 210 return True 209 211 else: 210 if self.debug:212 if moddebug and self.debug: 211 213 msg = "Access not personally barred." 212 214 self.logger.debug(msg) … … 215 217 def isVisitorBarred(self): 216 218 if self.isPermissionGranted(self.getVisitor().bars): 217 if self.debug:219 if moddebug and self.debug: 218 220 msg = "Access barred to visitor." 219 221 self.logger.debug(msg) 220 222 return True 221 223 else: 222 if self.debug:224 if moddebug and self.debug: 223 225 msg = "Access not barred to visitor." 224 226 self.logger.debug(msg) … … 227 229 def isPersonAuthorisedPersonally(self): 228 230 if self.isPermissionGranted(self.person.grants): 229 if self.debug:231 if moddebug and self.debug: 230 232 msg = "Access authorised by personal role." 231 233 self.logger.debug(msg) 232 234 return True 233 235 else: 234 if self.debug:236 if moddebug and self.debug: 235 237 msg = "Access not authorised by personal role." 236 238 self.logger.debug(msg) … … 239 241 def isVisitorAuthorisedPersonally(self): 240 242 if self.isPermissionGranted(self.getVisitor().grants): 241 if self.debug:243 if moddebug and self.debug: 242 244 msg = "Access authorised by visitor personal role." 243 245 self.logger.debug(msg) 244 246 return True 245 247 else: 246 if self.debug:248 if moddebug and self.debug: 247 249 msg = "Access not authorised by visitor personal role." 248 250 self.logger.debug(msg) … … 253 255 roleName = getattr(systemRole, 'name', '') 254 256 if self.isPermissionGranted(systemRole.grants): 255 if self.debug:257 if moddebug and self.debug: 256 258 msg = "Access authorised by '%s' system role." % roleName 257 259 self.logger.debug(msg) 258 260 return True 259 261 else: 260 if self.debug:262 if moddebug and self.debug: 261 263 msg = "Access not authorised by '%s' system role." % roleName 262 264 self.logger.debug(msg) … … 266 268 systemRole = self.getVisitorSystemRole() 267 269 if self.isPermissionGranted(systemRole.grants): 268 if self.debug:270 if moddebug and self.debug: 269 271 msg = "Access authorised by visitor's system role." 270 272 self.logger.debug(msg) 271 273 return True 272 274 else: 273 if self.debug:275 if moddebug and self.debug: 274 276 msg = "Access not authorised by visitor's system role." 275 277 self.logger.debug(msg) trunk/src/dm/application.py
r296 r308 1 1 from dm.ioc import * 2 2 from dm.builder import ApplicationBuilder 3 from dm.testunit import ApplicationBuilder4 3 5 4 class Application(object): trunk/src/dm/applicationtest.py
r2 r308 2 2 from dm.ioc import * 3 3 import unittest 4 5 features.allowReplace = True6 4 7 5 def suite(): trunk/src/dm/db.py
r307 r308 416 416 return style.pythonAttrToDBColumn(naiveName) 417 417 418 def makeSafeDbName(self, na iveName):419 if na iveName.upper() in self.getReservedNames():420 na iveName = 'x' + naiveName421 return self.makeSafeDbName(naiveName)422 else:423 return naiveName418 def makeSafeDbName(self, name): 419 if name.upper() in self.getReservedNames(): 420 name = 'x' + name 421 if name != self.makeSafeDbName(name): 422 raise Exception, "Can't make this name safe: %s" % name 423 return name 424 424 425 425 def getReservedNames(self): … … 840 840 recordedLen = len(recordedList) 841 841 actualLen = len(actualList) 842 print "Checking association list values for changes..."843 print "Recorded: %s, actual: %s)...." % (recordedLen, actualLen)842 #print "Checking association list values for changes..." 843 #print "Recorded: %s, actual: %s)...." % (recordedLen, actualLen) 844 844 if recordedLen == actualLen: 845 845 for i in recordedList: 846 846 if i.recordedValue not in actualList: 847 print "Missing item: %s" % i.recordedValue847 #print "Missing item: %s" % i.recordedValue 848 848 isChangedTemporal = True 849 849 break 850 else:851 print "Found item in record: %s" % i.recordedValue850 #else: 851 # print "Found item in record: %s" % i.recordedValue 852 852 if isChangedTemporal: 853 853 break 854 854 else: 855 print "Length mismatch!"855 #print "Length mismatch!" 856 856 isChangedTemporal = True 857 857 break … … 864 864 break 865 865 if isChangedTemporal: 866 print "Is changed!!!!!!! Creating new current version of associate list."866 #print "Is changed!!!!!!! Creating new current version of associate list." 867 867 loadedList = {self.domainObject: self.domainObject} 868 868 history = self.domainObject.temporalHistory … … 878 878 recordedLen = len(recordedList) 879 879 actualLen = len(actualList) 880 print "Checking association list values for changes..."881 print "Recorded: %s, actual: %s)...." % (recordedLen, actualLen)880 #print "Checking association list values for changes..." 881 #print "Recorded: %s, actual: %s)...." % (recordedLen, actualLen) 882 882 if recordedLen == actualLen: 883 883 for i in recordedList: 884 884 if i.recordedValue not in actualList: 885 print "Missing item: %s" % i.recordedValue885 #print "Missing item: %s" % i.recordedValue 886 886 isListChanged = True 887 887 break 888 else:889 print "Found item in record: %s" % i.recordedValue888 #else: 889 # print "Found item in record: %s" % i.recordedValue 890 890 else: 891 print "Length mismatch!"891 #print "Length mismatch!" 892 892 isListChanged = True 893 893 894 894 if isListChanged: 895 print "List is changed...."895 #print "List is changed...." 896 896 for item in actualRegister: 897 print "Adding list item to temporal record: %s" % item897 #print "Adding list item to temporal record: %s" % item 898 898 key = actualRegister.getRegisterKey(item) 899 899 try: … … 902 902 recordedKey=key 903 903 ) 904 print "Created: %s" % listItem904 #print "Created: %s" % listItem 905 905 906 906 except TypeError, inst: 907 907 msg = "Couldn't add item %s with key %s to temporal associate list register %s: %s" % (item, key, recordedRegister, inst) 908 print msg908 #print msg 909 909 raise Exception, msg 910 print "Recorded register now: %s" % [i for i in recordedRegister]910 #print "Recorded register now: %s" % [i for i in recordedRegister] 911 911 912 912 for metaAttr in self.meta.attributes: trunk/src/dm/dictionary.py
r237 r308 25 25 self.initTimezone() 26 26 self.validateDictionaryWords() 27 self.assertWebkitEnvironment() 27 28 28 29 def assertSystemName(self): … … 31 32 32 33 def assertSystemEnvironment(self): 33 self.environment.assertDjangoSettingsModule() 34 pass 35 36 def assertWebkitEnvironment(self): 37 if self[WEBKIT_NAME] == 'django': 38 self.environment.assertDjangoSettingsModule() 34 39 35 40 def setDefaultWords(self): … … 62 67 self[DJANGO_SECRET_KEY] = 'f*(d3d45zetsb3)$&2h5@lua()yc+kfn4w^dmrf_j1i(6jjkq' 63 68 self[EDITOR] = 'editor' 69 self[WEBKIT_NAME] = 'django' 64 70 65 71 def makeConfigFilePath(self): trunk/src/dm/dictionarywords.py
r252 r308 41 41 WWW_PORT = 'www.port' 42 42 IMAGES_DIR_PATH = 'images_dir' 43 WEBKIT_NAME = 'webkit_name' 43 44 DJANGO_SECRET_KEY = 'django.secret_key' 44 45 DJANGO_TEMPLATES_DIR = 'django.templates_dir' 46 PYLONS_SECRET_KEY = 'pylons.secret_key' 47 PYLONS_TEMPLATES_DIR = 'pylons.templates_dir' 45 48 EDITOR = 'editor' trunk/src/dm/djangotest.py
r176 r308 4 4 5 5 def suite(): 6 "Return a TestSuite of dm.db TestCases."7 6 suites = [ 8 7 dm.django.settingstest.suite(), trunk/src/dm/dom/meta.py
r307 r308 715 715 return self.owner.temporalHistory.getCurrent() 716 716 717 717 718 class AssociateList(DomainObjectAssociation): 718 719 "Models aquaintance with several domain objects." trunk/src/dm/dom/registry.py
r306 r308 22 22 23 23 def registerDomainClass(self, domainClass): 24 self.log.debug("Registering domain class: %s" % domainClass) 24 25 baseClass = DomainObject 25 26 if not issubclass(domainClass, baseClass): … … 27 28 domainClassName = domainClass.__name__ 28 29 classRegister = self.getDomainClassRegister() 30 #if domainClassName == 'TemporalObjectExampleHist_grants': 31 # raise domainClassName 29 32 if domainClassName in classRegister: 33 existingClass = classRegister[domainClassName] 30 34 if features.allowReplace: 31 35 return 32 msg = "Domain class '%s' is already defined." % domainClassName 36 msg = "Domain class '%s' is already defined: %s" % ( 37 domainClassName, existingClass 38 ) 33 39 raise Exception, msg 34 40 … … 110 116 'temporalListClassName': temporalListClassName, 111 117 }) 112 self.generateTemporalAssociateListClass(113 temporalMeta, metaAttr, temporalListClassName114 )118 #self.generateTemporalAssociateListClass( 119 # temporalMeta, metaAttr, temporalListClassName 120 #) 115 121 newAttr = AggregatesMany(temporalListClassName,'id','parent') 116 122 else: trunk/src/dm/dom/session.py
r68 r308 5 5 import sys 6 6 import mx.DateTime 7 from dm.dictionarywords import WEBKIT_NAME 8 from dm.dictionarywords import DJANGO_SECRET_KEY 9 from dm.dictionarywords import PYLONS_SECRET_KEY 10 from dm.exceptions import WebkitError 7 11 8 12 class Session(SimpleDatedObject): … … 23 27 def createKey(self): 24 28 "Returns new session key." 25 secretKey = self.dictionary['django.secret_key'] 29 webkitName = self.dictionary[WEBKIT_NAME] 30 if webkitName == 'django': 31 secretKey = self.dictionary[DJANGO_SECRET_KEY] 32 elif webkitName == 'pylons': 33 secretKey = self.dictionary[PYLONS_SECRET_KEY] 34 else: 35 secretKey = 'soso' 26 36 randomStr = str(random.randint(0, sys.maxint - 1)) + secretKey 27 37 return md5.new(randomStr).hexdigest() trunk/src/dm/exceptions.py
r236 r308 16 16 17 17 class MissingPluginSystem(DomainModelApplicationError): pass 18 19 class WebkitError(DomainModelApplicationError): pass 18 20 19 21 # todo: Rework the KForge exception classes. trunk/src/dm/logtest.py
r12 r308 32 32 def testLogWarning(self): 33 33 self.log.warning('Warning logging test. Please ignore this message.') 34 35 def testLogError(self):36 self.log.error('Error logging test. Please ignore this message.')37 38 def testLogCritical(self):39 self.log.critical('Critical logging test. Please ignore this message.')40 34 35 # Todo: Fixup not printing log to STDOUT during the tests. 36 # def testLogError(self): 37 # self.log.error('Error logging test. Please ignore this message.') 38 # 39 # def testLogCritical(self): 40 # self.log.critical('Critical logging test. Please ignore this message.') 41 trunk/src/dm/migrate.py
r306 r308 27 27 classData = {} 28 28 domainClass = domainClassRegister[className] 29 print "Dumping register %s" % className29 #print "Dumping register %s" % className 30 30 # Dumping class meta data 31 31 metaClassData = {} … … 151 151 self.idMap = {} 152 152 for className in self.importOrder: 153 print "Importing %s objects." % className153 #print "Importing %s objects." % className 154 154 domainClass = self.registry.getDomainClass(className) 155 155 classRegister = domainClass.createRegister() … … 167 167 classDataKeys.remove('metaData') 168 168 classDataKeys.sort() 169 print "Iterating over %s %s" % (className, classDataKeys)169 #print "Iterating over %s %s" % (className, classDataKeys) 170 170 for objectId in classDataKeys: 171 171 #if objectId == 'metaData': … … 176 176 className, objectId, objectData 177 177 ) 178 print msg178 #print msg 179 179 strObjectData = {} 180 180 for attr in domainClass.meta.attributes: … … 198 198 mappedValue, 199 199 ) 200 print msg200 #print msg 201 201 value = mappedValue 202 202 if value.__class__ == unicode: … … 213 213 if not domainObject: 214 214 raise Exception("Manipulator has no domain object.") 215 print "Created %s" % domainObject215 #print "Created %s" % domainObject 216 216 if domainObject.id > objectId: 217 217 msg = "Index id %s is ahead of import id %s." % ( 218 218 domainObject.id, objectId 219 219 ) 220 print "Warning: %s" % msg220 #print "Warning: %s" % msg 221 221 raise Exception, msg 222 222 behindWithId = False … … 225 225 domainObject.id 226 226 ) 227 print msg227 #print msg 228 228 domainObject.delete() 229 print " -- deleted"229 #print " -- deleted" 230 230 if hasattr(domainObject, 'purge'): 231 231 domainObject.purge() 232 print " -- purged"232 #print " -- purged" 233 233 elif domainObject.id == objectId: 234 234 #print "Perfect ID match!" … … 238 238 className, strObjectData, inst 239 239 ) 240 print ''241 print msg242 print ''240 #print '' 241 #print msg 242 #print '' 243 243 raise 244 244 … … 251 251 className, objectId 252 252 ) 253 print msg254 print "Importing %s objects completed OK." % className255 print "Imported all domain objects records OK."253 #print msg 254 #print "Importing %s objects completed OK." % className 255 #print "Imported all domain objects records OK." 256 256 257 257 trunk/src/dm/test.py
r296 r308 16 16 import dm.accesscontroltest 17 17 import dm.applicationtest 18 import dm.migratetest 18 19 import dm.viewtest 19 20 import dm.djangotest 20 import dm. migratetest21 import dm.pylonstest 21 22 from dm.testunit import ApplicationTestSuite 22 23 … … 37 38 dm.dictionarytest.suite(), 38 39 dm.commandtest.suite(), 39 #dm.filesystemtest.suite(),40 40 dm.accesscontroltest.suite(), 41 41 dm.viewtest.suite(), 42 dm. applicationtest.suite(),42 dm.migratetest.suite(), 43 43 dm.djangotest.suite(), 44 dm.migratetest.suite(), 44 dm.pylonstest.suite(), 45 #dm.filesystemtest.suite(), 46 #dm.applicationtest.suite(), 45 47 ] 46 48 return ApplicationTestSuite(suites) trunk/src/dm/testunit.py
r305 r308 7 7 8 8 import unittest 9 import dm.builder10 9 from dm.ioc import * 11 import dm.dom.builder 12 13 features.allowReplace = True 10 from dm.dom.builder import ModelBuilder 11 from dm.builder import ApplicationBuilder 12 from dm.application import Application 13 from dm.dictionary import SystemDictionary 14 from dm.dictionarywords import WEBKIT_NAME 14 15 15 16 … … 18 19 19 20 20 class ModelBuilder(dm.dom.builder.ModelBuilder):21 class DevModelBuilder(ModelBuilder): 21 22 22 23 def construct(self): 23 super( ModelBuilder, self).construct()24 super(DevModelBuilder, self).construct() 24 25 self.loadTemporal() 25 26 26 27 def loadTemporal(self): 27 28 from dm.dom.temporaltest import Temporal 29 from dm.dom.temporaltest import TemporalObjectExampleGrant 30 from dm.dom.temporaltest import TemporalObjectExample 31 from dm.dom.temporal import TemporalProperty, BitemporalProperty, BitemporalActual 28 32 self.registry.registerDomainClass(Temporal) 29 from dm.dom.temporaltest import TemporalObjectExampleGrant30 33 self.registry.registerDomainClass(TemporalObjectExampleGrant) 31 from dm.dom.temporaltest import TemporalObjectExample32 34 self.registry.registerDomainClass(TemporalObjectExample) 33 35 self.registry.temporals = Temporal.createRegister() 34 from dm.dom.temporal import TemporalProperty, BitemporalProperty, BitemporalActual35 36 self.registry.registerDomainClass(TemporalProperty) 36 37 self.registry.registerDomainClass(BitemporalProperty) … … 38 39 39 40 40 class ApplicationBuilder(dm.builder.ApplicationBuilder): 41 class DevSystemDictionary(SystemDictionary): 42 43 def setDefaultWords(self): 44 super(DevSystemDictionary, self).setDefaultWords() 45 #self[WEBKIT_NAME] = 'pylons' 46 47 48 class DevApplicationBuilder(ApplicationBuilder): 41 49 42 50 def findModelBuilder(self): 43 return ModelBuilder() 51 return DevModelBuilder() 52 53 def findSystemDictionary(self): 54 return DevSystemDictionary() 55 56 57 class DevApplication(Application): 58 59 builderClass = DevApplicationBuilder 44 60 45 61 46 62 class ApplicationTestSuite(unittest.TestSuite): 47 63 48 appBuilderClass =ApplicationBuilder64 #appBuilderClass = DevApplicationBuilder 49 65 50 def buildApplication(self): 51 appBuilder = self.appBuilderClass() 52 appBuilder.construct() 53 registry = RequiredFeature('DomainRegistry') 54 if registry != None: 55 domBuilder = RequiredFeature('ModelBuilder') 56 domBuilder.construct() 66 def assertDevMode(self): 57 67 dictionary = RequiredFeature('SystemDictionary') 58 68 if dictionary != None: … … 63 73 raise SystemModeError("The system was built in '%s' mode. The system must be built in '%s' mode for the test suite to be run. Please check the 'system_mode' setting in your configuration file '%s' and rebuild the database." % (currentSystem.mode, requiredSystemModeName, configFilePath)) 64 74 65 buildApplication = classmethod(buildApplication)75 assertDevMode = classmethod(assertDevMode) 66 76 67 77 trunk/src/dm/util/datastructure.py
r204 r308 1 from django.utils.datastructures import MultiValueDict 1 # MultiValueDict borrowed from Django 0.95.1, to avoid deep dependency. 2 2 3 class MultiValueDictKeyError(KeyError): 4 pass 5 6 class MultiValueDict(dict): 7 """ 8 Dict customized to handle multiple values for the same key. 9 10 >>> d = MultiValueDict({'name': ['Adrian', 'Simon'], 'position': ['Developer']}) 11 >>> d['name'] 12 'Simon' 13 >>> d.getlist('name') 14 ['Adrian', 'Simon'] 15 >>> d.get('lastname', 'nonexistent') 16 'nonexistent' 17 >>> d.setlist('lastname', ['Holovaty', 'Willison']) 18 19 This class exists to solve the irritating problem raised by cgi.parse_qs, 20 which returns a list for every key, even though most Web forms submit 21 single name-value pairs. 22 """ 23 def __init__(self, key_to_list_mapping=()): 24 dict.__init__(self, key_to_list_mapping) 25 26 def __repr__(self): 27 return "<MultiValueDict: %s>" % dict.__repr__(self) 28 29 def __getitem__(self, key): 30 """ 31 Returns the last data value for this key, or [] if it's an empty list; 32 raises KeyError if not found. 33 """ 34 try: 35 list_ = dict.__getitem__(self, key) 36 except KeyError: 37 raise MultiValueDictKeyError, "Key %r not found in %r" % (key, self) 38 try: 39 return list_[-1] 40 except IndexError: 41 return [] 42 43 def __setitem__(self, key, value): 44 dict.__setitem__(self, key, [value]) 45 46 def __copy__(self): 47 return self.__class__(dict.items(self)) 48 49 def __deepcopy__(self, memo=None): 50 import copy 51 if memo is None: memo = {} 52 result = self.__class__() 53 memo[id(self)] = result 54 for key, value in dict.items(self): 55 dict.__setitem__(result, copy.deepcopy(key, memo), copy.deepcopy(value, memo)) 56 return result 57 58 def get(self, key, default=None): 59 "Returns the default value if the requested data doesn't exist" 60 try: 61 val = self[key] 62 except KeyError: 63 return default 64 if val == []: 65 return default 66 return val 67 68 def getlist(self, key): 69 "Returns an empty list if the requested data doesn't exist" 70 try: 71 return dict.__getitem__(self, key) 72 except KeyError: 73 return [] 74 75 def setlist(self, key, list_): 76 dict.__setitem__(self, key, list_) 77 78 def setdefault(self, key, default=None): 79 if key not in self: 80 self[key] = default 81 return self[key] 82 83 def setlistdefault(self, key, default_list=()): 84 if key not in self: 85 self.setlist(key, default_list) 86 return self.getlist(key) 87 88 def appendlist(self, key, value): 89 "Appends an item to the internal list associated with key" 90 self.setlistdefault(key, []) 91 dict.__setitem__(self, key, self.getlist(key) + [value]) 92 93 def items(self): 94 """ 95 Returns a list of (key, value) pairs, where value is the last item in 96 the list associated with the key. 97 """ 98 return [(key, self[key]) for key in self.keys()] 99 100 def lists(self): 101 "Returns a list of (key, list) pairs." 102 return dict.items(self) 103 104 def values(self): 105 "Returns a list of the last value on every key list." 106 return [self[key] for key in self.keys()] 107 108 def copy(self): 109 "Returns a copy of this object." 110 return self.__deepcopy__() 111 112 def update(self, other_dict): 113 "update() extends rather than replaces existing key lists." 114 if isinstance(other_dict, MultiValueDict): 115 for key, value_list in other_dict.lists(): 116 self.setlistdefault(key, []).extend(value_list) 117 else: 118 try: 119 for key, value in other_dict.items(): 120 self.setlistdefault(key, []).append(value) 121 except TypeError: 122 raise ValueError, "MultiValueDict.update() takes either a MultiValueDict or dictionary" 123 trunk/src/dm/util/html.py
r204 r308 1 from django.utils.html import escape2 1 trunk/src/dm/util/http.py
r204 r308 1 from django.http import HttpRequest2 from django.http import HttpResponse3 from django.http import HttpResponseRedirecttrunk/src/dm/util/manipulator.py
r204 r308 1 from django import forms2 from django.core import validatorstrunk/src/dm/util/template.py
r204 r308 1 from django.template import Context2 from django.core import template_loader3 1 trunk/src/dm/view/base.py
r289 r308 10 10 from dm.strategy import ValidateCookieString 11 11 from dm.util.datastructure import MultiValueDict 12 from dm. util.httpimport HttpResponse13 from dm. util.httpimport HttpResponseRedirect14 from dm. util.templateimport Context15 from dm. uti
