profile.py 6.0 KB

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