Package omeroweb :: Package webadmin :: Module custom_forms
[hide private]
[frames] | no frames]

Source Code for Module omeroweb.webadmin.custom_forms

  1  #!/usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3  #  
  4  #  
  5  #  
  6  # Copyright (c) 2008 University of Dundee.  
  7  #  
  8  # This program is free software: you can redistribute it and/or modify 
  9  # it under the terms of the GNU Affero General Public License as 
 10  # published by the Free Software Foundation, either version 3 of the 
 11  # License, or (at your option) any later version. 
 12  #  
 13  # This program is distributed in the hope that it will be useful, 
 14  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 15  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 16  # GNU Affero General Public License for more details. 
 17  #  
 18  # You should have received a copy of the GNU Affero General Public License 
 19  # along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 20  #  
 21  # Author: Aleksandra Tarkowska <A(dot)Tarkowska(at)dundee(dot)ac(dot)uk>, 2008. 
 22  #  
 23  # Version: 1.0 
 24  # 
 25   
 26   
 27  import re 
 28   
 29  from django import forms 
 30  from django.forms.fields import Field, ChoiceField, EMPTY_VALUES 
 31  from django.forms.widgets import Select, SelectMultiple, MultipleHiddenInput 
 32  from django.forms import ModelChoiceField, ModelMultipleChoiceField, ValidationError 
 33  from django.utils.translation import ugettext_lazy as _ 
 34  from django.utils.encoding import smart_unicode 
 35   
 36  ################################################################## 
 37  # Fields 
 38   
