Commit 2a7d572e16ca48099012cbf2efe3c172dd4f27a9

Authored by Sergio Oliveira
2 parents 36507355 746c6fa1

Merge branch 'master' of github.com:TracyWebTech/colab

src/proxy/search_indexes.py
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 2
  3 +import math
  4 +
3 from datetime import datetime 5 from datetime import datetime
4 6
5 from django.db.models import Q 7 from django.db.models import Q
6 from haystack import indexes 8 from haystack import indexes
7 9
  10 +from search.base_indexes import BaseIndex
8 from .models import Ticket, Wiki, Revision 11 from .models import Ticket, Wiki, Revision
9 12
10 13
11 -class WikiIndex(indexes.SearchIndex, indexes.Indexable):  
12 - # common fields  
13 - text = indexes.CharField(document=True, use_template=True, stored=False)  
14 - url = indexes.CharField(model_attr='get_absolute_url', indexed=False) 14 +class WikiIndex(BaseIndex, indexes.Indexable):
15 title = indexes.CharField(model_attr='name') 15 title = indexes.CharField(model_attr='name')
16 - description = indexes.CharField(null=True)  
17 - author = indexes.CharField(null=True)  
18 - author_url = indexes.CharField(null=True, indexed=False)  
19 - created = indexes.DateTimeField(model_attr='created', null=True)  
20 - modified = indexes.DateTimeField(model_attr='modified', null=True)  
21 - type = indexes.CharField()  
22 - icon_name = indexes.CharField(indexed=False)  
23 - author_and_username = indexes.CharField(null=True, stored=False)  
24 - hits = indexes.IntegerField()  
25 -  
26 - # trac extra fields  
27 collaborators = indexes.CharField( 16 collaborators = indexes.CharField(
28 model_attr='collaborators', 17 model_attr='collaborators',
29 null=True, 18 null=True,
@@ -33,33 +22,6 @@ class WikiIndex(indexes.SearchIndex, indexes.Indexable): @@ -33,33 +22,6 @@ class WikiIndex(indexes.SearchIndex, indexes.Indexable):
33 def get_model(self): 22 def get_model(self):
34 return Wiki 23 return Wiki
35 24
36 - def get_updated_field(self):  
37 - return 'modified'  
38 -  
39 - def prepare_hits(self, obj):  
40 - return obj.hits  
41 -  
42 - def prepare_author(self, obj):  
43 - author = obj.get_author()  
44 - if author:  
45 - return author.get_full_name()  
46 - return obj.author  
47 -  
48 - def prepare_author_and_username(self, obj):  
49 - author = obj.get_author()  
50 - if not author:  
51 - return obj.author  
52 - return u'{}\n{}'.format(  
53 - author.get_full_name(),  
54 - author.username,  
55 - )  
56 -  
57 - def prepare_author_url(self, obj):  
58 - author = obj.get_author()  
59 - if author:  
60 - return author.get_absolute_url()  
61 - return None  
62 -  
63 def prepare_description(self, obj): 25 def prepare_description(self, obj):
64 return u'{}\n{}'.format(obj.wiki_text, obj.collaborators) 26 return u'{}\n{}'.format(obj.wiki_text, obj.collaborators)
65 27
@@ -70,23 +32,8 @@ class WikiIndex(indexes.SearchIndex, indexes.Indexable): @@ -70,23 +32,8 @@ class WikiIndex(indexes.SearchIndex, indexes.Indexable):
70 return u'wiki' 32 return u'wiki'
71 33
72 34
73 -class TicketIndex(indexes.SearchIndex, indexes.Indexable):  
74 - # common fields  
75 - text = indexes.CharField(document=True, use_template=True, stored=False)  
76 - url = indexes.CharField(model_attr='get_absolute_url', indexed=False)  
77 - title = indexes.CharField()  
78 - description = indexes.CharField(null=True)  
79 - author = indexes.CharField(null=True)  
80 - author_url = indexes.CharField(null=True, indexed=False)  
81 - created = indexes.DateTimeField(model_attr='created', null=True)  
82 - modified = indexes.DateTimeField(model_attr='modified', null=True)  
83 - type = indexes.CharField()  
84 - icon_name = indexes.CharField(indexed=False) 35 +class TicketIndex(BaseIndex, indexes.Indexable):
85 tag = indexes.CharField(model_attr='status', null=True) 36 tag = indexes.CharField(model_attr='status', null=True)
86 - author_and_username = indexes.CharField(null=True, stored=False)  
87 - hits = indexes.IntegerField()  
88 -  
89 - # trac extra fields  
90 milestone = indexes.CharField(model_attr='milestone', null=True) 37 milestone = indexes.CharField(model_attr='milestone', null=True)
91 component = indexes.CharField(model_attr='component', null=True) 38 component = indexes.CharField(model_attr='component', null=True)
92 severity = indexes.CharField(model_attr='severity', null=True) 39 severity = indexes.CharField(model_attr='severity', null=True)
@@ -101,33 +48,6 @@ class TicketIndex(indexes.SearchIndex, indexes.Indexable): @@ -101,33 +48,6 @@ class TicketIndex(indexes.SearchIndex, indexes.Indexable):
101 def get_model(self): 48 def get_model(self):
102 return Ticket 49 return Ticket
103 50
104 - def get_updated_field(self):  
105 - return 'modified'  
106 -  
107 - def prepare_hits(self, obj):  
108 - return obj.hits  
109 -  
110 - def prepare_author(self, obj):  
111 - author = obj.get_author()  
112 - if author:  
113 - return author.get_full_name()  
114 - return obj.author  
115 -  
116 - def prepare_author_and_username(self, obj):  
117 - author = obj.get_author()  
118 - if not author:  
119 - return obj.author  
120 - return u'{}\n{}'.format(  
121 - author.get_full_name(),  
122 - author.username,  
123 - )  
124 -  
125 - def prepare_author_url(self, obj):  
126 - author = obj.get_author()  
127 - if author:  
128 - return author.get_absolute_url()  
129 - return None  
130 -  
131 def prepare_description(self, obj): 51 def prepare_description(self, obj):
132 return u'{}\n{}\n{}\n{}\n{}\n{}\n{}'.format( 52 return u'{}\n{}\n{}\n{}\n{}\n{}\n{}'.format(
133 obj.description, obj.milestone, obj.component, obj.severity, 53 obj.description, obj.milestone, obj.component, obj.severity,
@@ -144,22 +64,9 @@ class TicketIndex(indexes.SearchIndex, indexes.Indexable): @@ -144,22 +64,9 @@ class TicketIndex(indexes.SearchIndex, indexes.Indexable):
144 return 'ticket' 64 return 'ticket'
145 65
146 66
147 -class RevisionIndex(indexes.SearchIndex, indexes.Indexable):  
148 - # common fields  
149 - text = indexes.CharField(document=True, use_template=True, stored=False)  
150 - url = indexes.CharField(model_attr='get_absolute_url', indexed=False)  
151 - title = indexes.CharField() 67 +class RevisionIndex(BaseIndex, indexes.Indexable):
152 description = indexes.CharField(model_attr='message', null=True) 68 description = indexes.CharField(model_attr='message', null=True)
153 - author = indexes.CharField(null=True)  
154 - author_url = indexes.CharField(null=True, indexed=False)  
155 - created = indexes.DateTimeField(model_attr='created', null=True)  
156 modified = indexes.DateTimeField(model_attr='created', null=True) 69 modified = indexes.DateTimeField(model_attr='created', null=True)
157 - type = indexes.CharField()  
158 - icon_name = indexes.CharField(indexed=False)  
159 - author_and_username = indexes.CharField(null=True, stored=False)  
160 - hits = indexes.IntegerField()  
161 -  
162 - # trac extra fields  
163 repository_name = indexes.CharField( 70 repository_name = indexes.CharField(
164 model_attr='repository_name', 71 model_attr='repository_name',
165 stored=False 72 stored=False
@@ -171,29 +78,11 @@ class RevisionIndex(indexes.SearchIndex, indexes.Indexable): @@ -171,29 +78,11 @@ class RevisionIndex(indexes.SearchIndex, indexes.Indexable):
171 def get_updated_field(self): 78 def get_updated_field(self):
172 return 'created' 79 return 'created'
173 80
174 - def prepare_hits(self, obj):  
175 - return obj.hits  
176 -  
177 - def prepare_author(self, obj):  
178 - author = obj.get_author()  
179 - if author:  
180 - return author.get_full_name()  
181 - return obj.author  
182 -  
183 - def prepare_author_and_username(self, obj):  
184 - author = obj.get_author()  
185 - if not author:  
186 - return obj.author  
187 - return u'{}\n{}'.format(  
188 - author.get_full_name(),  
189 - author.username,  
190 - )  
191 -  
192 - def prepare_author_url(self, obj):  
193 - author = obj.get_author()  
194 - if author:  
195 - return author.get_absolute_url()  
196 - return None 81 + def get_boost(self, obj, data):
  82 + if obj.hits <= 10:
  83 + data['boost'] = 0.8
  84 + else:
  85 + data['boost'] = math.log(obj.hits) * 0.8
197 86
198 def prepare_icon_name(self, obj): 87 def prepare_icon_name(self, obj):
199 return u'align-right' 88 return u'align-right'
src/search/base_indexes.py 0 → 100644
@@ -0,0 +1,55 @@ @@ -0,0 +1,55 @@
  1 +# -*- coding: utf-8 -*-
  2 +
  3 +import math
  4 +
  5 +from haystack import indexes
  6 +
  7 +
  8 +class BaseIndex(indexes.SearchIndex):
  9 + text = indexes.CharField(document=True, use_template=True, stored=False)
  10 + url = indexes.CharField(model_attr='get_absolute_url', indexed=False)
  11 + title = indexes.CharField()
  12 + description = indexes.CharField(null=True)
  13 + author = indexes.CharField(null=True)
  14 + author_url = indexes.CharField(null=True, indexed=False)
  15 + created = indexes.DateTimeField(model_attr='created', null=True)
  16 + modified = indexes.DateTimeField(model_attr='modified', null=True)
  17 + type = indexes.CharField()
  18 + icon_name = indexes.CharField(indexed=False)
  19 + author_and_username = indexes.CharField(null=True, stored=False)
  20 + hits = indexes.IntegerField(model_attr='hits')
  21 +
  22 + def get_updated_field(self):
  23 + return 'modified'
  24 +
  25 + def get_boost(self, obj, data):
  26 + if obj.hits <= 10:
  27 + data['boost'] = 1
  28 + else:
  29 + data['boost'] = math.log(obj.hits)
  30 +
  31 + def prepare(self, obj):
  32 + data = super(BaseIndex, self).prepare(obj)
  33 + self.get_boost(obj, data)
  34 + return data
  35 +
  36 + def prepare_author(self, obj):
  37 + author = obj.get_author()
  38 + if author:
  39 + return author.get_full_name()
  40 + return obj.author
  41 +
  42 + def prepare_author_and_username(self, obj):
  43 + author = obj.get_author()
  44 + if not author:
  45 + return obj.author
  46 + return u'{}\n{}'.format(
  47 + author.get_full_name(),
  48 + author.username,
  49 + )
  50 +
  51 + def prepare_author_url(self, obj):
  52 + author = obj.get_author()
  53 + if author:
  54 + return author.get_absolute_url()
  55 + return None
src/search/forms.py
@@ -6,6 +6,7 @@ from django import forms @@ -6,6 +6,7 @@ from django import forms
6 from django.conf import settings 6 from django.conf import settings
7 from django.utils.translation import ugettext_lazy as _ 7 from django.utils.translation import ugettext_lazy as _
8 from haystack.forms import SearchForm 8 from haystack.forms import SearchForm
  9 +from haystack.inputs import AltParser
9 10
10 from accounts.models import User 11 from accounts.models import User
11 from super_archives.models import Message, MailingList 12 from super_archives.models import Message, MailingList
@@ -49,9 +50,16 @@ class ColabSearchForm(SearchForm): @@ -49,9 +50,16 @@ class ColabSearchForm(SearchForm):
49 'NFKD', unicode(self.cleaned_data.get('q')) 50 'NFKD', unicode(self.cleaned_data.get('q'))
50 ).encode('ascii', 'ignore') 51 ).encode('ascii', 'ignore')
51 sqs = self.searchqueryset.auto_query(q) 52 sqs = self.searchqueryset.auto_query(q)
  53 + sqs = sqs.filter(content=AltParser(
  54 + 'dismax',
  55 + q,
  56 + pf='title^2.1 author^1.9 description^1.7',
  57 + mm='2<70%'
  58 + ))
52 else: 59 else:
53 sqs = self.searchqueryset.all() 60 sqs = self.searchqueryset.all()
54 61
  62 +
55 if self.cleaned_data['type']: 63 if self.cleaned_data['type']:
56 "It will consider other types with a whitespace" 64 "It will consider other types with a whitespace"
57 types = self.cleaned_data['type'] 65 types = self.cleaned_data['type']
src/static/css/screen.css
@@ -261,6 +261,7 @@ ul.unstyled-list .glyphicon-chevron-right { @@ -261,6 +261,7 @@ ul.unstyled-list .glyphicon-chevron-right {
261 .toggle-reply:focus { 261 .toggle-reply:focus {
262 background-color: #aaa; 262 background-color: #aaa;
263 border-color: #999; 263 border-color: #999;
  264 +}
264 265
265 /* Converse JS */ 266 /* Converse JS */
266 267
src/super_archives/search_indexes.py
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 2
  3 +import math
  4 +
3 from haystack import indexes 5 from haystack import indexes
4 6
  7 +from search.base_indexes import BaseIndex
5 from .models import Thread 8 from .models import Thread
6 9
7 10
8 -class ThreadIndex(indexes.SearchIndex, indexes.Indexable):  
9 - # common fields  
10 - text = indexes.CharField(document=True, use_template=True, stored=False)  
11 - url = indexes.CharField(  
12 - model_attr='get_absolute_url',  
13 - null=True,  
14 - indexed=False  
15 - ) 11 +class ThreadIndex(BaseIndex, indexes.Indexable):
16 title = indexes.CharField(model_attr='latest_message__subject_clean') 12 title = indexes.CharField(model_attr='latest_message__subject_clean')
17 description = indexes.CharField(use_template=True) 13 description = indexes.CharField(use_template=True)
18 latest_description = indexes.CharField( 14 latest_description = indexes.CharField(
@@ -23,19 +19,12 @@ class ThreadIndex(indexes.SearchIndex, indexes.Indexable): @@ -23,19 +19,12 @@ class ThreadIndex(indexes.SearchIndex, indexes.Indexable):
23 modified = indexes.DateTimeField( 19 modified = indexes.DateTimeField(
24 model_attr='latest_message__received_time' 20 model_attr='latest_message__received_time'
25 ) 21 )
26 - author = indexes.CharField(null=True)  
27 - author_url = indexes.CharField(null=True, indexed=False)  
28 - type = indexes.CharField()  
29 - icon_name = indexes.CharField(indexed=False)  
30 tag = indexes.CharField(model_attr='mailinglist__name') 22 tag = indexes.CharField(model_attr='mailinglist__name')
31 collaborators = indexes.CharField(use_template=True, stored=False) 23 collaborators = indexes.CharField(use_template=True, stored=False)
32 -  
33 - author_and_username = indexes.CharField(null=True, stored=False)  
34 mailinglist_url = indexes.CharField( 24 mailinglist_url = indexes.CharField(
35 model_attr='mailinglist__get_absolute_url', 25 model_attr='mailinglist__get_absolute_url',
36 indexed=False, 26 indexed=False,
37 ) 27 )
38 - hits = indexes.IntegerField()  
39 28
40 def get_model(self): 29 def get_model(self):
41 return Thread 30 return Thread
@@ -43,9 +32,6 @@ class ThreadIndex(indexes.SearchIndex, indexes.Indexable): @@ -43,9 +32,6 @@ class ThreadIndex(indexes.SearchIndex, indexes.Indexable):
43 def get_updated_field(self): 32 def get_updated_field(self):
44 return 'latest_message__received_time' 33 return 'latest_message__received_time'
45 34
46 - def prepare_hits(self, obj):  
47 - return obj.hits  
48 -  
49 def prepare_author(self, obj): 35 def prepare_author(self, obj):
50 return obj.message_set.first().from_address.get_full_name() 36 return obj.message_set.first().from_address.get_full_name()
51 37