diff --git a/bookwyrm/forms.py b/bookwyrm/forms.py
index 5af7c455..5ab90895 100644
--- a/bookwyrm/forms.py
+++ b/bookwyrm/forms.py
@@ -225,7 +225,7 @@ class LinkDomainForm(CustomForm):
class FileLinkForm(CustomForm):
class Meta:
model = models.FileLink
- fields = ["url", "filetype", "book", "added_by"]
+ fields = ["url", "filetype", "availability", "book", "added_by"]
class EditionForm(CustomForm):
diff --git a/bookwyrm/migrations/0129_auto_20220117_1716.py b/bookwyrm/migrations/0129_auto_20220117_1716.py
new file mode 100644
index 00000000..6b05fd27
--- /dev/null
+++ b/bookwyrm/migrations/0129_auto_20220117_1716.py
@@ -0,0 +1,32 @@
+# Generated by Django 3.2.10 on 2022-01-17 17:16
+
+import bookwyrm.models.fields
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("bookwyrm", "0128_merge_0126_auto_20220112_2315_0127_auto_20220110_2211"),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name="filelink",
+ name="availability",
+ field=bookwyrm.models.fields.CharField(
+ choices=[
+ ("free", "Free"),
+ ("purchase", "Purchasable"),
+ ("loan", "Available for loan"),
+ ],
+ default="free",
+ max_length=100,
+ ),
+ ),
+ migrations.AlterField(
+ model_name="filelink",
+ name="filetype",
+ field=bookwyrm.models.fields.CharField(max_length=50),
+ ),
+ ]
diff --git a/bookwyrm/models/link.py b/bookwyrm/models/link.py
index be7c104f..0e4148dd 100644
--- a/bookwyrm/models/link.py
+++ b/bookwyrm/models/link.py
@@ -47,13 +47,23 @@ class Link(ActivitypubMixin, BookWyrmModel):
return super().save(*args, **kwargs)
+AvailabilityChoices = [
+ ("free", _("Free")),
+ ("purchase", _("Purchasable")),
+ ("loan", _("Available for loan")),
+]
+
+
class FileLink(Link):
"""a link to a file"""
book = models.ForeignKey(
"Book", on_delete=models.CASCADE, related_name="file_links", null=True
)
- filetype = fields.CharField(max_length=5, activitypub_field="mediaType")
+ filetype = fields.CharField(max_length=50, activitypub_field="mediaType")
+ availability = fields.CharField(
+ max_length=100, choices=AvailabilityChoices, default="free"
+ )
StatusChoices = [
diff --git a/bookwyrm/settings.py b/bookwyrm/settings.py
index 06fc6a37..1d1ea154 100644
--- a/bookwyrm/settings.py
+++ b/bookwyrm/settings.py
@@ -14,7 +14,7 @@ VERSION = "0.2.0"
PAGE_LENGTH = env("PAGE_LENGTH", 15)
DEFAULT_LANGUAGE = env("DEFAULT_LANGUAGE", "English")
-JS_CACHE = "a47cc2ca"
+JS_CACHE = "76c5ff1f"
# email
EMAIL_BACKEND = env("EMAIL_BACKEND", "django.core.mail.backends.smtp.EmailBackend")
diff --git a/bookwyrm/static/js/autocomplete.js b/bookwyrm/static/js/autocomplete.js
index 89610083..84474e43 100644
--- a/bookwyrm/static/js/autocomplete.js
+++ b/bookwyrm/static/js/autocomplete.js
@@ -42,6 +42,8 @@
function getSuggestions(input, trie) {
// Follow the trie through the provided input
+ input = input.toLowerCase();
+
input.split("").forEach((letter) => {
if (!trie) {
return;
@@ -160,6 +162,23 @@ const tries = {
},
},
},
+ r: {
+ i: {
+ n: {
+ t: {
+ " ": {
+ b: {
+ o: {
+ o: {
+ k: "Print book",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
},
},
};
diff --git a/bookwyrm/templates/book/file_links/add_link_modal.html b/bookwyrm/templates/book/file_links/add_link_modal.html
index dfc222ee..0002b82b 100644
--- a/bookwyrm/templates/book/file_links/add_link_modal.html
+++ b/bookwyrm/templates/book/file_links/add_link_modal.html
@@ -30,7 +30,7 @@
+
+
+
+ {{ file_link_form.availability }}
+
+
{% endblock %}
diff --git a/bookwyrm/templates/book/file_links/edit_links.html b/bookwyrm/templates/book/file_links/edit_links.html
index c56f97a6..8dad6c40 100644
--- a/bookwyrm/templates/book/file_links/edit_links.html
+++ b/bookwyrm/templates/book/file_links/edit_links.html
@@ -33,9 +33,10 @@
{% trans "Added by" %} |
{% trans "Filetype" %} |
{% trans "Domain" %} |
- {% trans "Actions" %} |
+ {% trans "Status" %} |
+ {% trans "Actions" %} |
- {% for link in book.file_links.all %}
+ {% for link in links %}
{{ link.url }}
@@ -47,13 +48,44 @@
{{ link.filelink.filetype }}
|
- {{ link.domain.name }} ({{ link.domain.get_status_display }})
+ {{ link.domain.name }}
{% trans "Report spam" %}
|
- |
+
+
+ |
+
+
diff --git a/bookwyrm/templates/book/file_links/links.html b/bookwyrm/templates/book/file_links/links.html
index 10a6da2f..25e0ba89 100644
--- a/bookwyrm/templates/book/file_links/links.html
+++ b/bookwyrm/templates/book/file_links/links.html
@@ -30,6 +30,12 @@
{{ link.name }}
({{ link.filetype }})
+
+ {% if link.availability != "free" %}
+
+ {{ link.get_availability_display }}
+
+ {% endif %}
{% endfor %}
@@ -46,7 +52,7 @@
{% trans "Edit links" %}
-{% include 'book/file_links/add_link_modal.html' with book=book id="add-links" %}
{% endif %}
+{% include 'book/file_links/add_link_modal.html' with book=book id="add-links" %}
{% endif %}
diff --git a/bookwyrm/tests/views/books/test_links.py b/bookwyrm/tests/views/books/test_links.py
index 9e051926..2aee5aed 100644
--- a/bookwyrm/tests/views/books/test_links.py
+++ b/bookwyrm/tests/views/books/test_links.py
@@ -67,6 +67,7 @@ class LinkViews(TestCase):
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
@@ -87,3 +88,59 @@ class LinkViews(TestCase):
self.book.refresh_from_db()
self.assertEqual(self.book.file_links.first(), link)
+
+ def test_book_links(self):
+ """there are so many views, this just makes sure it LOADS"""
+ view = views.BookFileLinks.as_view()
+ models.FileLink.objects.create(
+ book=self.book,
+ added_by=self.local_user,
+ url="https://www.hello.com",
+ )
+ request = self.factory.get("")
+ request.user = self.local_user
+ result = view(request, self.book.id)
+ self.assertEqual(result.status_code, 200)
+ validate_html(result.render())
+
+ 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 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())
diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py
index 99060149..7cdfd92a 100644
--- a/bookwyrm/urls.py
+++ b/bookwyrm/urls.py
@@ -473,10 +473,15 @@ urlpatterns = [
rf"{BOOK_PATH}/filelink/?$", views.BookFileLinks.as_view(), name="file-link"
),
re_path(
- rf"{BOOK_PATH}/filelink/(?P\d+)/delete/?$",
+ rf"{BOOK_PATH}/filelink/(?P\d+)/?$",
views.BookFileLinks.as_view(),
name="file-link",
),
+ re_path(
+ rf"{BOOK_PATH}/filelink/(?P\d+)/delete/?$",
+ views.delete_link,
+ name="file-link-delete",
+ ),
re_path(
rf"{BOOK_PATH}/filelink/add/?$",
views.AddFileLink.as_view(),
diff --git a/bookwyrm/views/__init__.py b/bookwyrm/views/__init__.py
index 2ec501de..3f57c274 100644
--- a/bookwyrm/views/__init__.py
+++ b/bookwyrm/views/__init__.py
@@ -37,7 +37,7 @@ from .books.books import (
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
+from .books.links import BookFileLinks, AddFileLink, delete_link
# landing
from .landing.about import about, privacy, conduct
diff --git a/bookwyrm/views/books/links.py b/bookwyrm/views/books/links.py
index 989ca9c4..51621023 100644
--- a/bookwyrm/views/books/links.py
+++ b/bookwyrm/views/books/links.py
@@ -5,28 +5,49 @@ 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 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.edit_book", raise_exception=True), name="dispatch"
+)
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}
- )
+ 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 post(self, request, book_id, link_id):
- """delete link"""
+ """Edit a link"""
link = get_object_or_404(models.FileLink, id=link_id, book=book_id)
- link.delete()
+ form = forms.FileLinkForm(request.POST, instance=link)
+ form.save()
return self.get(request, book_id)
+@require_POST
+@login_required
+# pylint: disable=unused-argument
+def delete_link(request, book_id, link_id):
+ """delete link"""
+ link = get_object_or_404(models.FileLink, id=link_id, book=book_id)
+ link.delete()
+ return redirect("file-link", book_id)
+
+
@method_decorator(login_required, name="dispatch")
@method_decorator(
permission_required("bookwyrm.edit_book", raise_exception=True), name="dispatch"
|