Commit 8c079d9ac4dff5f018fc10a080a0694ffc599f2b

Authored by Alexandre A. Barbosa
2 parents aa5f7fe1 9f770f35

Merge pull request #91 from colab/multiple_filters_refactor

Multiple filters refactor
colab/search/forms.py
@@ -9,46 +9,25 @@ from haystack.forms import SearchForm @@ -9,46 +9,25 @@ from haystack.forms import SearchForm
9 from haystack.inputs import AltParser 9 from haystack.inputs import AltParser
10 from haystack.inputs import AutoQuery 10 from haystack.inputs import AutoQuery
11 11
12 -from colab.super_archives.models import MailingList 12 +from colab.plugins.utils import filters_importer
13 13
14 14
15 class ColabSearchForm(SearchForm): 15 class ColabSearchForm(SearchForm):
16 q = forms.CharField(label=_('Search'), required=False) 16 q = forms.CharField(label=_('Search'), required=False)
17 order = forms.CharField(widget=forms.HiddenInput(), required=False) 17 order = forms.CharField(widget=forms.HiddenInput(), required=False)
18 type = forms.CharField(required=False, label=_(u'Type')) 18 type = forms.CharField(required=False, label=_(u'Type'))
19 - author = forms.CharField(required=False, label=_(u'Author'))  
20 - modified_by = forms.CharField(required=False, label=_(u'Modified by'))  
21 - # ticket status  
22 - tag = forms.CharField(required=False, label=_(u'Status'))  
23 - # mailinglist tag  
24 - list = forms.MultipleChoiceField(  
25 - required=False,  
26 - label=_(u'Mailinglist'),  
27 - choices=[(v, v) for v in MailingList.objects.values_list(  
28 - 'name', flat=True)]  
29 - )  
30 - milestone = forms.CharField(required=False, label=_(u'Milestone'))  
31 - priority = forms.CharField(required=False, label=_(u'Priority'))  
32 - component = forms.CharField(required=False, label=_(u'Component'))  
33 - severity = forms.CharField(required=False, label=_(u'Severity'))  
34 - reporter = forms.CharField(required=False, label=_(u'Reporter'))  
35 - keywords = forms.CharField(required=False, label=_(u'Keywords'))  
36 - collaborators = forms.CharField(required=False, label=_(u'Collaborators'))  
37 - repository_name = forms.CharField(required=False, label=_(u'Repository'))  
38 - body = forms.CharField(required=False, label=_(u'Content'))  
39 - description = forms.CharField(required=False, label=_(u'Description'))  
40 - category = forms.CharField(required=False, label=_(u'Category'))  
41 - title = forms.CharField(required=False, label=_(u'Title'))  
42 - username = forms.CharField(required=False, label=_(u'Username'))  
43 - name = forms.CharField(required=False, label=_(u'Name'))  
44 - institution = forms.CharField(required=False, label=_(u'Institution'))  
45 - role = forms.CharField(required=False, label=_(u'Role'))  
46 since = forms.DateField(required=False, label=_(u'Since')) 19 since = forms.DateField(required=False, label=_(u'Since'))
47 until = forms.DateField(required=False, label=_(u'Until')) 20 until = forms.DateField(required=False, label=_(u'Until'))
48 - filename = forms.CharField(required=False, label=_(u'Filename'))  
49 - used_by = forms.CharField(required=False, label=_(u'Used by'))  
50 - mimetype = forms.CharField(required=False, label=_(u'File type'))  
51 - size = forms.CharField(required=False, label=_(u'Size')) 21 +
  22 + excluded_fields = []
  23 +
  24 + def __init__(self, *args, **kwargs):
  25 + super(ColabSearchForm, self).__init__(*args, **kwargs)
  26 + extra = filters_importer.import_plugin_filters({})
  27 + for filter_types in extra.values():
  28 + for field in filter_types['fields']:
  29 + self.fields[field[0]] = forms.CharField(required=False,
  30 + label=field[1])