39 -class OmeNameField(forms.CharField):
40 - def to_python(self, value):
41 omeName = value 42 if not value: 43 raise forms.ValidationError('This field is required.') 44 if not self.is_valid_omeName(omeName): 45 raise forms.ValidationError('%s is not a valid Omename.' % omeName) 46 return omeName
47
48 - def is_valid_omeName(self, omeName):
49 omeName_pattern = re.compile(r"(?:^|\s)[a-zA-Z0-9_.]") #TODO: PATTERN !!!!!!! 50 return omeName_pattern.match(omeName) is not None
51 52 # Group queryset iterator for group form 53
54 -class ServerQuerySetIterator(object):
55 - def __init__(self, queryset, empty_label):
56 self.queryset = queryset 57 self.empty_label = empty_label
58
59 - def __iter__(self):
60 if self.empty_label is not None: 61 yield (u"", self.empty_label) 62 for obj in self.queryset: 63 if obj.server is None: 64 name = "%s:%s" % (obj.host,obj.port) 65 else: 66 name = "%s:%s" % (obj.server,obj.port) 67 yield (smart_unicode(obj.id), smart_unicode(name))
68
69 -class ServerModelChoiceField(ModelChoiceField):
70
71 - def _get_choices(self):
72 # If self._choices is set, then somebody must have manually set 73 # the property self.choices. In this case, just return self._choices. 74 if hasattr(self, '_choices'): 75 return self._choices 76 # Otherwise, execute the QuerySet in self.queryset to determine the 77 # choices dynamically. Return a fresh QuerySetIterator that has not 78 # been consumed. Note that we're instantiating a new QuerySetIterator 79 # *each* time _get_choices() is called (and, thus, each time 80 # self.choices is accessed) so that we can ensure the QuerySet has not 81 # been consumed. 82 return ServerQuerySetIterator(self.queryset, self.empty_label)
83
84 - def _set_choices(self, value):
85 # This method is copied from ChoiceField._set_choices(). It's necessary 86 # because property() doesn't allow a subclass to overwrite only 87 # _get_choices without implementing _set_choices. 88 self._choices = self.widget.choices = list(value)
89 90 choices = property(_get_choices, _set_choices) 91
92 - def to_python(self, value):
93 if value in EMPTY_VALUES: 94 return None 95 res = False 96 for q in self.queryset: 97 if long(value) == q.id: 98 res = True 99 if not res: 100 raise ValidationError(self.error_messages['invalid_choice']) 101 return value
102 103 # Group queryset iterator for group form
104 -class GroupQuerySetIterator(object):
105 - def __init__(self, queryset, empty_label):
106 self.queryset = queryset 107 self.empty_label = empty_label
108
109 - def __iter__(self):
110 if self.empty_label is not None: 111 yield (u"", self.empty_label) 112 for obj in self.queryset: 113 if hasattr(obj.name, 'val'): 114 name = obj.name.val 115 else: 116 name = obj.name 117 l = len(name) 118 if l > 35: 119 name = name[:35] + "..." 120 name += " (%s)" % str(obj.getDetails().permissions) 121 if hasattr(obj.id, 'val'): 122 oid = obj.id.val 123 else: 124 oid = obj.id 125 yield (smart_unicode(oid), smart_unicode(name))
126
127 -class GroupModelChoiceField(ModelChoiceField):
128
129 - def _get_choices(self):
130 # If self._choices is set, then somebody must have manually set 131 # the property self.choices. In this case, just return self._choices. 132 if hasattr(self, '_choices'): 133 return self._choices 134 # Otherwise, execute the QuerySet in self.queryset to determine the 135 # choices dynamically. Return a fresh QuerySetIterator that has not 136 # been consumed. Note that we're instantiating a new QuerySetIterator 137 # *each* time _get_choices() is called (and, thus, each time 138 # self.choices is accessed) so that we can ensure the QuerySet has not 139 # been consumed. 140 return GroupQuerySetIterator(self.queryset, self.empty_label)
141
142 - def _set_choices(self, value):
143 # This method is copied from ChoiceField._set_choices(). It's necessary 144 # because property() doesn't allow a subclass to overwrite only 145 # _get_choices without implementing _set_choices. 146 self._choices = self.widget.choices = list(value)
147 148 choices = property(_get_choices, _set_choices) 149
150 - def to_python(self, value):
151 if value in EMPTY_VALUES: 152 return None 153 res = False 154 exps = [] 155 try: 156 for experimenter_type, experimenters in self.queryset: 157 for experimenter in experimenters: 158 exp.append(experimenter) 159 except: 160 exps = self.queryset 161 for experimenter in exps: 162 if hasattr(experimenter.id, 'val'): 163 if long(value) == experimenter.id.val: 164 res = True 165 else: 166 if long(value) == experimenter.id: 167 res = True 168 if not res: 169 raise ValidationError(self.error_messages['invalid_choice']) 170 return value
171
172 -class GroupModelMultipleChoiceField(GroupModelChoiceField):
173 """A MultipleChoiceField whose choices are a model QuerySet.""" 174 hidden_widget = MultipleHiddenInput 175 default_error_messages = { 176 'list': _(u'Enter a list of values.'), 177 'invalid_choice': _(u'Select a valid choice. That choice is not one of the' 178 u' available choices.'), 179 } 180
181 - def __init__(self, queryset, cache_choices=False, required=True, 182 widget=SelectMultiple, label=None, initial=None, 183 help_text=None, *args, **kwargs):
184 super(GroupModelMultipleChoiceField, self).__init__(queryset, None, 185 cache_choices, required, widget, label, initial, help_text, 186 *args, **kwargs)
187
188 - def to_python(self, value):
189 if self.required and not value: 190 raise ValidationError(self.error_messages['required']) 191 elif not self.required and not value: 192 return [] 193 if not isinstance(value, (list, tuple)): 194 raise ValidationError(self.error_messages['list']) 195 final_values = [] 196 for val in value: 197 try: 198 long(val) 199 except: 200 raise ValidationError(self.error_messages['invalid_choice']) 201 else: 202 res = False 203 for q in self.queryset: 204 if hasattr(q.id, 'val'): 205 if long(val) == q.id.val: 206 res = True 207 else: 208 if long(val) == q.id: 209 res = True 210 if not res: 211 raise ValidationError(self.error_messages['invalid_choice']) 212 else: 213 final_values.append(val) 214 return final_values
215 216 # Experimenter queryset iterator for experimenter form
217 -class ExperimenterQuerySetIterator(object):
218 - def __init__(self, queryset, empty_label):
219 self.queryset = queryset 220 221 self.empty_label = empty_label 222 223 self.rendered_set = [] 224 if self.empty_label is not None: 225 self.rendered_set.append( (u"", self.empty_label) ) 226 227 # queryset may be a list of Experimenters 'exp_list' OR may be ( ("Leaders", exp_list), ("Members", exp_list) ) 228 for obj in queryset: 229 if hasattr(obj, 'id'): 230 self.rendered_set.append(self.render(obj)) 231 else: 232 subset = [self.render(m) for m in obj[1]] 233 self.rendered_set.append( (obj[0], subset) )
234
235 - def __iter__(self):
236 for obj in self.rendered_set: 237 yield obj
238 239
240 - def render(self, obj):
241 try: 242 # lastName = obj.details.owner.lastName.val if hasattr(obj.details.owner.lastName, 'val') else "" 243 # firstName = obj.details.owner.firstName.val if hasattr(obj.details.owner.firstName, 'val') else "" 244 # middleName = obj.details.owner.middleName.val if hasattr(obj.details.owner.middleName, 'val') else "" 245 if hasattr(obj, 'getFullName'): 246 name = "%s (%s)" % (obj.getFullName(), obj.omeName) 247 else: 248 omeName = None 249 if hasattr(obj.omeName, 'val'): 250 omeName = obj.omeName.val 251 lastName = None 252 if hasattr(obj.lastName, 'val'): 253 lastName = obj.lastName.val 254 firstName = None 255 if hasattr(obj.firstName, 'val'): 256 firstName = obj.firstName.val 257 middleName = None 258 if hasattr(obj.middleName, 'val'): 259 middleName = obj.middleName.val 260 261 if middleName != '' and middleName is not None: 262 name = "%s%s %s. %s (%s)" % (myself, firstName, middleName[:1], lastName, omeName) 263 else: 264 name = "%s%s %s (%s)" % (myself, firstName, lastName, omeName) 265 266 267 l = len(name) 268 if l > 50: 269 name = name[:50] + "..." 270 except: 271 name = _("Unknown") 272 273 if hasattr(obj.id, 'val'): 274 oid = obj.id.val 275 else: 276 oid = obj.id 277 return (smart_unicode(oid), smart_unicode(name))
278
279 -class ExperimenterModelChoiceField(ModelChoiceField):
280
281 - def _get_choices(self):
282 # If self._choices is set, then somebody must have manually set 283 # the property self.choices. In this case, just return self._choices. 284 if hasattr(self, '_choices'): 285 return self._choices 286 # Otherwise, execute the QuerySet in self.queryset to determine the 287 # choices dynamically. Return a fresh QuerySetIterator that has not 288 # been consumed. Note that we're instantiating a new QuerySetIterator 289 # *each* time _get_choices() is called (and, thus, each time 290 # self.choices is accessed) so that we can ensure the QuerySet has not 291 # been consumed. 292 return ExperimenterQuerySetIterator(self.queryset, self.empty_label)
293
294 - def _set_choices(self, value):
295 # This method is copied from ChoiceField._set_choices(). It's necessary 296 # because property() doesn't allow a subclass to overwrite only 297 # _get_choices without implementing _set_choices. 298 self._choices = self.widget.choices = list(value)
299 300 choices = property(_get_choices, _set_choices) 301
302 - def to_python(self, value):
303 """ 304 Go through all values in queryset, looking to find 'value'. If not found raise ValidationError. 305 306 @return value: The input value 307 """ 308 309 if value in EMPTY_VALUES: 310 return None 311 res = False 312 313 def checkValue(q, value): 314 if not hasattr(q, 'id'): 315 return False 316 if hasattr(q.id, 'val'): 317 if long(value) == q.id.val: 318 return True 319 if long(value) == q.id: 320 return True
321 322 for q in self.queryset: 323 if isinstance(q, tuple) or isinstance(q, list): 324 for qu in q: 325 if isinstance(qu, tuple) or isinstance(qu, list): 326 for qq in qu: 327 if checkValue(qq, value): 328 res = True 329 else: 330 if checkValue(qu, value): 331 res = True 332 else: 333 if checkValue(q, value): 334 res = True 335 if not res: 336 raise ValidationError(self.error_messages['invalid_choice']) 337 return value
338
339 -class ExperimenterModelMultipleChoiceField(ExperimenterModelChoiceField):
340 """A MultipleChoiceField whose choices are a model QuerySet.""" 341 hidden_widget = MultipleHiddenInput 342 default_error_messages = { 343 'list': _(u'Enter a list of values.'), 344 'invalid_choice': _(u'Select a valid choice. That choice is not one of the' 345 u' available choices.'), 346 } 347
348 - def __init__(self, queryset, cache_choices=False, required=True, 349 widget=SelectMultiple, label=None, initial=None, 350 help_text=None, *args, **kwargs):
351 super(ExperimenterModelMultipleChoiceField, self).__init__(queryset, None, 352 cache_choices, required, widget, label, initial, help_text, 353 *args, **kwargs)
354 355
356 - def to_python(self, value):
357 if self.required and not value: 358 raise ValidationError(self.error_messages['required']) 359 elif not self.required and not value: 360 return [] 361 if not isinstance(value, (list, tuple)): 362 raise ValidationError(self.error_messages['list']) 363 final_values = [] 364 for val in value: 365 try: 366 long(val) 367 except: 368 raise ValidationError(self.error_messages['invalid_choice']) 369 else: 370 res = False 371 for q in self.queryset: 372 if hasattr(q.id, 'val'): 373 if long(val) == q.id.val: 374 res = True 375 else: 376 if long(val) == q.id: 377 res = True 378 if not res: 379 raise ValidationError(self.error_messages['invalid_choice']) 380 else: 381 final_values.append(val) 382 return final_values
383
384 -class DefaultGroupField(ChoiceField):
385
386 - def to_python(self, value):
387 """ 388 Check that the field was selected. 389 """ 390 if not value: 391 raise forms.ValidationError("Choose one of the 'Selected groups' to specify 'Default Group'.") 392 393 # Always return the cleaned data. 394 return value
395