import datetime from django.contrib.auth.decorators import login_required from django.core.exceptions import BadRequest, PermissionDenied from django.db.models import F, Min, OuterRef, Subquery from django.shortcuts import get_object_or_404, redirect, render from django.urls import reverse from django.utils.translation import gettext as _ from django.views.decorators.http import require_http_methods from catalog.models import * from common.utils import ( AuthedHttpRequest, CustomPaginator, PageLinksGenerator, get_uuid_or_404, target_identity_required, ) from ..forms import * from ..models import * PAGE_SIZE = 10 def render_relogin(request): return render( request, "common/error.html", { "url": reverse("mastodon:connect") + "?domain=" + request.user.mastodon.domain, "msg": _("Data saved but unable to crosspost to Fediverse instance."), "secondary_msg": _( "Redirecting to your Fediverse instance now to re-authenticate." ), }, ) def render_list_not_found(request): msg = _("List not found.") return render( request, "common/error.html", { "msg": msg, }, ) @login_required @target_identity_required def render_list( request: AuthedHttpRequest, user_name, type, shelf_type: ShelfType | None = None, item_category=None, tag_title=None, year=None, sort="time", ): target = request.target_identity viewer = request.user.identity tag = None sort = request.GET.get("sort") year = request.GET.get("year") if type == "mark" and shelf_type: queryset = target.shelf_manager.get_members(shelf_type, item_category) elif type == "tagmember": tag = Tag.objects.filter(owner=target, title=tag_title).first() if not tag: return render_list_not_found(request) if tag.visibility != 0 and target != viewer: return render_list_not_found(request) queryset = TagMember.objects.filter(parent=tag) elif type == "review" and item_category: queryset = Review.objects.filter(q_item_in_category(item_category)) else: raise BadRequest(_("Invalid parameter")) if sort == "rating": rating = Rating.objects.filter( owner_id=OuterRef("owner_id"), item_id=OuterRef("item_id") ) queryset = queryset.alias( rating_grade=Subquery(rating.values("grade")) ).order_by(F("rating_grade").desc(nulls_last=True)) else: queryset = queryset.order_by("-created_time") start_date = queryset.aggregate(Min("created_time"))["created_time__min"] if start_date: start_year = start_date.year current_year = datetime.datetime.now().year years = reversed(range(start_year, current_year + 1)) else: years = [] queryset = queryset.filter(q_owned_piece_visible_to_user(request.user, target)) if year: year = int(year) queryset = queryset.filter(created_time__year=year) paginator = CustomPaginator(queryset, request) # type:ignore page_number = int(request.GET.get("page", default=1)) members = paginator.get_page(page_number) pagination = PageLinksGenerator(page_number, paginator.num_pages, request.GET) shelf_labels = ( ShelfManager.get_labels_for_category(item_category) if item_category else [] ) return render( request, f"user_{type}_list.html", { "user": target.user, "identity": target, "members": members, "tag": tag, "pagination": pagination, "years": years, "year": year, "sort": sort, "shelf": shelf_type, "shelf_labels": shelf_labels, "category": item_category, }, ) @login_required @require_http_methods(["GET", "POST"]) def piece_delete(request, piece_uuid): piece = get_object_or_404(Piece, uid=get_uuid_or_404(piece_uuid)) return_url = request.GET.get("return_url", None) or "/" if not piece.is_editable_by(request.user): raise PermissionDenied(_("Insufficient permission")) if request.method == "GET": return render( request, "piece_delete.html", {"piece": piece, "return_url": return_url} ) else: piece.delete() return redirect(return_url)