diff --git a/bookwyrm/templates/book/book.html b/bookwyrm/templates/book/book.html
index 27d061a2..64daf3fa 100644
--- a/bookwyrm/templates/book/book.html
+++ b/bookwyrm/templates/book/book.html
@@ -147,7 +147,7 @@
{% include 'snippets/toggle/open_button.html' with text=button_text controls_text="add_description" controls_uid=book.id focus="id_description" hide_active=True id="hide_description" %}
diff --git a/bookwyrm/templates/book/file_links_modal.html b/bookwyrm/templates/book/file_links_modal.html
new file mode 100644
index 00000000..a2f8d0cd
--- /dev/null
+++ b/bookwyrm/templates/book/file_links_modal.html
@@ -0,0 +1,37 @@
+{% extends 'components/modal.html' %}
+{% load i18n %}
+
+{% block modal-title %}
+{% trans "Add file link" %}
+{% endblock %}
+
+{% block modal-form-open %}
+{% endblock %}
diff --git a/bookwyrm/views/__init__.py b/bookwyrm/views/__init__.py
index fb9db210..71c300f7 100644
--- a/bookwyrm/views/__init__.py
+++ b/bookwyrm/views/__init__.py
@@ -28,7 +28,13 @@ 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,
+ add_file_link,
+)
from .books.books import update_book_from_remote
from .books.edit_book import EditBook, ConfirmEditBook
from .books.editions import Editions, switch_edition
diff --git a/bookwyrm/views/books/books.py b/bookwyrm/views/books/books.py
index 2d49ae30..8edeffb3 100644
--- a/bookwyrm/views/books/books.py
+++ b/bookwyrm/views/books/books.py
@@ -4,6 +4,7 @@ from uuid import uuid4
from django.contrib.auth.decorators import login_required, permission_required
from django.core.files.base import ContentFile
from django.core.paginator import Paginator
+from django.db import transaction
from django.db.models import Avg, Q
from django.http import Http404
from django.shortcuts import get_object_or_404, redirect
@@ -40,7 +41,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 +85,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,
@@ -194,3 +196,21 @@ def update_book_from_remote(request, book_id, connector_identifier):
connector.update_book_from_remote(book)
return redirect("book", book.id)
+
+
+@login_required
+@require_POST
+@permission_required("bookwyrm.edit_book", raise_exception=True)
+@transaction.atomic
+def add_file_link(request, book_id):
+ """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)
+ form = forms.FileLinkForm(request.POST)
+ if not form.is_valid():
+ return redirect("book", book.id)
+
+ link = form.save()
+ book.file_links.add(link)
+ book.last_edited_by = request.user
+ book.save()
+ return redirect("book", book.id)