52 31
53 def search(self): 32 def search(self):
54 if not self.is_valid(): 33 if not self.is_valid():
@@ -56,46 +35,22 @@ class ColabSearchForm(SearchForm): @@ -56,46 +35,22 @@ class ColabSearchForm(SearchForm):
56 35
57 # filter_or goes here 36 # filter_or goes here
58 sqs = self.searchqueryset.all() 37 sqs = self.searchqueryset.all()
59 - mimetype = self.cleaned_data['mimetype']  
60 - if mimetype:  
61 - filter_mimetypes = {'mimetype__in': []}  
62 - for type_, display, mimelist in settings.FILE_TYPE_GROUPINGS:  
63 - if type_ in mimetype:  
64 - filter_mimetypes['mimetype__in'] += mimelist  
65 - if not self.cleaned_data['size']:  
66 - sqs = sqs.filter_or(mimetype__in=mimelist)  
67 -  
68 - if self.cleaned_data['size']:  
69 - # (1024 * 1024) / 2  
70 - # (1024 * 1024) * 10  
71 - filter_sizes = {}  
72 - filter_sizes_exp = {}  
73 - if '<500KB' in self.cleaned_data['size']:  
74 - filter_sizes['size__lt'] = 524288  
75 - if '500KB__10MB' in self.cleaned_data['size']:  
76 - filter_sizes_exp['size__gte'] = 524288  
77 - filter_sizes_exp['size__lte'] = 10485760  
78 - if '>10MB' in self.cleaned_data['size']:  
79 - filter_sizes['size__gt'] = 10485760  
80 -  
81 - if self.cleaned_data['mimetype']:  
82 - # Add the mimetypes filters to this dict and filter it  
83 - if filter_sizes_exp:  
84 - filter_sizes_exp.update(filter_mimetypes)  
85 - sqs = sqs.filter_or(**filter_sizes_exp)  
86 - for filter_or in filter_sizes.items():  
87 - filter_or = dict((filter_or, ))  
88 - filter_or.update(filter_mimetypes)  
89 - sqs = sqs.filter_or(**filter_or)  
90 - else:  
91 - for filter_or in filter_sizes.items():  
92 - filter_or = dict((filter_or, ))  
93 - sqs = sqs.filter_or(**filter_or)  
94 - sqs = sqs.filter_or(**filter_sizes_exp)  
95 38
96 - if self.cleaned_data['used_by']:  
97 - sqs = sqs.filter_or(used_by__in=self.cleaned_data['used_by']  
98 - .split()) 39 + kwargs = {}
  40 +
  41 + self.excluded_fields.extend(['q', 'type', 'since', 'until', 'order'])
  42 +
  43 + if self.cleaned_data['type']:
  44 + all_types = self.cleaned_data['type'].split(' ')
  45 + sqs = sqs.filter_or(type__in=all_types)
  46 +
  47 + for key in self.fields.keys():
  48 + value = self.cleaned_data[key]
  49 + if value and key not in self.excluded_fields:
  50 + print key, '-' + value
  51 + kwargs[key] = self.cleaned_data[key]
  52 +
  53 + sqs = sqs.filter(**kwargs)
