|
@@ -1,208 +1,189 @@
|
|
|
-from django.contrib import messages
|
|
|
from django.contrib.auth import get_user_model
|
|
|
-from django.core.exceptions import PermissionDenied
|
|
|
-from django.db.transaction import atomic
|
|
|
-from django.http import Http404, JsonResponse
|
|
|
-from django.shortcuts import render as django_render
|
|
|
+from django.http import Http404
|
|
|
+from django.shortcuts import render
|
|
|
from django.shortcuts import get_object_or_404, redirect
|
|
|
-from django.urls import reverse
|
|
|
from django.utils import six
|
|
|
-from django.utils.translation import ugettext as _
|
|
|
+from django.views import View
|
|
|
|
|
|
from misago.acl import add_acl
|
|
|
-from misago.conf import settings
|
|
|
-from misago.core.decorators import require_POST
|
|
|
from misago.core.shortcuts import paginate, pagination_dict, validate_slug
|
|
|
-from misago.core.utils import clean_return_path
|
|
|
-from misago.threads.permissions import allow_message_user
|
|
|
from misago.users.bans import get_user_ban
|
|
|
-from misago.users.decorators import deny_guests
|
|
|
from misago.users.online.utils import get_user_status
|
|
|
from misago.users.pages import user_profile
|
|
|
-from misago.users.permissions import allow_block_user, allow_follow_user
|
|
|
from misago.users.serializers import (
|
|
|
- BanDetailsSerializer, UserCardSerializer, UsernameChangeSerializer, UserSerializer)
|
|
|
+ BanDetailsSerializer, UsernameChangeSerializer, UserSerializer)
|
|
|
from misago.users.viewmodels import Followers, Follows, UserPosts, UserThreads
|
|
|
|
|
|
|
|
|
UserModel = get_user_model()
|
|
|
|
|
|
|
|
|
-def profile_view(f):
|
|
|
- def decorator(request, *args, **kwargs):
|
|
|
- relations = ('rank', 'online_tracker', 'ban_cache')
|
|
|
- queryset = UserModel.objects.select_related(*relations)
|
|
|
+class ProfileView(View):
|
|
|
+ def get(self, request, *args, **kwargs):
|
|
|
+ profile = self.get_profile(request, kwargs.pop('pk'), kwargs.pop('slug'))
|
|
|
|
|
|
- profile = get_object_or_404(queryset, pk=kwargs.pop('pk'))
|
|
|
+ # resolve that we can display requested section
|
|
|
+ sections = user_profile.get_sections(request, profile)
|
|
|
+ active_section = self.get_active_section(sections)
|
|
|
|
|
|
- if not profile.is_active and not request.user.is_staff:
|
|
|
+ if not active_section:
|
|
|
raise Http404()
|
|
|
|
|
|
- validate_slug(profile, kwargs.pop('slug'))
|
|
|
- kwargs['profile'] = profile
|
|
|
-
|
|
|
- add_acl(request.user, profile)
|
|
|
+ profile.status = get_user_status(request.user, profile)
|
|
|
+ context_data = self.get_context_data(request, profile)
|
|
|
|
|
|
- return f(request, *args, **kwargs)
|
|
|
- return decorator
|
|
|
+ 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 profile_view_restricted_visibility(f):
|
|
|
- @profile_view
|
|
|
- def decorator(request, *args, **kwargs):
|
|
|
- sections = user_profile.get_sections(request, kwargs['profile'])
|
|
|
- for section in sections:
|
|
|
- if section['is_active']:
|
|
|
- return f(request, *args, **kwargs)
|
|
|
- else:
|
|
|
- # we are trying to display page thats not in nav
|
|
|
- raise Http404()
|
|
|
- return decorator
|
|
|
-
|
|
|
+ def get_profile(self, request, pk, slug):
|
|
|
+ queryset = UserModel.objects.select_related(
|
|
|
+ 'rank', 'online_tracker', 'ban_cache')
|
|
|
|
|
|
-def render(request, template, context):
|
|
|
- request.frontend_context['PROFILE_PAGES'] = []
|
|
|
+ profile = get_object_or_404(queryset, pk=pk)
|
|
|
|
|
|
- context['sections'] = user_profile.get_sections(request, context['profile'])
|
|
|
+ if not profile.is_active and not request.user.is_staff:
|
|
|
+ raise Http404()
|
|
|
|
|
|
- for section in context['sections']:
|
|
|
- request.frontend_context['PROFILE_PAGES'].append({
|
|
|
- 'name': six.text_type(section['name']),
|
|
|
- 'icon': section['icon'],
|
|
|
- 'meta': section.get('metadata'),
|
|
|
- 'component': section['component'],
|
|
|
- })
|
|
|
+ validate_slug(profile, slug)
|
|
|
+ add_acl(request.user, profile)
|
|
|
|
|
|
- if section['is_active']:
|
|
|
- context['active_section'] = section
|
|
|
+ return profile
|
|
|
|
|
|
- if request.user.is_authenticated:
|
|
|
- is_authenticated_user = context['profile'].pk == request.user.pk
|
|
|
- else:
|
|
|
- is_authenticated_user = False
|
|
|
- context['is_authenticated_user'] = is_authenticated_user
|
|
|
+ def get_active_section(self, sections):
|
|
|
+ for section in sections:
|
|
|
+ if section['is_active']:
|
|
|
+ return section
|
|
|
|
|
|
- if request.user.is_authenticated:
|
|
|
- if is_authenticated_user:
|
|
|
- context['show_email'] = True
|
|
|
- else:
|
|
|
- context['show_email'] = request.user.acl['can_see_users_emails']
|
|
|
- else:
|
|
|
- context['show_email'] = False
|
|
|
+ def get_context_data(self, request, profile):
|
|
|
+ return {}
|
|
|
|
|
|
- context['profile'].status = get_user_status(request.user, context['profile'])
|
|
|
+ def complete_frontend_context(self, request, profile, sections):
|
|
|
+ request.frontend_context['PROFILE_PAGES'] = []
|
|
|
+ for section in sections:
|
|
|
+ request.frontend_context['PROFILE_PAGES'].append({
|
|
|
+ 'name': six.text_type(section['name']),
|
|
|
+ 'icon': section['icon'],
|
|
|
+ 'meta': section.get('metadata'),
|
|
|
+ 'component': section['component'],
|
|
|
+ })
|
|
|
|
|
|
- request.frontend_context['PROFILE'] = UserProfileSerializer(
|
|
|
- context['profile'], context={'user': request.user}).data
|
|
|
+ request.frontend_context['PROFILE'] = UserProfileSerializer(
|
|
|
+ profile, context={'user': request.user}).data
|
|
|
|
|
|
- if not context['profile'].is_active:
|
|
|
- request.frontend_context['PROFILE']['is_active'] = False
|
|
|
+ if not profile.is_active:
|
|
|
+ request.frontend_context['PROFILE']['is_active'] = False
|
|
|
|
|
|
- return django_render(request, template, context)
|
|
|
+ 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,
|
|
|
+ })
|
|
|
|
|
|
-@profile_view
|
|
|
-def landing(request, profile):
|
|
|
- return redirect(user_profile.get_default_link(), slug=profile.slug, pk=profile.pk)
|
|
|
|
|
|
+class LandingView(ProfileView):
|
|
|
+ def get(self, request, *args, **kwargs):
|
|
|
+ profile = self.get_profile(request, kwargs.pop('pk'), kwargs.pop('slug'))
|
|
|
|
|
|
-@profile_view
|
|
|
-def posts(request, profile):
|
|
|
- context = {
|
|
|
- 'profile': profile,
|
|
|
- }
|
|
|
+ return redirect(
|
|
|
+ user_profile.get_default_link(),
|
|
|
+ slug=profile.slug,
|
|
|
+ pk=profile.pk
|
|
|
+ )
|
|
|
|
|
|
- feed = UserPosts(request, profile)
|
|
|
- context.update(feed.get_template_context())
|
|
|
|
|
|
- request.frontend_context['POSTS'] = feed.get_frontend_context()
|
|
|
+class UserPostsView(ProfileView):
|
|
|
+ template_name = 'misago/profile/posts.html'
|
|
|
|
|
|
- return render(request, 'misago/profile/posts.html', context)
|
|
|
+ def get_context_data(self, request, profile):
|
|
|
+ feed = UserPosts(request, profile)
|
|
|
|
|
|
+ request.frontend_context['POSTS'] = feed.get_frontend_context()
|
|
|
+ return feed.get_template_context()
|
|
|
|
|
|
-@profile_view
|
|
|
-def threads(request, profile):
|
|
|
- context = {
|
|
|
- 'profile': profile
|
|
|
- }
|
|
|
|
|
|
- feed = UserThreads(request, profile)
|
|
|
- context.update(feed.get_template_context())
|
|
|
+class UserThreadsView(ProfileView):
|
|
|
+ template_name = 'misago/profile/threads.html'
|
|
|
|
|
|
- request.frontend_context['POSTS'] = feed.get_frontend_context()
|
|
|
+ def get_context_data(self, request, profile):
|
|
|
+ feed = UserThreads(request, profile)
|
|
|
|
|
|
- return render(request, 'misago/profile/threads.html', context)
|
|
|
+ request.frontend_context['POSTS'] = feed.get_frontend_context()
|
|
|
+ return feed.get_template_context()
|
|
|
|
|
|
|
|
|
-@profile_view
|
|
|
-def followers(request, profile):
|
|
|
- queryset = profile.followed_by.select_related('rank').order_by('slug')
|
|
|
+class UserFollowersView(ProfileView):
|
|
|
+ template_name = 'misago/profile/followers.html'
|
|
|
|
|
|
- page = paginate(queryset, None, 12, 4)
|
|
|
- paginator = pagination_dict(page)
|
|
|
+ def get_context_data(self, request, profile):
|
|
|
+ users = Followers(request, profile)
|
|
|
|
|
|
- request.frontend_context['PROFILE_FOLLOWERS'] = dict(
|
|
|
- results=UserCardSerializer(page.object_list, many=True).data,
|
|
|
- **paginator
|
|
|
- )
|
|
|
+ request.frontend_context['PROFILE_FOLLOWERS'] = users.get_frontend_context()
|
|
|
+ return users.get_template_context()
|
|
|
|
|
|
- return render(request, 'misago/profile/followers.html', {
|
|
|
- 'profile': profile,
|
|
|
- 'followers': page.object_list,
|
|
|
- 'count': paginator['count'],
|
|
|
- })
|
|
|
|
|
|
+class UserFollowsView(ProfileView):
|
|
|
+ template_name = 'misago/profile/follows.html'
|
|
|
|
|
|
-@profile_view
|
|
|
-def follows(request, profile):
|
|
|
- queryset = profile.follows.select_related('rank').order_by('slug')
|
|
|
+ def get_context_data(self, request, profile):
|
|
|
+ users = Follows(request, profile)
|
|
|
|
|
|
- page = paginate(queryset, None, settings.MISAGO_USERS_PER_PAGE, 4)
|
|
|
- paginator = pagination_dict(page)
|
|
|
+ request.frontend_context['PROFILE_FOLLOWS'] = users.get_frontend_context()
|
|
|
+ return users.get_template_context()
|
|
|
|
|
|
- request.frontend_context['PROFILE_FOLLOWS'] = dict(
|
|
|
- results=UserCardSerializer(page.object_list, many=True).data,
|
|
|
- **paginator
|
|
|
- )
|
|
|
|
|
|
- return render(request, 'misago/profile/follows.html', {
|
|
|
- 'profile': profile,
|
|
|
- 'follows': page.object_list,
|
|
|
- 'count': paginator['count'],
|
|
|
- })
|
|
|
+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')
|
|
|
|
|
|
-@profile_view_restricted_visibility
|
|
|
-def username_history(request, profile):
|
|
|
- queryset = profile.namechanges.select_related('user', 'changed_by')
|
|
|
- queryset = queryset.order_by('-id')
|
|
|
+ page = paginate(queryset, None, 14, 4)
|
|
|
|
|
|
- page = paginate(queryset, None, 14, 4)
|
|
|
+ data = pagination_dict(page)
|
|
|
+ data.update({
|
|
|
+ 'results': UsernameChangeSerializer(page.object_list, many=True).data
|
|
|
+ })
|
|
|
|
|
|
- data = pagination_dict(page)
|
|
|
- data.update({
|
|
|
- 'results': UsernameChangeSerializer(page.object_list, many=True).data
|
|
|
- })
|
|
|
+ request.frontend_context['PROFILE_NAME_HISTORY'] = data
|
|
|
|
|
|
- request.frontend_context['PROFILE_NAME_HISTORY'] = data
|
|
|
+ return {
|
|
|
+ 'history': page.object_list,
|
|
|
+ 'count': data['count'],
|
|
|
+ }
|
|
|
|
|
|
- return render(request, 'misago/profile/username_history.html', {
|
|
|
- 'profile': profile,
|
|
|
- 'history': page.object_list,
|
|
|
- 'count': data['count'],
|
|
|
- })
|
|
|
|
|
|
+class UserBanView(ProfileView):
|
|
|
+ template_name = 'misago/profile/ban_details.html'
|
|
|
|
|
|
-@profile_view_restricted_visibility
|
|
|
-def user_ban(request, profile):
|
|
|
- ban = get_user_ban(profile)
|
|
|
+ def get_context_data(self, request, profile):
|
|
|
+ ban = get_user_ban(profile)
|
|
|
|
|
|
- request.frontend_context['PROFILE_BAN'] = BanDetailsSerializer(ban).data
|
|
|
+ request.frontend_context['PROFILE_BAN'] = BanDetailsSerializer(ban).data
|
|
|
|
|
|
- return render(request, 'misago/profile/ban_details.html', {
|
|
|
- 'profile': profile,
|
|
|
- 'ban': ban,
|
|
|
- })
|
|
|
+ return {
|
|
|
+ 'ban': ban,
|
|
|
+ }
|
|
|
|
|
|
|
|
|
UserProfileSerializer = UserSerializer.subset_fields(
|