Merge pull request #1527 from bookwyrm-social/book-file-links

Book file links
This commit is contained in:
Mouse Reeve
2022-01-13 11:10:05 -08:00
committed by GitHub
53 changed files with 1681 additions and 206 deletions

View File

@ -9,10 +9,10 @@ from .admin.email_blocklist import EmailBlocklist
from .admin.ip_blocklist import IPBlocklist
from .admin.invite import ManageInvites, Invite, InviteRequest
from .admin.invite import ManageInviteRequests, ignore_invite_request
from .admin.link_domains import LinkDomain, update_domain_status
from .admin.reports import (
Report,
Reports,
make_report,
ReportAdmin,
ReportsAdmin,
resolve_report,
suspend_user,
unsuspend_user,
@ -28,10 +28,16 @@ from .preferences.delete_user import DeleteUser
from .preferences.block import Block, unblock
# books
from .books.books import Book, upload_cover, add_description, resolve_book
from .books.books import (
Book,
upload_cover,
add_description,
resolve_book,
)
from .books.books import update_book_from_remote
from .books.edit_book import EditBook, ConfirmEditBook
from .books.editions import Editions, switch_edition
from .books.links import BookFileLinks, AddFileLink
# landing
from .landing.about import about, privacy, conduct
@ -90,6 +96,7 @@ from .notifications import Notifications
from .outbox import Outbox
from .reading import ReadThrough, delete_readthrough, delete_progressupdate
from .reading import ReadingStatus
from .report import Report
from .rss_feed import RssFeed
from .search import Search
from .status import CreateStatus, EditStatus, DeleteStatus, update_progress

View File

@ -96,6 +96,9 @@ class Dashboard(View):
"statuses": status_queryset.count(),
"works": models.Work.objects.count(),
"reports": models.Report.objects.filter(resolved=False).count(),
"pending_domains": models.LinkDomain.objects.filter(
status="pending"
).count(),
"invite_requests": models.InviteRequest.objects.filter(
ignored=False, invite_sent=False
).count(),

View File

@ -0,0 +1,55 @@
""" Manage link domains"""
from django.contrib.auth.decorators import login_required, permission_required
from django.shortcuts import get_object_or_404, redirect
from django.template.response import TemplateResponse
from django.utils.decorators import method_decorator
from django.views import View
from django.views.decorators.http import require_POST
from bookwyrm import forms, models
# pylint: disable=no-self-use
@method_decorator(login_required, name="dispatch")
@method_decorator(
permission_required("bookwyrm.moderate_user", raise_exception=True),
name="dispatch",
)
class LinkDomain(View):
"""Moderate links"""
def get(self, request, status="pending"):
"""view pending domains"""
data = {
"domains": models.LinkDomain.objects.filter(status=status).prefetch_related(
"links"
),
"counts": {
"pending": models.LinkDomain.objects.filter(status="pending").count(),
"approved": models.LinkDomain.objects.filter(status="approved").count(),
"blocked": models.LinkDomain.objects.filter(status="blocked").count(),
},
"form": forms.EmailBlocklistForm(),
"status": status,
}
return TemplateResponse(
request, "settings/link_domains/link_domains.html", data
)
def post(self, request, status, domain_id):
"""Set display name"""
domain = get_object_or_404(models.LinkDomain, id=domain_id)
form = forms.LinkDomainForm(request.POST, instance=domain)
form.save()
return redirect("settings-link-domain", status=status)
@require_POST
@login_required
def update_domain_status(request, domain_id, status):
"""This domain seems fine"""
domain = get_object_or_404(models.LinkDomain, id=domain_id)
domain.raise_not_editable(request.user)
domain.status = status
domain.save()
return redirect("settings-link-domain", status="pending")

View File

@ -5,9 +5,8 @@ from django.shortcuts import get_object_or_404, redirect
from django.template.response import TemplateResponse
from django.utils.decorators import method_decorator
from django.views import View
from django.views.decorators.http import require_POST
from bookwyrm import emailing, forms, models
from bookwyrm import forms, models
# pylint: disable=no-self-use
@ -20,7 +19,7 @@ from bookwyrm import emailing, forms, models
permission_required("bookwyrm.moderate_post", raise_exception=True),
name="dispatch",
)
class Reports(View):
class ReportsAdmin(View):
"""list of reports"""
def get(self, request):
@ -52,7 +51,7 @@ class Reports(View):
permission_required("bookwyrm.moderate_post", raise_exception=True),
name="dispatch",
)
class Report(View):
class ReportAdmin(View):
"""view a specific report"""
def get(self, request, report_id):
@ -132,16 +131,3 @@ def resolve_report(_, report_id):
if not report.resolved:
return redirect("settings-report", report.id)
return redirect("settings-reports")
@login_required
@require_POST
def make_report(request):
"""a user reports something"""
form = forms.ReportForm(request.POST)
if not form.is_valid():
raise ValueError(form.errors)
report = form.save()
emailing.moderation_report_email(report)
return redirect(request.headers.get("Referer", "/"))