99 54
100 if self.cleaned_data['q']: 55 if self.cleaned_data['q']:
101 q = unicodedata.normalize( 56 q = unicodedata.normalize(
@@ -119,70 +74,15 @@ class ColabSearchForm(SearchForm): @@ -119,70 +74,15 @@ class ColabSearchForm(SearchForm):
119 else: 74 else:
120 sqs = sqs.filter(content=AutoQuery(q)) 75 sqs = sqs.filter(content=AutoQuery(q))
121 76
122 - if self.cleaned_data['type']:  
123 - sqs = sqs.filter(type=self.cleaned_data['type'])  
124 -  
125 if self.cleaned_data['order']: 77 if self.cleaned_data['order']:
126 for option, dict_order in settings.ORDERING_DATA.items(): 78 for option, dict_order in settings.ORDERING_DATA.items():
127 if self.cleaned_data['order'] == option: 79 if self.cleaned_data['order'] == option:
128 if dict_order['fields']: 80 if dict_order['fields']:
129 sqs = sqs.order_by(*dict_order['fields']) 81 sqs = sqs.order_by(*dict_order['fields'])
130 82
131 - if self.cleaned_data['author']:  
132 - sqs = sqs.filter(  
133 - fullname_and_username__contains=self.cleaned_data['author']  
134 - )  
135 -  
136 - if self.cleaned_data['modified_by']:  
137 - modified_by_data = self.cleaned_date['modified_by']  
138 - sqs = sqs.filter(  
139 - fullname_and_username__contains=modified_by_data  
140 - )  
141 -  
142 - if self.cleaned_data['milestone']:  
143 - sqs = sqs.filter(milestone=self.cleaned_data['milestone'])  
144 - if self.cleaned_data['priority']:  
145 - sqs = sqs.filter(priority=self.cleaned_data['priority'])  
146 - if self.cleaned_data['severity']:  
147 - sqs = sqs.filter(severity=self.cleaned_data['severity'])  
148 - if self.cleaned_data['reporter']:  
149 - sqs = sqs.filter(reporter=self.cleaned_data['reporter'])  
150 - if self.cleaned_data['keywords']:  
151 - sqs = sqs.filter(keywords=self.cleaned_data['keywords'])  
152 - if self.cleaned_data['collaborators']:  
153 - sqs = sqs.filter(collaborators=self.cleaned_data['collaborators'])  
154 - if self.cleaned_data['repository_name']:  
155 - sqs = sqs.filter(  
156 - repository_name=self.cleaned_data['repository_name']  
157 - )  
158 - if self.cleaned_data['body']:  
159 - sqs = sqs.filter(body=self.cleaned_data['body'])  
160 - if self.cleaned_data['description']:  
161 - sqs = sqs.filter(description=self.cleaned_data['description'])  
162 - if self.cleaned_data['category']:  
163 - sqs = sqs.filter(category=self.cleaned_data['category'])  
164 - if self.cleaned_data['title']:  
165 - sqs = sqs.filter(title=self.cleaned_data['title'])  
166 - if self.cleaned_data['username']:  
167 - sqs = sqs.filter(username=self.cleaned_data['username'])  
168 - if self.cleaned_data['name']:  
169 - sqs = sqs.filter(name=self.cleaned_data['name'])  
170 - if self.cleaned_data['institution']:  
171 - sqs = sqs.filter(institution=self.cleaned_data['institution'])  
172 - if self.cleaned_data['role']:  
173 - sqs = sqs.filter(role=self.cleaned_data['role'])  
174 - if self.cleaned_data['tag']:  
175 - sqs = sqs.filter(tag=self.cleaned_data['tag'])  
176 -  
177 - if self.cleaned_data['list']:  
178 - sqs = sqs.filter(tag__in=self.cleaned_data['list'])  
179 -  
180 if self.cleaned_data['since']: 83 if self.cleaned_data['since']:
181 sqs = sqs.filter(modified__gte=self.cleaned_data['since']) 84 sqs = sqs.filter(modified__gte=self.cleaned_data['since'])
182 if self.cleaned_data['until']: 85 if self.cleaned_data['until']:
183 sqs = sqs.filter(modified__lte=self.cleaned_data['until']) 86 sqs = sqs.filter(modified__lte=self.cleaned_data['until'])
184 87
185 - if self.cleaned_data['filename']:  
186 - sqs = sqs.filter(filename=self.cleaned_data['filename'])  
187 -  
188 return sqs 88 return sqs
colab/search/tests.py
@@ -5,6 +5,7 @@ import mock @@ -5,6 +5,7 @@ import mock
5 from colab.plugins.utils import filters_importer 5 from colab.plugins.utils import filters_importer
6 from django.test import TestCase, Client 6 from django.test import TestCase, Client
7 from django.core.management import call_command 7 from django.core.management import call_command
  8 +from colab.search.forms import ColabSearchForm
8 9
9 10
10 class SearchViewTest(TestCase): 11 class SearchViewTest(TestCase):
@@ -80,3 +81,50 @@ class SearchViewTest(TestCase): @@ -80,3 +81,50 @@ class SearchViewTest(TestCase):
80 value = [('plugin_name', 'PluginData', 'plugin_icon')] 81 value = [('plugin_name', 'PluginData', 'plugin_icon')]
81 82
82 self.assertEqual(request.context['filters_options'], value) 83 self.assertEqual(request.context['filters_options'], value)
  84 +
  85 + def test_search_dynamic_form_fields(self):
  86 + plugin_filter = {
  87 + 'plugin_name': {
  88 + 'name': 'PluginData',
  89 + 'icon': 'plugin_icon',
  90 + 'fields': (
  91 + ('field_1', 'Field1', ''),
  92 + ('field_2', 'Field2', ''),
  93 + ),
  94 + },
  95 + }
  96 + filters_importer.import_plugin_filters = mock.Mock(
  97 + return_value=plugin_filter)
  98 +
  99 + form = ColabSearchForm()
  100 +
  101 + self.assertIn('field_1', form.fields.keys())
  102 + self.assertIn('field_2', form.fields.keys())
  103 +
  104 + def test_search_multiple_filters(self):
  105 + request = self.client.get('/search/?q=&type=thread+user')
  106 + user_list = request.context['page'].object_list
  107 +
  108 + self.assertEqual(6, len(user_list))
  109 +
  110 + self.assertIn('admin@mail.com', user_list[0].object.email)
  111 + self.assertIn('admin', user_list[0].object.username)
  112 +
  113 + self.assertIn('chucknorris@mail.com', user_list[1].object.email)
  114 + self.assertIn('Chuck', user_list[1].object.first_name)
  115 + self.assertIn('Norris', user_list[1].object.last_name)
  116 + self.assertIn('chucknorris', user_list[1].object.username)
  117 +
  118 + self.assertIn('heisenberg@mail.com', user_list[2].object.email)
  119 + self.assertIn('Heisenberg', user_list[2].object.first_name)
  120 + self.assertIn('Norris', user_list[2].object.last_name)
  121 + self.assertIn('heisenbergnorris', user_list[2].object.username)
  122 +
  123 + self.assertIn('Admin Administrator', user_list[3].author)
  124 + self.assertIn('Response to Thread 1A', user_list[3].title)
  125 +
  126 + self.assertIn('Admin Administrator', user_list[4].author)
  127 + self.assertIn('Message 1 on Thread 1B', user_list[4].title)
  128 +
  129 + self.assertIn('Admin Administrator', user_list[5].author)
  130 + self.assertIn('Message 1 on Thread 1C', user_list[5].title)
colab/super_archives/filters.py
@@ -10,9 +10,9 @@ def get_filters(request): @@ -10,9 +10,9 @@ def get_filters(request):
10 'fields': ( 10 'fields': (
11 ('author', _(u'Author'), request.get('author')), 11 ('author', _(u'Author'), request.get('author')),
12 ( 12 (
13 - 'list', 13 + 'tag',
14 _(u'Mailinglist'), 14 _(u'Mailinglist'),
15 - request.get('list'), 15 + request.get('tag'),
16 'list', 16 'list',
17 [(v, v) for v in MailingList.objects.values_list( 17 [(v, v) for v in MailingList.objects.values_list(
18 'name', flat=True)] 18 'name', flat=True)]