lists.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. from datetime import timedelta
  2. from django.conf import settings
  3. from django.contrib.auth import get_user_model
  4. from django.core.urlresolvers import reverse
  5. from django.db.models import Count
  6. from django.shortcuts import redirect, render as django_render
  7. from django.utils import timezone
  8. from misago.forums.models import Forum
  9. from misago.core.cache import cache
  10. from misago.core.shortcuts import get_object_or_404, paginate, pagination_dict
  11. from misago.core.utils import format_plaintext_for_html
  12. from misago.users.models import Rank
  13. from misago.users.pages import users_list
  14. from misago.users.permissions.profiles import allow_browse_users_list
  15. from misago.users.serializers import UserSerializer, ScoredUserSerializer
  16. def render(request, template, context):
  17. request.frontend_context['USERS_LISTS'] = []
  18. context['pages'] = users_list.get_sections(request)
  19. for page in context['pages']:
  20. page['reversed_link'] = reverse(page['link'])
  21. request.frontend_context['USERS_LISTS'].append({
  22. 'name': unicode(page['name']),
  23. 'component': page['component'],
  24. })
  25. active_rank = context.get('rank')
  26. for rank in Rank.objects.filter(is_tab=True).order_by('order'):
  27. context['pages'].append({
  28. 'name': rank.name,
  29. 'reversed_link': reverse('misago:users_rank',
  30. kwargs={'rank_slug': rank.slug}),
  31. 'is_active': active_rank.pk == rank.pk if active_rank else None
  32. })
  33. if rank.description:
  34. description = {
  35. 'plain': rank.description,
  36. 'html': format_plaintext_for_html(rank.description)
  37. }
  38. else:
  39. description = None
  40. request.frontend_context['USERS_LISTS'].append({
  41. 'name': rank.name,
  42. 'slug': rank.slug,
  43. 'css_class': rank.css_class,
  44. 'description': description,
  45. 'component': 'rank',
  46. })
  47. for page in context['pages']:
  48. if page['is_active']:
  49. context['active_page'] = page
  50. break
  51. return django_render(request, template, context)
  52. def allow_see_list(f):
  53. def decorator(request, *args, **kwargs):
  54. allow_browse_users_list(request.user)
  55. return f(request, *args, **kwargs)
  56. return decorator
  57. @allow_see_list
  58. def lander(request):
  59. default = users_list.get_default_link()
  60. return redirect(default)
  61. @allow_see_list
  62. def active_posters(request):
  63. ranking = get_active_posters_rankig()
  64. request.frontend_context['USERS'] = {
  65. 'tracked_period': settings.MISAGO_RANKING_LENGTH,
  66. 'results': ScoredUserSerializer(ranking['users'], many=True).data,
  67. 'count': ranking['users_count']
  68. }
  69. template = "misago/userslists/active_posters.html"
  70. return render(request, template, {
  71. 'tracked_period': settings.MISAGO_RANKING_LENGTH,
  72. 'users': ranking['users'],
  73. 'users_count': ranking['users_count']
  74. })
  75. def get_active_posters_rankig():
  76. cache_key = 'misago_active_posters_ranking'
  77. ranking = cache.get(cache_key, 'nada')
  78. if ranking == 'nada':
  79. ranking = get_real_active_posts_ranking()
  80. cache.set(cache_key, ranking, 18*3600)
  81. return ranking
  82. def get_real_active_posts_ranking():
  83. tracked_period = settings.MISAGO_RANKING_LENGTH
  84. tracked_since = timezone.now() - timedelta(days=tracked_period)
  85. ranked_forums = [forum.pk for forum in Forum.objects.all_forums()]
  86. User = get_user_model()
  87. queryset = User.objects.filter(posts__gt=0)
  88. queryset = queryset.filter(post__posted_on__gte=tracked_since,
  89. post__forum__in=ranked_forums)
  90. queryset = queryset.annotate(score=Count('post'))
  91. queryset = queryset.select_related('user__rank')
  92. queryset = queryset.order_by('-score')
  93. queryset = queryset[:settings.MISAGO_RANKING_SIZE]
  94. return {
  95. 'users': [user for user in queryset],
  96. 'users_count': queryset.count()
  97. }
  98. @allow_see_list
  99. def rank(request, rank_slug, page=0):
  100. rank = get_object_or_404(Rank.objects.filter(is_tab=True), slug=rank_slug)
  101. queryset = rank.user_set.select_related('rank').order_by('slug')
  102. page = paginate(queryset, page, settings.MISAGO_USERS_PER_PAGE, 4)
  103. paginator = pagination_dict(page)
  104. request.frontend_context['USERS'] = dict(
  105. results=UserSerializer(page.object_list, many=True).data,
  106. **paginator
  107. )
  108. if rank.description:
  109. description = {
  110. 'plain': rank.description,
  111. 'html': format_plaintext_for_html(rank.description)
  112. }
  113. else:
  114. description = None
  115. template = "misago/userslists/rank.html"
  116. return render(request, template, {
  117. 'rank': rank,
  118. 'users': page.object_list,
  119. 'paginator': paginator
  120. })