list.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. from datetime import timedelta
  2. from django.contrib.auth import get_user_model
  3. from django.db.models import Count
  4. from django.utils import timezone
  5. from rest_framework.pagination import PageNumberPagination
  6. from misago.conf import settings
  7. from misago.core.cache import cache
  8. from misago.core.shortcuts import get_object_or_404
  9. from misago.forums.models import Forum
  10. from misago.users.online.utils import get_online_queryset
  11. from misago.users.permissions.profiles import allow_see_users_online_list
  12. from misago.users.models import Rank
  13. from misago.users.serializers import OnlineUserSerializer, ScoredUserSerializer
  14. def active(request, queryset):
  15. cache_key = 'misago_active_posters_ranking'
  16. ranking = cache.get(cache_key, False)
  17. if ranking is False:
  18. ranking = real_active()
  19. cache.set(cache_key, ranking, 18*3600)
  20. return ranking
  21. def real_active():
  22. tracked_period = settings.MISAGO_RANKING_LENGTH
  23. tracked_since = timezone.now() - timedelta(days=tracked_period)
  24. ranked_forums = [forum.pk for forum in Forum.objects.all_forums()]
  25. User = get_user_model()
  26. queryset = User.objects.filter(posts__gt=0)
  27. queryset = queryset.filter(post__posted_on__gte=tracked_since,
  28. post__forum__in=ranked_forums)
  29. queryset = queryset.annotate(num_posts=Count('post'))
  30. queryset = queryset.select_related('user__rank')
  31. queryset = queryset.order_by('-num_posts', 'slug')
  32. users_ranking = []
  33. for result in queryset[:settings.MISAGO_RANKING_SIZE]:
  34. result.score = result.num_posts
  35. users_ranking.append(result)
  36. return {
  37. 'results': ScoredUserSerializer(users_ranking, many=True).data,
  38. 'meta': {
  39. 'ranking_length': settings.MISAGO_RANKING_LENGTH
  40. }
  41. }
  42. def online(request, queryset):
  43. allow_see_users_online_list(request.user)
  44. cache_key = 'users_online_cache_%s' % request.user.acl_key
  45. online_list = cache.get(cache_key, False)
  46. if online_list is False:
  47. online_list = real_online(request)
  48. cache.set(cache_key, online_list, settings.MISAGO_ONLINE_LIST_CACHE)
  49. return online_list
  50. def real_online(request):
  51. queryset = get_online_queryset(request.user).order_by('last_click')
  52. queryset = queryset[:settings.MISAGO_ONLINE_LIST_SIZE]
  53. users_online = []
  54. for result in queryset:
  55. result.user.last_click = result.last_click
  56. users_online.append(result.user)
  57. return {'results': OnlineUserSerializer(users_online, many=True).data}
  58. def rank(request, queryset):
  59. rank_slug = request.query_params.get('rank')
  60. if not rank_slug:
  61. return
  62. rank = get_object_or_404(Rank.objects.filter(is_tab=True), slug=rank_slug)
  63. queryset = queryset.filter(rank=rank).order_by('slug')
  64. return {'queryset': queryset, 'paginate': True}
  65. LISTS = {
  66. 'active': active,
  67. 'online': online,
  68. 'rank': rank,
  69. }
  70. def list_endpoint(request, queryset):
  71. list_type = request.query_params.get('list')
  72. list_handler = LISTS.get(list_type)
  73. if list_handler:
  74. return list_handler(request, queryset)
  75. else:
  76. return