views.py 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. from datetime import timedelta
  2. from django.core.cache import cache
  3. from django.core.urlresolvers import reverse
  4. from django.shortcuts import redirect
  5. from django.template import RequestContext
  6. from django.utils import timezone
  7. from django.utils.translation import ugettext as _
  8. from misago.authn.decorators import block_guest
  9. from misago.csrf.decorators import check_csrf
  10. from misago.forums.models import Forum
  11. from misago.messages import Message
  12. from misago.readstracker.models import ForumRecord, ThreadRecord
  13. from misago.readstracker.trackers import ForumsTracker
  14. from misago.ranks.models import Rank
  15. from misago.sessions.models import Session
  16. from misago.threads.models import Thread, Post
  17. from misago.utils import make_pagination
  18. def home(request):
  19. # Threads ranking
  20. popular_threads = []
  21. if request.settings['thread_ranking_size'] > 0:
  22. popular_threads = cache.get('thread_ranking_%s' % request.user.make_acl_key(), 'nada')
  23. if popular_threads == 'nada':
  24. popular_threads = []
  25. for thread in Thread.objects.filter(moderated=False).filter(deleted=False).filter(forum__in=request.acl.threads.get_readable_forums(request.acl)).prefetch_related('forum').order_by('-score')[:request.settings['thread_ranking_size']]:
  26. thread.forum_name = thread.forum.name
  27. thread.forum_slug = thread.forum.slug
  28. popular_threads.append(thread)
  29. cache.set('thread_ranking_%s' % request.user.make_acl_key(), popular_threads, 60 * request.settings['thread_ranking_refresh'])
  30. # Ranks online
  31. ranks_list = cache.get('ranks_online', 'nada')
  32. if ranks_list == 'nada':
  33. ranks_dict = {}
  34. ranks_list = []
  35. users_list = []
  36. for rank in Rank.objects.filter(on_index=True).order_by('order'):
  37. rank_entry = {'id':rank.id, 'name': rank.name, 'style': rank.style, 'title': rank.title, 'online': []}
  38. ranks_list.append(rank_entry)
  39. ranks_dict[rank.pk] = rank_entry
  40. if ranks_dict:
  41. for session in Session.objects.select_related('user').filter(rank__in=ranks_dict.keys()).filter(last__gte=timezone.now() - timedelta(minutes=10)).filter(user__isnull=False):
  42. if not session.user_id in users_list:
  43. ranks_dict[session.user.rank_id]['online'].append(session.user)
  44. users_list.append(session.user_id)
  45. # Assert we are on list
  46. if (request.user.is_authenticated() and request.user.rank_id in ranks_dict.keys()
  47. and not request.user.id in users_list):
  48. ranks_dict[request.user.rank_id]['online'].append(request.user)
  49. del ranks_dict
  50. del users_list
  51. cache.set('ranks_online', ranks_list, 300)
  52. # Users online
  53. users_online = cache.get('users_online', 'nada')
  54. if users_online == 'nada':
  55. users_online = Session.objects.filter(matched=True).filter(crawler__isnull=True).filter(last__gte=timezone.now() - timedelta(seconds=300)).count()
  56. cache.set('users_online', users_online, 300)
  57. if not users_online and not request.user.is_crawler():
  58. # Cheatey trick to make sure we'll never display
  59. # zero users online to human client
  60. users_online = 1
  61. # Load reads tracker and build forums list
  62. reads_tracker = ForumsTracker(request.user)
  63. forums_list = Forum.objects.treelist(request.acl.forums, tracker=reads_tracker)
  64. # Whitelist ignored members
  65. Forum.objects.ignored_users(request.user, forums_list)
  66. # Render page
  67. return request.theme.render_to_response('index.html',
  68. {
  69. 'forums_list': forums_list,
  70. 'ranks_online': ranks_list,
  71. 'users_online': users_online,
  72. 'popular_threads': popular_threads,
  73. },
  74. context_instance=RequestContext(request));
  75. def category(request, forum, slug):
  76. if not request.acl.forums.can_see(forum):
  77. return error404(request)
  78. try:
  79. forum = Forum.objects.get(pk=forum, type='category')
  80. if not request.acl.forums.can_browse(forum):
  81. return error403(request, _("You don't have permission to browse this category."))
  82. except Forum.DoesNotExist:
  83. return error404(request)
  84. forum.subforums = Forum.objects.treelist(request.acl.forums, forum, tracker=ForumsTracker(request.user))
  85. return request.theme.render_to_response('category.html',
  86. {
  87. 'category': forum,
  88. 'parents': Forum.objects.forum_parents(forum.pk),
  89. },
  90. context_instance=RequestContext(request));
  91. def redirection(request, forum, slug):
  92. if not request.acl.forums.can_see(forum):
  93. return error404(request)
  94. try:
  95. forum = Forum.objects.get(pk=forum, type='redirect')
  96. if not request.acl.forums.can_browse(forum):
  97. return error403(request, _("You don't have permission to follow this redirect."))
  98. redirects_tracker = request.session.get('redirects', [])
  99. if forum.pk not in redirects_tracker:
  100. redirects_tracker.append(forum.pk)
  101. request.session['redirects'] = redirects_tracker
  102. forum.redirects += 1
  103. forum.save(force_update=True)
  104. return redirect(forum.redirect)
  105. except Forum.DoesNotExist:
  106. return error404(request)
  107. @block_guest
  108. @check_csrf
  109. def read_all(request):
  110. ForumRecord.objects.filter(user=request.user).delete()
  111. ThreadRecord.objects.filter(user=request.user).delete()
  112. now = timezone.now()
  113. bulk = []
  114. for forum in request.acl.forums.known_forums():
  115. new_record = ForumRecord(user=request.user, forum_id=forum, updated=now, cleared=now)
  116. bulk.append(new_record)
  117. if bulk:
  118. ForumRecord.objects.bulk_create(bulk)
  119. request.messages.set_flash(Message(_("All forums have been marked as read.")), 'success')
  120. return redirect(reverse('index'))
  121. def forum_map(request):
  122. return request.theme.render_to_response('forum_map.html',
  123. {
  124. 'ranks': Rank.objects.filter(as_tab=1).order_by('order'),
  125. 'forums': Forum.objects.treelist(request.acl.forums),
  126. },
  127. context_instance=RequestContext(request));
  128. def popular_threads(request, page=0):
  129. queryset = Thread.objects.filter(forum_id__in=request.acl.threads.get_readable_forums(request.acl)).filter(deleted=False).filter(moderated=False)
  130. items_total = queryset.count();
  131. pagination = make_pagination(page, items_total, 30)
  132. queryset = queryset.order_by('-score').prefetch_related('forum')[pagination['start']:pagination['stop']];
  133. if request.settings['avatars_on_threads_list']:
  134. queryset = queryset.prefetch_related('start_poster', 'last_poster')
  135. return request.theme.render_to_response('popular_threads.html',
  136. {
  137. 'items_total': items_total,
  138. 'threads': Thread.objects.with_reads(queryset, request.user),
  139. 'pagination': pagination,
  140. },
  141. context_instance=RequestContext(request));
  142. def new_threads(request, page=0):
  143. queryset = Thread.objects.filter(forum_id__in=request.acl.threads.get_readable_forums(request.acl)).filter(deleted=False).filter(moderated=False).filter(start__gte=(timezone.now() - timedelta(days=2)))
  144. items_total = queryset.count();
  145. pagination = make_pagination(page, items_total, 30)
  146. queryset = queryset.order_by('-start').prefetch_related('forum')[pagination['start']:pagination['stop']];
  147. if request.settings['avatars_on_threads_list']:
  148. queryset = queryset.prefetch_related('start_poster', 'last_poster')
  149. return request.theme.render_to_response('new_threads.html',
  150. {
  151. 'items_total': items_total,
  152. 'threads': Thread.objects.with_reads(queryset, request.user),
  153. 'pagination': pagination,
  154. },
  155. context_instance=RequestContext(request));
  156. def redirect_message(request, message, type='info', owner=None):
  157. request.messages.set_flash(message, type, owner)
  158. return redirect(reverse('index'))
  159. def error403(request, message=None):
  160. return error_view(request, 403, message)
  161. def error404(request, message=None):
  162. return error_view(request, 404, message)
  163. def error_view(request, error, message):
  164. response = request.theme.render_to_response(('error%s.html' % error),
  165. {
  166. 'message': message,
  167. 'hide_signin': True,
  168. 'exception_response': True,
  169. },
  170. context_instance=RequestContext(request));
  171. response.status_code = error
  172. return response