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