forked from mirrors/bookwyrm
167 lines
5.3 KiB
Python
167 lines
5.3 KiB
Python
""" non-interactive pages """
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.core.exceptions import PermissionDenied
|
|
from django.core.paginator import Paginator
|
|
from django.db.models import Q, Count
|
|
from django.http import Http404
|
|
from django.shortcuts import redirect
|
|
from django.template.response import TemplateResponse
|
|
from django.utils import timezone
|
|
from django.views import View
|
|
from django.views.decorators.http import require_POST
|
|
|
|
from bookwyrm import models
|
|
from bookwyrm.activitypub import ActivitypubResponse
|
|
from bookwyrm.settings import PAGE_LENGTH
|
|
from .helpers import get_user_from_username, is_api_request
|
|
|
|
|
|
# pylint: disable=no-self-use
|
|
class User(View):
|
|
"""user profile page"""
|
|
|
|
def get(self, request, username):
|
|
"""profile page for a user"""
|
|
user = get_user_from_username(request.user, username)
|
|
|
|
if is_api_request(request):
|
|
# we have a json request
|
|
return ActivitypubResponse(user.to_activity())
|
|
# otherwise we're at a UI view
|
|
|
|
shelf_preview = []
|
|
|
|
# only show shelves that should be visible
|
|
is_self = request.user.id == user.id
|
|
if not is_self:
|
|
shelves = (
|
|
models.Shelf.privacy_filter(
|
|
request.user, privacy_levels=["public", "followers"]
|
|
)
|
|
.filter(user=user, books__isnull=False)
|
|
.distinct()
|
|
)
|
|
else:
|
|
shelves = user.shelf_set.filter(books__isnull=False).distinct()
|
|
|
|
for user_shelf in shelves.all()[:3]:
|
|
shelf_preview.append(
|
|
{
|
|
"name": user_shelf.name,
|
|
"local_path": user_shelf.local_path,
|
|
"books": user_shelf.books.all()[:3],
|
|
"size": user_shelf.books.count(),
|
|
}
|
|
)
|
|
|
|
# user's posts
|
|
activities = (
|
|
models.Status.privacy_filter(
|
|
request.user,
|
|
)
|
|
.filter(user=user)
|
|
.select_related(
|
|
"user",
|
|
"reply_parent",
|
|
"review__book",
|
|
"comment__book",
|
|
"quotation__book",
|
|
)
|
|
.prefetch_related(
|
|
"mention_books",
|
|
"mention_users",
|
|
"attachments",
|
|
)
|
|
)
|
|
|
|
paginated = Paginator(activities, PAGE_LENGTH)
|
|
goal = models.AnnualGoal.objects.filter(
|
|
user=user, year=timezone.now().year
|
|
).first()
|
|
if goal:
|
|
try:
|
|
goal.raise_visible_to_user(request.user)
|
|
except Http404:
|
|
goal = None
|
|
|
|
data = {
|
|
"user": user,
|
|
"is_self": is_self,
|
|
"shelves": shelf_preview,
|
|
"shelf_count": shelves.count(),
|
|
"activities": paginated.get_page(request.GET.get("page", 1)),
|
|
"goal": goal,
|
|
}
|
|
|
|
return TemplateResponse(request, "user/user.html", data)
|
|
|
|
|
|
class Followers(View):
|
|
"""list of followers view"""
|
|
|
|
def get(self, request, username):
|
|
"""list of followers"""
|
|
user = get_user_from_username(request.user, username)
|
|
|
|
if is_api_request(request):
|
|
return ActivitypubResponse(user.to_followers_activity(**request.GET))
|
|
|
|
if user.hide_follows and user != request.user:
|
|
raise PermissionDenied()
|
|
|
|
followers = annotate_if_follows(request.user, user.followers)
|
|
paginated = Paginator(followers.all(), PAGE_LENGTH)
|
|
data = {
|
|
"user": user,
|
|
"is_self": request.user.id == user.id,
|
|
"follow_list": paginated.get_page(request.GET.get("page")),
|
|
}
|
|
return TemplateResponse(request, "user/relationships/followers.html", data)
|
|
|
|
|
|
class Following(View):
|
|
"""list of following view"""
|
|
|
|
def get(self, request, username):
|
|
"""list of followers"""
|
|
user = get_user_from_username(request.user, username)
|
|
|
|
if is_api_request(request):
|
|
return ActivitypubResponse(user.to_following_activity(**request.GET))
|
|
|
|
if user.hide_follows and user != request.user:
|
|
raise PermissionDenied()
|
|
|
|
following = annotate_if_follows(request.user, user.following)
|
|
paginated = Paginator(following.all(), PAGE_LENGTH)
|
|
data = {
|
|
"user": user,
|
|
"is_self": request.user.id == user.id,
|
|
"follow_list": paginated.get_page(request.GET.get("page")),
|
|
}
|
|
return TemplateResponse(request, "user/relationships/following.html", data)
|
|
|
|
|
|
def annotate_if_follows(user, queryset):
|
|
"""Sort a list of users by if you follow them"""
|
|
if not user.is_authenticated:
|
|
return queryset.order_by("-created_date")
|
|
|
|
return queryset.annotate(
|
|
request_user_follows=Count("followers", filter=Q(followers=user))
|
|
).order_by("-request_user_follows", "-created_date")
|
|
|
|
|
|
@require_POST
|
|
@login_required
|
|
def hide_suggestions(request):
|
|
"""not everyone wants user suggestions"""
|
|
request.user.show_suggested_users = False
|
|
request.user.save(broadcast=False, update_fields=["show_suggested_users"])
|
|
return redirect(request.headers.get("Referer", "/"))
|
|
|
|
|
|
# pylint: disable=unused-argument
|
|
def user_redirect(request, username):
|
|
"""redirect to a user's feed"""
|
|
return redirect("user-feed", username=username)
|