Test coverage report: frequently.views

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

Generated: Fri 2013-09-20 15:24 CEST

Source file: /Users/martin/Repos/django-frequently/frequently/views.py

Stats: 121 executed, 0 missed, 10 excluded, 96 ignored

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