profile.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. from django.conf import settings
  2. from django.contrib import messages
  3. from django.contrib.auth import get_user_model
  4. from django.core.exceptions import PermissionDenied
  5. from django.core.urlresolvers import reverse
  6. from django.db.transaction import atomic
  7. from django.http import Http404, JsonResponse
  8. from django.shortcuts import redirect, render as django_render
  9. from django.utils.translation import ugettext as _
  10. from misago.acl import add_acl
  11. from misago.core.decorators import require_POST
  12. from misago.core.shortcuts import (get_object_or_404, paginate,
  13. pagination_dict, validate_slug)
  14. from misago.core.utils import clean_return_path
  15. from misago.notifications import notify_user, read_user_notifications
  16. from misago.threads.permissions import allow_message_user
  17. from misago.users.bans import get_user_ban
  18. from misago.users.decorators import deny_guests
  19. from misago.users.online.utils import get_user_status
  20. from misago.users.pages import user_profile
  21. from misago.users.permissions.profiles import (allow_follow_user,
  22. allow_block_user)
  23. from misago.users.serializers import (UserSerializer, UserProfileSerializer,
  24. BanDetailsSerializer)
  25. from misago.users.serializers.usernamechange import UsernameChangeSerializer
  26. from misago.users.warnings import (get_warning_levels, get_user_warning_level,
  27. get_user_warning_obj)
  28. def profile_view(f):
  29. def decorator(request, *args, **kwargs):
  30. User = get_user_model()
  31. relations = ('rank', 'online_tracker', 'ban_cache')
  32. queryset = User.objects.select_related(*relations)
  33. profile = get_object_or_404(queryset, id=kwargs.pop('user_id'))
  34. validate_slug(profile, kwargs.pop('user_slug'))
  35. kwargs['profile'] = profile
  36. add_acl(request.user, profile)
  37. return f(request, *args, **kwargs)
  38. return decorator
  39. def profile_view_restricted_visibility(f):
  40. @profile_view
  41. def decorator(request, *args, **kwargs):
  42. sections = user_profile.get_sections(request, kwargs['profile'])
  43. for section in sections:
  44. if section['is_active']:
  45. return f(request, *args, **kwargs)
  46. else:
  47. # we are trying to display page thats not in nav
  48. raise Http404()
  49. return decorator
  50. def render(request, template, context):
  51. request.frontend_context['PROFILE_PAGES'] = []
  52. context['sections'] = user_profile.get_sections(request, context['profile'])
  53. for section in context['sections']:
  54. request.frontend_context['PROFILE_PAGES'].append({
  55. 'name': unicode(section['name']),
  56. 'icon': section['icon'],
  57. 'meta': section.get('metadata'),
  58. 'component': section['component'],
  59. })
  60. if section['is_active']:
  61. context['active_section'] = section
  62. if request.user.is_authenticated():
  63. is_authenticated_user = context['profile'].pk == request.user.pk
  64. else:
  65. is_authenticated_user = False
  66. context['is_authenticated_user'] = is_authenticated_user
  67. user_acl = request.user.acl
  68. if request.user.is_authenticated():
  69. if is_authenticated_user:
  70. context['show_email'] = True
  71. else:
  72. context['show_email'] = user_acl['can_see_users_emails']
  73. else:
  74. context['show_email'] = False
  75. context['profile'].status = get_user_status(context['profile'], user_acl)
  76. if request.user.is_authenticated():
  77. try:
  78. allow_message_user(request.user, context['profile'])
  79. context['can_message'] = True
  80. except PermissionDenied as e:
  81. context['can_message'] = False
  82. context['cant_message_reason'] = e
  83. request.frontend_context['PROFILE'] = UserProfileSerializer(
  84. context['profile'], context={'user': request.user}).data
  85. return django_render(request, template, context)
  86. @profile_view
  87. def lander(request, profile):
  88. return redirect(user_profile.get_default_link(),
  89. user_slug=profile.slug,
  90. user_id=profile.id)
  91. @profile_view
  92. def posts(request, profile):
  93. return render(request, 'misago/profile/posts.html', {
  94. 'profile': profile
  95. })
  96. @profile_view
  97. def threads(request, profile):
  98. return render(request, 'misago/profile/threads.html', {
  99. 'profile': profile
  100. })
  101. @profile_view
  102. def followers(request, profile):
  103. queryset = profile.followed_by.select_related('rank').order_by('slug')
  104. page = paginate(queryset, None, 12, 4)
  105. paginator = pagination_dict(page)
  106. request.frontend_context['PROFILE_FOLLOWERS'] = dict(
  107. results=UserSerializer(page.object_list, many=True).data,
  108. **paginator
  109. )
  110. return render(request, 'misago/profile/followers.html', {
  111. 'profile': profile,
  112. 'followers': page.object_list,
  113. 'count': paginator['count'],
  114. })
  115. @profile_view
  116. def follows(request, profile):
  117. queryset = profile.follows.select_related('rank').order_by('slug')
  118. page = paginate(queryset, None, settings.MISAGO_USERS_PER_PAGE, 4)
  119. paginator = pagination_dict(page)
  120. request.frontend_context['PROFILE_FOLLOWS'] = dict(
  121. results=UserSerializer(page.object_list, many=True).data,
  122. **paginator
  123. )
  124. return render(request, 'misago/profile/follows.html', {
  125. 'profile': profile,
  126. 'follows': page.object_list,
  127. 'count': paginator['count'],
  128. })
  129. @profile_view_restricted_visibility
  130. def username_history(request, profile):
  131. queryset = profile.namechanges.select_related('user', 'changed_by')
  132. queryset = queryset.order_by('-id')
  133. page = paginate(queryset, None, settings.MISAGO_USERS_PER_PAGE, 4)
  134. paginator = pagination_dict(page)
  135. request.frontend_context['PROFILE_NAME_HISTORY'] = dict(
  136. results=UsernameChangeSerializer(page.object_list, many=True).data,
  137. **paginator
  138. )
  139. return render(request, 'misago/profile/username_history.html', {
  140. 'profile': profile,
  141. 'history': page.object_list,
  142. 'count': paginator['count'],
  143. })
  144. @profile_view_restricted_visibility
  145. def user_ban(request, profile):
  146. ban = get_user_ban(profile)
  147. request.frontend_context['PROFILE_BAN'] = BanDetailsSerializer(ban).data
  148. return render(request, 'misago/profile/ban_details.html', {
  149. 'profile': profile,
  150. 'ban': ban,
  151. })