View File

@ -40,7 +40,7 @@ class Book(View):
.filter(Q(id=book_id) | Q(parent_work__id=book_id))
.order_by("-edition_rank")
.select_related("parent_work")
.prefetch_related("authors")
.prefetch_related("authors", "file_links")
.first()
)
@ -84,6 +84,7 @@ class Book(View):
}
if request.user.is_authenticated:
data["file_link_form"] = forms.FileLinkForm()
readthroughs = models.ReadThrough.objects.filter(
user=request.user,
book=book,

View File

@ -0,0 +1,62 @@
""" the good stuff! the books! """
from django.contrib.auth.decorators import login_required, permission_required
from django.db import transaction
from django.shortcuts import get_object_or_404, redirect
from django.template.response import TemplateResponse
from django.views import View
from django.utils.decorators import method_decorator
from bookwyrm import forms, models
# pylint: disable=no-self-use
class BookFileLinks(View):
"""View all links"""
def get(self, request, book_id):
"""view links"""
book = get_object_or_404(models.Edition, id=book_id)
return TemplateResponse(
request, "book/file_links/edit_links.html", {"book": book}
)
def post(self, request, book_id, link_id):
"""delete link"""
link = get_object_or_404(models.FileLink, id=link_id, book=book_id)
link.delete()
return self.get(request, book_id)
@method_decorator(login_required, name="dispatch")
@method_decorator(
permission_required("bookwyrm.edit_book", raise_exception=True), name="dispatch"
)
class AddFileLink(View):
"""a book! this is the stuff"""
def get(self, request, book_id):
"""Create link form"""
book = get_object_or_404(models.Edition, id=book_id)
data = {
"file_link_form": forms.FileLinkForm(),
"book": book,
}
return TemplateResponse(request, "book/file_links/file_link_page.html", data)
@transaction.atomic
def post(self, request, book_id, link_id=None):
"""Add a link to a copy of the book you can read"""
book = get_object_or_404(models.Book.objects.select_subclasses(), id=book_id)
link = get_object_or_404(models.FileLink, id=link_id) if link_id else None
form = forms.FileLinkForm(request.POST, instance=link)
if not form.is_valid():
data = {"file_link_form": form, "book": book}
return TemplateResponse(
request, "book/file_links/file_link_page.html", data
)
link = form.save()
book.file_links.add(link)
book.last_edited_by = request.user
book.save()
return redirect("book", book.id)

39
bookwyrm/views/report.py Normal file
View File

@ -0,0 +1,39 @@
""" moderation via flagged posts and users """
from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404, redirect
from django.template.response import TemplateResponse
from django.utils.decorators import method_decorator
from django.views import View
from bookwyrm import emailing, forms, models
# pylint: disable=no-self-use
@method_decorator(login_required, name="dispatch")
class Report(View):
"""Make reports"""
def get(self, request, user_id, status_id=None, link_id=None):
"""static view of report modal"""
data = {"user": get_object_or_404(models.User, id=user_id)}
if status_id:
data["status"] = status_id
if link_id:
data["link"] = get_object_or_404(models.Link, id=link_id)
return TemplateResponse(request, "report.html", data)
def post(self, request):
"""a user reports something"""
form = forms.ReportForm(request.POST)
if not form.is_valid():
raise ValueError(form.errors)
report = form.save()
if report.links.exists():
# revert the domain to pending
domain = report.links.first().domain
domain.status = "pending"
domain.save()
emailing.moderation_report_email(report)
return redirect("/")