Test coverage report: frequently.views

# frequently.views: 136 total statements, 100.0% covered

Generated: Fri 2015-09-11 18:53 CEST

Source file: /home/tyrdall/projects/django-frequently/src/frequently/views.py

Stats: 120 executed, 0 missed, 16 excluded, 99 ignored

1. `"""`
2. `Views for the ``django-frequently`` application.`
3. ``
4. `"""`
5. `from math import fsum`
6. ``
7. `from django.contrib import messages`
8. `from django.contrib.auth.models import User`
9. `from django.core.urlresolvers import reverse`
10. `from django.http import HttpResponse, Http404`
11. `from django.template.response import TemplateResponse`
12. `from django.utils import timezone`
13. `from django.utils.translation import ugettext_lazy as _`
14. `from django.views.generic import CreateView, DetailView, ListView`
15. ``
16. `from django_libs.views_mixins import AccessMixin`
17. ``
18. `from .forms import EntryForm`
19. `from .models import Entry, EntryCategory, Feedback`
20. ``
21. ``
22. `class EntryMixin(object):`
23. `"""`
24. `Mixin to handle and arrange the entry list.`
25. ``
26. `"""`
27. ``
28. `def get_ordered_entries(self, queryset=False):`
29. `"""`
30. `Custom ordering. First we get the average views and rating for`
31. `the categories's entries. Second we created a rank by multiplying`
32. `both. Last, we sort categories by this rank from top to bottom.`
33. ``
34. `Example:`
35. `- Cat_1`
36. `- Entry_1 (500 Views, Rating 2)`
37. `- Entry_2 (200 Views, Rating -4)`
38. `- Entry_3 (100 Views, Rating 3)`
39. `- Cat_2`
40. `- Entry_1 (200 Views, Rating 7)`
41. `- Entry_2 (50 Views, Rating 2)`
42. ``
43. `Result:`
44. `Cat_1 has a rank by: 88.88 (avg. views: 266.66, avg. rating: 0.33)`
45. `Cat_2 has a rank by: 562.5 (avg. views: 125, avg. rating: 4.5)`
46. ``
47. `Cat_2 will be displayed at the top. The algorithm is quality-oriented,`
48. `as you can see.`
49. ``
50. `"""`
51. `if queryset:`
52. `self.queryset = queryset`
53. `else:`
54. `self.queryset = EntryCategory.objects.all()`
55. `if self.queryset:`
56. `for category in self.queryset:`
57. `entries = category.get_entries()`
58. `if entries:`
59. `amount_list = [e.amount_of_views for e in entries]`
60. `rating_list = [e.rating() for e in entries]`
61. `views_per_entry = fsum(amount_list) / len(amount_list)`
62. `rating_per_entry = fsum(rating_list) / len(rating_list)`
63. `category.last_rank = views_per_entry * rating_per_entry`
64. `category.save()`
65. `else:`
66. `self.queryset = self.queryset.exclude(pk=category.pk)`
67. `self.queryset = sorted(self.queryset, key=lambda c: c.last_rank,`
68. `reverse=True)`
69. `return self.queryset`
70. ``
71. `def post(self, request, *args, **kwargs):`
72. `if "get_answer" in request.POST.keys():`
73. `entry = Entry.objects.get(pk=request.POST['get_answer'])`
74. `entry.last_view_date = timezone.now()`
75. `entry.amount_of_views += 1`
76. `entry.save()`
77. `return TemplateResponse(`
78. `request,`
79. `'frequently/partials/answer.html',`
80. `{`
81. `'entry': entry,`
82. `'rated_entries': self.request.session.get(`
83. `'rated_entries', False),`
84. `},`
85. `)`
86. `self.feedback = Feedback()`
87. `if "user_id" in request.POST.keys():`
88. `try:`
89. `user_id = int(request.POST.get('user_id'))`
90. `try:`
91. `self.feedback.user = User.objects.get(pk=user_id)`
92. `except User.DoesNotExist:`
93. `pass`
94. `except ValueError:`
95. `pass`
96. `if 'rating_id' in request.POST.keys() and request.is_ajax():`
97. `try:`
98. `entry_id = int(request.POST.get('rating_id').replace(`
99. `'rating_id', ''))`
100. `try:`
101. `entry = Entry.objects.get(pk=entry_id)`
102. `return HttpResponse(entry.rating())`
103. `except Entry.DoesNotExist:`
104. `raise Http404`
105. `except ValueError:`
106. `raise Http404`
107. `for key in request.POST.keys():`
108. `if key.startswith('up') or key.startswith('down'):`
109. `try:`
110. `entry_id = int(key.replace('up', '').replace('down', ''))`
111. `try:`
112. `entry = Entry.objects.get(pk=entry_id)`
113. `except Entry.DoesNotExist:`
114. `raise Http404`
115. `except ValueError:`
116. `raise Http404`
117. `if not request.session.get('rated_entries', False):`
118. `request.session['rated_entries'] = []`
119. `if entry.pk not in request.session['rated_entries']:`
120. `request.session['rated_entries'].append(entry.pk)`
121. `request.session.modified = True`
122. `self.feedback.entry = entry`
123. `if key.startswith('up'):`
124. `entry.upvotes += 1`
125. `self.feedback.validation = "P"`
126. `if key.startswith('down'):`
127. `entry.downvotes += 1`
128. `self.feedback.validation = "N"`
129. `entry.save()`
130. `self.feedback.save()`
131. `if request.is_ajax():`
132. `return TemplateResponse(`
133. `request,`
134. `'frequently/partials/feedback_form.html',`
135. `{`
136. `'feedback_entry': entry.pk,`
137. `'feedback': self.feedback,`
138. `},`
139. `)`
140. `elif key.startswith('feedback'):`
141. `try:`
142. `feedback_id = int(key.replace('feedback', ''))`
143. `try:`
144. `self.feedback = Feedback.objects.get(pk=feedback_id)`
145. `except Feedback.DoesNotExist:`
146. `raise Http404`
147. `except ValueError:`
148. `raise Http404`
149. `self.feedback.remark = request.POST.get("remark")`
150. `self.feedback.save()`
151. `if request.is_ajax():`
152. `return TemplateResponse(`
153. `request,`
154. `'frequently/partials/feedback_form.html',`
155. `{'feedback_send': True},`
156. `)`
157. `return self.get(self, request, *args, **kwargs)`
158. ``
159. ``
160. `class EntryCategoryListView(AccessMixin, EntryMixin, ListView):`
161. `"""`
162. `Main view to display all categories and their entries.`
163. ``
164. `"""`
165. `model = EntryCategory`
166. `template_name = "frequently/entry_list.html"`
167. `access_mixin_setting_name = 'FREQUENTLY_ALLOW_ANONYMOUS'`
168. ``
169. `def get_queryset(self):`
170. `"""`
171. `Customized to get the ordered categories and entries from the Mixin.`
172. ``
173. `"""`
174. `self.queryset = super(EntryCategoryListView, self).get_queryset()`
175. `return self.get_ordered_entries(self.queryset)`
176. ``
177. ``
178. `class EntryDetailView(AccessMixin, EntryMixin, DetailView):`
179. `"""`
180. `Main view to display one entry.`
181. ``
182. `"""`
183. `model = Entry`
184. `template_name = "frequently/entry_list.html"`
185. `access_mixin_setting_name = 'FREQUENTLY_ALLOW_ANONYMOUS'`
186. ``
187. `def get_object(self, **kwargs):`
188. `obj = super(EntryDetailView, self).get_object(**kwargs)`
189. `obj.last_view_date = timezone.now()`
190. `obj.amount_of_views += 1`
191. `obj.save()`
192. `return obj`
193. ``
194. `def get_context_data(self, **kwargs):`
195. `context = super(EntryDetailView, self).get_context_data(**kwargs)`
196. `context.update({`
197. `'rated_entries': self.request.session.get('rated_entries', False),`
198. `'object_list': self.get_ordered_entries(),`
199. `})`
200. `for key in self.request.POST.keys(): # pragma: nocover`
201. `if key.startswith('down') or key.startswith('up'):`
202. `context.update({`
203. `'feedback_entry': int(`
204. `key.replace('up', '').replace('down', '')),`
205. `'feedback': self.feedback,`
206. `})`
207. `return context`
208. `return context`
209. ``
210. ``
211. `class EntryCreateView(AccessMixin, CreateView):`
212. `"""`
213. `Feedback submission form view.`
214. ``
215. `"""`
216. `model = Entry`
217. `form_class = EntryForm`
218. `access_mixin_setting_name = 'FREQUENTLY_ALLOW_ANONYMOUS'`
219. ``
220. `def form_valid(self, form):`
221. `messages.add_message(self.request, messages.SUCCESS, _(`
222. `'Your question has been posted. Our team will review it as soon'`
223. `' as possible and get back to you with an answer.'))`
224. `return super(EntryCreateView, self).form_valid(form)`
225. ``
226. `def get_form_kwargs(self):`
227. `kwargs = super(EntryCreateView, self).get_form_kwargs()`
228. `if self.request.user.is_authenticated():`
229. `kwargs.update({`
230. `'owner': self.request.user,`
231. `})`
232. `return kwargs`
233. ``
234. `def get_success_url(self):`
235. `return reverse('frequently_list')`