diff --git a/bookwyrm/activitypub/base_activity.py b/bookwyrm/activitypub/base_activity.py index 448d5563..5e66077c 100644 --- a/bookwyrm/activitypub/base_activity.py +++ b/bookwyrm/activitypub/base_activity.py @@ -65,7 +65,7 @@ class ActivityObject: try: value = kwargs[field.name] if value in (None, MISSING, {}): - raise KeyError() + raise KeyError("Missing required field", field.name) try: is_subclass = issubclass(field.type, ActivityObject) except TypeError: diff --git a/bookwyrm/migrations/0146_auto_20220316_2320.py b/bookwyrm/migrations/0146_auto_20220316_2320.py new file mode 100644 index 00000000..e50bf25e --- /dev/null +++ b/bookwyrm/migrations/0146_auto_20220316_2320.py @@ -0,0 +1,80 @@ +# Generated by Django 3.2.12 on 2022-03-16 23:20 + +import bookwyrm.models.fields +from django.db import migrations +from bookwyrm.models import Shelf + + +def add_shelves(apps, schema_editor): + """add any superusers to the "admin" group""" + + db_alias = schema_editor.connection.alias + shelf_model = apps.get_model("bookwyrm", "Shelf") + + users = apps.get_model("bookwyrm", "User") + local_users = users.objects.using(db_alias).filter(local=True) + for user in local_users: + remote_id = f"{user.remote_id}/books/stopped" + shelf_model.objects.using(db_alias).create( + name="Stopped reading", + identifier=Shelf.STOPPED_READING, + user=user, + editable=False, + remote_id=remote_id, + ) + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0145_sitesettings_version"), + ] + + operations = [ + migrations.AlterField( + model_name="comment", + name="reading_status", + field=bookwyrm.models.fields.CharField( + blank=True, + choices=[ + ("to-read", "To-Read"), + ("reading", "Reading"), + ("read", "Read"), + ("stopped-reading", "Stopped-Reading"), + ], + max_length=255, + null=True, + ), + ), + migrations.AlterField( + model_name="quotation", + name="reading_status", + field=bookwyrm.models.fields.CharField( + blank=True, + choices=[ + ("to-read", "To-Read"), + ("reading", "Reading"), + ("read", "Read"), + ("stopped-reading", "Stopped-Reading"), + ], + max_length=255, + null=True, + ), + ), + migrations.AlterField( + model_name="review", + name="reading_status", + field=bookwyrm.models.fields.CharField( + blank=True, + choices=[ + ("to-read", "To-Read"), + ("reading", "Reading"), + ("read", "Read"), + ("stopped-reading", "Stopped-Reading"), + ], + max_length=255, + null=True, + ), + ), + migrations.RunPython(add_shelves, reverse_code=migrations.RunPython.noop), + ] diff --git a/bookwyrm/migrations/0148_merge_20220326_2006.py b/bookwyrm/migrations/0148_merge_20220326_2006.py new file mode 100644 index 00000000..97866276 --- /dev/null +++ b/bookwyrm/migrations/0148_merge_20220326_2006.py @@ -0,0 +1,13 @@ +# Generated by Django 3.2.12 on 2022-03-26 20:06 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0146_auto_20220316_2320"), + ("bookwyrm", "0147_alter_user_preferred_language"), + ] + + operations = [] diff --git a/bookwyrm/models/shelf.py b/bookwyrm/models/shelf.py index 8ea274ea..3291d565 100644 --- a/bookwyrm/models/shelf.py +++ b/bookwyrm/models/shelf.py @@ -18,8 +18,9 @@ class Shelf(OrderedCollectionMixin, BookWyrmModel): TO_READ = "to-read" READING = "reading" READ_FINISHED = "read" + STOPPED_READING = "stopped-reading" - READ_STATUS_IDENTIFIERS = (TO_READ, READING, READ_FINISHED) + READ_STATUS_IDENTIFIERS = (TO_READ, READING, READ_FINISHED, STOPPED_READING) name = fields.CharField(max_length=100) identifier = models.CharField(max_length=100) diff --git a/bookwyrm/models/status.py b/bookwyrm/models/status.py index 17fcd458..b933edce 100644 --- a/bookwyrm/models/status.py +++ b/bookwyrm/models/status.py @@ -265,7 +265,7 @@ class GeneratedNote(Status): ReadingStatusChoices = models.TextChoices( - "ReadingStatusChoices", ["to-read", "reading", "read"] + "ReadingStatusChoices", ["to-read", "reading", "read", "stopped-reading"] ) diff --git a/bookwyrm/models/user.py b/bookwyrm/models/user.py index be5c1992..dce74022 100644 --- a/bookwyrm/models/user.py +++ b/bookwyrm/models/user.py @@ -374,6 +374,10 @@ class User(OrderedCollectionPageMixin, AbstractUser): "name": "Read", "identifier": "read", }, + { + "name": "Stopped Reading", + "identifier": "stopped-reading", + }, ] for shelf in shelves: diff --git a/bookwyrm/templates/get_started/book_preview.html b/bookwyrm/templates/get_started/book_preview.html index 8a20d0d7..9cfb56b0 100644 --- a/bookwyrm/templates/get_started/book_preview.html +++ b/bookwyrm/templates/get_started/book_preview.html @@ -10,6 +10,7 @@ {% if shelf.identifier == 'to-read' %}{% trans "To Read" %} {% elif shelf.identifier == 'reading' %}{% trans "Currently Reading" %} {% elif shelf.identifier == 'read' %}{% trans "Read" %} + {% elif shelf.identifier == 'stopped-reading' %}{% trans "Stopped Reading" %} {% else %}{{ shelf.name }}{% endif %} {% endfor %} diff --git a/bookwyrm/templates/reading_progress/stop.html b/bookwyrm/templates/reading_progress/stop.html new file mode 100644 index 00000000..5811c09b --- /dev/null +++ b/bookwyrm/templates/reading_progress/stop.html @@ -0,0 +1,14 @@ +{% extends 'layout.html' %} +{% load i18n %} + +{% block title %} +{% blocktrans trimmed with book_title=book.title %} +Stop Reading "{{ book_title }}" +{% endblocktrans %} +{% endblock %} + +{% block content %} + +{% include "snippets/reading_modals/stop_reading_modal.html" with book=book active=True static=True %} + +{% endblock %} diff --git a/bookwyrm/templates/shelf/shelf.html b/bookwyrm/templates/shelf/shelf.html index cc4bb143..b36dc01c 100644 --- a/bookwyrm/templates/shelf/shelf.html +++ b/bookwyrm/templates/shelf/shelf.html @@ -86,6 +86,7 @@ {% if shelf.identifier == 'to-read' %}{% trans "To Read" %} {% elif shelf.identifier == 'reading' %}{% trans "Currently Reading" %} {% elif shelf.identifier == 'read' %}{% trans "Read" %} + {% elif shelf.identifier == 'stopped-reading' %}{% trans "Stopped Reading" %} {% else %}{{ shelf.name }}{% endif %} {% include 'snippets/privacy-icons.html' with item=shelf %} @@ -150,7 +151,7 @@ {% if is_self %} {% trans "Shelved" as text %}{% include 'snippets/table-sort-header.html' with field="shelved_date" sort=sort text=text %} {% trans "Started" as text %}{% include 'snippets/table-sort-header.html' with field="start_date" sort=sort text=text %} - {% trans "Finished" as text %}{% include 'snippets/table-sort-header.html' with field="finish_date" sort=sort text=text %} + {% if shelf.identifier == 'read' %}{% trans "Finished" as text %}{% else %}{% trans "Until" as text %}{% endif %}{% include 'snippets/table-sort-header.html' with field="finish_date" sort=sort text=text %} {% endif %} {% trans "Rating" as text %}{% include 'snippets/table-sort-header.html' with field="rating" sort=sort text=text %} {% endif %} @@ -180,7 +181,7 @@ {{ book.start_date|naturalday|default_if_none:""}} - + {{ book.finish_date|naturalday|default_if_none:""}} {% endif %} diff --git a/bookwyrm/templates/snippets/reading_modals/stop_reading_modal.html b/bookwyrm/templates/snippets/reading_modals/stop_reading_modal.html new file mode 100644 index 00000000..80fb2d5b --- /dev/null +++ b/bookwyrm/templates/snippets/reading_modals/stop_reading_modal.html @@ -0,0 +1,42 @@ +{% extends 'snippets/reading_modals/layout.html' %} +{% load i18n %} +{% load utilities %} + +{% block modal-title %} +{% blocktrans trimmed with book_title=book|book_title %} +Stop Reading "{{ book_title }}" +{% endblocktrans %} +{% endblock %} + +{% block modal-form-open %} +
+{% csrf_token %} + + + +{% endblock %} + +{% block reading-dates %} +
+
+
+ + +
+
+
+
+ + +
+
+
+{% endblock %} + +{% block form %} +{% include "snippets/reading_modals/form.html" with optional=True type="stop_modal" %} +{% endblock %} diff --git a/bookwyrm/templates/snippets/shelf_selector.html b/bookwyrm/templates/snippets/shelf_selector.html index 2d1f2a83..feea50d7 100644 --- a/bookwyrm/templates/snippets/shelf_selector.html +++ b/bookwyrm/templates/snippets/shelf_selector.html @@ -49,6 +49,13 @@ {% join "finish_reading" uuid as modal_id %} {% include 'snippets/shelve_button/modal_button.html' with class=button_class fallback_url=fallback_url %} +{% elif shelf.identifier == 'stopped-reading' %} + +{% trans "Stopped reading" as button_text %} +{% url 'reading-status' 'stop' book.id as fallback_url %} +{% join "stop_reading" uuid as modal_id %} +{% include 'snippets/shelve_button/modal_button.html' with class=button_class fallback_url=fallback_url %} + {% elif shelf.identifier == 'to-read' %} {% trans "Want to read" as button_text %} @@ -99,5 +106,8 @@ {% join "finish_reading" uuid as modal_id %} {% include 'snippets/reading_modals/finish_reading_modal.html' with book=active_shelf.book id=modal_id move_from=current.id readthrough=readthrough refresh=True class="" %} +{% join "stop_reading" uuid as modal_id %} +{% include 'snippets/reading_modals/stop_reading_modal.html' with book=active_shelf.book id=modal_id move_from=current.id readthrough=readthrough refresh=True class="" %} + {% endwith %} {% endblock %} diff --git a/bookwyrm/templates/snippets/shelve_button/shelve_button.html b/bookwyrm/templates/snippets/shelve_button/shelve_button.html index 04dc4e4b..010bff05 100644 --- a/bookwyrm/templates/snippets/shelve_button/shelve_button.html +++ b/bookwyrm/templates/snippets/shelve_button/shelve_button.html @@ -29,6 +29,9 @@ {% join "finish_reading" uuid as modal_id %} {% include 'snippets/reading_modals/finish_reading_modal.html' with book=active_shelf_book id=modal_id readthrough=readthrough class="" %} +{% join "stop_reading" uuid as modal_id %} +{% include 'snippets/reading_modals/stop_reading_modal.html' with book=active_shelf_book id=modal_id readthrough=readthrough class="" %} + {% join "progress_update" uuid as modal_id %} {% include 'snippets/reading_modals/progress_update_modal.html' with book=active_shelf_book id=modal_id readthrough=readthrough class="" %} diff --git a/bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html b/bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html index 2b87e21f..50d3e257 100644 --- a/bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html +++ b/bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html @@ -26,6 +26,13 @@ {% join "finish_reading" button_uuid as modal_id %} {% include 'snippets/shelve_button/modal_button.html' with class=class fallback_url=fallback_url %} + {% elif shelf.identifier == 'stopped-reading' %} + + {% trans "Stop reading" as button_text %} + {% url 'reading-status' 'stop' book.id as fallback_url %} + {% join "stop_reading" button_uuid as modal_id %} + {% include 'snippets/shelve_button/modal_button.html' with class=class fallback_url=fallback_url %} + {% elif shelf.identifier == 'to-read' %} {% trans "Want to read" as button_text %} diff --git a/bookwyrm/templates/snippets/shelve_button/shelve_button_options.html b/bookwyrm/templates/snippets/shelve_button/shelve_button_options.html index 04f4bdc2..fb7ee452 100644 --- a/bookwyrm/templates/snippets/shelve_button/shelve_button_options.html +++ b/bookwyrm/templates/snippets/shelve_button/shelve_button_options.html @@ -33,6 +33,13 @@ {% join "finish_reading" button_uuid as modal_id %} {% include 'snippets/shelve_button/modal_button.html' with class=class fallback_url=fallback_url %} + {% elif shelf.identifier == 'stopped-reading' %} + + {% trans "Stop reading" as button_text %} + {% url 'reading-status' 'stop' book.id as fallback_url %} + {% join "stop_reading" button_uuid as modal_id %} + {% include 'snippets/shelve_button/modal_button.html' with class=class fallback_url=fallback_url %} + {% elif shelf.identifier == 'to-read' %} {% trans "Want to read" as button_text %} diff --git a/bookwyrm/templates/user/user.html b/bookwyrm/templates/user/user.html index ccc4a44e..af85159f 100755 --- a/bookwyrm/templates/user/user.html +++ b/bookwyrm/templates/user/user.html @@ -33,8 +33,9 @@ {% if shelf.name == 'To Read' %}{% trans "To Read" %} {% elif shelf.name == 'Currently Reading' %}{% trans "Currently Reading" %} {% elif shelf.name == 'Read' %}{% trans "Read" %} + {% elif shelf.name == 'Stopped Reading' %}{% trans "Stopped Reading" %} {% else %}{{ shelf.name }}{% endif %} - {% if shelf.size > 3 %}({% blocktrans with size=shelf.size %}View all {{ size }}{% endblocktrans %}){% endif %} + {% if shelf.size > 4 %}({% blocktrans with size=shelf.size %}View all {{ size }}{% endblocktrans %}){% endif %}
{% for book in shelf.books %} diff --git a/bookwyrm/tests/models/test_user_model.py b/bookwyrm/tests/models/test_user_model.py index adcee8fb..37e2192b 100644 --- a/bookwyrm/tests/models/test_user_model.py +++ b/bookwyrm/tests/models/test_user_model.py @@ -53,15 +53,17 @@ class User(TestCase): def test_user_shelves(self): shelves = models.Shelf.objects.filter(user=self.user).all() - self.assertEqual(len(shelves), 3) + self.assertEqual(len(shelves), 4) names = [s.name for s in shelves] self.assertTrue("To Read" in names) self.assertTrue("Currently Reading" in names) self.assertTrue("Read" in names) + self.assertTrue("Stopped Reading" in names) ids = [s.identifier for s in shelves] self.assertTrue("to-read" in ids) self.assertTrue("reading" in ids) self.assertTrue("read" in ids) + self.assertTrue("stopped-reading" in ids) def test_activitypub_serialize(self): activity = self.user.to_activity() diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py index bb4cbbe2..5abacae1 100644 --- a/bookwyrm/urls.py +++ b/bookwyrm/urls.py @@ -622,7 +622,7 @@ urlpatterns = [ name="reading-status-update", ), re_path( - r"^reading-status/(?Pwant|start|finish)/(?P\d+)/?$", + r"^reading-status/(?Pwant|start|finish|stop)/(?P\d+)/?$", views.ReadingStatus.as_view(), name="reading-status", ), diff --git a/bookwyrm/views/helpers.py b/bookwyrm/views/helpers.py index a2c4b20d..7d8eced7 100644 --- a/bookwyrm/views/helpers.py +++ b/bookwyrm/views/helpers.py @@ -138,6 +138,7 @@ def handle_reading_status(user, shelf, book, privacy): "to-read": "wants to read", "reading": "started reading", "read": "finished reading", + "stopped-reading": "stopped reading", }[shelf.identifier] except KeyError: # it's a non-standard shelf, don't worry about it diff --git a/bookwyrm/views/reading.py b/bookwyrm/views/reading.py index 2cd05202..3cd153d2 100644 --- a/bookwyrm/views/reading.py +++ b/bookwyrm/views/reading.py @@ -29,6 +29,7 @@ class ReadingStatus(View): "want": "want.html", "start": "start.html", "finish": "finish.html", + "stop": "stop.html", }.get(status) if not template: return HttpResponseNotFound() @@ -41,6 +42,7 @@ class ReadingStatus(View): "want": models.Shelf.TO_READ, "start": models.Shelf.READING, "finish": models.Shelf.READ_FINISHED, + "stop": models.Shelf.STOPPED_READING, }.get(status) if not identifier: return HttpResponseBadRequest()