moviewyrm/bookwyrm/views/user.py

168 lines
5.3 KiB
Python
Raw Normal View History

2021-03-08 16:49:10 +00:00
""" non-interactive pages """
2021-09-08 17:02:06 +00:00
from django.contrib.auth.decorators import login_required
2022-02-28 20:04:47 +00:00
from django.core.exceptions import PermissionDenied
2021-01-12 20:05:30 +00:00
from django.core.paginator import Paginator
from django.db.models import Q, Count
from django.http import Http404
2021-09-08 17:02:06 +00:00
from django.shortcuts import redirect
2021-01-12 20:05:30 +00:00
from django.template.response import TemplateResponse
2021-01-16 20:39:51 +00:00
from django.utils import timezone
2021-01-12 20:05:30 +00:00
from django.views import View
2021-09-08 17:02:06 +00:00
from django.views.decorators.http import require_POST
2021-01-12 20:05:30 +00:00
2021-06-14 16:57:51 +00:00
from bookwyrm import models
2021-01-12 20:05:30 +00:00
from bookwyrm.activitypub import ActivitypubResponse
from bookwyrm.settings import PAGE_LENGTH
2021-03-23 02:17:46 +00:00
from .helpers import get_user_from_username, is_api_request
2021-01-12 20:05:30 +00:00
2021-06-14 16:57:51 +00:00
# pylint: disable=no-self-use
2021-01-12 20:05:30 +00:00
class User(View):
2021-04-26 16:15:42 +00:00
"""user profile page"""
2021-03-08 16:49:10 +00:00
2021-01-12 20:05:30 +00:00
def get(self, request, username):
2021-04-26 16:15:42 +00:00
"""profile page for a user"""
user = get_user_from_username(request.user, username)
2021-01-12 20:05:30 +00:00
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
2021-01-12 20:05:30 +00:00
is_self = request.user.id == user.id
if not is_self:
2022-02-04 02:59:08 +00:00
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()
2021-01-12 20:05:30 +00:00
2022-01-28 03:38:51 +00:00
for user_shelf in shelves.all()[:3]:
2021-03-08 16:49:10 +00:00
shelf_preview.append(
{
"name": user_shelf.name,
"local_path": user_shelf.local_path,
2021-04-20 19:31:45 +00:00
"books": user_shelf.books.all()[:3],
2021-03-08 16:49:10 +00:00
"size": user_shelf.books.count(),
}
)
2021-01-12 20:05:30 +00:00
# user's posts
activities = (
2021-10-06 17:37:09 +00:00
models.Status.privacy_filter(
request.user,
)
2021-10-06 17:37:09 +00:00
.filter(user=user)
2021-09-20 22:25:29 +00:00
.select_related(
"user",
"reply_parent",
"review__book",
"comment__book",
"quotation__book",
)
.prefetch_related(
"mention_books",
"mention_users",
"attachments",
)
2021-01-12 20:05:30 +00:00
)
2021-01-12 20:05:30 +00:00
paginated = Paginator(activities, PAGE_LENGTH)
2021-01-16 20:39:51 +00:00
goal = models.AnnualGoal.objects.filter(
2021-03-08 16:49:10 +00:00
user=user, year=timezone.now().year
).first()
if goal:
try:
goal.raise_visible_to_user(request.user)
except Http404:
goal = None
2021-01-12 20:05:30 +00:00
data = {
2021-03-08 16:49:10 +00:00
"user": user,
"is_self": is_self,
"shelves": shelf_preview,
"shelf_count": shelves.count(),
2021-04-19 22:01:20 +00:00
"activities": paginated.get_page(request.GET.get("page", 1)),
2021-03-08 16:49:10 +00:00
"goal": goal,
2021-01-12 20:05:30 +00:00
}
2021-03-08 16:49:10 +00:00
return TemplateResponse(request, "user/user.html", data)
2021-01-12 20:05:30 +00:00
class Followers(View):
2021-04-26 16:15:42 +00:00
"""list of followers view"""
2021-03-08 16:49:10 +00:00
2021-01-12 20:05:30 +00:00
def get(self, request, username):
2021-04-26 16:15:42 +00:00
"""list of followers"""
user = get_user_from_username(request.user, username)
2021-01-12 20:05:30 +00:00
if is_api_request(request):
2021-03-08 16:49:10 +00:00
return ActivitypubResponse(user.to_followers_activity(**request.GET))
2021-01-12 20:05:30 +00:00
2022-02-28 20:04:47 +00:00
if user.hide_follows:
raise PermissionDenied()
followers = annotate_if_follows(request.user, user.followers)
paginated = Paginator(followers.all(), PAGE_LENGTH)
2021-01-12 20:05:30 +00:00
data = {
2021-03-08 16:49:10 +00:00
"user": user,
"is_self": request.user.id == user.id,
"follow_list": paginated.get_page(request.GET.get("page")),
2021-01-12 20:05:30 +00:00
}
return TemplateResponse(request, "user/relationships/followers.html", data)
2021-03-08 16:49:10 +00:00
2021-01-12 20:05:30 +00:00
class Following(View):
2021-04-26 16:15:42 +00:00
"""list of following view"""
2021-03-08 16:49:10 +00:00
2021-01-12 20:05:30 +00:00
def get(self, request, username):
2021-04-26 16:15:42 +00:00
"""list of followers"""
user = get_user_from_username(request.user, username)
2021-01-12 20:05:30 +00:00
if is_api_request(request):
2021-03-08 16:49:10 +00:00
return ActivitypubResponse(user.to_following_activity(**request.GET))
2021-01-12 20:05:30 +00:00
2022-02-28 20:04:47 +00:00
if user.hide_follows:
raise PermissionDenied()
following = annotate_if_follows(request.user, user.following)
paginated = Paginator(following.all(), PAGE_LENGTH)
2021-01-12 20:05:30 +00:00
data = {
2021-03-08 16:49:10 +00:00
"user": user,
"is_self": request.user.id == user.id,
"follow_list": paginated.get_page(request.GET.get("page")),
2021-01-12 20:05:30 +00:00
}
return TemplateResponse(request, "user/relationships/following.html", data)
2021-09-08 17:02:06 +00:00
2021-10-04 10:31:28 +00:00
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")
2021-09-08 17:02:06 +00:00
@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", "/"))
2021-12-28 20:51:45 +00:00
# pylint: disable=unused-argument
def user_redirect(request, username):
"""redirect to a user's feed"""
return redirect("user-feed", username=username)