def test_add_link_post(self, *_): """there are so many views, this just makes sure it LOADS""" view = views.AddFileLink.as_view() form = forms.FileLinkForm() form.data["url"] = "https://www.example.com" form.data["filetype"] = "HTML" form.data["book"] = self.book.id form.data["added_by"] = self.local_user.id form.data["availability"] = "loan" request = self.factory.post("", form.data) request.user = self.local_user with patch( "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" ) as mock: view(request, self.book.id) self.assertEqual(mock.call_count, 1) activity = json.loads(mock.call_args[1]["args"][1]) self.assertEqual(activity["type"], "Update") self.assertEqual(activity["object"]["type"], "Edition") link = models.FileLink.objects.get() self.assertEqual(link.name, "www.example.com") self.assertEqual(link.url, "https://www.example.com") self.assertEqual(link.filetype, "HTML") self.book.refresh_from_db() self.assertEqual(self.book.file_links.first(), link)
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)
def get(self, request, book_id): """view links""" book = get_object_or_404(models.Edition, id=book_id) links = book.file_links.order_by("domain__status", "created_date") annotated_links = [] for link in links.all(): link.form = forms.FileLinkForm(instance=link) annotated_links.append(link) data = {"book": book, "links": annotated_links} return TemplateResponse(request, "book/file_links/edit_links.html", data)
def test_delete_link(self): """remove a link""" link = models.FileLink.objects.create( book=self.book, added_by=self.local_user, url="https://www.hello.com", ) form = forms.FileLinkForm() form.data["url"] = "https://www.example.com" form.data["filetype"] = "HTML" form.data["book"] = self.book.id form.data["added_by"] = self.local_user.id form.data["availability"] = "loan" request = self.factory.post("", form.data) request.user = self.local_user views.delete_link(request, self.book.id, link.id) self.assertFalse(models.FileLink.objects.exists())
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)
def test_book_links_post(self): """there are so many views, this just makes sure it LOADS""" link = models.FileLink.objects.create( book=self.book, added_by=self.local_user, url="https://www.hello.com", ) view = views.BookFileLinks.as_view() form = forms.FileLinkForm() form.data["url"] = link.url form.data["filetype"] = "HTML" form.data["book"] = self.book.id form.data["added_by"] = self.local_user.id form.data["availability"] = "loan" request = self.factory.post("", form.data) request.user = self.local_user view(request, self.book.id, link.id) link.refresh_from_db() self.assertEqual(link.filetype, "HTML") self.assertEqual(link.availability, "loan")
def post(self, request, book_id, link_id): """Edit a link""" link = get_object_or_404(models.FileLink, id=link_id, book=book_id) form = forms.FileLinkForm(request.POST, instance=link) form.save() return self.get(request, book_id)
class Book(View): """a book! this is the stuff""" def get(self, request, book_id, **kwargs): """info about a book""" if is_api_request(request): book = get_object_or_404(models.Book.objects.select_subclasses(), id=book_id) return ActivitypubResponse(book.to_activity()) user_statuses = (kwargs.get("user_statuses", False) if request.user.is_authenticated else False) # it's safe to use this OR because edition and work and subclasses of the same # table, so they never have clashing IDs book = (models.Edition.viewer_aware_objects( request.user).filter(Q(id=book_id) | Q( parent_work__id=book_id)).order_by("-edition_rank"). select_related("parent_work").prefetch_related( "authors", "file_links").first()) if not book or not book.parent_work: raise Http404() if redirect_local_path := not user_statuses and maybe_redirect_local_path( request, book): return redirect_local_path # all reviews for all editions of the book reviews = models.Review.privacy_filter( request.user).filter(book__parent_work__editions=book) # the reviews to show if user_statuses: if user_statuses == "review": queryset = book.review_set.select_subclasses() elif user_statuses == "comment": queryset = book.comment_set else: queryset = book.quotation_set queryset = queryset.filter(user=request.user, deleted=False) else: queryset = reviews.exclude(Q(content__isnull=True) | Q(content="")) queryset = queryset.select_related("user").order_by("-published_date") paginated = Paginator(queryset, PAGE_LENGTH) lists = models.List.privacy_filter(request.user, ).filter( listitem__approved=True, listitem__book__in=book.parent_work.editions.all(), ) data = { "book": book, "statuses": paginated.get_page(request.GET.get("page")), "review_count": reviews.count(), "ratings": reviews.filter(Q(content__isnull=True) | Q(content="")).select_related("user") if not user_statuses else None, "rating": reviews.aggregate(Avg("rating"))["rating__avg"], "lists": lists, "update_error": kwargs.get("update_error", False), } 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, book=book, ).order_by("start_date") for readthrough in readthroughs: readthrough.progress_updates = ( readthrough.progressupdate_set.all().order_by( "-updated_date")) data["readthroughs"] = readthroughs data["user_shelfbooks"] = models.ShelfBook.objects.filter( user=request.user, book=book).select_related("shelf") data["other_edition_shelves"] = models.ShelfBook.objects.filter( ~Q(book=book), user=request.user, book__parent_work=book.parent_work, ).select_related("shelf", "book") filters = {"user": request.user, "deleted": False} data["user_statuses"] = { "review_count": book.review_set.filter(**filters).count(), "comment_count": book.comment_set.filter(**filters).count(), "quotation_count": book.quotation_set.filter(**filters).count(), } return TemplateResponse(request, "book/book.html", data)