profile.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. from django.contrib.auth import get_user_model
  2. from django.http import Http404
  3. from django.shortcuts import get_object_or_404, redirect, render
  4. from django.views import View
  5. from misago.acl.objectacl import add_acl_to_obj
  6. from misago.core.shortcuts import paginate, pagination_dict, validate_slug
  7. from misago.users.bans import get_user_ban
  8. from misago.users.online.utils import get_user_status
  9. from misago.users.pages import user_profile
  10. from misago.users.profilefields import profilefields, serialize_profilefields_data
  11. from misago.users.serializers import (
  12. BanDetailsSerializer,
  13. UsernameChangeSerializer,
  14. UserSerializer,
  15. )
  16. from misago.users.viewmodels import Followers, Follows, UserPosts, UserThreads
  17. UserModel = get_user_model()
  18. class ProfileView(View):
  19. def get(self, request, *args, **kwargs):
  20. profile = self.get_profile(request, kwargs.pop("pk"), kwargs.pop("slug"))
  21. # resolve that we can display requested section
  22. sections = user_profile.get_sections(request, profile)
  23. active_section = self.get_active_section(sections)
  24. if not active_section:
  25. raise Http404()
  26. profile.status = get_user_status(request, profile)
  27. context_data = self.get_context_data(request, profile)
  28. self.complete_frontend_context(request, profile, sections)
  29. self.complete_context_data(request, profile, sections, context_data)
  30. return render(request, self.template_name, context_data)
  31. def get_profile(self, request, pk, slug):
  32. queryset = UserModel.objects.select_related(
  33. "rank", "online_tracker", "ban_cache"
  34. )
  35. profile = get_object_or_404(queryset, pk=pk)
  36. if not profile.is_active and not request.user.is_staff:
  37. raise Http404()
  38. validate_slug(profile, slug)
  39. add_acl_to_obj(request.user_acl, profile)
  40. return profile
  41. def get_active_section(self, sections):
  42. for section in sections:
  43. if section["is_active"]:
  44. return section
  45. def get_context_data(self, request, profile):
  46. return {}
  47. def complete_frontend_context(self, request, profile, sections):
  48. request.frontend_context["PROFILE_PAGES"] = []
  49. for section in sections:
  50. request.frontend_context["PROFILE_PAGES"].append(
  51. {
  52. "name": str(section["name"]),
  53. "icon": section["icon"],
  54. "meta": section.get("metadata"),
  55. "component": section["component"],
  56. }
  57. )
  58. request.frontend_context["PROFILE"] = UserProfileSerializer(
  59. profile, context={"request": request}
  60. ).data
  61. if not profile.is_active:
  62. request.frontend_context["PROFILE"]["is_active"] = False
  63. if profile.is_deleting_account:
  64. request.frontend_context["PROFILE"]["is_deleting_account"] = True
  65. def complete_context_data(self, request, profile, sections, context):
  66. context["profile"] = profile
  67. context["sections"] = sections
  68. for section in sections:
  69. if section["is_active"]:
  70. context["active_section"] = section
  71. break
  72. if request.user.is_authenticated:
  73. is_authenticated_user = profile.pk == request.user.pk
  74. context.update(
  75. {
  76. "is_authenticated_user": is_authenticated_user,
  77. "show_email": is_authenticated_user,
  78. }
  79. )
  80. if not context["show_email"]:
  81. context["show_email"] = request.user_acl["can_see_users_emails"]
  82. else:
  83. context.update({"is_authenticated_user": False, "show_email": False})
  84. class LandingView(ProfileView):
  85. def get(self, request, *args, **kwargs):
  86. profile = self.get_profile(request, kwargs.pop("pk"), kwargs.pop("slug"))
  87. return redirect(
  88. user_profile.get_default_link(), slug=profile.slug, pk=profile.pk
  89. )
  90. class UserPostsView(ProfileView):
  91. template_name = "misago/profile/posts.html"
  92. def get_context_data(self, request, profile):
  93. feed = UserPosts(request, profile)
  94. request.frontend_context["POSTS"] = feed.get_frontend_context()
  95. return feed.get_template_context()
  96. class UserThreadsView(ProfileView):
  97. template_name = "misago/profile/threads.html"
  98. def get_context_data(self, request, profile):
  99. feed = UserThreads(request, profile)
  100. request.frontend_context["POSTS"] = feed.get_frontend_context()
  101. return feed.get_template_context()
  102. class UserFollowersView(ProfileView):
  103. template_name = "misago/profile/followers.html"
  104. def get_context_data(self, request, profile):
  105. users = Followers(request, profile)
  106. request.frontend_context["PROFILE_FOLLOWERS"] = users.get_frontend_context()
  107. return users.get_template_context()
  108. class UserFollowsView(ProfileView):
  109. template_name = "misago/profile/follows.html"
  110. def get_context_data(self, request, profile):
  111. users = Follows(request, profile)
  112. request.frontend_context["PROFILE_FOLLOWS"] = users.get_frontend_context()
  113. return users.get_template_context()
  114. class UserProfileDetailsView(ProfileView):
  115. template_name = "misago/profile/details.html"
  116. def get_context_data(self, request, profile):
  117. details = serialize_profilefields_data(request, profilefields, profile)
  118. request.frontend_context["PROFILE_DETAILS"] = details
  119. return {"profile_details": details}
  120. class UserUsernameHistoryView(ProfileView):
  121. template_name = "misago/profile/username_history.html"
  122. def get_context_data(self, request, profile):
  123. queryset = profile.namechanges.select_related("user", "changed_by")
  124. queryset = queryset.order_by("-id")
  125. page = paginate(queryset, None, 14, 4)
  126. data = pagination_dict(page)
  127. data.update(
  128. {"results": UsernameChangeSerializer(page.object_list, many=True).data}
  129. )
  130. request.frontend_context["PROFILE_NAME_HISTORY"] = data
  131. return {"history": page.object_list, "count": data["count"]}
  132. class UserBanView(ProfileView):
  133. template_name = "misago/profile/ban_details.html"
  134. def get_context_data(self, request, profile):
  135. ban = get_user_ban(profile, request.cache_versions)
  136. request.frontend_context["PROFILE_BAN"] = BanDetailsSerializer(ban).data
  137. return {"ban": ban}
  138. UserProfileSerializer = UserSerializer.subset_fields(
  139. "id",
  140. "username",
  141. "slug",
  142. "email",
  143. "joined_on",
  144. "rank",
  145. "title",
  146. "avatars",
  147. "is_avatar_locked",
  148. "signature",
  149. "is_signature_locked",
  150. "followers",
  151. "following",
  152. "threads",
  153. "posts",
  154. "acl",
  155. "is_followed",
  156. "is_blocked",
  157. "real_name",
  158. "status",
  159. "api",
  160. "url",
  161. )