forked from fwenzel/reporter
/
views.py
155 lines (123 loc) · 4.83 KB
/
views.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import datetime
from django.conf import settings
from django.contrib.syndication.views import Feed
from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.utils.feedgenerator import Atom1Feed
import jingo
from tower import ugettext as _, ugettext_lazy as _lazy
from feedback import APP_IDS, stats
from feedback.models import Term
from input.decorators import cache_page
from input.urlresolvers import reverse
from .client import Client, SearchError
from .forms import ReporterSearchForm, VERSION_CHOICES
def _get_results(request):
form = ReporterSearchForm(request.GET)
if form.is_valid():
query = form.cleaned_data.get('q', '')
search_opts = form.cleaned_data
c = Client()
opinions = c.query(query, **search_opts)
else:
query = ''
opinions = []
return (opinions, form)
class SearchFeed(Feed):
# TODO(davedash): Gracefully degrade for unavailable search.
feed_type = Atom1Feed
author_name = _lazy('Firefox Input')
subtitle = _lazy("Search Results in Firefox Beta Feedback.")
def get_object(self, request):
data = dict(opinions=_get_results(request)[0], request=request)
return data
def link(self, obj):
"""Global feed link. Also used as GUID."""
return reverse('search') + '?' + obj['request'].META['QUERY_STRING']
def title(self, obj):
"""Global feed title."""
request = obj['request']
query = request.GET.get('q')
# L10n: This is the title to the Search ATOM feed.
return (_("Firefox Input: '{query}'").format(query=query) if query else
_('Firefox Input'))
def items(self, obj):
"""List of comments."""
return obj['opinions'][:settings.SEARCH_PERPAGE]
def item_categories(self, item):
"""Categorize comments. Style: "product:firefox" etc."""
categories = {'product': APP_IDS.get(item.product).short,
'version': item.version,
'os': item.os,
'locale': item.locale,
'sentiment': 'positive' if item.positive else 'negative',
}
return (':'.join(i) for i in categories.items())
def item_description(self, item):
"""A comment's main text."""
return item.description
def item_link(self, item):
"""Permalink per item. Also used as GUID."""
# TODO make this a working link. bug 575770.
return item.get_url_path()
def item_pubdate(self, item):
"""Publishing date of a comment."""
return item.created
def item_title(self, item):
"""A comment's title."""
return unicode(item)
@cache_page(use_get=True)
def index(request):
try:
(opinions, form) = _get_results(request)
except SearchError, e:
return jingo.render(request, 'search/unavailable.html',
{'search_error': e}, status=500)
page = form.data.get('page', 1)
data = {
'form': form,
'versions': VERSION_CHOICES[request.default_app],
}
# Determine date period chosen
if not getattr(form, 'cleaned_data', None):
period = None
else:
if (form.cleaned_data.get('date_end') == datetime.date.today() and
form.cleaned_data.get('date_start')):
_ago = lambda x: datetime.date.today() - datetime.timedelta(days=x)
period = {_ago(1): '1d',
_ago(7): '7d',
_ago(30): '30d'}.get(
form.cleaned_data.get('date_start'), 'custom')
elif not form.cleaned_data.get('date_start'):
period = 'infin'
else:
period = 'custom'
data['period'] = period
if opinions:
pp = settings.SEARCH_PERPAGE
pager = Paginator(opinions, pp)
data['opinion_count'] = pager.count
# If page request (e.g., 9999) is out of range, deliver last page of
# results.
try:
data['page'] = pager.page(page)
except (EmptyPage, InvalidPage):
data['page'] = pager.page(pager.num_pages)
data['opinions'] = data['page'].object_list
data['sent'] = stats.sentiment(qs=opinions)
data['demo'] = stats.demographics(qs=opinions)
# terms deactivated, cf. bug 582606
#frequent_terms = Term.objects.frequent(
# opinions=(o.id for o in opinions))[:settings.TRENDS_COUNT]
#data['terms'] = stats.frequent_terms(qs=frequent_terms)
else:
data.update({
'opinion_count': 0,
'opinions': None,
'sent': stats.sentiment(None),
'demo': stats.demographics(None),
})
data['defaults'] = form.data
template = 'search/%ssearch.html' % (
'mobile/' if request.mobile_site else '')
return jingo.render(request, template, data)