Merge branch 'main' into themes

This commit is contained in:
Mouse Reeve
2022-02-28 13:27:05 -08:00
committed by GitHub
27 changed files with 234 additions and 97 deletions

View File

@ -6,7 +6,7 @@ from .admin.automod import AutoMod, automod_delete, run_automod
from .admin.dashboard import Dashboard
from .admin.federation import Federation, FederatedServer
from .admin.federation import AddFederatedServer, ImportServerBlocklist
from .admin.federation import block_server, unblock_server
from .admin.federation import block_server, unblock_server, refresh_server
from .admin.email_blocklist import EmailBlocklist
from .admin.ip_blocklist import IPBlocklist
from .admin.invite import ManageInvites, Invite, InviteRequest

View File

@ -11,6 +11,7 @@ from django.views.decorators.http import require_POST
from bookwyrm import forms, models
from bookwyrm.settings import PAGE_LENGTH
from bookwyrm.models.user import get_or_create_remote_server
# pylint: disable= no-self-use
@ -37,6 +38,12 @@ class Federation(View):
page = paginated.get_page(request.GET.get("page"))
data = {
"federated_count": models.FederatedServer.objects.filter(
status="federated"
).count(),
"blocked_count": models.FederatedServer.objects.filter(
status="blocked"
).count(),
"servers": page,
"page_range": paginated.get_elided_page_range(
page.number, on_each_side=2, on_ends=1
@ -157,3 +164,14 @@ def unblock_server(request, server):
server = get_object_or_404(models.FederatedServer, id=server)
server.unblock()
return redirect("settings-federated-server", server.id)
@login_required
@require_POST
@permission_required("bookwyrm.control_federation", raise_exception=True)
# pylint: disable=unused-argument
def refresh_server(request, server):
"""unblock a server"""
server = get_object_or_404(models.FederatedServer, id=server)
get_or_create_remote_server(server.server_name, refresh=True)
return redirect("settings-federated-server", server.id)

View File

@ -83,6 +83,7 @@ class Book(View):
}
if request.user.is_authenticated:
data["list_options"] = request.user.list_set.exclude(id__in=data["lists"])
data["file_link_form"] = forms.FileLinkForm()
readthroughs = models.ReadThrough.objects.filter(
user=request.user,

View File

@ -1,11 +1,10 @@
""" book list views"""
from typing import Optional
from urllib.parse import urlencode
from django.contrib.auth.decorators import login_required
from django.core.exceptions import PermissionDenied
from django.core.paginator import Paginator
from django.db import IntegrityError, transaction
from django.db import transaction
from django.db.models import Avg, DecimalField, Q, Max
from django.db.models.functions import Coalesce
from django.http import HttpResponseBadRequest, HttpResponse
@ -26,7 +25,7 @@ from bookwyrm.views.helpers import is_api_request
class List(View):
"""book list page"""
def get(self, request, list_id):
def get(self, request, list_id, add_failed=False, add_succeeded=False):
"""display a book list"""
book_list = get_object_or_404(models.List, id=list_id)
book_list.raise_visible_to_user(request.user)
@ -37,33 +36,10 @@ class List(View):
query = request.GET.get("q")
suggestions = None
# sort_by shall be "order" unless a valid alternative is given
sort_by = request.GET.get("sort_by", "order")
if sort_by not in ("order", "title", "rating"):
sort_by = "order"
# direction shall be "ascending" unless a valid alternative is given
direction = request.GET.get("direction", "ascending")
if direction not in ("ascending", "descending"):
direction = "ascending"
directional_sort_by = {
"order": "order",
"title": "book__title",
"rating": "average_rating",
}[sort_by]
if direction == "descending":
directional_sort_by = "-" + directional_sort_by
items = book_list.listitem_set.prefetch_related("user", "book", "book__authors")
if sort_by == "rating":
items = items.annotate(
average_rating=Avg(
Coalesce("book__review__rating", 0.0),
output_field=DecimalField(),
)
)
items = items.filter(approved=True).order_by(directional_sort_by)
items = book_list.listitem_set.filter(approved=True).prefetch_related(
"user", "book", "book__authors"
)
items = sort_list(request, items)
paginated = Paginator(items, PAGE_LENGTH)
@ -106,10 +82,10 @@ class List(View):
"suggested_books": suggestions,
"list_form": forms.ListForm(instance=book_list),
"query": query or "",
"sort_form": forms.SortListForm(
{"direction": direction, "sort_by": sort_by}
),
"sort_form": forms.SortListForm(request.GET),
"embed_url": embed_url,
"add_failed": add_failed,
"add_succeeded": add_succeeded,
}
return TemplateResponse(request, "lists/list.html", data)
@ -131,6 +107,36 @@ class List(View):
return redirect(book_list.local_path)
def sort_list(request, items):
"""helper to handle the surprisngly involved sorting"""
# sort_by shall be "order" unless a valid alternative is given
sort_by = request.GET.get("sort_by", "order")
if sort_by not in ("order", "title", "rating"):
sort_by = "order"
# direction shall be "ascending" unless a valid alternative is given
direction = request.GET.get("direction", "ascending")
if direction not in ("ascending", "descending"):
direction = "ascending"
directional_sort_by = {
"order": "order",
"title": "book__title",
"rating": "average_rating",
}[sort_by]
if direction == "descending":
directional_sort_by = "-" + directional_sort_by
if sort_by == "rating":
items = items.annotate(
average_rating=Avg(
Coalesce("book__review__rating", 0.0),
output_field=DecimalField(),
)
)
return items.order_by(directional_sort_by)
@require_POST
@login_required
def save_list(request, list_id):
@ -179,8 +185,8 @@ def add_book(request):
form = forms.ListItemForm(request.POST)
if not form.is_valid():
# this shouldn't happen, there aren't validated fields
raise Exception(form.errors)
return List().get(request, book_list.id, add_failed=True)
item = form.save(commit=False)
if book_list.curation == "curated":
@ -196,17 +202,9 @@ def add_book(request):
) or 0
increment_order_in_reverse(book_list.id, order_max + 1)
item.order = order_max + 1
item.save()
try:
item.save()
except IntegrityError:
# if the book is already on the list, don't flip out
pass
path = reverse("list", args=[book_list.id])
params = request.GET.copy()
params["updated"] = True
return redirect(f"{path}?{urlencode(params)}")
return List().get(request, book_list.id, add_succeeded=True)
@require_POST

View File

@ -1,5 +1,6 @@
""" 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
@ -105,6 +106,9 @@ class Followers(View):
if is_api_request(request):
return ActivitypubResponse(user.to_followers_activity(**request.GET))
if user.hide_follows:
raise PermissionDenied()
followers = annotate_if_follows(request.user, user.followers)
paginated = Paginator(followers.all(), PAGE_LENGTH)
data = {
@ -125,6 +129,9 @@ class Following(View):
if is_api_request(request):
return ActivitypubResponse(user.to_following_activity(**request.GET))
if user.hide_follows:
raise PermissionDenied()
following = annotate_if_follows(request.user, user.following)
paginated = Paginator(following.all(), PAGE_LENGTH)
data = {