/webapp-django/crashstats/supersearch/forms.py

https://github.com/lauraxt/socorro · Python · 123 lines · 87 code · 28 blank · 8 comment · 20 complexity · 2a38ce55bb583e05231c1bedbc01db9f MD5 · raw file

  1. import json
  2. from django import forms
  3. from . import form_fields
  4. TYPE_TO_FIELD_MAPPING = {
  5. 'enum': form_fields.MultipleValueField,
  6. 'string': form_fields.StringField,
  7. 'number': form_fields.IntegerField,
  8. 'bool': form_fields.BooleanField,
  9. 'flag': form_fields.StringField,
  10. 'date': form_fields.DateTimeField,
  11. }
  12. def make_restricted_choices(sequence, exclude=None):
  13. if exclude is None:
  14. exclude = []
  15. return [(x, x) for x in sequence if x not in exclude]
  16. class SearchForm(forms.Form):
  17. '''Handle the data populating the search form. '''
  18. def __init__(
  19. self,
  20. all_fields,
  21. current_products,
  22. current_versions,
  23. current_platforms,
  24. user,
  25. *args,
  26. **kwargs
  27. ):
  28. super(self.__class__, self).__init__(*args, **kwargs)
  29. self.all_fields = all_fields.copy()
  30. # Default values loaded from a database.
  31. if 'product' in self.all_fields:
  32. self.all_fields['product']['form_field_choices'] = \
  33. current_products.keys()
  34. if 'version' in self.all_fields:
  35. self.all_fields['version']['form_field_choices'] = [
  36. x['version'] for x in current_versions
  37. ]
  38. if 'platform' in self.all_fields:
  39. self.all_fields['platform']['form_field_choices'] = [
  40. x['name'] for x in current_platforms
  41. ]
  42. # Generate the list of fields.
  43. for field_name, field_data in all_fields.iteritems():
  44. if not field_data['is_exposed']:
  45. del self.all_fields[field_name]
  46. continue
  47. if field_data['permissions_needed']:
  48. user_has_permissions = True
  49. for permission in field_data['permissions_needed']:
  50. if not user.has_perm(permission):
  51. user_has_permissions = False
  52. break
  53. if not user_has_permissions:
  54. # The user is lacking one of the permissions needed
  55. # for this field, so we do not add it to the list
  56. # of fields.
  57. del self.all_fields[field_name]
  58. continue
  59. field_type = TYPE_TO_FIELD_MAPPING.get(
  60. field_data['query_type'],
  61. form_fields.MultipleValueField
  62. )
  63. field_obj = field_type(
  64. required=field_data['is_mandatory']
  65. )
  66. if field_data['form_field_choices']:
  67. field_obj.choices = make_restricted_choices(
  68. field_data['form_field_choices'], ['any', 'all']
  69. )
  70. self.fields[field_name] = field_obj
  71. def get_fields_list(self, exclude=None):
  72. '''Return a dictionary describing the fields, to pass to the
  73. dynamic_form.js library. '''
  74. fields_list = {}
  75. if exclude is None:
  76. exclude = []
  77. for field in self.all_fields.itervalues():
  78. if field['name'] in exclude:
  79. continue
  80. fields_list[field['name']] = {
  81. 'name': field['name'].replace('_', ' '),
  82. 'valueType': field['query_type'],
  83. 'values': field['form_field_choices'],
  84. 'multiple': True,
  85. 'extensible': True,
  86. }
  87. return fields_list
  88. class QueryForm(forms.Form):
  89. query = forms.CharField()
  90. indices = form_fields.MultipleValueField(required=False)
  91. def clean_query(self):
  92. try:
  93. return json.loads(self.cleaned_data['query'])
  94. except ValueError as x:
  95. raise forms.ValidationError(x)