]> git.openstreetmap.org Git - osqa.git/blob - osqa/forum/views/users.py
initial import
[osqa.git] / osqa / forum / views / users.py
1 from django.contrib.auth.decorators import login_required\r
2 from forum.models import User\r
3 from django.core.paginator import Paginator, EmptyPage, InvalidPage\r
4 from django.template.defaultfilters import slugify\r
5 from django.contrib.contenttypes.models import ContentType\r
6 from django.core.urlresolvers import reverse\r
7 from django.shortcuts import render_to_response, get_object_or_404\r
8 from django.template import RequestContext\r
9 from django.http import HttpResponse, HttpResponseForbidden, HttpResponseRedirect, Http404\r
10 from django.utils.translation import ugettext as _\r
11 from django.utils.http import urlquote_plus\r
12 from django.utils.html import strip_tags\r
13 from django.utils import simplejson\r
14 from django.core.urlresolvers import reverse\r
15 from forum.forms import *\r
16 from forum.utils.html import sanitize_html\r
17 from forum.authentication import user_updated \r
18 import time\r
19 from django.contrib.contenttypes.models import ContentType\r
20 \r
21 question_type = ContentType.objects.get_for_model(Question)\r
22 answer_type = ContentType.objects.get_for_model(Answer)\r
23 comment_type = ContentType.objects.get_for_model(Comment)\r
24 question_revision_type = ContentType.objects.get_for_model(QuestionRevision)\r
25 answer_revision_type = ContentType.objects.get_for_model(AnswerRevision)\r
26 repute_type = ContentType.objects.get_for_model(Repute)\r
27 question_type_id = question_type.id\r
28 answer_type_id = answer_type.id\r
29 comment_type_id = comment_type.id\r
30 question_revision_type_id = question_revision_type.id\r
31 answer_revision_type_id = answer_revision_type.id\r
32 repute_type_id = repute_type.id\r
33 \r
34 USERS_PAGE_SIZE = 35# refactor - move to some constants file\r
35 \r
36 def users(request):\r
37     is_paginated = True\r
38     sortby = request.GET.get('sort', 'reputation')\r
39     suser = request.REQUEST.get('q',  "")\r
40     try:\r
41         page = int(request.GET.get('page', '1'))\r
42     except ValueError:\r
43         page = 1\r
44 \r
45     if suser == "":\r
46         if sortby == "newest":\r
47             objects_list = Paginator(User.objects.all().order_by('-date_joined'), USERS_PAGE_SIZE)\r
48         elif sortby == "last":\r
49             objects_list = Paginator(User.objects.all().order_by('date_joined'), USERS_PAGE_SIZE)\r
50         elif sortby == "user":\r
51             objects_list = Paginator(User.objects.all().order_by('username'), USERS_PAGE_SIZE)\r
52         # default\r
53         else:\r
54             objects_list = Paginator(User.objects.all().order_by('-reputation'), USERS_PAGE_SIZE)\r
55         base_url = reverse('users') + '?sort=%s&' % sortby\r
56     else:\r
57         sortby = "reputation"\r
58         objects_list = Paginator(User.objects.filter(username__icontains=suser).order_by('-reputation'), USERS_PAGE_SIZE)\r
59         base_url = reverse('users') + '?name=%s&sort=%s&' % (suser, sortby)\r
60 \r
61     try:\r
62         users = objects_list.page(page)\r
63     except (EmptyPage, InvalidPage):\r
64         users = objects_list.page(objects_list.num_pages)\r
65 \r
66     return render_to_response('users.html', {\r
67                                 "users" : users,\r
68                                 "suser" : suser,\r
69                                 "keywords" : suser,\r
70                                 "tab_id" : sortby,\r
71                                 "context" : {\r
72                                     'is_paginated' : is_paginated,\r
73                                     'pages': objects_list.num_pages,\r
74                                     'page': page,\r
75                                     'has_previous': users.has_previous(),\r
76                                     'has_next': users.has_next(),\r
77                                     'previous': users.previous_page_number(),\r
78                                     'next': users.next_page_number(),\r
79                                     'base_url' : base_url\r
80                                 }\r
81 \r
82                                 }, context_instance=RequestContext(request))\r
83 \r
84 @login_required\r
85 def moderate_user(request, id):\r
86     """ajax handler of user moderation\r
87     """\r
88     if not request.user.is_superuser or request.method != 'POST':\r
89         raise Http404\r
90     if not request.is_ajax():\r
91         return HttpResponseForbidden(mimetype="application/json")\r
92 \r
93     user = get_object_or_404(User, id=id)\r
94     form = ModerateUserForm(request.POST, instance=user)\r
95 \r
96     if form.is_valid():\r
97         form.save()\r
98         logging.debug('data saved')\r
99         response = HttpResponse(simplejson.dumps(''), mimetype="application/json")\r
100     else:\r
101         response = HttpResponseForbidden(mimetype="application/json")\r
102     return response\r
103 \r
104 def set_new_email(user, new_email, nomessage=False):\r
105     if new_email != user.email:\r
106         user.email = new_email\r
107         user.email_isvalid = False\r
108         user.save()\r
109         #if settings.EMAIL_VALIDATION == 'on':\r
110         #    send_new_email_key(user,nomessage=nomessage)    \r
111 \r
112 @login_required\r
113 def edit_user(request, id):\r
114     user = get_object_or_404(User, id=id)\r
115     if request.user != user:\r
116         raise Http404\r
117     if request.method == "POST":\r
118         form = EditUserForm(user, request.POST)\r
119         if form.is_valid():\r
120             new_email = sanitize_html(form.cleaned_data['email'])\r
121 \r
122             set_new_email(user, new_email)\r
123 \r
124             #user.username = sanitize_html(form.cleaned_data['username'])\r
125             user.real_name = sanitize_html(form.cleaned_data['realname'])\r
126             user.website = sanitize_html(form.cleaned_data['website'])\r
127             user.location = sanitize_html(form.cleaned_data['city'])\r
128             user.date_of_birth = sanitize_html(form.cleaned_data['birthday'])\r
129             if len(user.date_of_birth) == 0:\r
130                 user.date_of_birth = '1900-01-01'\r
131             user.about = sanitize_html(form.cleaned_data['about'])\r
132 \r
133             user.save()\r
134             # send user updated singal if full fields have been updated\r
135             if user.email and user.real_name and user.website and user.location and \\r
136                 user.date_of_birth and user.about:\r
137                 user_updated.send(sender=user.__class__, instance=user, updated_by=user)\r
138             return HttpResponseRedirect(user.get_profile_url())\r
139     else:\r
140         form = EditUserForm(user)\r
141     return render_to_response('user_edit.html', {\r
142                                                 'form' : form,\r
143                                                 'gravatar_faq_url' : reverse('faq') + '#gravatar',\r
144                                     }, context_instance=RequestContext(request))\r
145 \r
146 def user_stats(request, user_id, user_view):\r
147     user = get_object_or_404(User, id=user_id)\r
148 \r
149     questions = Question.objects.filter(deleted=False, author=user).order_by('-added_at')\r
150 \r
151     answered_questions = Question.objects.extra(\r
152         select={\r
153             'vote_up_count' : 'answer.vote_up_count',\r
154             'vote_down_count' : 'answer.vote_down_count',\r
155             'answer_id' : 'answer.id',\r
156             'accepted' : 'answer.accepted',\r
157             'vote_count' : 'answer.score',\r
158             'comment_count' : 'answer.comment_count'\r
159             },\r
160         tables=['question', 'answer'],\r
161         where=['NOT answer.deleted AND NOT question.deleted AND answer.author_id=%s AND answer.question_id=question.id'],\r
162         params=[user_id],\r
163         order_by=['-vote_count', '-answer_id'],\r
164         select_params=[user_id]\r
165     ).distinct().values('comment_count',\r
166                         'id',\r
167                         'answer_id',\r
168                         'title',\r
169                         'author_id',\r
170                         'accepted',\r
171                         'vote_count',\r
172                         'answer_count',\r
173                         'vote_up_count',\r
174                         'vote_down_count')[:100]\r
175 \r
176     up_votes = user.get_up_vote_count()\r
177     down_votes = user.get_down_vote_count()\r
178     votes_today = user.get_vote_count_today()\r
179     votes_total = int(settings.MAX_VOTES_PER_DAY)\r
180 \r
181     #question_id_set = set(map(lambda v: v['id'], list(questions))) \\r
182     #                    | set(map(lambda v: v['id'], list(answered_questions)))\r
183 \r
184     user_tags = Tag.objects.filter(questions__author=user)\r
185     try:\r
186         from django.db.models import Count\r
187         awards = Award.objects.extra(\r
188                                         select={'id': 'badge.id', \r
189                                                 'name':'badge.name', \r
190                                                 'description': 'badge.description', \r
191                                                 'type': 'badge.type'},\r
192                                         tables=['award', 'badge'],\r
193                                         order_by=['-awarded_at'],\r
194                                         where=['user_id=%s AND badge_id=badge.id'],\r
195                                         params=[user.id]\r
196                                     ).values('id', 'name', 'description', 'type')\r
197         total_awards = awards.count()\r
198         awards = awards.annotate(count = Count('badge__id'))\r
199         user_tags = user_tags.annotate(user_tag_usage_count=Count('name'))\r
200 \r
201     except ImportError:\r
202         awards = Award.objects.extra(\r
203                                         select={'id': 'badge.id', \r
204                                                 'count': 'count(badge_id)', \r
205                                                 'name':'badge.name', \r
206                                                 'description': 'badge.description', \r
207                                                 'type': 'badge.type'},\r
208                                         tables=['award', 'badge'],\r
209                                         order_by=['-awarded_at'],\r
210                                         where=['user_id=%s AND badge_id=badge.id'],\r
211                                         params=[user.id]\r
212                                     ).values('id', 'count', 'name', 'description', 'type')\r
213         total_awards = awards.count()\r
214         awards.query.group_by = ['badge_id']\r
215 \r
216         user_tags = user_tags.extra(\r
217             select={'user_tag_usage_count': 'COUNT(1)',},\r
218             order_by=['-user_tag_usage_count'],\r
219         )\r
220         user_tags.query.group_by = ['name']\r
221 \r
222     if request.user.is_superuser:\r
223         moderate_user_form = ModerateUserForm(instance=user)\r
224     else:\r
225         moderate_user_form = None\r
226 \r
227     return render_to_response(user_view.template_file,{\r
228                                 'moderate_user_form': moderate_user_form,\r
229                                 "tab_name" : user_view.id,\r
230                                 "tab_description" : user_view.tab_description,\r
231                                 "page_title" : user_view.page_title,\r
232                                 "view_user" : user,\r
233                                 "questions" : questions,\r
234                                 "answered_questions" : answered_questions,\r
235                                 "up_votes" : up_votes,\r
236                                 "down_votes" : down_votes,\r
237                                 "total_votes": up_votes + down_votes,\r
238                                 "votes_today_left": votes_total-votes_today,\r
239                                 "votes_total_per_day": votes_total,\r
240                                 "user_tags" : user_tags[:50],\r
241                                 "awards": awards,\r
242                                 "total_awards" : total_awards,\r
243                             }, context_instance=RequestContext(request))\r
244 \r
245 def user_recent(request, user_id, user_view):\r
246     user = get_object_or_404(User, id=user_id)\r
247     def get_type_name(type_id):\r
248         for item in TYPE_ACTIVITY:\r
249             if type_id in item:\r
250                 return item[1]\r
251 \r
252     class Event:\r
253         def __init__(self, time, type, title, summary, answer_id, question_id):\r
254             self.time = time\r
255             self.type = get_type_name(type)\r
256             self.type_id = type\r
257             self.title = title\r
258             self.summary = summary\r
259             slug_title = slugify(title)\r
260             self.title_link = reverse('question', kwargs={'id':question_id, 'slug':slug_title})\r
261             if int(answer_id) > 0:\r
262                 self.title_link += '#%s' % answer_id\r
263 \r
264     class AwardEvent:\r
265         def __init__(self, time, type, id):\r
266             self.time = time\r
267             self.type = get_type_name(type)\r
268             self.type_id = type\r
269             self.badge = get_object_or_404(Badge, id=id)\r
270 \r
271     activities = []\r
272     # ask questions\r
273     questions = Activity.objects.extra(\r
274         select={\r
275             'title' : 'question.title',\r
276             'question_id' : 'question.id',\r
277             'active_at' : 'activity.active_at',\r
278             'activity_type' : 'activity.activity_type'\r
279             },\r
280         tables=['activity', 'question'],\r
281         where=['activity.content_type_id = %s AND activity.object_id = ' +\r
282             'question.id AND NOT question.deleted AND activity.user_id = %s AND activity.activity_type = %s'],\r
283         params=[question_type_id, user_id, TYPE_ACTIVITY_ASK_QUESTION],\r
284         order_by=['-activity.active_at']\r
285     ).values(\r
286             'title',\r
287             'question_id',\r
288             'active_at',\r
289             'activity_type'\r
290             )\r
291     if len(questions) > 0:\r
292         questions = [(Event(q['active_at'], q['activity_type'], q['title'], '', '0', \\r
293                       q['question_id'])) for q in questions]\r
294         activities.extend(questions)\r
295 \r
296     # answers\r
297     answers = Activity.objects.extra(\r
298         select={\r
299             'title' : 'question.title',\r
300             'question_id' : 'question.id',\r
301             'answer_id' : 'answer.id',\r
302             'active_at' : 'activity.active_at',\r
303             'activity_type' : 'activity.activity_type'\r
304             },\r
305         tables=['activity', 'answer', 'question'],\r
306         where=['activity.content_type_id = %s AND activity.object_id = answer.id AND ' + \r
307             'answer.question_id=question.id AND NOT answer.deleted AND activity.user_id=%s AND '+\r
308             'activity.activity_type=%s AND NOT question.deleted'],\r
309         params=[answer_type_id, user_id, TYPE_ACTIVITY_ANSWER],\r
310         order_by=['-activity.active_at']\r
311     ).values(\r
312             'title',\r
313             'question_id',\r
314             'answer_id',\r
315             'active_at',\r
316             'activity_type'\r
317             )\r
318     if len(answers) > 0:\r
319         answers = [(Event(q['active_at'], q['activity_type'], q['title'], '', q['answer_id'], \\r
320                     q['question_id'])) for q in answers]\r
321         activities.extend(answers)\r
322 \r
323     # question comments\r
324     comments = Activity.objects.extra(\r
325         select={\r
326             'title' : 'question.title',\r
327             'question_id' : 'comment.object_id',\r
328             'added_at' : 'comment.added_at',\r
329             'activity_type' : 'activity.activity_type'\r
330             },\r
331         tables=['activity', 'question', 'comment'],\r
332 \r
333         where=['activity.content_type_id = %s AND activity.object_id = comment.id AND '+\r
334             'activity.user_id = comment.user_id AND comment.object_id=question.id AND '+\r
335             'comment.content_type_id=%s AND activity.user_id = %s AND activity.activity_type=%s AND ' +\r
336             'NOT question.deleted'],\r
337         params=[comment_type_id, question_type_id, user_id, TYPE_ACTIVITY_COMMENT_QUESTION],\r
338         order_by=['-comment.added_at']\r
339     ).values(\r
340             'title',\r
341             'question_id',\r
342             'added_at',\r
343             'activity_type'\r
344             )\r
345 \r
346     if len(comments) > 0:\r
347         comments = [(Event(q['added_at'], q['activity_type'], q['title'], '', '0', \\r
348                      q['question_id'])) for q in comments]\r
349         activities.extend(comments)\r
350 \r
351     # answer comments\r
352     comments = Activity.objects.extra(\r
353         select={\r
354             'title' : 'question.title',\r
355             'question_id' : 'question.id',\r
356             'answer_id' : 'answer.id',\r
357             'added_at' : 'comment.added_at',\r
358             'activity_type' : 'activity.activity_type'\r
359             },\r
360         tables=['activity', 'question', 'answer', 'comment'],\r
361 \r
362         where=['activity.content_type_id = %s AND activity.object_id = comment.id AND '+\r
363             'activity.user_id = comment.user_id AND comment.object_id=answer.id AND '+\r
364             'comment.content_type_id=%s AND question.id = answer.question_id AND '+\r
365             'activity.user_id = %s AND activity.activity_type=%s AND '+\r
366             'NOT answer.deleted AND NOT question.deleted'],\r
367         params=[comment_type_id, answer_type_id, user_id, TYPE_ACTIVITY_COMMENT_ANSWER],\r
368         order_by=['-comment.added_at']\r
369     ).values(\r
370             'title',\r
371             'question_id',\r
372             'answer_id',\r
373             'added_at',\r
374             'activity_type'\r
375             )\r
376 \r
377     if len(comments) > 0:\r
378         comments = [(Event(q['added_at'], q['activity_type'], q['title'], '', q['answer_id'], \\r
379                      q['question_id'])) for q in comments]\r
380         activities.extend(comments)\r
381 \r
382     # question revisions\r
383     revisions = Activity.objects.extra(\r
384         select={\r
385             'title' : 'question_revision.title',\r
386             'question_id' : 'question_revision.question_id',\r
387             'added_at' : 'activity.active_at',\r
388             'activity_type' : 'activity.activity_type',\r
389             'summary' : 'question_revision.summary'\r
390             },\r
391         tables=['activity', 'question_revision', 'question'],\r
392         where=['activity.content_type_id = %s AND activity.object_id = question_revision.id AND '+\r
393             'question_revision.id=question.id AND NOT question.deleted AND '+\r
394             'activity.user_id = question_revision.author_id AND activity.user_id = %s AND '+\r
395             'activity.activity_type=%s'],\r
396         params=[question_revision_type_id, user_id, TYPE_ACTIVITY_UPDATE_QUESTION],\r
397         order_by=['-activity.active_at']\r
398     ).values(\r
399             'title',\r
400             'question_id',\r
401             'added_at',\r
402             'activity_type',\r
403             'summary'\r
404             )\r
405 \r
406     if len(revisions) > 0:\r
407         revisions = [(Event(q['added_at'], q['activity_type'], q['title'], q['summary'], '0', \\r
408                       q['question_id'])) for q in revisions]\r
409         activities.extend(revisions)\r
410 \r
411     # answer revisions\r
412     revisions = Activity.objects.extra(\r
413         select={\r
414             'title' : 'question.title',\r
415             'question_id' : 'question.id',\r
416             'answer_id' : 'answer.id',\r
417             'added_at' : 'activity.active_at',\r
418             'activity_type' : 'activity.activity_type',\r
419             'summary' : 'answer_revision.summary'\r
420             },\r
421         tables=['activity', 'answer_revision', 'question', 'answer'],\r
422 \r
423         where=['activity.content_type_id = %s AND activity.object_id = answer_revision.id AND '+\r
424             'activity.user_id = answer_revision.author_id AND activity.user_id = %s AND '+\r
425             'answer_revision.answer_id=answer.id AND answer.question_id = question.id AND '+\r
426             'NOT question.deleted AND NOT answer.deleted AND '+\r
427             'activity.activity_type=%s'],\r
428         params=[answer_revision_type_id, user_id, TYPE_ACTIVITY_UPDATE_ANSWER],\r
429         order_by=['-activity.active_at']\r
430     ).values(\r
431             'title',\r
432             'question_id',\r
433             'added_at',\r
434             'answer_id',\r
435             'activity_type',\r
436             'summary'\r
437             )\r
438 \r
439     if len(revisions) > 0:\r
440         revisions = [(Event(q['added_at'], q['activity_type'], q['title'], q['summary'], \\r
441                       q['answer_id'], q['question_id'])) for q in revisions]\r
442         activities.extend(revisions)\r
443 \r
444     # accepted answers\r
445     accept_answers = Activity.objects.extra(\r
446         select={\r
447             'title' : 'question.title',\r
448             'question_id' : 'question.id',\r
449             'added_at' : 'activity.active_at',\r
450             'activity_type' : 'activity.activity_type',\r
451             },\r
452         tables=['activity', 'answer', 'question'],\r
453         where=['activity.content_type_id = %s AND activity.object_id = answer.id AND '+\r
454             'activity.user_id = question.author_id AND activity.user_id = %s AND '+\r
455             'NOT answer.deleted AND NOT question.deleted AND '+\r
456             'answer.question_id=question.id AND activity.activity_type=%s'],\r
457         params=[answer_type_id, user_id, TYPE_ACTIVITY_MARK_ANSWER],\r
458         order_by=['-activity.active_at']\r
459     ).values(\r
460             'title',\r
461             'question_id',\r
462             'added_at',\r
463             'activity_type',\r
464             )\r
465     if len(accept_answers) > 0:\r
466         accept_answers = [(Event(q['added_at'], q['activity_type'], q['title'], '', '0', \\r
467             q['question_id'])) for q in accept_answers]\r
468         activities.extend(accept_answers)\r
469     #award history\r
470     awards = Activity.objects.extra(\r
471         select={\r
472             'badge_id' : 'badge.id',\r
473             'awarded_at': 'award.awarded_at',\r
474             'activity_type' : 'activity.activity_type'\r
475             },\r
476         tables=['activity', 'award', 'badge'],\r
477         where=['activity.user_id = award.user_id AND activity.user_id = %s AND '+\r
478             'award.badge_id=badge.id AND activity.object_id=award.id AND activity.activity_type=%s'],\r
479         params=[user_id, TYPE_ACTIVITY_PRIZE],\r
480         order_by=['-activity.active_at']\r
481     ).values(\r
482             'badge_id',\r
483             'awarded_at',\r
484             'activity_type'\r
485             )\r
486     if len(awards) > 0:\r
487         awards = [(AwardEvent(q['awarded_at'], q['activity_type'], q['badge_id'])) for q in awards]\r
488         activities.extend(awards)\r
489 \r
490     activities.sort(lambda x,y: cmp(y.time, x.time))\r
491 \r
492     return render_to_response(user_view.template_file,{\r
493                                     "tab_name" : user_view.id,\r
494                                     "tab_description" : user_view.tab_description,\r
495                                     "page_title" : user_view.page_title,\r
496                                     "view_user" : user,\r
497                                     "activities" : activities[:user_view.data_size]\r
498                                 }, context_instance=RequestContext(request))\r
499 \r
500 def user_responses(request, user_id, user_view):\r
501     """\r
502     We list answers for question, comments, and answer accepted by others for this user.\r
503     """\r
504     class Response:\r
505         def __init__(self, type, title, question_id, answer_id, time, username, user_id, content):\r
506             self.type = type\r
507             self.title = title\r
508             self.titlelink = reverse('question', args=[question_id]) + u'%s#%s' % (slugify(title), answer_id)\r
509             self.time = time\r
510             self.userlink = reverse('users') + u'%s/%s/' % (user_id, username)\r
511             self.username = username\r
512             self.content = u'%s ...' % strip_tags(content)[:300]\r
513 \r
514         def __unicode__(self):\r
515             return u'%s %s' % (self.type, self.titlelink)\r
516 \r
517     user = get_object_or_404(User, id=user_id)\r
518     responses = []\r
519     answers = Answer.objects.extra(\r
520                                     select={\r
521                                         'title' : 'question.title',\r
522                                         'question_id' : 'question.id',\r
523                                         'answer_id' : 'answer.id',\r
524                                         'added_at' : 'answer.added_at',\r
525                                         'html' : 'answer.html',\r
526                                         'username' : 'auth_user.username',\r
527                                         'user_id' : 'auth_user.id'\r
528                                         },\r
529                                     select_params=[user_id],\r
530                                     tables=['answer', 'question', 'auth_user'],\r
531                                     where=['answer.question_id = question.id AND NOT answer.deleted AND NOT question.deleted AND '+\r
532                                         'question.author_id = %s AND answer.author_id <> %s AND answer.author_id=auth_user.id'],\r
533                                     params=[user_id, user_id],\r
534                                     order_by=['-answer.id']\r
535                                 ).values(\r
536                                         'title',\r
537                                         'question_id',\r
538                                         'answer_id',\r
539                                         'added_at',\r
540                                         'html',\r
541                                         'username',\r
542                                         'user_id'\r
543                                         )\r
544     if len(answers) > 0:\r
545         answers = [(Response(TYPE_RESPONSE['QUESTION_ANSWERED'], a['title'], a['question_id'],\r
546         a['answer_id'], a['added_at'], a['username'], a['user_id'], a['html'])) for a in answers]\r
547         responses.extend(answers)\r
548 \r
549 \r
550     # question comments\r
551     comments = Comment.active.extra(\r
552                                 select={\r
553                                     'title' : 'question.title',\r
554                                     'question_id' : 'comment.object_id',\r
555                                     'added_at' : 'comment.added_at',\r
556                                     'comment' : 'comment.comment',\r
557                                     'username' : 'auth_user.username',\r
558                                     'user_id' : 'auth_user.id'\r
559                                     },\r
560                                 tables=['question', 'auth_user', 'comment'],\r
561                                 where=['NOT question.deleted AND question.author_id = %s AND comment.object_id=question.id AND '+\r
562                                     'comment.content_type_id=%s AND comment.user_id <> %s AND comment.user_id = auth_user.id'],\r
563                                 params=[user_id, question_type_id, user_id],\r
564                                 order_by=['-comment.added_at']\r
565                             ).values(\r
566                                     'title',\r
567                                     'question_id',\r
568                                     'added_at',\r
569                                     'comment',\r
570                                     'username',\r
571                                     'user_id'\r
572                                     )\r
573 \r
574     if len(comments) > 0:\r
575         comments = [(Response(TYPE_RESPONSE['QUESTION_COMMENTED'], c['title'], c['question_id'],\r
576             '', c['added_at'], c['username'], c['user_id'], c['comment'])) for c in comments]\r
577         responses.extend(comments)\r
578 \r
579     # answer comments\r
580     comments = Comment.active.extra(\r
581         select={\r
582             'title' : 'question.title',\r
583             'question_id' : 'question.id',\r
584             'answer_id' : 'answer.id',\r
585             'added_at' : 'comment.added_at',\r
586             'comment' : 'comment.comment',\r
587             'username' : 'auth_user.username',\r
588             'user_id' : 'auth_user.id'\r
589             },\r
590         tables=['answer', 'auth_user', 'comment', 'question'],\r
591         where=['NOT answer.deleted AND answer.author_id = %s AND comment.object_id=answer.id AND '+\r
592             'comment.content_type_id=%s AND comment.user_id <> %s AND comment.user_id = auth_user.id '+\r
593             'AND question.id = answer.question_id'],\r
594         params=[user_id, answer_type_id, user_id],\r
595         order_by=['-comment.added_at']\r
596     ).values(\r
597             'title',\r
598             'question_id',\r
599             'answer_id',\r
600             'added_at',\r
601             'comment',\r
602             'username',\r
603             'user_id'\r
604             )\r
605 \r
606     if len(comments) > 0:\r
607         comments = [(Response(TYPE_RESPONSE['ANSWER_COMMENTED'], c['title'], c['question_id'],\r
608         c['answer_id'], c['added_at'], c['username'], c['user_id'], c['comment'])) for c in comments]\r
609         responses.extend(comments)\r
610 \r
611     # answer has been accepted\r
612     answers = Answer.objects.extra(\r
613         select={\r
614             'title' : 'question.title',\r
615             'question_id' : 'question.id',\r
616             'answer_id' : 'answer.id',\r
617             'added_at' : 'answer.accepted_at',\r
618             'html' : 'answer.html',\r
619             'username' : 'auth_user.username',\r
620             'user_id' : 'auth_user.id'\r
621             },\r
622         select_params=[user_id],\r
623         tables=['answer', 'question', 'auth_user'],\r
624         where=['answer.question_id = question.id AND NOT answer.deleted AND NOT question.deleted AND '+\r
625             'answer.author_id = %s AND answer.accepted=True AND question.author_id=auth_user.id'],\r
626         params=[user_id],\r
627         order_by=['-answer.id']\r
628     ).values(\r
629             'title',\r
630             'question_id',\r
631             'answer_id',\r
632             'added_at',\r
633             'html',\r
634             'username',\r
635             'user_id'\r
636             )\r
637     if len(answers) > 0:\r
638         answers = [(Response(TYPE_RESPONSE['ANSWER_ACCEPTED'], a['title'], a['question_id'],\r
639             a['answer_id'], a['added_at'], a['username'], a['user_id'], a['html'])) for a in answers]\r
640         responses.extend(answers)\r
641 \r
642     # sort posts by time\r
643     responses.sort(lambda x,y: cmp(y.time, x.time))\r
644 \r
645     return render_to_response(user_view.template_file,{\r
646         "tab_name" : user_view.id,\r
647         "tab_description" : user_view.tab_description,\r
648         "page_title" : user_view.page_title,\r
649         "view_user" : user,\r
650         "responses" : responses[:user_view.data_size],\r
651 \r
652     }, context_instance=RequestContext(request))\r
653 \r
654 def user_votes(request, user_id, user_view):\r
655     user = get_object_or_404(User, id=user_id)\r
656     if not request.user == user:\r
657         raise Http404\r
658     votes = []\r
659     question_votes = Vote.active.extra(\r
660         select={\r
661             'title' : 'question.title',\r
662             'question_id' : 'question.id',\r
663             'answer_id' : 0,\r
664             'voted_at' : 'vote.voted_at',\r
665             'vote' : 'vote',\r
666             },\r
667         select_params=[user_id],\r
668         tables=['vote', 'question', 'auth_user'],\r
669         where=['vote.content_type_id = %s AND vote.user_id = %s AND vote.object_id = question.id '+\r
670             'AND vote.user_id=auth_user.id'],\r
671         params=[question_type_id, user_id],\r
672         order_by=['-vote.id']\r
673     ).values(\r
674             'title',\r
675             'question_id',\r
676             'answer_id',\r
677             'voted_at',\r
678             'vote',\r
679             )\r
680     if(len(question_votes) > 0):\r
681         votes.extend(question_votes)\r
682 \r
683     answer_votes = Vote.active.extra(\r
684         select={\r
685             'title' : 'question.title',\r
686             'question_id' : 'question.id',\r
687             'answer_id' : 'answer.id',\r
688             'voted_at' : 'vote.voted_at',\r
689             'vote' : 'vote',\r
690             },\r
691         select_params=[user_id],\r
692         tables=['vote', 'answer', 'question', 'auth_user'],\r
693         where=['vote.content_type_id = %s AND vote.user_id = %s AND vote.object_id = answer.id '+\r
694             'AND answer.question_id = question.id AND vote.user_id=auth_user.id'],\r
695         params=[answer_type_id, user_id],\r
696         order_by=['-vote.id']\r
697     ).values(\r
698             'title',\r
699             'question_id',\r
700             'answer_id',\r
701             'voted_at',\r
702             'vote',\r
703             )\r
704 \r
705     if(len(answer_votes) > 0):\r
706         votes.extend(answer_votes)\r
707     votes.sort(lambda x,y: cmp(y['voted_at'], x['voted_at']))\r
708     return render_to_response(user_view.template_file,{\r
709         "tab_name" : user_view.id,\r
710         "tab_description" : user_view.tab_description,\r
711         "page_title" : user_view.page_title,\r
712         "view_user" : user,\r
713         "votes" : votes[:user_view.data_size]\r
714 \r
715     }, context_instance=RequestContext(request))\r
716 \r
717 def user_reputation(request, user_id, user_view):\r
718     user = get_object_or_404(User, id=user_id)\r
719 \r
720     reputation = user.reputes.order_by('-reputed_at')\r
721 \r
722     graph_data = simplejson.dumps([\r
723             (time.mktime(rep.reputed_at.timetuple()) * 1000, rep.reputation)\r
724             for rep in reputation\r
725     ])\r
726 \r
727     return render_to_response(user_view.template_file, {\r
728                               "tab_name": user_view.id,\r
729                               "tab_description": user_view.tab_description,\r
730                               "page_title": user_view.page_title,\r
731                               "view_user": user,\r
732                               "reputation": reputation,\r
733                               "graph_data": graph_data\r
734                               }, context_instance=RequestContext(request))\r
735 \r
736 def user_favorites(request, user_id, user_view):\r
737     user = get_object_or_404(User, id=user_id)\r
738     questions = Question.objects.extra(\r
739         select={\r
740             'vote_count' : 'question.vote_up_count + question.vote_down_count',\r
741             'favorited_myself' : 'SELECT count(*) FROM favorite_question f WHERE f.user_id = %s '+\r
742                 'AND f.question_id = question.id',\r
743             'la_user_id' : 'auth_user.id',\r
744             'la_username' : 'auth_user.username',\r
745             'la_user_gold' : 'forum_user.gold',\r
746             'la_user_silver' : 'forum_user.silver',\r
747             'la_user_bronze' : 'forum_user.bronze',\r
748             'la_user_reputation' : 'forum_user.reputation'\r
749             },\r
750         select_params=[user_id],\r
751         tables=['question', 'auth_user', 'favorite_question', 'forum_user'],\r
752         where=['NOT question.deleted AND question.last_activity_by_id = auth_user.id '+\r
753             'AND favorite_question.question_id = question.id AND favorite_question.user_id = %s AND forum_user.user_ptr_id = auth_user.id'],\r
754         params=[user_id],\r
755         order_by=['-vote_count', '-question.id']\r
756     ).values('vote_count',\r
757              'favorited_myself',\r
758              'id',\r
759              'title',\r
760              'author_id',\r
761              'added_at',\r
762              'answer_accepted',\r
763              'answer_count',\r
764              'comment_count',\r
765              'view_count',\r
766              'favourite_count',\r
767              'summary',\r
768              'tagnames',\r
769              'vote_up_count',\r
770              'vote_down_count',\r
771              'last_activity_at',\r
772              'la_user_id',\r
773              'la_username',\r
774              'la_user_gold',\r
775              'la_user_silver',\r
776              'la_user_bronze',\r
777              'la_user_reputation')\r
778     return render_to_response(user_view.template_file,{\r
779         "tab_name" : user_view.id,\r
780         "tab_description" : user_view.tab_description,\r
781         "page_title" : user_view.page_title,\r
782         "questions" : questions[:user_view.data_size],\r
783         "view_user" : user\r
784     }, context_instance=RequestContext(request))\r
785 \r
786 def user_subscription_settings(request, user_id, user_view):\r
787     user = get_object_or_404(User, id=user_id)\r
788 \r
789     if request.method == 'POST':\r
790         form = SubscriptionSettingsForm(request.POST)\r
791 \r
792         if 'notswitch' in request.POST:\r
793             user.subscription_settings.enable_notifications = not user.subscription_settings.enable_notifications\r
794             user.subscription_settings.save()\r
795 \r
796             if user.subscription_settings.enable_notifications:\r
797                 request.user.message_set.create(message=_('Notifications are now enabled'))\r
798             else:\r
799                 request.user.message_set.create(message=_('Notifications are now disabled'))\r
800         else:\r
801             form.is_valid()\r
802             for k,v in form.cleaned_data.items():\r
803                 setattr(user.subscription_settings, k, v)\r
804 \r
805             user.subscription_settings.save()\r
806             request.user.message_set.create(message=_('New subscription settings are now saved'))\r
807     else:\r
808         form = SubscriptionSettingsForm(user.subscription_settings.__dict__)\r
809 \r
810     notificatons_on = user.subscription_settings.enable_notifications\r
811 \r
812     return render_to_response(user_view.template_file,{\r
813         'tab_name':user_view.id,\r
814         'tab_description':user_view.tab_description,\r
815         'page_title':user_view.page_title,\r
816         'view_user':user,\r
817         'notificatons_on': notificatons_on,\r
818         'form':form,\r
819     }, context_instance=RequestContext(request))\r
820 \r
821 class UserView:\r
822     def __init__(self, id, tab_title, tab_description, page_title, view_func, template_file, data_size=0):\r
823         self.id = id\r
824         self.tab_title = tab_title\r
825         self.tab_description = tab_description\r
826         self.page_title = page_title\r
827         self.view_func = view_func \r
828         self.template_file = template_file\r
829         self.data_size = data_size\r
830         \r
831 USER_TEMPLATE_VIEWS = (\r
832     UserView(\r
833         id = 'stats',\r
834         tab_title = _('overview'),\r
835         tab_description = _('user profile'),\r
836         page_title = _('user profile overview'),\r
837         view_func = user_stats,\r
838         template_file = 'user_stats.html'\r
839     ),\r
840     UserView(\r
841         id = 'recent',\r
842         tab_title = _('recent activity'),\r
843         tab_description = _('recent user activity'),\r
844         page_title = _('profile - recent activity'),\r
845         view_func = user_recent,\r
846         template_file = 'user_recent.html',\r
847         data_size = 50\r
848     ),\r
849     UserView(\r
850         id = 'responses',\r
851         tab_title = _('responses'),\r
852         tab_description = _('comments and answers to others questions'),\r
853         page_title = _('profile - responses'),\r
854         view_func = user_responses,\r
855         template_file = 'user_responses.html',\r
856         data_size = 50\r
857     ),\r
858     UserView(\r
859         id = 'reputation',\r
860         tab_title = _('reputation'),\r
861         tab_description = _('user reputation in the community'),\r
862         page_title = _('profile - user reputation'),\r
863         view_func = user_reputation,\r
864         template_file = 'user_reputation.html'\r
865     ),\r
866     UserView(\r
867         id = 'favorites',\r
868         tab_title = _('favorite questions'),\r
869         tab_description = _('users favorite questions'),\r
870         page_title = _('profile - favorite questions'),\r
871         view_func = user_favorites,\r
872         template_file = 'user_favorites.html',\r
873         data_size = 50\r
874     ),\r
875     UserView(\r
876         id = 'votes',\r
877         tab_title = _('casted votes'),\r
878         tab_description = _('user vote record'),\r
879         page_title = _('profile - votes'),\r
880         view_func = user_votes,\r
881         template_file = 'user_votes.html',\r
882         data_size = 50\r
883     ),\r
884     UserView(\r
885         id = 'subscriptions',\r
886         tab_title = _('subscriptions'),\r
887         tab_description = _('subscription settings'),\r
888         page_title = _('profile - subscriptions'),\r
889         view_func = user_subscription_settings,\r
890         template_file = 'user_subscriptions.html'\r
891     )\r
892 )\r
893 \r
894 def user(request, id, slug=None):\r
895     sort = request.GET.get('sort', 'stats')\r
896     user_view = dict((v.id, v) for v in USER_TEMPLATE_VIEWS).get(sort, USER_TEMPLATE_VIEWS[0])\r
897     from forum.views import users\r
898     func = user_view.view_func\r
899     return func(request, id, user_view)\r
900 \r
901 @login_required\r
902 def account_settings(request):\r
903     """\r
904     index pages to changes some basic account settings :\r
905      - change password\r
906      - change email\r
907      - associate a new openid\r
908      - delete account\r
909 \r
910     url : /\r
911 \r
912     template : authopenid/settings.html\r
913     """\r
914     logging.debug('')\r
915     msg = request.GET.get('msg', '')\r
916     is_openid = False\r
917 \r
918     return render_to_response('account_settings.html', {\r
919         'msg': msg,\r
920         'is_openid': is_openid\r
921         }, context_instance=RequestContext(request))\r
922 \r