from django.contrib.auth import get_user_model from django.http import Http404 from django.shortcuts import get_object_or_404, redirect, render from django.views import View from ...acl.objectacl import add_acl_to_obj from ...core.shortcuts import paginate, pagination_dict, validate_slug from ..bans import get_user_ban from ..online.utils import get_user_status from ..pages import user_profile from ..profilefields import profilefields, serialize_profilefields_data from ..serializers import BanDetailsSerializer, UsernameChangeSerializer, UserSerializer from ..viewmodels import Followers, Follows, UserPosts, UserThreads User = get_user_model() class ProfileView(View): def get(self, request, *args, **kwargs): profile = self.get_profile(request, kwargs.pop("pk"), kwargs.pop("slug")) # resolve that we can display requested section sections = user_profile.get_sections(request, profile) active_section = self.get_active_section(sections) if not active_section: raise Http404() profile.status = get_user_status(request, profile) context_data = self.get_context_data(request, profile) self.complete_frontend_context(request, profile, sections) self.complete_context_data(request, profile, sections, context_data) return render(request, self.template_name, context_data) def get_profile(self, request, pk, slug): queryset = User.objects.select_related("rank", "online_tracker", "ban_cache") profile = get_object_or_404(queryset, pk=pk) if not profile.is_active and not request.user.is_staff: raise Http404() validate_slug(profile, slug) add_acl_to_obj(request.user_acl, profile) return profile def get_active_section(self, sections): for section in sections: if section["is_active"]: return section def get_context_data(self, request, profile): return {} def complete_frontend_context(self, request, profile, sections): request.frontend_context["PROFILE_PAGES"] = [] for section in sections: request.frontend_context["PROFILE_PAGES"].append( { "name": str(section["name"]), "icon": section["icon"], "meta": section.get("metadata"), "component": section["component"], } ) request.frontend_context["PROFILE"] = UserProfileSerializer( profile, context={"request": request} ).data if not profile.is_active: request.frontend_context["PROFILE"]["is_active"] = False if profile.is_deleting_account: request.frontend_context["PROFILE"]["is_deleting_account"] = True def complete_context_data(self, request, profile, sections, context): context["profile"] = profile context["sections"] = sections for section in sections: if section["is_active"]: context["active_section"] = section break if request.user.is_authenticated: is_authenticated_user = profile.pk == request.user.pk context.update( { "is_authenticated_user": is_authenticated_user, "show_email": is_authenticated_user, } ) if not context["show_email"]: context["show_email"] = request.user_acl["can_see_users_emails"] else: context.update({"is_authenticated_user": False, "show_email": False}) class LandingView(ProfileView): def get(self, request, *args, **kwargs): profile = self.get_profile(request, kwargs.pop("pk"), kwargs.pop("slug")) return redirect( user_profile.get_default_link(), slug=profile.slug, pk=profile.pk ) class UserPostsView(ProfileView): template_name = "misago/profile/posts.html" def get_context_data(self, request, profile): feed = UserPosts(request, profile) request.frontend_context["POSTS"] = feed.get_frontend_context() return feed.get_template_context() class UserThreadsView(ProfileView): template_name = "misago/profile/threads.html" def get_context_data(self, request, profile): feed = UserThreads(request, profile) request.frontend_context["POSTS"] = feed.get_frontend_context() return feed.get_template_context() class UserFollowersView(ProfileView): template_name = "misago/profile/followers.html" def get_context_data(self, request, profile): users = Followers(request, profile) request.frontend_context["PROFILE_FOLLOWERS"] = users.get_frontend_context() return users.get_template_context() class UserFollowsView(ProfileView): template_name = "misago/profile/follows.html" def get_context_data(self, request, profile): users = Follows(request, profile) request.frontend_context["PROFILE_FOLLOWS"] = users.get_frontend_context() return users.get_template_context() class UserProfileDetailsView(ProfileView): template_name = "misago/profile/details.html" def get_context_data(self, request, profile): details = serialize_profilefields_data(request, profilefields, profile) request.frontend_context["PROFILE_DETAILS"] = details return {"profile_details": details} class UserUsernameHistoryView(ProfileView): template_name = "misago/profile/username_history.html" def get_context_data(self, request, profile): queryset = profile.namechanges.select_related("user", "changed_by") queryset = queryset.order_by("-id") page = paginate(queryset, None, 14, 4) data = pagination_dict(page) data.update( {"results": UsernameChangeSerializer(page.object_list, many=True).data} ) request.frontend_context["PROFILE_NAME_HISTORY"] = data return {"history": page.object_list, "count": data["count"]} class UserBanView(ProfileView): template_name = "misago/profile/ban_details.html" def get_context_data(self, request, profile): ban = get_user_ban(profile, request.cache_versions) request.frontend_context["PROFILE_BAN"] = BanDetailsSerializer(ban).data return {"ban": ban} UserProfileSerializer = UserSerializer.subset_fields( "id", "username", "slug", "email", "joined_on", "rank", "title", "avatars", "is_avatar_locked", "signature", "is_signature_locked", "followers", "following", "threads", "posts", "acl", "is_followed", "is_blocked", "real_name", "status", "api", "url", )