bookwyrm/bookwyrm/views/user.py

176 lines
5.3 KiB
Python
Raw Normal View History

""" The user profile """
2021-09-08 17:02:06 +00:00
from django.contrib.auth.decorators import login_required
2021-01-12 20:05:30 +00:00
from django.core.paginator import Paginator
from django.db.models import Q
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, INSTANCE_ACTOR_USERNAME
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 not user.local and not request.user.is_authenticated:
return redirect(user.remote_id)
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
# if it's not an API request, never show the instance actor profile page
if user.localname == INSTANCE_ACTOR_USERNAME:
raise Http404()
2021-01-12 20:05:30 +00:00
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)
2022-07-08 19:19:51 +00:00
.exclude(
privacy="direct",
review__isnull=True,
comment__isnull=True,
quotation__isnull=True,
)
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 UserReviewsComments(View):
"""user's activity filtered by reviews and comments"""
def get(self, request, username):
"""user's activity filtered by reviews and comments"""
user = get_user_from_username(request.user, username)
is_self = request.user.id == user.id
activities = (
models.Status.privacy_filter(
request.user,
)
.filter(
Q(review__isnull=False) | Q(comment__isnull=False),
user=user,
)
.exclude(
privacy="direct",
)
.select_related(
"user",
"reply_parent",
"review__book",
"comment__book",
"quotation__book",
)
.prefetch_related(
"mention_books",
"mention_users",
"attachments",
)
)
paginated = Paginator(activities, PAGE_LENGTH)
data = {
"user": user,
"is_self": is_self,
"activities": paginated.get_page(request.GET.get("page", 1)),
}
return TemplateResponse(request, "user/reviews_comments.html", data)
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("/")
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)
2022-07-03 07:14:13 +00:00
@login_required
def toggle_guided_tour(request, tour):
"""most people don't want a tour every time they load a page"""
request.user.show_guided_tour = tour
request.user.save(broadcast=False, update_fields=["show_guided_tour"])
return redirect("/")