From 30288c6ebb362feb5e05e51d1cd09787dd13fbd7 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 5 Aug 2021 16:39:09 -0700 Subject: [PATCH 01/75] Update books feed on shelve --- bookwyrm/activitystreams.py | 64 +++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/bookwyrm/activitystreams.py b/bookwyrm/activitystreams.py index 01ca3f770..6b75a65fa 100644 --- a/bookwyrm/activitystreams.py +++ b/bookwyrm/activitystreams.py @@ -199,6 +199,40 @@ class BooksStream(ActivityStream): privacy_levels=["public"], ) + def add_book_statuses(self, user, book): + """add statuses about a book to a user's feed""" + work = book.parent_work + statuses = privacy_filter( + user, + models.Status.objects.select_subclasses() + .filter( + Q(comment__book__parent_work=work) + | Q(quotation__book__parent_work=work) + | Q(review__book__parent_work=work) + | Q(mention_books__parent_work=work) + ) + .distinct(), + privacy_levels=["public"], + ) + self.bulk_add_objects_to_store(statuses, self.stream_id(user)) + + def remove_book_statuses(self, user, book): + """add statuses about a book to a user's feed""" + work = book.parent_work + statuses = privacy_filter( + user, + models.Status.objects.select_subclasses() + .filter( + Q(comment__book__parent_work=work) + | Q(quotation__book__parent_work=work) + | Q(review__book__parent_work=work) + | Q(mention_books__parent_work=work) + ) + .distinct(), + privacy_levels=["public"], + ) + self.bulk_remove_objects_from_store(statuses, self.stream_id(user)) + # determine which streams are enabled in settings.py available_streams = [s["key"] for s in STREAMS] @@ -316,3 +350,33 @@ def populate_streams_on_account_create(sender, instance, created, *args, **kwarg for stream in streams.values(): stream.populate_streams(instance) + + +@receiver(signals.pre_save, sender=models.ShelfBook) +# pylint: disable=unused-argument +def add_statuses_on_shelve(sender, instance, created, *args, **kwargs): + """update books stream when user shelves a book""" + if not created or not instance.user.local: + return + # check if the book is already on the user's shelves + if models.ShelfBook.objects.filter( + user=instance.user, book__in=instance.book.parent_work.editions.all() + ).exists(): + return + + BooksStream().add_book_statuses(instance.user, instance.book) + + +@receiver(signals.post_delete, sender=models.ShelfBook) +# pylint: disable=unused-argument +def remove_statuses_on_shelve(sender, instance, *args, **kwargs): + """update books stream when user unshelves a book""" + if not instance.user.local: + return + # check if the book is actually unshelved, not just moved + if models.ShelfBook.objects.filter( + user=instance.user, book__in=instance.book.parent_work.editions.all() + ).exists(): + return + + BooksStream().remove_book_statuses(instance.user, instance.book) From 70f4ecf870dd269da4b123e1682385466a904d9e Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 5 Aug 2021 17:13:47 -0700 Subject: [PATCH 02/75] Removes invalid argument --- bookwyrm/activitystreams.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bookwyrm/activitystreams.py b/bookwyrm/activitystreams.py index 6b75a65fa..bad7c59f8 100644 --- a/bookwyrm/activitystreams.py +++ b/bookwyrm/activitystreams.py @@ -354,9 +354,9 @@ def populate_streams_on_account_create(sender, instance, created, *args, **kwarg @receiver(signals.pre_save, sender=models.ShelfBook) # pylint: disable=unused-argument -def add_statuses_on_shelve(sender, instance, created, *args, **kwargs): +def add_statuses_on_shelve(sender, instance, *args, **kwargs): """update books stream when user shelves a book""" - if not created or not instance.user.local: + if not instance.user.local: return # check if the book is already on the user's shelves if models.ShelfBook.objects.filter( From 70a535adb7c36395a6f63587817b1730762297cc Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 5 Aug 2021 17:19:39 -0700 Subject: [PATCH 03/75] Adds books stream mock --- bookwyrm/tests/test_activitystreams.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bookwyrm/tests/test_activitystreams.py b/bookwyrm/tests/test_activitystreams.py index ba4950895..ac57d8b3d 100644 --- a/bookwyrm/tests/test_activitystreams.py +++ b/bookwyrm/tests/test_activitystreams.py @@ -6,6 +6,7 @@ from bookwyrm import activitystreams, models @patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") @patch("bookwyrm.activitystreams.ActivityStream.add_status") +@patch("bookwyrm.activitystreams.BooksStream.add_book_statuses") @patch("bookwyrm.suggested_users.rerank_suggestions_task.delay") class Activitystreams(TestCase): """using redis to build activity streams""" From d390b395e69e515fe13f36ec4a6081570c4f1865 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 5 Aug 2021 17:47:28 -0700 Subject: [PATCH 04/75] fixes book mock in user view tests --- bookwyrm/tests/views/test_edit_user.py | 4 +++- bookwyrm/tests/views/test_user.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/bookwyrm/tests/views/test_edit_user.py b/bookwyrm/tests/views/test_edit_user.py index ccfb4c90d..df89d5b09 100644 --- a/bookwyrm/tests/views/test_edit_user.py +++ b/bookwyrm/tests/views/test_edit_user.py @@ -34,7 +34,9 @@ class EditUserViews(TestCase): "rat@local.com", "rat@rat.rat", "password", local=True, localname="rat" ) - self.book = models.Edition.objects.create(title="test") + self.book = models.Edition.objects.create( + title="test", parent_work=models.Work.objects.create(title="test work") + ) with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): models.ShelfBook.objects.create( book=self.book, diff --git a/bookwyrm/tests/views/test_user.py b/bookwyrm/tests/views/test_user.py index 0efdf16a3..740f0d299 100644 --- a/bookwyrm/tests/views/test_user.py +++ b/bookwyrm/tests/views/test_user.py @@ -28,7 +28,9 @@ class UserViews(TestCase): self.rat = models.User.objects.create_user( "rat@local.com", "rat@rat.rat", "password", local=True, localname="rat" ) - self.book = models.Edition.objects.create(title="test") + self.book = models.Edition.objects.create( + title="test", parent_work=models.Work.objects.create(title="test work") + ) with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"): models.ShelfBook.objects.create( From d0114d2e8353025c1288cd34d0ac2f3ef5add3da Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 5 Aug 2021 18:05:57 -0700 Subject: [PATCH 05/75] Adds test for book add description view --- bookwyrm/tests/views/test_book.py | 12 ++++++++++++ bookwyrm/views/books.py | 9 +++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/bookwyrm/tests/views/test_book.py b/bookwyrm/tests/views/test_book.py index 6f6116b2e..51f8b5d56 100644 --- a/bookwyrm/tests/views/test_book.py +++ b/bookwyrm/tests/views/test_book.py @@ -299,3 +299,15 @@ class BookViews(TestCase): self.book.refresh_from_db() self.assertTrue(self.book.cover) + + def test_add_description(self): + """add a book description""" + self.local_user.groups.add(self.group) + request = self.factory.post("", {"description": "new description hi"}) + request.user = self.local_user + + views.add_description(request, self.book.id) + + self.book.refresh_from_db() + self.assertEqual(self.book.description, "new description hi") + self.assertEqual(self.book.last_edited_by, self.local_user) diff --git a/bookwyrm/views/books.py b/bookwyrm/views/books.py index 492d0cac4..d56e2f22c 100644 --- a/bookwyrm/views/books.py +++ b/bookwyrm/views/books.py @@ -339,18 +339,15 @@ def set_cover_from_url(url): @permission_required("bookwyrm.edit_book", raise_exception=True) def add_description(request, book_id): """upload a new cover""" - if not request.method == "POST": - return redirect("/") - book = get_object_or_404(models.Edition, id=book_id) description = request.POST.get("description") book.description = description book.last_edited_by = request.user - book.save() + book.save(update_fields=["description", "last_edited_by"]) - return redirect("/book/%s" % book.id) + return redirect("book", book.id) @require_POST @@ -360,7 +357,7 @@ def resolve_book(request): connector = connector_manager.get_or_create_connector(remote_id) book = connector.get_or_create_book(remote_id) - return redirect("/book/%d" % book.id) + return redirect("book", book.id) @login_required From 41742d6698074e29ba4077fb04a296cd4841ce74 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 5 Aug 2021 18:16:23 -0700 Subject: [PATCH 06/75] Adds inventaire get connector test --- .../tests/connectors/test_inventaire_connector.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/bookwyrm/tests/connectors/test_inventaire_connector.py b/bookwyrm/tests/connectors/test_inventaire_connector.py index c66f0400d..381017727 100644 --- a/bookwyrm/tests/connectors/test_inventaire_connector.py +++ b/bookwyrm/tests/connectors/test_inventaire_connector.py @@ -171,3 +171,15 @@ class Inventaire(TestCase): } self.assertEqual(get_language_code(options), "there") self.assertIsNone(get_language_code({})) + + @responses.activate + def test_get_description(self): + """extract a wikipedia excerpt""" + responses.add( + responses.GET, + "https://inventaire.io/api/data?action=wp-extract&lang=en&title=test_path", + json={"extract": "hi hi"}, + ) + + extract = self.connector.get_description({"enwiki": "test_path"}) + self.assertEqual(extract, "hi hi") From 48175023bcad05526479c5830ed4cd25c30a53de Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 5 Aug 2021 18:58:32 -0700 Subject: [PATCH 07/75] Mocks broadcast --- bookwyrm/tests/views/test_book.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bookwyrm/tests/views/test_book.py b/bookwyrm/tests/views/test_book.py index 51f8b5d56..3b6748523 100644 --- a/bookwyrm/tests/views/test_book.py +++ b/bookwyrm/tests/views/test_book.py @@ -306,7 +306,8 @@ class BookViews(TestCase): request = self.factory.post("", {"description": "new description hi"}) request.user = self.local_user - views.add_description(request, self.book.id) + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + views.add_description(request, self.book.id) self.book.refresh_from_db() self.assertEqual(self.book.description, "new description hi") From 2e7dd9d4ef0018dcaba5e8ecbf158e813eb5051e Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 5 Aug 2021 19:51:31 -0700 Subject: [PATCH 08/75] Fixes over-reporting user last active date --- .../0081_alter_user_last_active_date.py | 19 +++++++++++++++++++ bookwyrm/models/user.py | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 bookwyrm/migrations/0081_alter_user_last_active_date.py diff --git a/bookwyrm/migrations/0081_alter_user_last_active_date.py b/bookwyrm/migrations/0081_alter_user_last_active_date.py new file mode 100644 index 000000000..dc6b640f6 --- /dev/null +++ b/bookwyrm/migrations/0081_alter_user_last_active_date.py @@ -0,0 +1,19 @@ +# Generated by Django 3.2.4 on 2021-08-06 02:51 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0080_alter_shelfbook_options"), + ] + + operations = [ + migrations.AlterField( + model_name="user", + name="last_active_date", + field=models.DateTimeField(default=django.utils.timezone.now), + ), + ] diff --git a/bookwyrm/models/user.py b/bookwyrm/models/user.py index 21b6bbaac..cb6941c9b 100644 --- a/bookwyrm/models/user.py +++ b/bookwyrm/models/user.py @@ -111,7 +111,7 @@ class User(OrderedCollectionPageMixin, AbstractUser): remote_id = fields.RemoteIdField(null=True, unique=True, activitypub_field="id") created_date = models.DateTimeField(auto_now_add=True) updated_date = models.DateTimeField(auto_now=True) - last_active_date = models.DateTimeField(auto_now=True) + last_active_date = models.DateTimeField(default=timezone.now) manually_approves_followers = fields.BooleanField(default=False) show_goal = models.BooleanField(default=True) discoverable = fields.BooleanField(default=False) From d126d7ba91caa8c0ec52dee20b0b22bedae81711 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 6 Aug 2021 08:43:05 -0700 Subject: [PATCH 09/75] Disable comically inefficient book count comparisons Oops! Hopefully I can restore these in a way that doesn't break at even a moderate scale --- bookwyrm/suggested_users.py | 54 +++++++++++++------------- bookwyrm/tests/test_suggested_users.py | 6 +-- 2 files changed, 31 insertions(+), 29 deletions(-) diff --git a/bookwyrm/suggested_users.py b/bookwyrm/suggested_users.py index 3a95ef7fe..de04b7e3c 100644 --- a/bookwyrm/suggested_users.py +++ b/bookwyrm/suggested_users.py @@ -19,7 +19,7 @@ class SuggestedUsers(RedisStore): def get_rank(self, obj): """get computed rank""" - return obj.mutuals + (1.0 - (1.0 / (obj.shared_books + 1))) + return obj.mutuals # + (1.0 - (1.0 / (obj.shared_books + 1))) def store_id(self, user): # pylint: disable=no-self-use """the key used to store this user's recs""" @@ -31,7 +31,7 @@ class SuggestedUsers(RedisStore): """calculate mutuals count and shared books count from rank""" return { "mutuals": math.floor(rank), - "shared_books": int(1 / (-1 * (rank % 1 - 1))) - 1, + # "shared_books": int(1 / (-1 * (rank % 1 - 1))) - 1, } def get_objects_for_store(self, store): @@ -95,7 +95,7 @@ class SuggestedUsers(RedisStore): logger.exception(err) continue user.mutuals = counts["mutuals"] - user.shared_books = counts["shared_books"] + # user.shared_books = counts["shared_books"] results.append(user) return results @@ -103,7 +103,9 @@ class SuggestedUsers(RedisStore): def get_annotated_users(viewer, *args, **kwargs): """Users, annotated with things they have in common""" return ( - models.User.objects.filter(discoverable=True, is_active=True, *args, **kwargs) + models.User.objects.filter( + discoverable=True, is_active=True, bookwyrm_user=True, *args, **kwargs + ) .exclude(Q(id__in=viewer.blocks.all()) | Q(blocks=viewer)) .annotate( mutuals=Count( @@ -115,16 +117,16 @@ def get_annotated_users(viewer, *args, **kwargs): ), distinct=True, ), - shared_books=Count( - "shelfbook", - filter=Q( - ~Q(id=viewer.id), - shelfbook__book__parent_work__in=[ - s.book.parent_work for s in viewer.shelfbook_set.all() - ], - ), - distinct=True, - ), + # shared_books=Count( + # "shelfbook", + # filter=Q( + # ~Q(id=viewer.id), + # shelfbook__book__parent_work__in=[ + # s.book.parent_work for s in viewer.shelfbook_set.all() + # ], + # ), + # distinct=True, + # ), ) ) @@ -162,18 +164,18 @@ def update_suggestions_on_unfollow(sender, instance, **kwargs): rerank_user_task.delay(instance.user_object.id, update_only=False) -@receiver(signals.post_save, sender=models.ShelfBook) -@receiver(signals.post_delete, sender=models.ShelfBook) -# pylint: disable=unused-argument -def update_rank_on_shelving(sender, instance, *args, **kwargs): - """when a user shelves or unshelves a book, re-compute their rank""" - # if it's a local user, re-calculate who is rec'ed to them - if instance.user.local: - rerank_suggestions_task.delay(instance.user.id) - - # if the user is discoverable, update their rankings - if instance.user.discoverable: - rerank_user_task.delay(instance.user.id) +# @receiver(signals.post_save, sender=models.ShelfBook) +# @receiver(signals.post_delete, sender=models.ShelfBook) +# # pylint: disable=unused-argument +# def update_rank_on_shelving(sender, instance, *args, **kwargs): +# """when a user shelves or unshelves a book, re-compute their rank""" +# # if it's a local user, re-calculate who is rec'ed to them +# if instance.user.local: +# rerank_suggestions_task.delay(instance.user.id) +# +# # if the user is discoverable, update their rankings +# if instance.user.discoverable: +# rerank_user_task.delay(instance.user.id) @receiver(signals.post_save, sender=models.User) diff --git a/bookwyrm/tests/test_suggested_users.py b/bookwyrm/tests/test_suggested_users.py index 41e8911eb..7e4a9d00f 100644 --- a/bookwyrm/tests/test_suggested_users.py +++ b/bookwyrm/tests/test_suggested_users.py @@ -29,7 +29,7 @@ class SuggestedUsers(TestCase): Mock = namedtuple("AnnotatedUserMock", ("mutuals", "shared_books")) annotated_user_mock = Mock(3, 27) rank = suggested_users.get_rank(annotated_user_mock) - self.assertEqual(rank, 3.9642857142857144) + self.assertEqual(rank, 3) # 3.9642857142857144) def test_store_id(self, *_): """redis key generation""" @@ -42,7 +42,7 @@ class SuggestedUsers(TestCase): """reverse the rank computation to get the mutuals and shared books counts""" counts = suggested_users.get_counts_from_rank(3.9642857142857144) self.assertEqual(counts["mutuals"], 3) - self.assertEqual(counts["shared_books"], 27) + # self.assertEqual(counts["shared_books"], 27) def test_get_objects_for_store(self, *_): """list of people to follow for a given user""" @@ -126,7 +126,7 @@ class SuggestedUsers(TestCase): user_1_annotated = result.get(id=user_1.id) self.assertEqual(user_1_annotated.mutuals, 1) - self.assertEqual(user_1_annotated.shared_books, 1) + # self.assertEqual(user_1_annotated.shared_books, 1) def test_get_annotated_users_counts(self, *_): """correct counting for multiple shared attributed""" From 9030f0d08b5aabd729d5b13bfe5c0e54b9ee8e93 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 6 Aug 2021 09:14:07 -0700 Subject: [PATCH 10/75] Bookwyrm user was already set --- bookwyrm/suggested_users.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/bookwyrm/suggested_users.py b/bookwyrm/suggested_users.py index de04b7e3c..9c42d79d8 100644 --- a/bookwyrm/suggested_users.py +++ b/bookwyrm/suggested_users.py @@ -103,9 +103,7 @@ class SuggestedUsers(RedisStore): def get_annotated_users(viewer, *args, **kwargs): """Users, annotated with things they have in common""" return ( - models.User.objects.filter( - discoverable=True, is_active=True, bookwyrm_user=True, *args, **kwargs - ) + models.User.objects.filter(discoverable=True, is_active=True, *args, **kwargs) .exclude(Q(id__in=viewer.blocks.all()) | Q(blocks=viewer)) .annotate( mutuals=Count( From 134db20c57f4d8787aa9c237b311665a19e420aa Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 6 Aug 2021 09:40:01 -0700 Subject: [PATCH 11/75] Fixes directory view --- bookwyrm/views/directory.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/views/directory.py b/bookwyrm/views/directory.py index 8a2e78dc2..8d893047a 100644 --- a/bookwyrm/views/directory.py +++ b/bookwyrm/views/directory.py @@ -28,7 +28,7 @@ class Directory(View): if sort == "recent": users = users.order_by("-last_active_date") else: - users = users.order_by("-mutuals", "-shared_books", "-last_active_date") + users = users.order_by("-mutuals", "-last_active_date") paginated = Paginator(users, 12) From 9804d4cf514585b66d286cc8d1d55a6b13f1eb3b Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 6 Aug 2021 10:19:38 -0700 Subject: [PATCH 12/75] Adds more book view tests --- bookwyrm/tests/views/test_book.py | 78 +++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/bookwyrm/tests/views/test_book.py b/bookwyrm/tests/views/test_book.py index 3b6748523..6280f54ff 100644 --- a/bookwyrm/tests/views/test_book.py +++ b/bookwyrm/tests/views/test_book.py @@ -12,6 +12,7 @@ from django.core.files.uploadedfile import SimpleUploadedFile from django.template.response import TemplateResponse from django.test import TestCase from django.test.client import RequestFactory +from django.utils import timezone from bookwyrm import forms, models, views from bookwyrm.activitypub import ActivitypubResponse @@ -52,6 +53,11 @@ class BookViews(TestCase): def test_book_page(self): """there are so many views, this just makes sure it LOADS""" view = views.Book.as_view() + models.ReadThrough.objects.create( + user=self.local_user, + book=self.book, + start_date=timezone.now(), + ) request = self.factory.get("") request.user = self.local_user with patch("bookwyrm.views.books.is_api_request") as is_api: @@ -67,6 +73,78 @@ class BookViews(TestCase): self.assertIsInstance(result, ActivitypubResponse) self.assertEqual(result.status_code, 200) + @patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") + def test_book_page_statuses(self, _): + """there are so many views, this just makes sure it LOADS""" + view = views.Book.as_view() + + review = models.Review.objects.create( + user=self.local_user, + book=self.book, + content="hi", + ) + + comment = models.Comment.objects.create( + user=self.local_user, + book=self.book, + content="hi", + ) + + quote = models.Quotation.objects.create( + user=self.local_user, + book=self.book, + content="hi", + quote="wow", + ) + + request = self.factory.get("") + request.user = self.local_user + with patch("bookwyrm.views.books.is_api_request") as is_api: + is_api.return_value = False + result = view(request, self.book.id, user_statuses="review") + self.assertIsInstance(result, TemplateResponse) + result.render() + self.assertEqual(result.status_code, 200) + self.assertEqual(result.context_data["statuses"].object_list[0], review) + + with patch("bookwyrm.views.books.is_api_request") as is_api: + is_api.return_value = False + result = view(request, self.book.id, user_statuses="comment") + self.assertIsInstance(result, TemplateResponse) + result.render() + self.assertEqual(result.status_code, 200) + self.assertEqual(result.context_data["statuses"].object_list[0], comment) + + with patch("bookwyrm.views.books.is_api_request") as is_api: + is_api.return_value = False + result = view(request, self.book.id, user_statuses="quotation") + self.assertIsInstance(result, TemplateResponse) + result.render() + self.assertEqual(result.status_code, 200) + self.assertEqual(result.context_data["statuses"].object_list[0], quote) + + def test_book_page_invalid_id(self): + """there are so many views, this just makes sure it LOADS""" + view = views.Book.as_view() + request = self.factory.get("") + request.user = self.local_user + with patch("bookwyrm.views.books.is_api_request") as is_api: + is_api.return_value = False + result = view(request, 0) + self.assertEqual(result.status_code, 404) + + def test_book_page_work_id(self): + """there are so many views, this just makes sure it LOADS""" + view = views.Book.as_view() + request = self.factory.get("") + request.user = self.local_user + with patch("bookwyrm.views.books.is_api_request") as is_api: + is_api.return_value = False + result = view(request, self.work.id) + result.render() + self.assertEqual(result.status_code, 200) + self.assertEqual(result.context_data["book"], self.book) + def test_edit_book_page(self): """there are so many views, this just makes sure it LOADS""" view = views.EditBook.as_view() From 3abceb8563e3229e8d1ef5d34f89b8667ed917dc Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 6 Aug 2021 10:33:14 -0700 Subject: [PATCH 13/75] Templatetag test --- bookwyrm/tests/test_templatetags.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/bookwyrm/tests/test_templatetags.py b/bookwyrm/tests/test_templatetags.py index 3c5d8b258..d75d368c1 100644 --- a/bookwyrm/tests/test_templatetags.py +++ b/bookwyrm/tests/test_templatetags.py @@ -175,3 +175,10 @@ class TemplateTags(TestCase): result = bookwyrm_tags.related_status(notification) self.assertIsInstance(result, models.Status) + + def test_get_next_shelf(self, *_): + """self progress helper""" + self.assertEqual(bookwyrm_tags.get_next_shelf("to-read"), "reading") + self.assertEqual(bookwyrm_tags.get_next_shelf("reading"), "read") + self.assertEqual(bookwyrm_tags.get_next_shelf("read"), "read") + self.assertEqual(bookwyrm_tags.get_next_shelf("blooooga"), "to-read") From 0d2622e4ffbb0436d94dbc81adf22bd6e4cb8d5a Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 6 Aug 2021 11:23:38 -0700 Subject: [PATCH 14/75] Tests login view --- bookwyrm/tests/views/test_authentication.py | 64 ++++++++++++++++++++- bookwyrm/views/authentication.py | 3 +- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/bookwyrm/tests/views/test_authentication.py b/bookwyrm/tests/views/test_authentication.py index 10531f517..e2d67fbe1 100644 --- a/bookwyrm/tests/views/test_authentication.py +++ b/bookwyrm/tests/views/test_authentication.py @@ -8,7 +8,7 @@ from django.template.response import TemplateResponse from django.test import TestCase from django.test.client import RequestFactory -from bookwyrm import models, views +from bookwyrm import forms, models, views from bookwyrm.settings import DOMAIN @@ -22,7 +22,7 @@ class AuthenticationViews(TestCase): self.factory = RequestFactory() with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"): self.local_user = models.User.objects.create_user( - "mouse@local.com", + "mouse@your.domain.here", "mouse@mouse.com", "password", local=True, @@ -49,6 +49,66 @@ class AuthenticationViews(TestCase): self.assertEqual(result.url, "/") self.assertEqual(result.status_code, 302) + def test_login_post_localname(self, _): + """there are so many views, this just makes sure it LOADS""" + view = views.Login.as_view() + form = forms.LoginForm() + form.data["localname"] = "mouse@mouse.com" + form.data["password"] = "password" + request = self.factory.post("", form.data) + request.user = self.anonymous_user + + with patch("bookwyrm.views.authentication.login"): + result = view(request) + self.assertEqual(result.url, "/") + self.assertEqual(result.status_code, 302) + + def test_login_post_username(self, _): + """there are so many views, this just makes sure it LOADS""" + view = views.Login.as_view() + form = forms.LoginForm() + form.data["localname"] = "mouse@your.domain.here" + form.data["password"] = "password" + request = self.factory.post("", form.data) + request.user = self.anonymous_user + + with patch("bookwyrm.views.authentication.login"): + result = view(request) + self.assertEqual(result.url, "/") + self.assertEqual(result.status_code, 302) + + def test_login_post_email(self, _): + """there are so many views, this just makes sure it LOADS""" + view = views.Login.as_view() + form = forms.LoginForm() + form.data["localname"] = "mouse" + form.data["password"] = "password" + request = self.factory.post("", form.data) + request.user = self.anonymous_user + + with patch("bookwyrm.views.authentication.login"): + result = view(request) + self.assertEqual(result.url, "/") + self.assertEqual(result.status_code, 302) + + def test_login_post_invalid_credentials(self, _): + """there are so many views, this just makes sure it LOADS""" + view = views.Login.as_view() + form = forms.LoginForm() + form.data["localname"] = "mouse" + form.data["password"] = "passsword1" + request = self.factory.post("", form.data) + request.user = self.anonymous_user + + with patch("bookwyrm.views.authentication.login"): + result = view(request) + result.render() + self.assertEqual(result.status_code, 200) + self.assertEqual( + result.context_data["login_form"].non_field_errors, + "Username or password are incorrect", + ) + def test_register(self, _): """create a user""" view = views.Register.as_view() diff --git a/bookwyrm/views/authentication.py b/bookwyrm/views/authentication.py index 003e94b09..6598aef2a 100644 --- a/bookwyrm/views/authentication.py +++ b/bookwyrm/views/authentication.py @@ -6,6 +6,7 @@ from django.shortcuts import get_object_or_404, redirect from django.template.response import TemplateResponse from django.utils import timezone from django.utils.decorators import method_decorator +from django.utils.translation import gettext_lazy as _ from django.views.decorators.csrf import csrf_exempt from django.views import View @@ -54,7 +55,7 @@ class Login(View): return redirect(request.GET.get("next", "/")) # login errors - login_form.non_field_errors = "Username or password are incorrect" + login_form.non_field_errors = _("Username or password are incorrect") register_form = forms.RegisterForm() data = {"login_form": login_form, "register_form": register_form} return TemplateResponse(request, "login.html", data) From 568e30230a58d5d1263af36633b304c9dcf5a72b Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 6 Aug 2021 11:43:55 -0700 Subject: [PATCH 15/75] Adds start import view test --- bookwyrm/tests/views/test_import.py | 26 ++++++++++++++++++++++++-- locale/de_DE/LC_MESSAGES/django.po | 6 +++++- locale/en_US/LC_MESSAGES/django.po | 6 +++++- locale/es/LC_MESSAGES/django.po | 6 +++++- locale/fr_FR/LC_MESSAGES/django.po | 6 +++++- locale/zh_Hans/LC_MESSAGES/django.po | 6 +++++- locale/zh_Hant/LC_MESSAGES/django.po | 6 +++++- 7 files changed, 54 insertions(+), 8 deletions(-) diff --git a/bookwyrm/tests/views/test_import.py b/bookwyrm/tests/views/test_import.py index 13c0ef5d2..d9d67d568 100644 --- a/bookwyrm/tests/views/test_import.py +++ b/bookwyrm/tests/views/test_import.py @@ -1,11 +1,12 @@ """ test for app action functionality """ +import pathlib from unittest.mock import patch +from django.core.files.uploadedfile import SimpleUploadedFile from django.template.response import TemplateResponse from django.test import TestCase from django.test.client import RequestFactory -from bookwyrm import models -from bookwyrm import views +from bookwyrm import forms, models, views class ImportViews(TestCase): @@ -47,6 +48,27 @@ class ImportViews(TestCase): result.render() self.assertEqual(result.status_code, 200) + def test_start_import(self): + """retry failed items""" + view = views.Import.as_view() + form = forms.ImportForm() + form.data["source"] = "LibraryThing" + form.data["privacy"] = "public" + form.data["include_reviews"] = False + csv_file = pathlib.Path(__file__).parent.joinpath("../data/goodreads.csv") + form.data["csv_file"] = SimpleUploadedFile( + csv_file, open(csv_file, "rb").read(), content_type="text/csv" + ) + + request = self.factory.post("", form.data) + request.user = self.local_user + + with patch("bookwyrm.importers.Importer.start_import"): + view(request) + job = models.ImportJob.objects.get() + self.assertFalse(job.include_reviews) + self.assertEqual(job.privacy, "public") + def test_retry_import(self): """retry failed items""" view = views.ImportStatus.as_view() diff --git a/locale/de_DE/LC_MESSAGES/django.po b/locale/de_DE/LC_MESSAGES/django.po index b047f0310..140f91dcc 100644 --- a/locale/de_DE/LC_MESSAGES/django.po +++ b/locale/de_DE/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-08-05 01:33+0000\n" +"POT-Creation-Date: 2021-08-06 18:34+0000\n" "PO-Revision-Date: 2021-03-02 17:19-0800\n" "Last-Translator: Mouse Reeve \n" "Language-Team: English \n" @@ -3295,6 +3295,10 @@ msgstr "" msgid "%(title)s: %(subtitle)s" msgstr "" +#: bookwyrm/views/authentication.py:58 +msgid "Username or password are incorrect" +msgstr "" + #: bookwyrm/views/import_data.py:67 #, fuzzy #| msgid "Email address:" diff --git a/locale/en_US/LC_MESSAGES/django.po b/locale/en_US/LC_MESSAGES/django.po index 153d8b9a1..ab56046ee 100644 --- a/locale/en_US/LC_MESSAGES/django.po +++ b/locale/en_US/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-08-05 01:33+0000\n" +"POT-Creation-Date: 2021-08-06 18:34+0000\n" "PO-Revision-Date: 2021-02-28 17:19-0800\n" "Last-Translator: Mouse Reeve \n" "Language-Team: English \n" @@ -2991,6 +2991,10 @@ msgstr "" msgid "%(title)s: %(subtitle)s" msgstr "" +#: bookwyrm/views/authentication.py:58 +msgid "Username or password are incorrect" +msgstr "" + #: bookwyrm/views/import_data.py:67 msgid "Not a valid csv file" msgstr "" diff --git a/locale/es/LC_MESSAGES/django.po b/locale/es/LC_MESSAGES/django.po index 5bae4d7e2..dbf7540c7 100644 --- a/locale/es/LC_MESSAGES/django.po +++ b/locale/es/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-08-05 01:33+0000\n" +"POT-Creation-Date: 2021-08-06 18:34+0000\n" "PO-Revision-Date: 2021-03-19 11:49+0800\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -3036,6 +3036,10 @@ msgstr "" msgid "%(title)s: %(subtitle)s" msgstr "" +#: bookwyrm/views/authentication.py:58 +msgid "Username or password are incorrect" +msgstr "" + #: bookwyrm/views/import_data.py:67 msgid "Not a valid csv file" msgstr "No un archivo csv válido" diff --git a/locale/fr_FR/LC_MESSAGES/django.po b/locale/fr_FR/LC_MESSAGES/django.po index 399e40563..b4405df5a 100644 --- a/locale/fr_FR/LC_MESSAGES/django.po +++ b/locale/fr_FR/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-08-05 01:33+0000\n" +"POT-Creation-Date: 2021-08-06 18:34+0000\n" "PO-Revision-Date: 2021-04-05 12:44+0100\n" "Last-Translator: Fabien Basmaison \n" "Language-Team: Mouse Reeve \n" @@ -3015,6 +3015,10 @@ msgstr "Ce fichier dépasse la taille limite : 10 Mo" msgid "%(title)s: %(subtitle)s" msgstr "%(title)s (%(subtitle)s)" +#: bookwyrm/views/authentication.py:58 +msgid "Username or password are incorrect" +msgstr "" + #: bookwyrm/views/import_data.py:67 msgid "Not a valid csv file" msgstr "Fichier CSV non valide" diff --git a/locale/zh_Hans/LC_MESSAGES/django.po b/locale/zh_Hans/LC_MESSAGES/django.po index d9921655e..471de85d0 100644 --- a/locale/zh_Hans/LC_MESSAGES/django.po +++ b/locale/zh_Hans/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-08-05 01:33+0000\n" +"POT-Creation-Date: 2021-08-06 18:34+0000\n" "PO-Revision-Date: 2021-03-20 00:56+0000\n" "Last-Translator: Kana \n" "Language-Team: Mouse Reeve \n" @@ -2992,6 +2992,10 @@ msgstr "文件超过了最大大小: 10MB" msgid "%(title)s: %(subtitle)s" msgstr "%(title)s:%(subtitle)s" +#: bookwyrm/views/authentication.py:58 +msgid "Username or password are incorrect" +msgstr "" + #: bookwyrm/views/import_data.py:67 msgid "Not a valid csv file" msgstr "不是有效的 csv 文件" diff --git a/locale/zh_Hant/LC_MESSAGES/django.po b/locale/zh_Hant/LC_MESSAGES/django.po index 5ce42251b..40b12995b 100644 --- a/locale/zh_Hant/LC_MESSAGES/django.po +++ b/locale/zh_Hant/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-08-05 01:33+0000\n" +"POT-Creation-Date: 2021-08-06 18:34+0000\n" "PO-Revision-Date: 2021-06-30 10:36+0000\n" "Last-Translator: Grace Cheng \n" "Language-Team: LANGUAGE \n" @@ -3011,6 +3011,10 @@ msgstr "檔案超過了最大大小: 10MB" msgid "%(title)s: %(subtitle)s" msgstr "" +#: bookwyrm/views/authentication.py:58 +msgid "Username or password are incorrect" +msgstr "" + #: bookwyrm/views/import_data.py:67 msgid "Not a valid csv file" msgstr "不是有效的 csv 檔案" From 3082c4ce5c7d7dafa5016cef1a463e1e94412aaa Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 6 Aug 2021 11:55:20 -0700 Subject: [PATCH 16/75] Tests invite create view --- bookwyrm/tests/views/test_invite.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/bookwyrm/tests/views/test_invite.py b/bookwyrm/tests/views/test_invite.py index 1eaf57c03..6ad464208 100644 --- a/bookwyrm/tests/views/test_invite.py +++ b/bookwyrm/tests/views/test_invite.py @@ -52,6 +52,26 @@ class InviteViews(TestCase): result.render() self.assertEqual(result.status_code, 200) + def test_manage_invites_post(self): + """there are so many views, this just makes sure it LOADS""" + view = views.ManageInvites.as_view() + form = forms.CreateInviteForm() + form.data["use_limit"] = 3 + form.data["expiry"] = "" + request = self.factory.post("", form.data) + request.user = self.local_user + request.user.is_superuser = True + + result = view(request) + + self.assertIsInstance(result, TemplateResponse) + result.render() + self.assertEqual(result.status_code, 200) + + invite = models.SiteInvite.objects.get() + self.assertEqual(invite.use_limit, 3) + self.assertIsNone(invite.expiry) + def test_invite_request(self): """request to join a server""" form = forms.InviteRequestForm() From 3e2f1806e9a3d490599665afb442a10ebd8acc5d Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 6 Aug 2021 14:42:18 -0700 Subject: [PATCH 17/75] Adds email confirmation code field --- .../migrations/0082_auto_20210806_2141.py | 51 +++++++++++++++++++ bookwyrm/models/base_model.py | 8 +++ bookwyrm/models/site.py | 9 +--- bookwyrm/models/user.py | 3 +- 4 files changed, 62 insertions(+), 9 deletions(-) create mode 100644 bookwyrm/migrations/0082_auto_20210806_2141.py diff --git a/bookwyrm/migrations/0082_auto_20210806_2141.py b/bookwyrm/migrations/0082_auto_20210806_2141.py new file mode 100644 index 000000000..76c8c9628 --- /dev/null +++ b/bookwyrm/migrations/0082_auto_20210806_2141.py @@ -0,0 +1,51 @@ +# Generated by Django 3.2.4 on 2021-08-06 21:41 + +import bookwyrm.models.base_model +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0081_alter_user_last_active_date"), + ] + + operations = [ + migrations.AddField( + model_name="user", + name="confirmation_code", + field=models.CharField( + default=bookwyrm.models.base_model.new_access_code, max_length=32 + ), + ), + migrations.AlterField( + model_name="connector", + name="deactivation_reason", + field=models.CharField( + blank=True, + choices=[ + ("pending", "Pending"), + ("self_deletion", "Self Deletion"), + ("moderator_deletion", "Moderator Deletion"), + ("domain_block", "Domain Block"), + ], + max_length=255, + null=True, + ), + ), + migrations.AlterField( + model_name="user", + name="deactivation_reason", + field=models.CharField( + blank=True, + choices=[ + ("pending", "Pending"), + ("self_deletion", "Self Deletion"), + ("moderator_deletion", "Moderator Deletion"), + ("domain_block", "Domain Block"), + ], + max_length=255, + null=True, + ), + ), + ] diff --git a/bookwyrm/models/base_model.py b/bookwyrm/models/base_model.py index 2cb7c0365..5b55ea50f 100644 --- a/bookwyrm/models/base_model.py +++ b/bookwyrm/models/base_model.py @@ -1,4 +1,6 @@ """ base model with default fields """ +import base64 +from Crypto import Random from django.db import models from django.dispatch import receiver @@ -9,6 +11,7 @@ from .fields import RemoteIdField DeactivationReason = models.TextChoices( "DeactivationReason", [ + "pending", "self_deletion", "moderator_deletion", "domain_block", @@ -16,6 +19,11 @@ DeactivationReason = models.TextChoices( ) +def new_access_code(): + """the identifier for a user invite""" + return base64.b32encode(Random.get_random_bytes(5)).decode("ascii") + + class BookWyrmModel(models.Model): """shared fields""" diff --git a/bookwyrm/models/site.py b/bookwyrm/models/site.py index 872f6b454..fdc068664 100644 --- a/bookwyrm/models/site.py +++ b/bookwyrm/models/site.py @@ -1,8 +1,6 @@ """ the particulars for this instance of BookWyrm """ -import base64 import datetime -from Crypto import Random from django.db import models, IntegrityError from django.dispatch import receiver from django.utils import timezone @@ -10,7 +8,7 @@ from model_utils import FieldTracker from bookwyrm.preview_images import generate_site_preview_image_task from bookwyrm.settings import DOMAIN, ENABLE_PREVIEW_IMAGES -from .base_model import BookWyrmModel +from .base_model import BookWyrmModel, new_access_code from .user import User @@ -61,11 +59,6 @@ class SiteSettings(models.Model): return default_settings -def new_access_code(): - """the identifier for a user invite""" - return base64.b32encode(Random.get_random_bytes(5)).decode("ascii") - - class SiteInvite(models.Model): """gives someone access to create an account on the instance""" diff --git a/bookwyrm/models/user.py b/bookwyrm/models/user.py index cb6941c9b..08bd87b3c 100644 --- a/bookwyrm/models/user.py +++ b/bookwyrm/models/user.py @@ -22,7 +22,7 @@ from bookwyrm.signatures import create_key_pair from bookwyrm.tasks import app from bookwyrm.utils import regex from .activitypub_mixin import OrderedCollectionPageMixin, ActivitypubMixin -from .base_model import BookWyrmModel, DeactivationReason +from .base_model import BookWyrmModel, DeactivationReason, new_access_code from .federated_server import FederatedServer from . import fields, Review @@ -123,6 +123,7 @@ class User(OrderedCollectionPageMixin, AbstractUser): deactivation_reason = models.CharField( max_length=255, choices=DeactivationReason.choices, null=True, blank=True ) + confirmation_code = models.CharField(max_length=32, default=new_access_code) name_field = "username" property_fields = [("following_link", "following")] From 247a7f74896e91ba09c6ae3e9467bb332fa8eee9 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 6 Aug 2021 15:38:37 -0700 Subject: [PATCH 18/75] Email confirmation email --- .env.dev.example | 3 +++ .env.prod.example | 3 +++ bookwyrm/emailing.py | 7 +++++++ bookwyrm/models/user.py | 16 +++++++++++++--- bookwyrm/settings.py | 3 +++ .../templates/email/confirm/html_content.html | 14 ++++++++++++++ bookwyrm/templates/email/confirm/subject.html | 4 ++++ .../templates/email/confirm/text_content.html | 11 +++++++++++ bookwyrm/views/authentication.py | 15 ++++++++++++--- bookwyrm/views/site.py | 2 ++ 10 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 bookwyrm/templates/email/confirm/html_content.html create mode 100644 bookwyrm/templates/email/confirm/subject.html create mode 100644 bookwyrm/templates/email/confirm/text_content.html diff --git a/.env.dev.example b/.env.dev.example index f42aaaaec..a74e7bb36 100644 --- a/.env.dev.example +++ b/.env.dev.example @@ -36,6 +36,9 @@ FLOWER_PORT=8888 #FLOWER_USER=mouse #FLOWER_PASSWORD=changeme +# make users confirm their email addresses after registration +CONFIRM_EMAIL=false + EMAIL_HOST="smtp.mailgun.org" EMAIL_PORT=587 EMAIL_HOST_USER=mail@your.domain.here diff --git a/.env.prod.example b/.env.prod.example index 5115469ca..c5edb55ec 100644 --- a/.env.prod.example +++ b/.env.prod.example @@ -36,6 +36,9 @@ FLOWER_PORT=8888 FLOWER_USER=mouse FLOWER_PASSWORD=changeme +# make users confirm their email addresses after registration +CONFIRM_EMAIL=true + EMAIL_HOST="smtp.mailgun.org" EMAIL_PORT=587 EMAIL_HOST_USER=mail@your.domain.here diff --git a/bookwyrm/emailing.py b/bookwyrm/emailing.py index 657310b05..516d64c93 100644 --- a/bookwyrm/emailing.py +++ b/bookwyrm/emailing.py @@ -23,6 +23,13 @@ def email_data(): } +def email_confirmation_email(user): + """newly registered users confirm email address""" + data = email_data() + data["confirmation_code"] = user.confirmation_code + data["confirmation_link"] = user.confirmation_link + send_email.delay(user.email, *format_email("confirm_email", data)) + def invite_email(invite_request): """send out an invite code""" data = email_data() diff --git a/bookwyrm/models/user.py b/bookwyrm/models/user.py index 08bd87b3c..94b7b41e1 100644 --- a/bookwyrm/models/user.py +++ b/bookwyrm/models/user.py @@ -17,7 +17,7 @@ from bookwyrm.connectors import get_data, ConnectorException from bookwyrm.models.shelf import Shelf from bookwyrm.models.status import Status, Review from bookwyrm.preview_images import generate_user_preview_image_task -from bookwyrm.settings import DOMAIN, ENABLE_PREVIEW_IMAGES +from bookwyrm.settings import DOMAIN, ENABLE_PREVIEW_IMAGES, USE_HTTPS from bookwyrm.signatures import create_key_pair from bookwyrm.tasks import app from bookwyrm.utils import regex @@ -26,6 +26,10 @@ from .base_model import BookWyrmModel, DeactivationReason, new_access_code from .federated_server import FederatedServer from . import fields, Review +def site_link(): + """helper for generating links to the site""" + protocol = "https" if USE_HTTPS else "http" + return f"{protocol}://{DOMAIN}" class User(OrderedCollectionPageMixin, AbstractUser): """a user who wants to read books""" @@ -129,6 +133,12 @@ class User(OrderedCollectionPageMixin, AbstractUser): property_fields = [("following_link", "following")] field_tracker = FieldTracker(fields=["name", "avatar"]) + @property + def confirmation_link(self): + """helper for generating confirmation links""" + link = site_link() + return f"{link}/confirm-email/{self.confirmation_code}" + @property def following_link(self): """just how to find out the following info""" @@ -260,9 +270,9 @@ class User(OrderedCollectionPageMixin, AbstractUser): return # populate fields for local users - self.remote_id = "https://%s/user/%s" % (DOMAIN, self.localname) + self.remote_id = "%s/user/%s" % (site_link(), self.localname) self.inbox = "%s/inbox" % self.remote_id - self.shared_inbox = "https://%s/inbox" % DOMAIN + self.shared_inbox = "%s/inbox" % site_link() self.outbox = "%s/outbox" % self.remote_id # an id needs to be set before we can proceed with related models diff --git a/bookwyrm/settings.py b/bookwyrm/settings.py index 180191d98..130889ac2 100644 --- a/bookwyrm/settings.py +++ b/bookwyrm/settings.py @@ -24,6 +24,9 @@ CELERY_ACCEPT_CONTENT = ["application/json"] CELERY_TASK_SERIALIZER = "json" CELERY_RESULT_SERIALIZER = "json" +# make users confirm their email addresses after registration +CONFIRM_EMAIL = env("CONFIRM_EMAIL", True) + # email EMAIL_BACKEND = env("EMAIL_BACKEND", "django.core.mail.backends.smtp.EmailBackend") EMAIL_HOST = env("EMAIL_HOST") diff --git a/bookwyrm/templates/email/confirm/html_content.html b/bookwyrm/templates/email/confirm/html_content.html new file mode 100644 index 000000000..b47642af7 --- /dev/null +++ b/bookwyrm/templates/email/confirm/html_content.html @@ -0,0 +1,14 @@ +{% extends 'email/html_layout.html' %} +{% load i18n %} + +{% block content %} +

+{% blocktrans trimmed %} +One last step before you join {{ site_name }}! Please confirm your email address by clicking the link below: +{% endblocktrans %} +

+ +{% trans "Confirm Email" as text %} +{% include 'email/snippets/action.html' with path=confirmation_link text=text %} + +{% endblock %} diff --git a/bookwyrm/templates/email/confirm/subject.html b/bookwyrm/templates/email/confirm/subject.html new file mode 100644 index 000000000..b81a5a83f --- /dev/null +++ b/bookwyrm/templates/email/confirm/subject.html @@ -0,0 +1,4 @@ +{% load i18n %} +{% blocktrans trimmed %} +Please confirm your email +{% endblocktrans %} diff --git a/bookwyrm/templates/email/confirm/text_content.html b/bookwyrm/templates/email/confirm/text_content.html new file mode 100644 index 000000000..e3d739383 --- /dev/null +++ b/bookwyrm/templates/email/confirm/text_content.html @@ -0,0 +1,11 @@ +{% extends 'email/text_layout.html' %} +{% load i18n %} +{% block content %} +{% blocktrans trimmed %} +One last step before you join {{ site_name }}! Please confirm your email address by clicking the link below: +{% endblocktrans %} + +{{ confirmation_link }} + + +{% endblock %} diff --git a/bookwyrm/views/authentication.py b/bookwyrm/views/authentication.py index 003e94b09..43b4bb373 100644 --- a/bookwyrm/views/authentication.py +++ b/bookwyrm/views/authentication.py @@ -9,8 +9,8 @@ from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_exempt from django.views import View -from bookwyrm import forms, models -from bookwyrm.settings import DOMAIN +from bookwyrm import emailing, forms, models +from bookwyrm.settings import DOMAIN, CONFIRM_EMAIL # pylint: disable= no-self-use @@ -104,13 +104,22 @@ class Register(View): username = "%s@%s" % (localname, DOMAIN) user = models.User.objects.create_user( - username, email, password, localname=localname, local=True + username, + email, + password, + localname=localname, + local=True, + is_active=not CONFIRM_EMAIL, ) if invite: invite.times_used += 1 invite.invitees.add(user) invite.save() + if CONFIRM_EMAIL: + emailing.email_confirmation_email(user) + return redirect("confirm-email") + login(request, user) return redirect("get-started-profile") diff --git a/bookwyrm/views/site.py b/bookwyrm/views/site.py index 46bdf7226..42e8a6dd5 100644 --- a/bookwyrm/views/site.py +++ b/bookwyrm/views/site.py @@ -46,4 +46,6 @@ def email_preview(request): data["text_content_path"] = "email/{}/text_content.html".format(template) data["reset_link"] = "https://example.com/link" data["invite_link"] = "https://example.com/link" + data["confirmation_link"] = "https://example.com/link" + data["confirmation_code"] = "AKJHKDGKJSDFG" return TemplateResponse(request, "email/preview.html", data) From 5926224d7e5784be753da402822ff8e5a9a879f0 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 6 Aug 2021 16:24:57 -0700 Subject: [PATCH 19/75] Confirm email views --- .env.dev.example | 3 - .env.prod.example | 3 - bookwyrm/emailing.py | 1 + ...806_2141.py => 0082_auto_20210806_2324.py} | 7 +- bookwyrm/models/site.py | 1 + bookwyrm/models/user.py | 6 +- bookwyrm/settings.py | 3 - bookwyrm/templates/confirm_email.html | 1 + bookwyrm/urls.py | 7 ++ bookwyrm/views/__init__.py | 1 + bookwyrm/views/authentication.py | 73 +++++++++++++++---- 11 files changed, 78 insertions(+), 28 deletions(-) rename bookwyrm/migrations/{0082_auto_20210806_2141.py => 0082_auto_20210806_2324.py} (87%) create mode 100644 bookwyrm/templates/confirm_email.html diff --git a/.env.dev.example b/.env.dev.example index a74e7bb36..f42aaaaec 100644 --- a/.env.dev.example +++ b/.env.dev.example @@ -36,9 +36,6 @@ FLOWER_PORT=8888 #FLOWER_USER=mouse #FLOWER_PASSWORD=changeme -# make users confirm their email addresses after registration -CONFIRM_EMAIL=false - EMAIL_HOST="smtp.mailgun.org" EMAIL_PORT=587 EMAIL_HOST_USER=mail@your.domain.here diff --git a/.env.prod.example b/.env.prod.example index c5edb55ec..5115469ca 100644 --- a/.env.prod.example +++ b/.env.prod.example @@ -36,9 +36,6 @@ FLOWER_PORT=8888 FLOWER_USER=mouse FLOWER_PASSWORD=changeme -# make users confirm their email addresses after registration -CONFIRM_EMAIL=true - EMAIL_HOST="smtp.mailgun.org" EMAIL_PORT=587 EMAIL_HOST_USER=mail@your.domain.here diff --git a/bookwyrm/emailing.py b/bookwyrm/emailing.py index 516d64c93..cf46baf33 100644 --- a/bookwyrm/emailing.py +++ b/bookwyrm/emailing.py @@ -30,6 +30,7 @@ def email_confirmation_email(user): data["confirmation_link"] = user.confirmation_link send_email.delay(user.email, *format_email("confirm_email", data)) + def invite_email(invite_request): """send out an invite code""" data = email_data() diff --git a/bookwyrm/migrations/0082_auto_20210806_2141.py b/bookwyrm/migrations/0082_auto_20210806_2324.py similarity index 87% rename from bookwyrm/migrations/0082_auto_20210806_2141.py rename to bookwyrm/migrations/0082_auto_20210806_2324.py index 76c8c9628..ab0aa158b 100644 --- a/bookwyrm/migrations/0082_auto_20210806_2141.py +++ b/bookwyrm/migrations/0082_auto_20210806_2324.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.4 on 2021-08-06 21:41 +# Generated by Django 3.2.4 on 2021-08-06 23:24 import bookwyrm.models.base_model from django.db import migrations, models @@ -11,6 +11,11 @@ class Migration(migrations.Migration): ] operations = [ + migrations.AddField( + model_name="sitesettings", + name="require_confirm_email", + field=models.BooleanField(default=True), + ), migrations.AddField( model_name="user", name="confirmation_code", diff --git a/bookwyrm/models/site.py b/bookwyrm/models/site.py index fdc068664..ef3f7c3ca 100644 --- a/bookwyrm/models/site.py +++ b/bookwyrm/models/site.py @@ -31,6 +31,7 @@ class SiteSettings(models.Model): # registration allow_registration = models.BooleanField(default=True) allow_invite_requests = models.BooleanField(default=True) + require_confirm_email = models.BooleanField(default=True) # images logo = models.ImageField(upload_to="logos/", null=True, blank=True) diff --git a/bookwyrm/models/user.py b/bookwyrm/models/user.py index 94b7b41e1..e10bcd293 100644 --- a/bookwyrm/models/user.py +++ b/bookwyrm/models/user.py @@ -26,11 +26,13 @@ from .base_model import BookWyrmModel, DeactivationReason, new_access_code from .federated_server import FederatedServer from . import fields, Review + def site_link(): """helper for generating links to the site""" protocol = "https" if USE_HTTPS else "http" return f"{protocol}://{DOMAIN}" + class User(OrderedCollectionPageMixin, AbstractUser): """a user who wants to read books""" @@ -218,7 +220,7 @@ class User(OrderedCollectionPageMixin, AbstractUser): self.following.order_by("-updated_date").all(), remote_id=remote_id, id_only=True, - **kwargs + **kwargs, ) def to_followers_activity(self, **kwargs): @@ -228,7 +230,7 @@ class User(OrderedCollectionPageMixin, AbstractUser): self.followers.order_by("-updated_date").all(), remote_id=remote_id, id_only=True, - **kwargs + **kwargs, ) def to_activity(self, **kwargs): diff --git a/bookwyrm/settings.py b/bookwyrm/settings.py index 130889ac2..180191d98 100644 --- a/bookwyrm/settings.py +++ b/bookwyrm/settings.py @@ -24,9 +24,6 @@ CELERY_ACCEPT_CONTENT = ["application/json"] CELERY_TASK_SERIALIZER = "json" CELERY_RESULT_SERIALIZER = "json" -# make users confirm their email addresses after registration -CONFIRM_EMAIL = env("CONFIRM_EMAIL", True) - # email EMAIL_BACKEND = env("EMAIL_BACKEND", "django.core.mail.backends.smtp.EmailBackend") EMAIL_HOST = env("EMAIL_HOST") diff --git a/bookwyrm/templates/confirm_email.html b/bookwyrm/templates/confirm_email.html new file mode 100644 index 000000000..ac5b92825 --- /dev/null +++ b/bookwyrm/templates/confirm_email.html @@ -0,0 +1 @@ +{% extends "layout.html" %} diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py index d3e2dad1a..e7036feb9 100644 --- a/bookwyrm/urls.py +++ b/bookwyrm/urls.py @@ -46,7 +46,14 @@ urlpatterns = [ re_path("^api/updates/stream/(?P[a-z]+)/?$", views.get_unread_status_count), # authentication re_path(r"^login/?$", views.Login.as_view(), name="login"), + re_path(r"^login/(?Pconfirmed)?$", views.Login.as_view(), name="login"), re_path(r"^register/?$", views.Register.as_view()), + re_path(r"confirm-email/?$", views.ConfirmEmail.as_view(), name="confirm-email"), + re_path( + r"confirm-email/(?P[A-Za-z0-9]+)/?$", + views.ConfirmEmailCode.as_view(), + name="confirm-email-code", + ), re_path(r"^logout/?$", views.Logout.as_view(), name="logout"), re_path( r"^password-reset/?$", diff --git a/bookwyrm/views/__init__.py b/bookwyrm/views/__init__.py index 41bb64e54..112271a76 100644 --- a/bookwyrm/views/__init__.py +++ b/bookwyrm/views/__init__.py @@ -1,6 +1,7 @@ """ make sure all our nice views are available """ from .announcements import Announcements, Announcement, delete_announcement from .authentication import Login, Register, Logout +from .authentication import ConfirmEmail, ConfirmEmailCode from .author import Author, EditAuthor from .block import Block, unblock from .books import Book, EditBook, ConfirmEditBook, Editions diff --git a/bookwyrm/views/authentication.py b/bookwyrm/views/authentication.py index 43b4bb373..edf960cc1 100644 --- a/bookwyrm/views/authentication.py +++ b/bookwyrm/views/authentication.py @@ -10,20 +10,21 @@ from django.views.decorators.csrf import csrf_exempt from django.views import View from bookwyrm import emailing, forms, models -from bookwyrm.settings import DOMAIN, CONFIRM_EMAIL +from bookwyrm.settings import DOMAIN -# pylint: disable= no-self-use +# pylint: disable=no-self-use @method_decorator(csrf_exempt, name="dispatch") class Login(View): """authenticate an existing user""" - def get(self, request): + def get(self, request, confirmed=None): """login page""" if request.user.is_authenticated: return redirect("/") - # sene user to the login page + # send user to the login page data = { + "show_confirmed_email": confirmed, "login_form": forms.LoginForm(), "register_form": forms.RegisterForm(), } @@ -37,14 +38,15 @@ class Login(View): localname = login_form.data["localname"] if "@" in localname: # looks like an email address to me - email = localname try: - username = models.User.objects.get(email=email) + username = models.User.objects.get(email=localname).username except models.User.DoesNotExist: # maybe it's a full username? username = localname else: username = "%s@%s" % (localname, DOMAIN) password = login_form.data["password"] + + # perform authentication user = authenticate(request, username=username, password=password) if user is not None: # successful login @@ -53,6 +55,12 @@ class Login(View): user.save(broadcast=False, update_fields=["last_active_date"]) return redirect(request.GET.get("next", "/")) + # maybe the user is pending email confirmation + if models.User.objects.filter( + username=username, is_active=False, deactivation_reason="pending" + ).exists(): + return redirect("confirm-email") + # login errors login_form.non_field_errors = "Username or password are incorrect" register_form = forms.RegisterForm() @@ -60,12 +68,23 @@ class Login(View): return TemplateResponse(request, "login.html", data) +@method_decorator(login_required, name="dispatch") +class Logout(View): + """log out""" + + def get(self, request): + """done with this place! outa here!""" + logout(request) + return redirect("/") + + class Register(View): """register a user""" def post(self, request): """join the server""" - if not models.SiteSettings.get().allow_registration: + settings = models.SiteSettings.get() + if not settings.allow_registration: invite_code = request.POST.get("invite_code") if not invite_code: @@ -109,14 +128,15 @@ class Register(View): password, localname=localname, local=True, - is_active=not CONFIRM_EMAIL, + deactivation_reason="pending" if settings.require_confirm_email else None, + is_active=not settings.require_confirm_email, ) if invite: invite.times_used += 1 invite.invitees.add(user) invite.save() - if CONFIRM_EMAIL: + if settings.require_confirm_email: emailing.email_confirmation_email(user) return redirect("confirm-email") @@ -124,11 +144,32 @@ class Register(View): return redirect("get-started-profile") -@method_decorator(login_required, name="dispatch") -class Logout(View): - """log out""" +class ConfirmEmail(View): + """enter code to confirm email address""" - def get(self, request): - """done with this place! outa here!""" - logout(request) - return redirect("/") + def get(self, request): # pylint: disable=unused-argument + """you need a code! keep looking""" + settings = models.SiteSettings.get() + if request.user.is_authenticated or not settings.require_confirm_email: + return redirect("/") + + return TemplateResponse(request, "confirm_email.html") + + +class ConfirmEmailCode(View): + """confirm email address""" + + def get(self, request, code): # pylint: disable=unused-argument + """you got the code! good work""" + settings = models.SiteSettings.get() + if request.user.is_authenticated or not settings.require_confirm_email: + return redirect("/") + + # look up the user associated with this code + user = get_object_or_404(models.User, confirmation_code=code) + # update the user + user.is_active = True + user.deactivation_reason = None + user.save(broadcast=False, update_fields=["is_active", "deactivation_reason"]) + # direct the user to log in + return redirect("login", confirmed="confirmed") From 1ad057d89d5e99fc4eff546cb1abe93289f53b9a Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 6 Aug 2021 17:23:44 -0700 Subject: [PATCH 20/75] Confirmation templates --- bookwyrm/emailing.py | 2 +- bookwyrm/templates/confirm_email.html | 1 - .../confirm_email/confirm_email.html | 44 +++++++++++++++++++ .../templates/confirm_email/resend_form.html | 19 ++++++++ bookwyrm/templates/settings/site.html | 7 +++ bookwyrm/views/authentication.py | 34 ++++++++------ 6 files changed, 92 insertions(+), 15 deletions(-) delete mode 100644 bookwyrm/templates/confirm_email.html create mode 100644 bookwyrm/templates/confirm_email/confirm_email.html create mode 100644 bookwyrm/templates/confirm_email/resend_form.html diff --git a/bookwyrm/emailing.py b/bookwyrm/emailing.py index cf46baf33..fff3985ef 100644 --- a/bookwyrm/emailing.py +++ b/bookwyrm/emailing.py @@ -28,7 +28,7 @@ def email_confirmation_email(user): data = email_data() data["confirmation_code"] = user.confirmation_code data["confirmation_link"] = user.confirmation_link - send_email.delay(user.email, *format_email("confirm_email", data)) + send_email.delay(user.email, *format_email("confirm", data)) def invite_email(invite_request): diff --git a/bookwyrm/templates/confirm_email.html b/bookwyrm/templates/confirm_email.html deleted file mode 100644 index ac5b92825..000000000 --- a/bookwyrm/templates/confirm_email.html +++ /dev/null @@ -1 +0,0 @@ -{% extends "layout.html" %} diff --git a/bookwyrm/templates/confirm_email/confirm_email.html b/bookwyrm/templates/confirm_email/confirm_email.html new file mode 100644 index 000000000..85ca2bb1b --- /dev/null +++ b/bookwyrm/templates/confirm_email/confirm_email.html @@ -0,0 +1,44 @@ +{% extends "layout.html" %} +{% load i18n %} + +{% block title %}{% trans "Confirm email" %}{% endblock %} + +{% block content %} +

{% trans "Confirm your email address" %}

+ +
+
+
+
+

{% trans "A confirmation code has been sent to the email address you used to register your account." %}

+ {% if not valid %} +

{% trans "Sorry! We couldn't find that code." %}

+ {% endif %} +
+ {% csrf_token %} + +
+
+ +
+
+ +
+
+
+
+ +
+ {% trans "Can't find your code?" as button_text %} + {% include "snippets/toggle/open_button.html" with text=button_text controls_text="resend-form" focus="resend-form-header" %} + {% include "confirm_email/resend_form.html" with controls_text="resend-form" %} +
+
+
+
+
+ {% include 'snippets/about.html' %} +
+
+
+{% endblock %} diff --git a/bookwyrm/templates/confirm_email/resend_form.html b/bookwyrm/templates/confirm_email/resend_form.html new file mode 100644 index 000000000..00a89403f --- /dev/null +++ b/bookwyrm/templates/confirm_email/resend_form.html @@ -0,0 +1,19 @@ +{% extends "components/inline_form.html" %} +{% load i18n %} +{% block header %} +{% trans "Resend confirmation link" %} +{% endblock %} + +{% block form %} +
+
+ +
+ +
+
+
+ +
+
+{% endblock %} diff --git a/bookwyrm/templates/settings/site.html b/bookwyrm/templates/settings/site.html index d36371a41..f64b529ad 100644 --- a/bookwyrm/templates/settings/site.html +++ b/bookwyrm/templates/settings/site.html @@ -91,6 +91,13 @@ {% trans "Allow invite requests" %} +
+ +

{% trans "(Recommended if registration is open)" %}

+
{{ site_form.registration_closed_text }} diff --git a/bookwyrm/views/authentication.py b/bookwyrm/views/authentication.py index edf960cc1..dedcf408a 100644 --- a/bookwyrm/views/authentication.py +++ b/bookwyrm/views/authentication.py @@ -144,18 +144,6 @@ class Register(View): return redirect("get-started-profile") -class ConfirmEmail(View): - """enter code to confirm email address""" - - def get(self, request): # pylint: disable=unused-argument - """you need a code! keep looking""" - settings = models.SiteSettings.get() - if request.user.is_authenticated or not settings.require_confirm_email: - return redirect("/") - - return TemplateResponse(request, "confirm_email.html") - - class ConfirmEmailCode(View): """confirm email address""" @@ -166,10 +154,30 @@ class ConfirmEmailCode(View): return redirect("/") # look up the user associated with this code - user = get_object_or_404(models.User, confirmation_code=code) + try: + user = models.User.objects.get(confirmation_code=code) + except models.User.DoesNotExist: + return TemplateResponse(request, "confirm_email/confirm_email.html", {"valid": False}) # update the user user.is_active = True user.deactivation_reason = None user.save(broadcast=False, update_fields=["is_active", "deactivation_reason"]) # direct the user to log in return redirect("login", confirmed="confirmed") + + +class ConfirmEmail(View): + """enter code to confirm email address""" + + def get(self, request): # pylint: disable=unused-argument + """you need a code! keep looking""" + settings = models.SiteSettings.get() + if request.user.is_authenticated or not settings.require_confirm_email: + return redirect("/") + + return TemplateResponse(request, "confirm_email/confirm_email.html", {"valid": True}) + + def post(self, request): + """same as clicking the link""" + code = request.POST.get("code") + return ConfirmEmailCode().get(request, code) From 9077516fa14c9d64c06d1a81e0c2185d63d74229 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 6 Aug 2021 17:39:22 -0700 Subject: [PATCH 21/75] Resend links --- .../confirm_email/confirm_email.html | 2 +- .../templates/confirm_email/resend_form.html | 5 +++-- bookwyrm/templates/login.html | 5 +++++ bookwyrm/urls.py | 1 + bookwyrm/views/__init__.py | 2 +- bookwyrm/views/authentication.py | 22 +++++++++++++++++-- 6 files changed, 31 insertions(+), 6 deletions(-) diff --git a/bookwyrm/templates/confirm_email/confirm_email.html b/bookwyrm/templates/confirm_email/confirm_email.html index 85ca2bb1b..6c9eda5ee 100644 --- a/bookwyrm/templates/confirm_email/confirm_email.html +++ b/bookwyrm/templates/confirm_email/confirm_email.html @@ -19,7 +19,7 @@
- +
diff --git a/bookwyrm/templates/confirm_email/resend_form.html b/bookwyrm/templates/confirm_email/resend_form.html index 00a89403f..7c0c10980 100644 --- a/bookwyrm/templates/confirm_email/resend_form.html +++ b/bookwyrm/templates/confirm_email/resend_form.html @@ -5,11 +5,12 @@ {% endblock %} {% block form %} -
+ + {% csrf_token %}
- +
diff --git a/bookwyrm/templates/login.html b/bookwyrm/templates/login.html index e3d0133cf..19c103eac 100644 --- a/bookwyrm/templates/login.html +++ b/bookwyrm/templates/login.html @@ -11,8 +11,13 @@ {% if login_form.non_field_errors %}

{{ login_form.non_field_errors }}

{% endif %} + + {% if show_confirmed_email %} +

{% trans "Success! Email address confirmed." %}

+ {% endif %} {% csrf_token %} + {% if show_confirmed_email %}{% endif %}
diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py index e7036feb9..eb8491a94 100644 --- a/bookwyrm/urls.py +++ b/bookwyrm/urls.py @@ -54,6 +54,7 @@ urlpatterns = [ views.ConfirmEmailCode.as_view(), name="confirm-email-code", ), + re_path(r"resend-link", views.resend_link, name="resend-link"), re_path(r"^logout/?$", views.Logout.as_view(), name="logout"), re_path( r"^password-reset/?$", diff --git a/bookwyrm/views/__init__.py b/bookwyrm/views/__init__.py index 112271a76..eccb7f5e5 100644 --- a/bookwyrm/views/__init__.py +++ b/bookwyrm/views/__init__.py @@ -1,7 +1,7 @@ """ make sure all our nice views are available """ from .announcements import Announcements, Announcement, delete_announcement from .authentication import Login, Register, Logout -from .authentication import ConfirmEmail, ConfirmEmailCode +from .authentication import ConfirmEmail, ConfirmEmailCode, resend_link from .author import Author, EditAuthor from .block import Block, unblock from .books import Book, EditBook, ConfirmEditBook, Editions diff --git a/bookwyrm/views/authentication.py b/bookwyrm/views/authentication.py index dedcf408a..f81be8d15 100644 --- a/bookwyrm/views/authentication.py +++ b/bookwyrm/views/authentication.py @@ -7,6 +7,7 @@ from django.template.response import TemplateResponse from django.utils import timezone from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_exempt +from django.views.decorators.http import require_POST from django.views import View from bookwyrm import emailing, forms, models @@ -53,6 +54,8 @@ class Login(View): login(request, user) user.last_active_date = timezone.now() user.save(broadcast=False, update_fields=["last_active_date"]) + if request.POST.get("first_login"): + return redirect("get-started-profile") return redirect(request.GET.get("next", "/")) # maybe the user is pending email confirmation @@ -157,7 +160,9 @@ class ConfirmEmailCode(View): try: user = models.User.objects.get(confirmation_code=code) except models.User.DoesNotExist: - return TemplateResponse(request, "confirm_email/confirm_email.html", {"valid": False}) + return TemplateResponse( + request, "confirm_email/confirm_email.html", {"valid": False} + ) # update the user user.is_active = True user.deactivation_reason = None @@ -175,9 +180,22 @@ class ConfirmEmail(View): if request.user.is_authenticated or not settings.require_confirm_email: return redirect("/") - return TemplateResponse(request, "confirm_email/confirm_email.html", {"valid": True}) + return TemplateResponse( + request, "confirm_email/confirm_email.html", {"valid": True} + ) def post(self, request): """same as clicking the link""" code = request.POST.get("code") return ConfirmEmailCode().get(request, code) + + +@require_POST +def resend_link(request): + """resend confirmation link""" + email = request.POST.get("email") + user = get_object_or_404(models.User, email=email) + emailing.email_confirmation_email(user) + return TemplateResponse( + request, "confirm_email/confirm_email.html", {"valid": True} + ) From cec69430692ee29075fab8d45ced4ae9e497abc4 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 6 Aug 2021 17:43:50 -0700 Subject: [PATCH 22/75] Adds missing mock --- bookwyrm/tests/views/test_book.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bookwyrm/tests/views/test_book.py b/bookwyrm/tests/views/test_book.py index 6280f54ff..c5d86a12d 100644 --- a/bookwyrm/tests/views/test_book.py +++ b/bookwyrm/tests/views/test_book.py @@ -74,7 +74,8 @@ class BookViews(TestCase): self.assertEqual(result.status_code, 200) @patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") - def test_book_page_statuses(self, _): + @patch("bookwyrm.activitystreams.ActivityStream.add_status") + def test_book_page_statuses(self, *_): """there are so many views, this just makes sure it LOADS""" view = views.Book.as_view() From 98a98f8e691f533edaef220877e145207a7661b2 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 6 Aug 2021 18:13:51 -0700 Subject: [PATCH 23/75] Updates test env --- .github/workflows/django-tests.yml | 1 + bookwyrm/tests/views/test_authentication.py | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/django-tests.yml b/.github/workflows/django-tests.yml index 03147744a..038751935 100644 --- a/.github/workflows/django-tests.yml +++ b/.github/workflows/django-tests.yml @@ -36,6 +36,7 @@ jobs: env: SECRET_KEY: beepbeep DEBUG: false + USE_HTTPS: true DOMAIN: your.domain.here BOOKWYRM_DATABASE_BACKEND: postgres MEDIA_ROOT: images/ diff --git a/bookwyrm/tests/views/test_authentication.py b/bookwyrm/tests/views/test_authentication.py index e2d67fbe1..bbafe7bd5 100644 --- a/bookwyrm/tests/views/test_authentication.py +++ b/bookwyrm/tests/views/test_authentication.py @@ -31,7 +31,9 @@ class AuthenticationViews(TestCase): self.anonymous_user = AnonymousUser self.anonymous_user.is_authenticated = False - self.settings = models.SiteSettings.objects.create(id=1) + self.settings = models.SiteSettings.objects.create( + id=1, require_email_confirmation=False + ) def test_login_get(self, _): """there are so many views, this just makes sure it LOADS""" From a3d5a0347770e6eb6621aed5a362a5d6abd0fe28 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 6 Aug 2021 18:47:25 -0700 Subject: [PATCH 24/75] Updates locales --- locale/de_DE/LC_MESSAGES/django.po | 121 +++++++++++++++++++------- locale/en_US/LC_MESSAGES/django.po | 108 +++++++++++++++++------ locale/es/LC_MESSAGES/django.po | 121 ++++++++++++++++++++------ locale/fr_FR/LC_MESSAGES/django.po | 123 ++++++++++++++++++++------- locale/zh_Hans/LC_MESSAGES/django.po | 118 +++++++++++++++++++------ locale/zh_Hant/LC_MESSAGES/django.po | 118 +++++++++++++++++++------ 6 files changed, 552 insertions(+), 157 deletions(-) diff --git a/locale/de_DE/LC_MESSAGES/django.po b/locale/de_DE/LC_MESSAGES/django.po index 140f91dcc..4906082a5 100644 --- a/locale/de_DE/LC_MESSAGES/django.po +++ b/locale/de_DE/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-08-06 18:34+0000\n" +"POT-Creation-Date: 2021-08-07 01:35+0000\n" "PO-Revision-Date: 2021-03-02 17:19-0800\n" "Last-Translator: Mouse Reeve \n" "Language-Team: English \n" @@ -306,7 +306,7 @@ msgstr "" #: bookwyrm/templates/settings/announcement_form.html:69 #: bookwyrm/templates/settings/edit_server.html:68 #: bookwyrm/templates/settings/federated_server.html:98 -#: bookwyrm/templates/settings/site.html:101 +#: bookwyrm/templates/settings/site.html:108 #: bookwyrm/templates/snippets/shelve_button/finish_reading_modal.html:42 #: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:42 #: bookwyrm/templates/snippets/shelve_button/start_reading_modal.html:36 @@ -739,6 +739,58 @@ msgstr "Schließen" msgid "Compose status" msgstr "Status teilen" +#: bookwyrm/templates/confirm_email/confirm_email.html:4 +#, fuzzy +#| msgid "Confirm" +msgid "Confirm email" +msgstr "Bestätigen" + +#: bookwyrm/templates/confirm_email/confirm_email.html:7 +#, fuzzy +#| msgid "Email address:" +msgid "Confirm your email address" +msgstr "E-Mail Adresse" + +#: bookwyrm/templates/confirm_email/confirm_email.html:13 +msgid "A confirmation code has been sent to the email address you used to register your account." +msgstr "" + +#: bookwyrm/templates/confirm_email/confirm_email.html:15 +msgid "Sorry! We couldn't find that code." +msgstr "" + +#: bookwyrm/templates/confirm_email/confirm_email.html:19 +#, fuzzy +#| msgid "Confirm password:" +msgid "Confirmation code:" +msgstr "Passwort bestätigen:" + +#: bookwyrm/templates/confirm_email/confirm_email.html:25 +#: bookwyrm/templates/discover/landing_layout.html:70 +#: bookwyrm/templates/moderation/report_modal.html:33 +msgid "Submit" +msgstr "Absenden" + +#: bookwyrm/templates/confirm_email/confirm_email.html:32 +msgid "Can't find your code?" +msgstr "" + +#: bookwyrm/templates/confirm_email/resend_form.html:4 +msgid "Resend confirmation link" +msgstr "" + +#: bookwyrm/templates/confirm_email/resend_form.html:11 +#: bookwyrm/templates/discover/landing_layout.html:64 +#: bookwyrm/templates/password_reset_request.html:18 +#: bookwyrm/templates/preferences/edit_user.html:38 +#: bookwyrm/templates/snippets/register_form.html:13 +msgid "Email address:" +msgstr "E-Mail Adresse" + +#: bookwyrm/templates/confirm_email/resend_form.html:17 +msgid "Resend link" +msgstr "" + #: bookwyrm/templates/directory/community_filter.html:5 #, fuzzy #| msgid "Comment" @@ -882,7 +934,7 @@ msgid "Join %(name)s" msgstr "Tritt %(name)s bei" #: bookwyrm/templates/discover/landing_layout.html:51 -#: bookwyrm/templates/login.html:51 +#: bookwyrm/templates/login.html:56 msgid "This instance is closed" msgstr "Diese Instanz ist geschlossen" @@ -894,22 +946,26 @@ msgstr "" msgid "Request an Invitation" msgstr "" -#: bookwyrm/templates/discover/landing_layout.html:64 -#: bookwyrm/templates/password_reset_request.html:18 -#: bookwyrm/templates/preferences/edit_user.html:38 -#: bookwyrm/templates/snippets/register_form.html:13 -msgid "Email address:" -msgstr "E-Mail Adresse" - -#: bookwyrm/templates/discover/landing_layout.html:70 -#: bookwyrm/templates/moderation/report_modal.html:33 -msgid "Submit" -msgstr "Absenden" - #: bookwyrm/templates/discover/landing_layout.html:79 msgid "Your Account" msgstr "Dein Account" +#: bookwyrm/templates/email/confirm/html_content.html:6 +#: bookwyrm/templates/email/confirm/text_content.html:4 +#, python-format +msgid "One last step before you join %(site_name)s! Please confirm your email address by clicking the link below:" +msgstr "" + +#: bookwyrm/templates/email/confirm/html_content.html:11 +#, fuzzy +#| msgid "Confirm" +msgid "Confirm Email" +msgstr "Bestätigen" + +#: bookwyrm/templates/email/confirm/subject.html:2 +msgid "Please confirm your email" +msgstr "" + #: bookwyrm/templates/email/html_layout.html:15 #: bookwyrm/templates/email/text_layout.html:2 msgid "Hi there," @@ -1342,7 +1398,7 @@ msgid "Imported" msgstr "Importiert" #: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:12 -#: bookwyrm/templates/login.html:46 +#: bookwyrm/templates/login.html:51 msgid "Create an Account" msgstr "Erstelle einen Account" @@ -1412,7 +1468,7 @@ msgid "Notifications" msgstr "Benachrichtigungen" #: bookwyrm/templates/layout.html:158 bookwyrm/templates/layout.html:162 -#: bookwyrm/templates/login.html:17 +#: bookwyrm/templates/login.html:22 #: bookwyrm/templates/snippets/register_form.html:4 msgid "Username:" msgstr "" @@ -1421,12 +1477,12 @@ msgstr "" msgid "password" msgstr "Passwort" -#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:36 +#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:41 msgid "Forgot your password?" msgstr "Passwort vergessen?" #: bookwyrm/templates/layout.html:167 bookwyrm/templates/login.html:10 -#: bookwyrm/templates/login.html:33 +#: bookwyrm/templates/login.html:38 msgid "Log in" msgstr "Anmelden" @@ -1619,16 +1675,20 @@ msgstr "Deine Listen" msgid "Login" msgstr "" -#: bookwyrm/templates/login.html:23 bookwyrm/templates/password_reset.html:17 +#: bookwyrm/templates/login.html:16 +msgid "Success! Email address confirmed." +msgstr "" + +#: bookwyrm/templates/login.html:28 bookwyrm/templates/password_reset.html:17 #: bookwyrm/templates/snippets/register_form.html:22 msgid "Password:" msgstr "Passwort:" -#: bookwyrm/templates/login.html:52 +#: bookwyrm/templates/login.html:57 msgid "Contact an administrator to get an invite" msgstr "Kontaktiere für eine Einladung eine*n Admin" -#: bookwyrm/templates/login.html:63 +#: bookwyrm/templates/login.html:68 msgid "More about this site" msgstr "Mehr über diese Seite" @@ -2554,7 +2614,15 @@ msgstr "Registrierungen erlauben" msgid "Allow invite requests" msgstr "Folgeanfragen" -#: bookwyrm/templates/settings/site.html:95 +#: bookwyrm/templates/settings/site.html:97 +msgid "Require users to confirm email address" +msgstr "" + +#: bookwyrm/templates/settings/site.html:99 +msgid "(Recommended if registration is open)" +msgstr "" + +#: bookwyrm/templates/settings/site.html:102 msgid "Registration closed text:" msgstr "Registrierungen geschlossen text" @@ -3295,7 +3363,7 @@ msgstr "" msgid "%(title)s: %(subtitle)s" msgstr "" -#: bookwyrm/views/authentication.py:58 +#: bookwyrm/views/authentication.py:69 msgid "Username or password are incorrect" msgstr "" @@ -3375,11 +3443,6 @@ msgstr "" #~ msgid "Enter a valid integer." #~ msgstr "E-Mail Adresse" -#, fuzzy -#~| msgid "Email address:" -#~ msgid "Enter a valid email address." -#~ msgstr "E-Mail Adresse" - #, fuzzy #~| msgid "Email address:" #~ msgid "Enter a valid IPv4 address." diff --git a/locale/en_US/LC_MESSAGES/django.po b/locale/en_US/LC_MESSAGES/django.po index ab56046ee..e8e3b0b31 100644 --- a/locale/en_US/LC_MESSAGES/django.po +++ b/locale/en_US/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-08-06 18:34+0000\n" +"POT-Creation-Date: 2021-08-07 01:35+0000\n" "PO-Revision-Date: 2021-02-28 17:19-0800\n" "Last-Translator: Mouse Reeve \n" "Language-Team: English \n" @@ -282,7 +282,7 @@ msgstr "" #: bookwyrm/templates/settings/announcement_form.html:69 #: bookwyrm/templates/settings/edit_server.html:68 #: bookwyrm/templates/settings/federated_server.html:98 -#: bookwyrm/templates/settings/site.html:101 +#: bookwyrm/templates/settings/site.html:108 #: bookwyrm/templates/snippets/shelve_button/finish_reading_modal.html:42 #: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:42 #: bookwyrm/templates/snippets/shelve_button/start_reading_modal.html:36 @@ -680,6 +680,52 @@ msgstr "" msgid "Compose status" msgstr "" +#: bookwyrm/templates/confirm_email/confirm_email.html:4 +msgid "Confirm email" +msgstr "" + +#: bookwyrm/templates/confirm_email/confirm_email.html:7 +msgid "Confirm your email address" +msgstr "" + +#: bookwyrm/templates/confirm_email/confirm_email.html:13 +msgid "A confirmation code has been sent to the email address you used to register your account." +msgstr "" + +#: bookwyrm/templates/confirm_email/confirm_email.html:15 +msgid "Sorry! We couldn't find that code." +msgstr "" + +#: bookwyrm/templates/confirm_email/confirm_email.html:19 +msgid "Confirmation code:" +msgstr "" + +#: bookwyrm/templates/confirm_email/confirm_email.html:25 +#: bookwyrm/templates/discover/landing_layout.html:70 +#: bookwyrm/templates/moderation/report_modal.html:33 +msgid "Submit" +msgstr "" + +#: bookwyrm/templates/confirm_email/confirm_email.html:32 +msgid "Can't find your code?" +msgstr "" + +#: bookwyrm/templates/confirm_email/resend_form.html:4 +msgid "Resend confirmation link" +msgstr "" + +#: bookwyrm/templates/confirm_email/resend_form.html:11 +#: bookwyrm/templates/discover/landing_layout.html:64 +#: bookwyrm/templates/password_reset_request.html:18 +#: bookwyrm/templates/preferences/edit_user.html:38 +#: bookwyrm/templates/snippets/register_form.html:13 +msgid "Email address:" +msgstr "" + +#: bookwyrm/templates/confirm_email/resend_form.html:17 +msgid "Resend link" +msgstr "" + #: bookwyrm/templates/directory/community_filter.html:5 msgid "Community" msgstr "" @@ -806,7 +852,7 @@ msgid "Join %(name)s" msgstr "" #: bookwyrm/templates/discover/landing_layout.html:51 -#: bookwyrm/templates/login.html:51 +#: bookwyrm/templates/login.html:56 msgid "This instance is closed" msgstr "" @@ -818,22 +864,24 @@ msgstr "" msgid "Request an Invitation" msgstr "" -#: bookwyrm/templates/discover/landing_layout.html:64 -#: bookwyrm/templates/password_reset_request.html:18 -#: bookwyrm/templates/preferences/edit_user.html:38 -#: bookwyrm/templates/snippets/register_form.html:13 -msgid "Email address:" -msgstr "" - -#: bookwyrm/templates/discover/landing_layout.html:70 -#: bookwyrm/templates/moderation/report_modal.html:33 -msgid "Submit" -msgstr "" - #: bookwyrm/templates/discover/landing_layout.html:79 msgid "Your Account" msgstr "" +#: bookwyrm/templates/email/confirm/html_content.html:6 +#: bookwyrm/templates/email/confirm/text_content.html:4 +#, python-format +msgid "One last step before you join %(site_name)s! Please confirm your email address by clicking the link below:" +msgstr "" + +#: bookwyrm/templates/email/confirm/html_content.html:11 +msgid "Confirm Email" +msgstr "" + +#: bookwyrm/templates/email/confirm/subject.html:2 +msgid "Please confirm your email" +msgstr "" + #: bookwyrm/templates/email/html_layout.html:15 #: bookwyrm/templates/email/text_layout.html:2 msgid "Hi there," @@ -1235,7 +1283,7 @@ msgid "Imported" msgstr "" #: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:12 -#: bookwyrm/templates/login.html:46 +#: bookwyrm/templates/login.html:51 msgid "Create an Account" msgstr "" @@ -1303,7 +1351,7 @@ msgid "Notifications" msgstr "" #: bookwyrm/templates/layout.html:158 bookwyrm/templates/layout.html:162 -#: bookwyrm/templates/login.html:17 +#: bookwyrm/templates/login.html:22 #: bookwyrm/templates/snippets/register_form.html:4 msgid "Username:" msgstr "" @@ -1312,12 +1360,12 @@ msgstr "" msgid "password" msgstr "" -#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:36 +#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:41 msgid "Forgot your password?" msgstr "" #: bookwyrm/templates/layout.html:167 bookwyrm/templates/login.html:10 -#: bookwyrm/templates/login.html:33 +#: bookwyrm/templates/login.html:38 msgid "Log in" msgstr "" @@ -1493,16 +1541,20 @@ msgstr "" msgid "Login" msgstr "" -#: bookwyrm/templates/login.html:23 bookwyrm/templates/password_reset.html:17 +#: bookwyrm/templates/login.html:16 +msgid "Success! Email address confirmed." +msgstr "" + +#: bookwyrm/templates/login.html:28 bookwyrm/templates/password_reset.html:17 #: bookwyrm/templates/snippets/register_form.html:22 msgid "Password:" msgstr "" -#: bookwyrm/templates/login.html:52 +#: bookwyrm/templates/login.html:57 msgid "Contact an administrator to get an invite" msgstr "" -#: bookwyrm/templates/login.html:63 +#: bookwyrm/templates/login.html:68 msgid "More about this site" msgstr "" @@ -2315,7 +2367,15 @@ msgstr "" msgid "Allow invite requests" msgstr "" -#: bookwyrm/templates/settings/site.html:95 +#: bookwyrm/templates/settings/site.html:97 +msgid "Require users to confirm email address" +msgstr "" + +#: bookwyrm/templates/settings/site.html:99 +msgid "(Recommended if registration is open)" +msgstr "" + +#: bookwyrm/templates/settings/site.html:102 msgid "Registration closed text:" msgstr "" @@ -2991,7 +3051,7 @@ msgstr "" msgid "%(title)s: %(subtitle)s" msgstr "" -#: bookwyrm/views/authentication.py:58 +#: bookwyrm/views/authentication.py:69 msgid "Username or password are incorrect" msgstr "" diff --git a/locale/es/LC_MESSAGES/django.po b/locale/es/LC_MESSAGES/django.po index dbf7540c7..9fc28535e 100644 --- a/locale/es/LC_MESSAGES/django.po +++ b/locale/es/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-08-06 18:34+0000\n" +"POT-Creation-Date: 2021-08-07 01:35+0000\n" "PO-Revision-Date: 2021-03-19 11:49+0800\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -288,7 +288,7 @@ msgstr "Clave Goodreads:" #: bookwyrm/templates/settings/announcement_form.html:69 #: bookwyrm/templates/settings/edit_server.html:68 #: bookwyrm/templates/settings/federated_server.html:98 -#: bookwyrm/templates/settings/site.html:101 +#: bookwyrm/templates/settings/site.html:108 #: bookwyrm/templates/snippets/shelve_button/finish_reading_modal.html:42 #: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:42 #: bookwyrm/templates/snippets/shelve_button/start_reading_modal.html:36 @@ -688,6 +688,60 @@ msgstr "Cerrar" msgid "Compose status" msgstr "Componer status" +#: bookwyrm/templates/confirm_email/confirm_email.html:4 +#, fuzzy +#| msgid "Confirm" +msgid "Confirm email" +msgstr "Confirmar" + +#: bookwyrm/templates/confirm_email/confirm_email.html:7 +#, fuzzy +#| msgid "Enter a valid email address." +msgid "Confirm your email address" +msgstr "Ingrese una dirección de correo electrónico válida." + +#: bookwyrm/templates/confirm_email/confirm_email.html:13 +msgid "A confirmation code has been sent to the email address you used to register your account." +msgstr "" + +#: bookwyrm/templates/confirm_email/confirm_email.html:15 +msgid "Sorry! We couldn't find that code." +msgstr "" + +#: bookwyrm/templates/confirm_email/confirm_email.html:19 +#, fuzzy +#| msgid "Confirm password:" +msgid "Confirmation code:" +msgstr "Confirmar contraseña:" + +#: bookwyrm/templates/confirm_email/confirm_email.html:25 +#: bookwyrm/templates/discover/landing_layout.html:70 +#: bookwyrm/templates/moderation/report_modal.html:33 +msgid "Submit" +msgstr "Enviar" + +#: bookwyrm/templates/confirm_email/confirm_email.html:32 +msgid "Can't find your code?" +msgstr "" + +#: bookwyrm/templates/confirm_email/resend_form.html:4 +msgid "Resend confirmation link" +msgstr "" + +#: bookwyrm/templates/confirm_email/resend_form.html:11 +#: bookwyrm/templates/discover/landing_layout.html:64 +#: bookwyrm/templates/password_reset_request.html:18 +#: bookwyrm/templates/preferences/edit_user.html:38 +#: bookwyrm/templates/snippets/register_form.html:13 +msgid "Email address:" +msgstr "Dirección de correo electrónico:" + +#: bookwyrm/templates/confirm_email/resend_form.html:17 +#, fuzzy +#| msgid "Re-send invite" +msgid "Resend link" +msgstr "Re-enviar invitación" + #: bookwyrm/templates/directory/community_filter.html:5 msgid "Community" msgstr "Comunidad" @@ -816,7 +870,7 @@ msgid "Join %(name)s" msgstr "Unirse con %(name)s" #: bookwyrm/templates/discover/landing_layout.html:51 -#: bookwyrm/templates/login.html:51 +#: bookwyrm/templates/login.html:56 msgid "This instance is closed" msgstr "Esta instancia está cerrada." @@ -828,22 +882,26 @@ msgstr "¡Gracias! Tu solicitud ha sido recibido." msgid "Request an Invitation" msgstr "Solicitar una invitación" -#: bookwyrm/templates/discover/landing_layout.html:64 -#: bookwyrm/templates/password_reset_request.html:18 -#: bookwyrm/templates/preferences/edit_user.html:38 -#: bookwyrm/templates/snippets/register_form.html:13 -msgid "Email address:" -msgstr "Dirección de correo electrónico:" - -#: bookwyrm/templates/discover/landing_layout.html:70 -#: bookwyrm/templates/moderation/report_modal.html:33 -msgid "Submit" -msgstr "Enviar" - #: bookwyrm/templates/discover/landing_layout.html:79 msgid "Your Account" msgstr "Tu cuenta" +#: bookwyrm/templates/email/confirm/html_content.html:6 +#: bookwyrm/templates/email/confirm/text_content.html:4 +#, python-format +msgid "One last step before you join %(site_name)s! Please confirm your email address by clicking the link below:" +msgstr "" + +#: bookwyrm/templates/email/confirm/html_content.html:11 +#, fuzzy +#| msgid "Confirm" +msgid "Confirm Email" +msgstr "Confirmar" + +#: bookwyrm/templates/email/confirm/subject.html:2 +msgid "Please confirm your email" +msgstr "" + #: bookwyrm/templates/email/html_layout.html:15 #: bookwyrm/templates/email/text_layout.html:2 msgid "Hi there," @@ -1250,7 +1308,7 @@ msgid "Imported" msgstr "Importado" #: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:12 -#: bookwyrm/templates/login.html:46 +#: bookwyrm/templates/login.html:51 msgid "Create an Account" msgstr "Crear una cuenta" @@ -1318,7 +1376,7 @@ msgid "Notifications" msgstr "Notificaciones" #: bookwyrm/templates/layout.html:158 bookwyrm/templates/layout.html:162 -#: bookwyrm/templates/login.html:17 +#: bookwyrm/templates/login.html:22 #: bookwyrm/templates/snippets/register_form.html:4 msgid "Username:" msgstr "Nombre de usuario:" @@ -1327,12 +1385,12 @@ msgstr "Nombre de usuario:" msgid "password" msgstr "contraseña" -#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:36 +#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:41 msgid "Forgot your password?" msgstr "¿Olvidaste tu contraseña?" #: bookwyrm/templates/layout.html:167 bookwyrm/templates/login.html:10 -#: bookwyrm/templates/login.html:33 +#: bookwyrm/templates/login.html:38 msgid "Log in" msgstr "Iniciar sesión" @@ -1510,16 +1568,20 @@ msgstr "Tus listas" msgid "Login" msgstr "Iniciar sesión" -#: bookwyrm/templates/login.html:23 bookwyrm/templates/password_reset.html:17 +#: bookwyrm/templates/login.html:16 +msgid "Success! Email address confirmed." +msgstr "" + +#: bookwyrm/templates/login.html:28 bookwyrm/templates/password_reset.html:17 #: bookwyrm/templates/snippets/register_form.html:22 msgid "Password:" msgstr "Contraseña:" -#: bookwyrm/templates/login.html:52 +#: bookwyrm/templates/login.html:57 msgid "Contact an administrator to get an invite" msgstr "Contactar a unx administradorx para recibir una invitación" -#: bookwyrm/templates/login.html:63 +#: bookwyrm/templates/login.html:68 msgid "More about this site" msgstr "Más sobre este sitio" @@ -2351,7 +2413,15 @@ msgstr "Permitir registración:" msgid "Allow invite requests" msgstr "Permitir solicitudes de invitación:" -#: bookwyrm/templates/settings/site.html:95 +#: bookwyrm/templates/settings/site.html:97 +msgid "Require users to confirm email address" +msgstr "" + +#: bookwyrm/templates/settings/site.html:99 +msgid "(Recommended if registration is open)" +msgstr "" + +#: bookwyrm/templates/settings/site.html:102 msgid "Registration closed text:" msgstr "Texto de registración cerrada:" @@ -3036,7 +3106,7 @@ msgstr "" msgid "%(title)s: %(subtitle)s" msgstr "" -#: bookwyrm/views/authentication.py:58 +#: bookwyrm/views/authentication.py:69 msgid "Username or password are incorrect" msgstr "" @@ -3117,9 +3187,6 @@ msgstr "Un enlace para reestablecer tu contraseña se enviará a %s" #~ msgid "Enter a valid integer." #~ msgstr "Ingrese un entero válido." -#~ msgid "Enter a valid email address." -#~ msgstr "Ingrese una dirección de correo electrónico válida." - #~ msgid "Enter a valid “slug” consisting of letters, numbers, underscores or hyphens." #~ msgstr "Ingrese un “slug” válido que consiste de letras, numeros, guiones bajos, o guiones" diff --git a/locale/fr_FR/LC_MESSAGES/django.po b/locale/fr_FR/LC_MESSAGES/django.po index b4405df5a..f0a559f97 100644 --- a/locale/fr_FR/LC_MESSAGES/django.po +++ b/locale/fr_FR/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-08-06 18:34+0000\n" +"POT-Creation-Date: 2021-08-07 01:35+0000\n" "PO-Revision-Date: 2021-04-05 12:44+0100\n" "Last-Translator: Fabien Basmaison \n" "Language-Team: Mouse Reeve \n" @@ -286,7 +286,7 @@ msgstr "Clé Goodreads :" #: bookwyrm/templates/settings/announcement_form.html:69 #: bookwyrm/templates/settings/edit_server.html:68 #: bookwyrm/templates/settings/federated_server.html:98 -#: bookwyrm/templates/settings/site.html:101 +#: bookwyrm/templates/settings/site.html:108 #: bookwyrm/templates/snippets/shelve_button/finish_reading_modal.html:42 #: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:42 #: bookwyrm/templates/snippets/shelve_button/start_reading_modal.html:36 @@ -684,6 +684,60 @@ msgstr "Fermer" msgid "Compose status" msgstr "Rédiger un statut" +#: bookwyrm/templates/confirm_email/confirm_email.html:4 +#, fuzzy +#| msgid "Confirm" +msgid "Confirm email" +msgstr "Confirmer" + +#: bookwyrm/templates/confirm_email/confirm_email.html:7 +#, fuzzy +#| msgid "Email address:" +msgid "Confirm your email address" +msgstr "Adresse email :" + +#: bookwyrm/templates/confirm_email/confirm_email.html:13 +msgid "A confirmation code has been sent to the email address you used to register your account." +msgstr "" + +#: bookwyrm/templates/confirm_email/confirm_email.html:15 +msgid "Sorry! We couldn't find that code." +msgstr "" + +#: bookwyrm/templates/confirm_email/confirm_email.html:19 +#, fuzzy +#| msgid "Confirm password:" +msgid "Confirmation code:" +msgstr "Confirmez le mot de passe :" + +#: bookwyrm/templates/confirm_email/confirm_email.html:25 +#: bookwyrm/templates/discover/landing_layout.html:70 +#: bookwyrm/templates/moderation/report_modal.html:33 +msgid "Submit" +msgstr "Valider" + +#: bookwyrm/templates/confirm_email/confirm_email.html:32 +msgid "Can't find your code?" +msgstr "" + +#: bookwyrm/templates/confirm_email/resend_form.html:4 +msgid "Resend confirmation link" +msgstr "" + +#: bookwyrm/templates/confirm_email/resend_form.html:11 +#: bookwyrm/templates/discover/landing_layout.html:64 +#: bookwyrm/templates/password_reset_request.html:18 +#: bookwyrm/templates/preferences/edit_user.html:38 +#: bookwyrm/templates/snippets/register_form.html:13 +msgid "Email address:" +msgstr "Adresse email :" + +#: bookwyrm/templates/confirm_email/resend_form.html:17 +#, fuzzy +#| msgid "Re-send invite" +msgid "Resend link" +msgstr "Envoyer l’invitation de nouveau" + #: bookwyrm/templates/directory/community_filter.html:5 msgid "Community" msgstr "Communauté" @@ -812,7 +866,7 @@ msgid "Join %(name)s" msgstr "Rejoignez %(name)s" #: bookwyrm/templates/discover/landing_layout.html:51 -#: bookwyrm/templates/login.html:51 +#: bookwyrm/templates/login.html:56 msgid "This instance is closed" msgstr "Cette instance est fermée" @@ -824,22 +878,26 @@ msgstr "Merci ! Votre demande a bien été reçue." msgid "Request an Invitation" msgstr "Demander une invitation" -#: bookwyrm/templates/discover/landing_layout.html:64 -#: bookwyrm/templates/password_reset_request.html:18 -#: bookwyrm/templates/preferences/edit_user.html:38 -#: bookwyrm/templates/snippets/register_form.html:13 -msgid "Email address:" -msgstr "Adresse email :" - -#: bookwyrm/templates/discover/landing_layout.html:70 -#: bookwyrm/templates/moderation/report_modal.html:33 -msgid "Submit" -msgstr "Valider" - #: bookwyrm/templates/discover/landing_layout.html:79 msgid "Your Account" msgstr "Votre compte" +#: bookwyrm/templates/email/confirm/html_content.html:6 +#: bookwyrm/templates/email/confirm/text_content.html:4 +#, python-format +msgid "One last step before you join %(site_name)s! Please confirm your email address by clicking the link below:" +msgstr "" + +#: bookwyrm/templates/email/confirm/html_content.html:11 +#, fuzzy +#| msgid "Confirm" +msgid "Confirm Email" +msgstr "Confirmer" + +#: bookwyrm/templates/email/confirm/subject.html:2 +msgid "Please confirm your email" +msgstr "" + #: bookwyrm/templates/email/html_layout.html:15 #: bookwyrm/templates/email/text_layout.html:2 msgid "Hi there," @@ -1246,7 +1304,7 @@ msgid "Imported" msgstr "Importé" #: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:12 -#: bookwyrm/templates/login.html:46 +#: bookwyrm/templates/login.html:51 msgid "Create an Account" msgstr "Créer un compte" @@ -1314,7 +1372,7 @@ msgid "Notifications" msgstr "Notifications" #: bookwyrm/templates/layout.html:158 bookwyrm/templates/layout.html:162 -#: bookwyrm/templates/login.html:17 +#: bookwyrm/templates/login.html:22 #: bookwyrm/templates/snippets/register_form.html:4 msgid "Username:" msgstr "Nom du compte :" @@ -1323,12 +1381,12 @@ msgstr "Nom du compte :" msgid "password" msgstr "Mot de passe" -#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:36 +#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:41 msgid "Forgot your password?" msgstr "Mot de passe oublié ?" #: bookwyrm/templates/layout.html:167 bookwyrm/templates/login.html:10 -#: bookwyrm/templates/login.html:33 +#: bookwyrm/templates/login.html:38 msgid "Log in" msgstr "Se connecter" @@ -1504,16 +1562,20 @@ msgstr "Vos listes" msgid "Login" msgstr "Connexion" -#: bookwyrm/templates/login.html:23 bookwyrm/templates/password_reset.html:17 +#: bookwyrm/templates/login.html:16 +msgid "Success! Email address confirmed." +msgstr "" + +#: bookwyrm/templates/login.html:28 bookwyrm/templates/password_reset.html:17 #: bookwyrm/templates/snippets/register_form.html:22 msgid "Password:" msgstr "Mot de passe :" -#: bookwyrm/templates/login.html:52 +#: bookwyrm/templates/login.html:57 msgid "Contact an administrator to get an invite" msgstr "Contacter un administrateur pour obtenir une invitation" -#: bookwyrm/templates/login.html:63 +#: bookwyrm/templates/login.html:68 msgid "More about this site" msgstr "En savoir plus sur ce site" @@ -2333,7 +2395,15 @@ msgstr "Autoriser les inscriptions" msgid "Allow invite requests" msgstr "Autoriser les demandes d’invitation" -#: bookwyrm/templates/settings/site.html:95 +#: bookwyrm/templates/settings/site.html:97 +msgid "Require users to confirm email address" +msgstr "" + +#: bookwyrm/templates/settings/site.html:99 +msgid "(Recommended if registration is open)" +msgstr "" + +#: bookwyrm/templates/settings/site.html:102 msgid "Registration closed text:" msgstr "Texte affiché lorsque les inscriptions sont closes :" @@ -3015,7 +3085,7 @@ msgstr "Ce fichier dépasse la taille limite : 10 Mo" msgid "%(title)s: %(subtitle)s" msgstr "%(title)s (%(subtitle)s)" -#: bookwyrm/views/authentication.py:58 +#: bookwyrm/views/authentication.py:69 msgid "Username or password are incorrect" msgstr "" @@ -3066,11 +3136,6 @@ msgstr "Un lien de réinitialisation a été envoyé à %s." #~ msgid "Enter a valid integer." #~ msgstr "Adresse email :" -#, fuzzy -#~| msgid "Email address:" -#~ msgid "Enter a valid email address." -#~ msgstr "Adresse email :" - #, fuzzy #~| msgid "Email address:" #~ msgid "Enter a valid IPv4 address." diff --git a/locale/zh_Hans/LC_MESSAGES/django.po b/locale/zh_Hans/LC_MESSAGES/django.po index 471de85d0..adb0d36c6 100644 --- a/locale/zh_Hans/LC_MESSAGES/django.po +++ b/locale/zh_Hans/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-08-06 18:34+0000\n" +"POT-Creation-Date: 2021-08-07 01:35+0000\n" "PO-Revision-Date: 2021-03-20 00:56+0000\n" "Last-Translator: Kana \n" "Language-Team: Mouse Reeve \n" @@ -284,7 +284,7 @@ msgstr "Goodreads key:" #: bookwyrm/templates/settings/announcement_form.html:69 #: bookwyrm/templates/settings/edit_server.html:68 #: bookwyrm/templates/settings/federated_server.html:98 -#: bookwyrm/templates/settings/site.html:101 +#: bookwyrm/templates/settings/site.html:108 #: bookwyrm/templates/snippets/shelve_button/finish_reading_modal.html:42 #: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:42 #: bookwyrm/templates/snippets/shelve_button/start_reading_modal.html:36 @@ -681,6 +681,60 @@ msgstr "关闭" msgid "Compose status" msgstr "撰写状态" +#: bookwyrm/templates/confirm_email/confirm_email.html:4 +#, fuzzy +#| msgid "Confirm" +msgid "Confirm email" +msgstr "确认" + +#: bookwyrm/templates/confirm_email/confirm_email.html:7 +#, fuzzy +#| msgid "Email address:" +msgid "Confirm your email address" +msgstr "邮箱地址:" + +#: bookwyrm/templates/confirm_email/confirm_email.html:13 +msgid "A confirmation code has been sent to the email address you used to register your account." +msgstr "" + +#: bookwyrm/templates/confirm_email/confirm_email.html:15 +msgid "Sorry! We couldn't find that code." +msgstr "" + +#: bookwyrm/templates/confirm_email/confirm_email.html:19 +#, fuzzy +#| msgid "Confirm password:" +msgid "Confirmation code:" +msgstr "确认密码:" + +#: bookwyrm/templates/confirm_email/confirm_email.html:25 +#: bookwyrm/templates/discover/landing_layout.html:70 +#: bookwyrm/templates/moderation/report_modal.html:33 +msgid "Submit" +msgstr "提交" + +#: bookwyrm/templates/confirm_email/confirm_email.html:32 +msgid "Can't find your code?" +msgstr "" + +#: bookwyrm/templates/confirm_email/resend_form.html:4 +msgid "Resend confirmation link" +msgstr "" + +#: bookwyrm/templates/confirm_email/resend_form.html:11 +#: bookwyrm/templates/discover/landing_layout.html:64 +#: bookwyrm/templates/password_reset_request.html:18 +#: bookwyrm/templates/preferences/edit_user.html:38 +#: bookwyrm/templates/snippets/register_form.html:13 +msgid "Email address:" +msgstr "邮箱地址:" + +#: bookwyrm/templates/confirm_email/resend_form.html:17 +#, fuzzy +#| msgid "Re-send invite" +msgid "Resend link" +msgstr "重新发送请求" + #: bookwyrm/templates/directory/community_filter.html:5 msgid "Community" msgstr "社区" @@ -807,7 +861,7 @@ msgid "Join %(name)s" msgstr "加入 %(name)s" #: bookwyrm/templates/discover/landing_layout.html:51 -#: bookwyrm/templates/login.html:51 +#: bookwyrm/templates/login.html:56 msgid "This instance is closed" msgstr "本实例不开放。" @@ -819,22 +873,26 @@ msgstr "谢谢你!我们已经收到了你的请求。" msgid "Request an Invitation" msgstr "请求邀请" -#: bookwyrm/templates/discover/landing_layout.html:64 -#: bookwyrm/templates/password_reset_request.html:18 -#: bookwyrm/templates/preferences/edit_user.html:38 -#: bookwyrm/templates/snippets/register_form.html:13 -msgid "Email address:" -msgstr "邮箱地址:" - -#: bookwyrm/templates/discover/landing_layout.html:70 -#: bookwyrm/templates/moderation/report_modal.html:33 -msgid "Submit" -msgstr "提交" - #: bookwyrm/templates/discover/landing_layout.html:79 msgid "Your Account" msgstr "你的帐号" +#: bookwyrm/templates/email/confirm/html_content.html:6 +#: bookwyrm/templates/email/confirm/text_content.html:4 +#, python-format +msgid "One last step before you join %(site_name)s! Please confirm your email address by clicking the link below:" +msgstr "" + +#: bookwyrm/templates/email/confirm/html_content.html:11 +#, fuzzy +#| msgid "Confirm" +msgid "Confirm Email" +msgstr "确认" + +#: bookwyrm/templates/email/confirm/subject.html:2 +msgid "Please confirm your email" +msgstr "" + #: bookwyrm/templates/email/html_layout.html:15 #: bookwyrm/templates/email/text_layout.html:2 msgid "Hi there," @@ -1237,7 +1295,7 @@ msgid "Imported" msgstr "已导入" #: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:12 -#: bookwyrm/templates/login.html:46 +#: bookwyrm/templates/login.html:51 msgid "Create an Account" msgstr "创建帐号" @@ -1305,7 +1363,7 @@ msgid "Notifications" msgstr "通知" #: bookwyrm/templates/layout.html:158 bookwyrm/templates/layout.html:162 -#: bookwyrm/templates/login.html:17 +#: bookwyrm/templates/login.html:22 #: bookwyrm/templates/snippets/register_form.html:4 msgid "Username:" msgstr "用户名:" @@ -1314,12 +1372,12 @@ msgstr "用户名:" msgid "password" msgstr "密码" -#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:36 +#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:41 msgid "Forgot your password?" msgstr "忘记了密码?" #: bookwyrm/templates/layout.html:167 bookwyrm/templates/login.html:10 -#: bookwyrm/templates/login.html:33 +#: bookwyrm/templates/login.html:38 msgid "Log in" msgstr "登录" @@ -1495,16 +1553,20 @@ msgstr "你的列表" msgid "Login" msgstr "登录" -#: bookwyrm/templates/login.html:23 bookwyrm/templates/password_reset.html:17 +#: bookwyrm/templates/login.html:16 +msgid "Success! Email address confirmed." +msgstr "" + +#: bookwyrm/templates/login.html:28 bookwyrm/templates/password_reset.html:17 #: bookwyrm/templates/snippets/register_form.html:22 msgid "Password:" msgstr "密码:" -#: bookwyrm/templates/login.html:52 +#: bookwyrm/templates/login.html:57 msgid "Contact an administrator to get an invite" msgstr "联系管理员以取得邀请" -#: bookwyrm/templates/login.html:63 +#: bookwyrm/templates/login.html:68 msgid "More about this site" msgstr "更多关于本站点的信息" @@ -2319,7 +2381,15 @@ msgstr "允许注册" msgid "Allow invite requests" msgstr "允许请求邀请" -#: bookwyrm/templates/settings/site.html:95 +#: bookwyrm/templates/settings/site.html:97 +msgid "Require users to confirm email address" +msgstr "" + +#: bookwyrm/templates/settings/site.html:99 +msgid "(Recommended if registration is open)" +msgstr "" + +#: bookwyrm/templates/settings/site.html:102 msgid "Registration closed text:" msgstr "注册关闭文字:" @@ -2992,7 +3062,7 @@ msgstr "文件超过了最大大小: 10MB" msgid "%(title)s: %(subtitle)s" msgstr "%(title)s:%(subtitle)s" -#: bookwyrm/views/authentication.py:58 +#: bookwyrm/views/authentication.py:69 msgid "Username or password are incorrect" msgstr "" diff --git a/locale/zh_Hant/LC_MESSAGES/django.po b/locale/zh_Hant/LC_MESSAGES/django.po index 40b12995b..c496bb924 100644 --- a/locale/zh_Hant/LC_MESSAGES/django.po +++ b/locale/zh_Hant/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-08-06 18:34+0000\n" +"POT-Creation-Date: 2021-08-07 01:35+0000\n" "PO-Revision-Date: 2021-06-30 10:36+0000\n" "Last-Translator: Grace Cheng \n" "Language-Team: LANGUAGE \n" @@ -288,7 +288,7 @@ msgstr "Goodreads key:" #: bookwyrm/templates/settings/announcement_form.html:69 #: bookwyrm/templates/settings/edit_server.html:68 #: bookwyrm/templates/settings/federated_server.html:98 -#: bookwyrm/templates/settings/site.html:101 +#: bookwyrm/templates/settings/site.html:108 #: bookwyrm/templates/snippets/shelve_button/finish_reading_modal.html:42 #: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:42 #: bookwyrm/templates/snippets/shelve_button/start_reading_modal.html:36 @@ -687,6 +687,60 @@ msgstr "關閉" msgid "Compose status" msgstr "撰寫狀態" +#: bookwyrm/templates/confirm_email/confirm_email.html:4 +#, fuzzy +#| msgid "Confirm" +msgid "Confirm email" +msgstr "確認" + +#: bookwyrm/templates/confirm_email/confirm_email.html:7 +#, fuzzy +#| msgid "Email address:" +msgid "Confirm your email address" +msgstr "郵箱地址:" + +#: bookwyrm/templates/confirm_email/confirm_email.html:13 +msgid "A confirmation code has been sent to the email address you used to register your account." +msgstr "" + +#: bookwyrm/templates/confirm_email/confirm_email.html:15 +msgid "Sorry! We couldn't find that code." +msgstr "" + +#: bookwyrm/templates/confirm_email/confirm_email.html:19 +#, fuzzy +#| msgid "Confirm password:" +msgid "Confirmation code:" +msgstr "確認密碼:" + +#: bookwyrm/templates/confirm_email/confirm_email.html:25 +#: bookwyrm/templates/discover/landing_layout.html:70 +#: bookwyrm/templates/moderation/report_modal.html:33 +msgid "Submit" +msgstr "提交" + +#: bookwyrm/templates/confirm_email/confirm_email.html:32 +msgid "Can't find your code?" +msgstr "" + +#: bookwyrm/templates/confirm_email/resend_form.html:4 +msgid "Resend confirmation link" +msgstr "" + +#: bookwyrm/templates/confirm_email/resend_form.html:11 +#: bookwyrm/templates/discover/landing_layout.html:64 +#: bookwyrm/templates/password_reset_request.html:18 +#: bookwyrm/templates/preferences/edit_user.html:38 +#: bookwyrm/templates/snippets/register_form.html:13 +msgid "Email address:" +msgstr "郵箱地址:" + +#: bookwyrm/templates/confirm_email/resend_form.html:17 +#, fuzzy +#| msgid "Re-send invite" +msgid "Resend link" +msgstr "重新發送請求" + #: bookwyrm/templates/directory/community_filter.html:5 msgid "Community" msgstr "社群" @@ -813,7 +867,7 @@ msgid "Join %(name)s" msgstr "加入 %(name)s" #: bookwyrm/templates/discover/landing_layout.html:51 -#: bookwyrm/templates/login.html:51 +#: bookwyrm/templates/login.html:56 msgid "This instance is closed" msgstr "本實例不開放。" @@ -825,22 +879,26 @@ msgstr "謝謝你!我們已經受到了你的請求。" msgid "Request an Invitation" msgstr "請求邀請" -#: bookwyrm/templates/discover/landing_layout.html:64 -#: bookwyrm/templates/password_reset_request.html:18 -#: bookwyrm/templates/preferences/edit_user.html:38 -#: bookwyrm/templates/snippets/register_form.html:13 -msgid "Email address:" -msgstr "郵箱地址:" - -#: bookwyrm/templates/discover/landing_layout.html:70 -#: bookwyrm/templates/moderation/report_modal.html:33 -msgid "Submit" -msgstr "提交" - #: bookwyrm/templates/discover/landing_layout.html:79 msgid "Your Account" msgstr "你的帳號" +#: bookwyrm/templates/email/confirm/html_content.html:6 +#: bookwyrm/templates/email/confirm/text_content.html:4 +#, python-format +msgid "One last step before you join %(site_name)s! Please confirm your email address by clicking the link below:" +msgstr "" + +#: bookwyrm/templates/email/confirm/html_content.html:11 +#, fuzzy +#| msgid "Confirm" +msgid "Confirm Email" +msgstr "確認" + +#: bookwyrm/templates/email/confirm/subject.html:2 +msgid "Please confirm your email" +msgstr "" + #: bookwyrm/templates/email/html_layout.html:15 #: bookwyrm/templates/email/text_layout.html:2 msgid "Hi there," @@ -1247,7 +1305,7 @@ msgid "Imported" msgstr "已匯入" #: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:12 -#: bookwyrm/templates/login.html:46 +#: bookwyrm/templates/login.html:51 msgid "Create an Account" msgstr "建立帳號" @@ -1315,7 +1373,7 @@ msgid "Notifications" msgstr "通知" #: bookwyrm/templates/layout.html:158 bookwyrm/templates/layout.html:162 -#: bookwyrm/templates/login.html:17 +#: bookwyrm/templates/login.html:22 #: bookwyrm/templates/snippets/register_form.html:4 msgid "Username:" msgstr "使用者名稱:" @@ -1324,12 +1382,12 @@ msgstr "使用者名稱:" msgid "password" msgstr "密碼" -#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:36 +#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:41 msgid "Forgot your password?" msgstr "忘記了密碼?" #: bookwyrm/templates/layout.html:167 bookwyrm/templates/login.html:10 -#: bookwyrm/templates/login.html:33 +#: bookwyrm/templates/login.html:38 msgid "Log in" msgstr "登入" @@ -1505,16 +1563,20 @@ msgstr "你的列表" msgid "Login" msgstr "登入" -#: bookwyrm/templates/login.html:23 bookwyrm/templates/password_reset.html:17 +#: bookwyrm/templates/login.html:16 +msgid "Success! Email address confirmed." +msgstr "" + +#: bookwyrm/templates/login.html:28 bookwyrm/templates/password_reset.html:17 #: bookwyrm/templates/snippets/register_form.html:22 msgid "Password:" msgstr "密碼:" -#: bookwyrm/templates/login.html:52 +#: bookwyrm/templates/login.html:57 msgid "Contact an administrator to get an invite" msgstr "聯絡管理員以取得邀請" -#: bookwyrm/templates/login.html:63 +#: bookwyrm/templates/login.html:68 msgid "More about this site" msgstr "關於本網站的更多" @@ -2338,7 +2400,15 @@ msgstr "允許註冊:" msgid "Allow invite requests" msgstr "允許請求邀請:" -#: bookwyrm/templates/settings/site.html:95 +#: bookwyrm/templates/settings/site.html:97 +msgid "Require users to confirm email address" +msgstr "" + +#: bookwyrm/templates/settings/site.html:99 +msgid "(Recommended if registration is open)" +msgstr "" + +#: bookwyrm/templates/settings/site.html:102 msgid "Registration closed text:" msgstr "註冊關閉文字:" @@ -3011,7 +3081,7 @@ msgstr "檔案超過了最大大小: 10MB" msgid "%(title)s: %(subtitle)s" msgstr "" -#: bookwyrm/views/authentication.py:58 +#: bookwyrm/views/authentication.py:69 msgid "Username or password are incorrect" msgstr "" From e198e663d1b821a596a56b12986a00441c86b815 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 6 Aug 2021 18:48:16 -0700 Subject: [PATCH 25/75] Fixes names of site settings field in tests --- bookwyrm/tests/views/test_authentication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/tests/views/test_authentication.py b/bookwyrm/tests/views/test_authentication.py index bbafe7bd5..bd4b3b029 100644 --- a/bookwyrm/tests/views/test_authentication.py +++ b/bookwyrm/tests/views/test_authentication.py @@ -32,7 +32,7 @@ class AuthenticationViews(TestCase): self.anonymous_user.is_authenticated = False self.settings = models.SiteSettings.objects.create( - id=1, require_email_confirmation=False + id=1, require_confirm_email=False ) def test_login_get(self, _): From aad5de3b618b20d2c24cfe456f1f7a2e0324243d Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 6 Aug 2021 19:03:15 -0700 Subject: [PATCH 26/75] Improves cross-edition display for lists --- bookwyrm/templatetags/bookwyrm_tags.py | 2 +- bookwyrm/views/books.py | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/bookwyrm/templatetags/bookwyrm_tags.py b/bookwyrm/templatetags/bookwyrm_tags.py index 5cba5455f..4811f4fd5 100644 --- a/bookwyrm/templatetags/bookwyrm_tags.py +++ b/bookwyrm/templatetags/bookwyrm_tags.py @@ -12,7 +12,7 @@ register = template.Library() def get_rating(book, user): """get the overall rating of a book""" queryset = views.helpers.privacy_filter( - user, models.Review.objects.filter(book=book) + user, models.Review.objects.filter(book__in=book.parent_work.editions.all()) ) return queryset.aggregate(Avg("rating"))["rating__avg"] diff --git a/bookwyrm/views/books.py b/bookwyrm/views/books.py index d56e2f22c..6cd0427c1 100644 --- a/bookwyrm/views/books.py +++ b/bookwyrm/views/books.py @@ -65,6 +65,13 @@ class Book(View): queryset = queryset.select_related("user") paginated = Paginator(queryset, PAGE_LENGTH) + lists = privacy_filter( + request.user, + models.List.objects.filter( + listitem__approved=True, + listitem__book__in=book.parent_work.editions.all(), + ), + ) data = { "book": book, "statuses": paginated.get_page(request.GET.get("page")), @@ -75,9 +82,7 @@ class Book(View): if not user_statuses else None, "rating": reviews.aggregate(Avg("rating"))["rating__avg"], - "lists": privacy_filter( - request.user, book.list_set.filter(listitem__approved=True) - ), + "lists": lists, } if request.user.is_authenticated: From 0fa9fd7331e71dd981b8effa6faeb4aba61fada6 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 7 Aug 2021 07:28:24 -0700 Subject: [PATCH 27/75] Registration with confirm email tests --- bookwyrm/tests/views/test_authentication.py | 97 +++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/bookwyrm/tests/views/test_authentication.py b/bookwyrm/tests/views/test_authentication.py index bd4b3b029..dc9f5dd53 100644 --- a/bookwyrm/tests/views/test_authentication.py +++ b/bookwyrm/tests/views/test_authentication.py @@ -132,6 +132,32 @@ class AuthenticationViews(TestCase): self.assertEqual(nutria.localname, "nutria-user.user_nutria") self.assertEqual(nutria.local, True) + def test_register_email_confirm(self, _): + """create a user""" + self.settings.require_confirm_email = True + self.settings.save() + + view = views.Register.as_view() + self.assertEqual(models.User.objects.count(), 1) + request = self.factory.post( + "register/", + { + "localname": "nutria", + "password": "mouseword", + "email": "aa@bb.cccc", + }, + ) + with patch("bookwyrm.views.authentication.login"): + response = view(request) + self.assertEqual(response.status_code, 302) + nutria = models.User.objects.get(localname="nutria") + self.assertEqual(nutria.username, "nutria@%s" % DOMAIN) + self.assertEqual(nutria.local, True) + + self.assertFalse(nutria.is_active) + self.assertEqual(nutria.deactivation_reason, "pending") + self.assertIsNotNone(nutria.confirmation_code) + def test_register_trailing_space(self, _): """django handles this so weirdly""" view = views.Register.as_view() @@ -251,3 +277,74 @@ class AuthenticationViews(TestCase): with self.assertRaises(Http404): response = view(request) self.assertEqual(models.User.objects.count(), 2) + + def test_confirm_email_code_get(self, _): + """there are so many views, this just makes sure it LOADS""" + self.settings.require_confirm_email = True + self.settings.save() + + self.local_user.is_active = False + self.local_user.deactivation_reason = "pending" + self.local_user.confirmation_code = "12345" + self.local_user.save( + broadcast=False, + update_fields=["is_active", "deactivation_reason", "confirmation_code"], + ) + view = views.ConfirmEmailCode.as_view() + request = self.factory.get("") + request.user = self.anonymous_user + + result = view(request, "12345") + self.assertEqual(result.url, "/login/confirmed") + self.assertEqual(result.status_code, 302) + + self.local_user.refresh_from_db() + self.assertTrue(self.local_user.is_active) + self.assertIsNone(self.local_user.deactivation_reason) + + request.user = self.local_user + result = view(request, "12345") + self.assertEqual(result.url, "/") + self.assertEqual(result.status_code, 302) + + def test_confirm_email_code_get_invalid_code(self, _): + """there are so many views, this just makes sure it LOADS""" + self.settings.require_confirm_email = True + self.settings.save() + + self.local_user.is_active = False + self.local_user.deactivation_reason = "pending" + self.local_user.confirmation_code = "12345" + self.local_user.save( + broadcast=False, + update_fields=["is_active", "deactivation_reason", "confirmation_code"], + ) + view = views.ConfirmEmailCode.as_view() + request = self.factory.get("") + request.user = self.anonymous_user + + result = view(request, "abcde") + self.assertIsInstance(result, TemplateResponse) + result.render() + self.assertEqual(result.status_code, 200) + self.assertFalse(self.local_user.is_active) + self.assertEqual(self.local_user.deactivation_reason, "pending") + + def test_confirm_email_get(self, _): + """there are so many views, this just makes sure it LOADS""" + self.settings.require_confirm_email = True + self.settings.save() + + login = views.ConfirmEmail.as_view() + request = self.factory.get("") + request.user = self.anonymous_user + + result = login(request) + self.assertIsInstance(result, TemplateResponse) + result.render() + self.assertEqual(result.status_code, 200) + + request.user = self.local_user + result = login(request) + self.assertEqual(result.url, "/") + self.assertEqual(result.status_code, 302) From 226c325099e1bd5ff723dd2c0df6549999067dc6 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 7 Aug 2021 07:37:18 -0700 Subject: [PATCH 28/75] Adds plaintext code to emails --- bookwyrm/templates/email/confirm/html_content.html | 6 ++++++ bookwyrm/templates/email/confirm/text_content.html | 3 +++ 2 files changed, 9 insertions(+) diff --git a/bookwyrm/templates/email/confirm/html_content.html b/bookwyrm/templates/email/confirm/html_content.html index b47642af7..231b0388e 100644 --- a/bookwyrm/templates/email/confirm/html_content.html +++ b/bookwyrm/templates/email/confirm/html_content.html @@ -11,4 +11,10 @@ One last step before you join {{ site_name }}! Please confirm your email address {% trans "Confirm Email" as text %} {% include 'email/snippets/action.html' with path=confirmation_link text=text %} +

+{% blocktrans trimmed %} +Or enter the code "{{ confirmation_code }}" at login. +{% endblocktrans %} +

+ {% endblock %} diff --git a/bookwyrm/templates/email/confirm/text_content.html b/bookwyrm/templates/email/confirm/text_content.html index e3d739383..847009e55 100644 --- a/bookwyrm/templates/email/confirm/text_content.html +++ b/bookwyrm/templates/email/confirm/text_content.html @@ -7,5 +7,8 @@ One last step before you join {{ site_name }}! Please confirm your email address {{ confirmation_link }} +{% blocktrans trimmed %} +Or enter the code "{{ confirmation_code }}" at login. +{% endblocktrans %} {% endblock %} From 68e4462486d03573b278ef5da42b73ce5fd7bf5d Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 7 Aug 2021 07:43:30 -0700 Subject: [PATCH 29/75] Make email a required html field in register form --- bookwyrm/templates/snippets/register_form.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/templates/snippets/register_form.html b/bookwyrm/templates/snippets/register_form.html index cd7ea8063..9e610bd13 100644 --- a/bookwyrm/templates/snippets/register_form.html +++ b/bookwyrm/templates/snippets/register_form.html @@ -12,7 +12,7 @@
- + {% for error in register_form.email.errors %}

{{ error | escape }}

{% endfor %} From 38f614a526209e78b469e477261a8efef5d0ebda Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 7 Aug 2021 07:56:30 -0700 Subject: [PATCH 30/75] Include generated notes in books stream --- bookwyrm/activitystreams.py | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/bookwyrm/activitystreams.py b/bookwyrm/activitystreams.py index bad7c59f8..66dcad84e 100644 --- a/bookwyrm/activitystreams.py +++ b/bookwyrm/activitystreams.py @@ -358,25 +358,39 @@ def add_statuses_on_shelve(sender, instance, *args, **kwargs): """update books stream when user shelves a book""" if not instance.user.local: return - # check if the book is already on the user's shelves - if models.ShelfBook.objects.filter( - user=instance.user, book__in=instance.book.parent_work.editions.all() - ).exists(): + book = None + if hasattr(instance, "book"): + book = instance.book + elif instance.mention_books.exists(): + book = instance.mention_books.first() + if not book: return - BooksStream().add_book_statuses(instance.user, instance.book) + # check if the book is already on the user's shelves + editions = book.parent_work.editions.all() + if models.ShelfBook.objects.filter(user=instance.user, book__in=editions).exists(): + return + + BooksStream().add_book_statuses(instance.user, book) @receiver(signals.post_delete, sender=models.ShelfBook) # pylint: disable=unused-argument -def remove_statuses_on_shelve(sender, instance, *args, **kwargs): +def remove_statuses_on_unshelve(sender, instance, *args, **kwargs): """update books stream when user unshelves a book""" if not instance.user.local: return + + book = None + if hasattr(instance, "book"): + book = instance.book + elif instance.mention_books.exists(): + book = instance.mention_books.first() + if not book: + return # check if the book is actually unshelved, not just moved - if models.ShelfBook.objects.filter( - user=instance.user, book__in=instance.book.parent_work.editions.all() - ).exists(): + editions = book.parent_work.editions.all() + if models.ShelfBook.objects.filter(user=instance.user, book__in=editions).exists(): return BooksStream().remove_book_statuses(instance.user, instance.book) From 026c6ac025f2725f0e2805da4e7040e212a4d4a5 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 7 Aug 2021 08:01:14 -0700 Subject: [PATCH 31/75] Mocks emailer in registration test --- bookwyrm/tests/views/test_authentication.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bookwyrm/tests/views/test_authentication.py b/bookwyrm/tests/views/test_authentication.py index dc9f5dd53..22008e100 100644 --- a/bookwyrm/tests/views/test_authentication.py +++ b/bookwyrm/tests/views/test_authentication.py @@ -132,7 +132,8 @@ class AuthenticationViews(TestCase): self.assertEqual(nutria.localname, "nutria-user.user_nutria") self.assertEqual(nutria.local, True) - def test_register_email_confirm(self, _): + @patch("bookwyrm.emailing.send_email.delay") + def test_register_email_confirm(self, *_): """create a user""" self.settings.require_confirm_email = True self.settings.save() From 468f1f135c42b819f6f2f884dbe39fbf9101dd04 Mon Sep 17 00:00:00 2001 From: reese Date: Sat, 7 Aug 2021 11:35:07 -0500 Subject: [PATCH 32/75] update spanish translations --- locale/es/LC_MESSAGES/django.mo | Bin 42719 -> 44832 bytes locale/es/LC_MESSAGES/django.po | 135 ++++++++++---------------------- 2 files changed, 41 insertions(+), 94 deletions(-) diff --git a/locale/es/LC_MESSAGES/django.mo b/locale/es/LC_MESSAGES/django.mo index 23869cf45428ccb9c4d7e0d8a06dc96b209e7775..c73db384d7792b0008f0fef891c4d286b5a253f7 100644 GIT binary patch delta 15136 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 LV$IFrOFI|=dHQfG delta 13429 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 E0Qt|D8~^|S diff --git a/locale/es/LC_MESSAGES/django.po b/locale/es/LC_MESSAGES/django.po index 9fc28535e..31ccd53cd 100644 --- a/locale/es/LC_MESSAGES/django.po +++ b/locale/es/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-08-07 01:35+0000\n" +"POT-Creation-Date: 2021-08-07 16:23+0000\n" "PO-Revision-Date: 2021-03-19 11:49+0800\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -100,10 +100,8 @@ msgid "Home" msgstr "Hogar" #: bookwyrm/settings.py:124 -#, fuzzy -#| msgid "Book Title" msgid "Books Timeline" -msgstr "Título" +msgstr "Línea temporal de libros" #: bookwyrm/settings.py:124 bookwyrm/templates/search/layout.html:21 #: bookwyrm/templates/search/layout.html:42 @@ -132,10 +130,8 @@ msgid "Simplified Chinese" msgstr "Chino simplificado" #: bookwyrm/settings.py:175 -#, fuzzy -#| msgid "Additional info:" msgid "Traditional Chinese" -msgstr "Más informacion:" +msgstr "Chino tradicional" #: bookwyrm/templates/404.html:4 bookwyrm/templates/404.html:8 msgid "Not Found" @@ -190,10 +186,8 @@ msgid "View on Inventaire" msgstr "Ver en Inventaire" #: bookwyrm/templates/author/author.html:85 -#, fuzzy -#| msgid "View on OpenLibrary" msgid "View on LibraryThing" -msgstr "Ver en OpenLibrary" +msgstr "Ver en LibraryThing" #: bookwyrm/templates/author/author.html:93 msgid "View on Goodreads" @@ -534,16 +528,12 @@ msgid "Authors" msgstr "Autores" #: bookwyrm/templates/book/edit_book.html:202 -#, fuzzy, python-format -#| msgid "Remove from %(name)s" msgid "Remove %(name)s" -msgstr "Quitar de %(name)s" +msgstr "Quitar %(name)s" #: bookwyrm/templates/book/edit_book.html:205 -#, fuzzy, python-format -#| msgid "Remove from %(name)s" msgid "Author page for %(name)s" -msgstr "Quitar de %(name)s" +msgstr "Página de autor por %(name)s" #: bookwyrm/templates/book/edit_book.html:212 msgid "Add Authors:" @@ -689,16 +679,12 @@ msgid "Compose status" msgstr "Componer status" #: bookwyrm/templates/confirm_email/confirm_email.html:4 -#, fuzzy -#| msgid "Confirm" msgid "Confirm email" -msgstr "Confirmar" +msgstr "Confirmar correo electrónico" #: bookwyrm/templates/confirm_email/confirm_email.html:7 -#, fuzzy -#| msgid "Enter a valid email address." msgid "Confirm your email address" -msgstr "Ingrese una dirección de correo electrónico válida." +msgstr "Confirmar tu dirección de correo electrónico" #: bookwyrm/templates/confirm_email/confirm_email.html:13 msgid "A confirmation code has been sent to the email address you used to register your account." @@ -709,10 +695,8 @@ msgid "Sorry! We couldn't find that code." msgstr "" #: bookwyrm/templates/confirm_email/confirm_email.html:19 -#, fuzzy -#| msgid "Confirm password:" msgid "Confirmation code:" -msgstr "Confirmar contraseña:" +msgstr "Código de confirmación:" #: bookwyrm/templates/confirm_email/confirm_email.html:25 #: bookwyrm/templates/discover/landing_layout.html:70 @@ -737,10 +721,8 @@ msgid "Email address:" msgstr "Dirección de correo electrónico:" #: bookwyrm/templates/confirm_email/resend_form.html:17 -#, fuzzy -#| msgid "Re-send invite" msgid "Resend link" -msgstr "Re-enviar invitación" +msgstr "Re-enviar enlace" #: bookwyrm/templates/directory/community_filter.html:5 msgid "Community" @@ -791,10 +773,8 @@ msgstr "Activ@ recientemente" #: bookwyrm/templates/directory/user_card.html:18 #: bookwyrm/templates/user/user_preview.html:16 #: bookwyrm/templates/user/user_preview.html:17 -#, fuzzy -#| msgid "Your Account" msgid "Locked account" -msgstr "Tu cuenta" +msgstr "Cuenta bloqueada" #: bookwyrm/templates/directory/user_card.html:40 msgid "follower you follow" @@ -893,15 +873,23 @@ msgid "One last step before you join %(site_name)s! Please confirm your email ad msgstr "" #: bookwyrm/templates/email/confirm/html_content.html:11 -#, fuzzy -#| msgid "Confirm" msgid "Confirm Email" -msgstr "Confirmar" +msgstr "Confirmar correo electrónico" + +#: bookwyrm/templates/email/confirm/html_content.html:15 +#, python-format +msgid "Or enter the code \"%(confirmation_code)s\" at login." +msgstr "" #: bookwyrm/templates/email/confirm/subject.html:2 msgid "Please confirm your email" msgstr "" +#: bookwyrm/templates/email/confirm/text_content.html:10 +#, python-format +msgid "Or enter the code \"%(confirmation_code)s\" at login." +msgstr "" + #: bookwyrm/templates/email/html_layout.html:15 #: bookwyrm/templates/email/text_layout.html:2 msgid "Hi there," @@ -983,10 +971,8 @@ msgid "You have no messages right now." msgstr "No tienes ningún mensaje en este momento." #: bookwyrm/templates/feed/feed.html:22 -#, fuzzy, python-format -#| msgid "load 0 unread status(es)" msgid "load 0 unread status(es)" -msgstr "cargar 0 status(es) no leídos" +msgstr "cargar 0 status(es) no leído(s)" #: bookwyrm/templates/feed/feed.html:38 msgid "There aren't any activities right now! Try following a user to get started" @@ -1229,10 +1215,8 @@ msgid "Import Status" msgstr "Status de importación" #: bookwyrm/templates/import_status.html:11 -#, fuzzy -#| msgid "Back to reports" msgid "Back to imports" -msgstr "Volver a los informes" +msgstr "Volver a las importaciones" #: bookwyrm/templates/import_status.html:15 msgid "Import started:" @@ -1281,10 +1265,8 @@ msgid "Successfully imported" msgstr "Importado exitosamente" #: bookwyrm/templates/import_status.html:114 -#, fuzzy -#| msgid "Import still in progress." msgid "Import Progress" -msgstr "Importación todavia en progreso" +msgstr "Progreso de importación" #: bookwyrm/templates/import_status.html:119 msgid "Book" @@ -1399,10 +1381,8 @@ msgid "Join" msgstr "Unirse" #: bookwyrm/templates/layout.html:213 -#, fuzzy -#| msgid "About this server" msgid "About this instance" -msgstr "Sobre este servidor" +msgstr "Sobre esta instancia" #: bookwyrm/templates/layout.html:217 msgid "Contact site admin" @@ -1836,10 +1816,8 @@ msgstr "Nueva contraseña:" #: bookwyrm/templates/preferences/delete_user.html:7 #: bookwyrm/templates/preferences/delete_user.html:26 #: bookwyrm/templates/preferences/layout.html:23 -#, fuzzy -#| msgid "Create an Account" msgid "Delete Account" -msgstr "Crear una cuenta" +msgstr "Quitar cuenta" #: bookwyrm/templates/preferences/delete_user.html:12 msgid "Permanently delete account" @@ -1859,10 +1837,8 @@ msgid "Show set reading goal prompt in feed:" msgstr "Mostrar meta de lectura en el feed:" #: bookwyrm/templates/preferences/edit_user.html:58 -#, fuzzy -#| msgid "Post privacy" msgid "Default post privacy:" -msgstr "Privacidad de publicación" +msgstr "Privacidad de publicación por defecto:" #: bookwyrm/templates/preferences/edit_user.html:70 #, python-format @@ -1886,22 +1862,16 @@ msgid "Relationships" msgstr "Relaciones" #: bookwyrm/templates/reading_progress/finish.html:5 -#, fuzzy, python-format -#| msgid "Finish \"%(book_title)s\"" msgid "Finish \"%(book_title)s\"" -msgstr "Terminar \"%(book_title)s\"" +msgstr "Terminar \"%(book_title)s\"" #: bookwyrm/templates/reading_progress/start.html:5 -#, fuzzy, python-format -#| msgid "Edit \"%(book_title)s\"" msgid "Start \"%(book_title)s\"" -msgstr "Editar \"%(book_title)s\"" +msgstr "Empezar \"%(book_title)s\"" #: bookwyrm/templates/reading_progress/want.html:5 -#, fuzzy, python-format -#| msgid "Want to Read \"%(book_title)s\"" msgid "Want to Read \"%(book_title)s\"" -msgstr "Quiero leer \"%(book_title)s\"" +msgstr "Quiero leer \"%(book_title)s\"" #: bookwyrm/templates/rss/title.html:5 #: bookwyrm/templates/snippets/status/status_header.html:36 @@ -1967,10 +1937,8 @@ msgstr "Administrar usuarios" #: bookwyrm/templates/settings/admin_layout.html:39 #: bookwyrm/templates/settings/federation.html:3 #: bookwyrm/templates/settings/federation.html:5 -#, fuzzy -#| msgid "Federated Servers" msgid "Federated Instances" -msgstr "Servidores federalizados" +msgstr "Instancias federalizadas" #: bookwyrm/templates/settings/admin_layout.html:44 msgid "Instance Settings" @@ -2097,17 +2065,13 @@ msgstr "inactivo" #: bookwyrm/templates/settings/federation.html:10 #: bookwyrm/templates/settings/server_blocklist.html:3 #: bookwyrm/templates/settings/server_blocklist.html:20 -#, fuzzy -#| msgid "View instance" msgid "Add instance" -msgstr "Ver instancia" +msgstr "Agregar instancia" #: bookwyrm/templates/settings/edit_server.html:7 #: bookwyrm/templates/settings/server_blocklist.html:7 -#, fuzzy -#| msgid "Back to server list" msgid "Back to instance list" -msgstr "Volver a la lista de servidores" +msgstr "Volver a la lista de instancias" #: bookwyrm/templates/settings/edit_server.html:16 #: bookwyrm/templates/settings/server_blocklist.html:16 @@ -2217,10 +2181,8 @@ msgstr "Todos los usuarios en esta instancia serán re-activados." #: bookwyrm/templates/settings/federation.html:19 #: bookwyrm/templates/user_admin/server_filter.html:5 -#, fuzzy -#| msgid "Instance Name:" msgid "Instance name" -msgstr "Nombre de instancia:" +msgstr "Nombre de instancia" #: bookwyrm/templates/settings/federation.html:23 msgid "Date federated" @@ -2402,16 +2364,12 @@ msgid "Additional info:" msgstr "Más informacion:" #: bookwyrm/templates/settings/site.html:85 -#, fuzzy -#| msgid "Allow registration:" msgid "Allow registration" -msgstr "Permitir registración:" +msgstr "Permitir registración" #: bookwyrm/templates/settings/site.html:91 -#, fuzzy -#| msgid "Allow invite requests:" msgid "Allow invite requests" -msgstr "Permitir solicitudes de invitación:" +msgstr "Permitir solicitudes de invitación" #: bookwyrm/templates/settings/site.html:97 msgid "Require users to confirm email address" @@ -2442,10 +2400,8 @@ msgid "No cover" msgstr "Sin portada" #: bookwyrm/templates/snippets/book_titleby.html:6 -#, fuzzy, python-format -#| msgid "%(title)s by " msgid "%(title)s by" -msgstr "%(title)s por " +msgstr "%(title)s por" #: bookwyrm/templates/snippets/boost_button.html:20 #: bookwyrm/templates/snippets/boost_button.html:21 @@ -2673,8 +2629,6 @@ msgid "page %(page)s of %(total_pages)s" msgstr "página %(page)s de %(total_pages)s" #: bookwyrm/templates/snippets/page_text.html:6 -#, fuzzy, python-format -#| msgid "page %(page)s" msgid "page %(page)s" msgstr "página %(pages)s" @@ -2862,10 +2816,8 @@ msgstr[1] "%(shared_books)s libros en tus estantes" #: bookwyrm/templates/snippets/suggested_users.html:31 #: bookwyrm/templates/user/user_preview.html:36 -#, fuzzy -#| msgid "followed you" msgid "Follows you" -msgstr "te siguió" +msgstr "Te sigue" #: bookwyrm/templates/snippets/switch_edition_button.html:5 msgid "Switch to this edition" @@ -3018,11 +2970,8 @@ msgstr[0] "%(mutuals_display)s seguidor que sigues" msgstr[1] "%(mutuals_display)s seguidores que sigues" #: bookwyrm/templates/user/user_preview.html:38 -#, fuzzy -#| msgid "follower you follow" -#| msgid_plural "followers you follow" msgid "No followers you follow" -msgstr "seguidor que tu sigues" +msgstr "Ningún seguidor que tu sigues" #: bookwyrm/templates/user_admin/user.html:9 msgid "Back to users" @@ -3047,10 +2996,8 @@ msgid "Last Active" msgstr "Actividad reciente" #: bookwyrm/templates/user_admin/user_admin.html:38 -#, fuzzy -#| msgid "View instance" msgid "Remote instance" -msgstr "Ver instancia" +msgstr "Instancia remota" #: bookwyrm/templates/user_admin/user_admin.html:47 msgid "Active" From a0d2f3897016dbeb37cf214102d2cc56f5c81ee4 Mon Sep 17 00:00:00 2001 From: Fabien Basmaison Date: Sat, 7 Aug 2021 19:35:43 +0200 Subject: [PATCH 33/75] [french] Translate strings about email confirmation. --- locale/fr_FR/LC_MESSAGES/django.po | 38 +++++++++++------------------- 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/locale/fr_FR/LC_MESSAGES/django.po b/locale/fr_FR/LC_MESSAGES/django.po index f0a559f97..badfcdcaf 100644 --- a/locale/fr_FR/LC_MESSAGES/django.po +++ b/locale/fr_FR/LC_MESSAGES/django.po @@ -685,30 +685,24 @@ msgid "Compose status" msgstr "Rédiger un statut" #: bookwyrm/templates/confirm_email/confirm_email.html:4 -#, fuzzy -#| msgid "Confirm" msgid "Confirm email" -msgstr "Confirmer" +msgstr "Confirmation de l’email" #: bookwyrm/templates/confirm_email/confirm_email.html:7 -#, fuzzy -#| msgid "Email address:" msgid "Confirm your email address" -msgstr "Adresse email :" +msgstr "Veuillez confirmer votre adresse email" #: bookwyrm/templates/confirm_email/confirm_email.html:13 msgid "A confirmation code has been sent to the email address you used to register your account." -msgstr "" +msgstr "Un code de confirmation a été envoyé à l’adresse email rattachée à votre compte." #: bookwyrm/templates/confirm_email/confirm_email.html:15 msgid "Sorry! We couldn't find that code." -msgstr "" +msgstr "Pardon ! Nous ne reconnaissons pas ce code." #: bookwyrm/templates/confirm_email/confirm_email.html:19 -#, fuzzy -#| msgid "Confirm password:" msgid "Confirmation code:" -msgstr "Confirmez le mot de passe :" +msgstr "Code de confirmation :" #: bookwyrm/templates/confirm_email/confirm_email.html:25 #: bookwyrm/templates/discover/landing_layout.html:70 @@ -718,11 +712,11 @@ msgstr "Valider" #: bookwyrm/templates/confirm_email/confirm_email.html:32 msgid "Can't find your code?" -msgstr "" +msgstr "Vous ne trouvez pas votre code ?" #: bookwyrm/templates/confirm_email/resend_form.html:4 msgid "Resend confirmation link" -msgstr "" +msgstr "Envoyer le lien de confirmation de nouveau" #: bookwyrm/templates/confirm_email/resend_form.html:11 #: bookwyrm/templates/discover/landing_layout.html:64 @@ -733,10 +727,8 @@ msgid "Email address:" msgstr "Adresse email :" #: bookwyrm/templates/confirm_email/resend_form.html:17 -#, fuzzy -#| msgid "Re-send invite" msgid "Resend link" -msgstr "Envoyer l’invitation de nouveau" +msgstr "Envoyer le lien de nouveau" #: bookwyrm/templates/directory/community_filter.html:5 msgid "Community" @@ -886,17 +878,15 @@ msgstr "Votre compte" #: bookwyrm/templates/email/confirm/text_content.html:4 #, python-format msgid "One last step before you join %(site_name)s! Please confirm your email address by clicking the link below:" -msgstr "" +msgstr "Une dernière petite étape avant de rejoindre %(site_name)s ! Veuillez confirmer votre adresse email en cliquant le lien ci‑dessous :" #: bookwyrm/templates/email/confirm/html_content.html:11 -#, fuzzy -#| msgid "Confirm" msgid "Confirm Email" -msgstr "Confirmer" +msgstr "Confirmation de l’email" #: bookwyrm/templates/email/confirm/subject.html:2 msgid "Please confirm your email" -msgstr "" +msgstr "Veuillez confirmer votre adresse email" #: bookwyrm/templates/email/html_layout.html:15 #: bookwyrm/templates/email/text_layout.html:2 @@ -1564,7 +1554,7 @@ msgstr "Connexion" #: bookwyrm/templates/login.html:16 msgid "Success! Email address confirmed." -msgstr "" +msgstr "Bravo ! L’adresse email a été confirmée." #: bookwyrm/templates/login.html:28 bookwyrm/templates/password_reset.html:17 #: bookwyrm/templates/snippets/register_form.html:22 @@ -2397,11 +2387,11 @@ msgstr "Autoriser les demandes d’invitation" #: bookwyrm/templates/settings/site.html:97 msgid "Require users to confirm email address" -msgstr "" +msgstr "Demander aux utilisateurs et utilisatrices de confirmer leur adresse email" #: bookwyrm/templates/settings/site.html:99 msgid "(Recommended if registration is open)" -msgstr "" +msgstr "(Recommandé si les inscriptions sont ouvertes)" #: bookwyrm/templates/settings/site.html:102 msgid "Registration closed text:" From cce7d9a6484af4c203105e4c49fafe9de5ba0591 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 7 Aug 2021 10:59:55 -0700 Subject: [PATCH 34/75] Don't skip updates statuses when adding to streams Generated note books are added post-initial save --- bookwyrm/activitystreams.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/bookwyrm/activitystreams.py b/bookwyrm/activitystreams.py index 66dcad84e..754b4b159 100644 --- a/bookwyrm/activitystreams.py +++ b/bookwyrm/activitystreams.py @@ -260,9 +260,6 @@ def add_status_on_create(sender, instance, created, *args, **kwargs): stream.remove_object_from_related_stores(instance) return - if not created: - return - for stream in streams.values(): stream.add_status(instance) From 040758c833ea4670aa955f676091ae5564a396da Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 7 Aug 2021 11:15:02 -0700 Subject: [PATCH 35/75] Renames "discover" --- .../{discover => landing}/about.html | 2 +- .../discover.html => landing/landing.html} | 14 +++++------ .../{discover => landing}/landing_layout.html | 0 .../{discover => landing}/large-book.html | 0 .../{discover => landing}/small-book.html | 1 - bookwyrm/tests/views/test_landing.py | 4 ++-- bookwyrm/views/__init__.py | 3 ++- bookwyrm/views/discover.py | 23 +++++++++++++++++++ bookwyrm/views/helpers.py | 4 ++-- bookwyrm/views/landing.py | 14 +++++------ 10 files changed, 44 insertions(+), 21 deletions(-) rename bookwyrm/templates/{discover => landing}/about.html (95%) rename bookwyrm/templates/{discover/discover.html => landing/landing.html} (72%) rename bookwyrm/templates/{discover => landing}/landing_layout.html (100%) rename bookwyrm/templates/{discover => landing}/large-book.html (100%) rename bookwyrm/templates/{discover => landing}/small-book.html (99%) create mode 100644 bookwyrm/views/discover.py diff --git a/bookwyrm/templates/discover/about.html b/bookwyrm/templates/landing/about.html similarity index 95% rename from bookwyrm/templates/discover/about.html rename to bookwyrm/templates/landing/about.html index a6f3a026a..dd7036c4f 100644 --- a/bookwyrm/templates/discover/about.html +++ b/bookwyrm/templates/landing/about.html @@ -1,4 +1,4 @@ -{% extends 'discover/landing_layout.html' %} +{% extends 'landing/landing_layout.html' %} {% load i18n %} {% block panel %} diff --git a/bookwyrm/templates/discover/discover.html b/bookwyrm/templates/landing/landing.html similarity index 72% rename from bookwyrm/templates/discover/discover.html rename to bookwyrm/templates/landing/landing.html index d553c3680..38180c3bf 100644 --- a/bookwyrm/templates/discover/discover.html +++ b/bookwyrm/templates/landing/landing.html @@ -1,4 +1,4 @@ -{% extends 'discover/landing_layout.html' %} +{% extends 'landing/landing_layout.html' %} {% load i18n %} {% block panel %} @@ -10,18 +10,18 @@
- {% include 'discover/large-book.html' with book=books.0 %} + {% include 'landing/large-book.html' with book=books.0 %}
- {% include 'discover/small-book.html' with book=books.1 %} + {% include 'landing/small-book.html' with book=books.1 %}
- {% include 'discover/small-book.html' with book=books.2 %} + {% include 'landing/small-book.html' with book=books.2 %}
@@ -30,18 +30,18 @@
- {% include 'discover/small-book.html' with book=books.3 %} + {% include 'landing/small-book.html' with book=books.3 %}
- {% include 'discover/small-book.html' with book=books.4 %} + {% include 'landing/small-book.html' with book=books.4 %}
- {% include 'discover/large-book.html' with book=books.5 %} + {% include 'landing/large-book.html' with book=books.5 %}
diff --git a/bookwyrm/templates/discover/landing_layout.html b/bookwyrm/templates/landing/landing_layout.html similarity index 100% rename from bookwyrm/templates/discover/landing_layout.html rename to bookwyrm/templates/landing/landing_layout.html diff --git a/bookwyrm/templates/discover/large-book.html b/bookwyrm/templates/landing/large-book.html similarity index 100% rename from bookwyrm/templates/discover/large-book.html rename to bookwyrm/templates/landing/large-book.html diff --git a/bookwyrm/templates/discover/small-book.html b/bookwyrm/templates/landing/small-book.html similarity index 99% rename from bookwyrm/templates/discover/small-book.html rename to bookwyrm/templates/landing/small-book.html index 73133de45..3f7cbecc3 100644 --- a/bookwyrm/templates/discover/small-book.html +++ b/bookwyrm/templates/landing/small-book.html @@ -1,4 +1,3 @@ - {% load bookwyrm_tags %} {% load i18n %} diff --git a/bookwyrm/tests/views/test_landing.py b/bookwyrm/tests/views/test_landing.py index 4d1531e45..476da74b1 100644 --- a/bookwyrm/tests/views/test_landing.py +++ b/bookwyrm/tests/views/test_landing.py @@ -54,9 +54,9 @@ class LandingViews(TestCase): result.render() self.assertEqual(result.status_code, 200) - def test_discover(self): + def test_landing(self): """there are so many views, this just makes sure it LOADS""" - view = views.Discover.as_view() + view = views.Landing.as_view() request = self.factory.get("") result = view(request) self.assertIsInstance(result, TemplateResponse) diff --git a/bookwyrm/views/__init__.py b/bookwyrm/views/__init__.py index eccb7f5e5..15b55accb 100644 --- a/bookwyrm/views/__init__.py +++ b/bookwyrm/views/__init__.py @@ -7,6 +7,7 @@ from .block import Block, unblock from .books import Book, EditBook, ConfirmEditBook, Editions from .books import upload_cover, add_description, switch_edition, resolve_book from .directory import Directory +from .discover import Discover from .edit_user import EditUser, DeleteUser from .federation import Federation, FederatedServer from .federation import AddFederatedServer, ImportServerBlocklist @@ -22,7 +23,7 @@ from .interaction import Favorite, Unfavorite, Boost, Unboost from .invite import ManageInvites, Invite, InviteRequest from .invite import ManageInviteRequests, ignore_invite_request from .isbn import Isbn -from .landing import About, Home, Discover +from .landing import About, Home, Landing from .list import Lists, List, Curate, UserLists from .notifications import Notifications from .outbox import Outbox diff --git a/bookwyrm/views/discover.py b/bookwyrm/views/discover.py new file mode 100644 index 000000000..9bef6974d --- /dev/null +++ b/bookwyrm/views/discover.py @@ -0,0 +1,23 @@ +""" What's up locally """ +from django.contrib.auth.decorators import login_required +from django.template.response import TemplateResponse +from django.utils.decorators import method_decorator +from django.views import View + +from bookwyrm import forms +from . import helpers + + +# pylint: disable= no-self-use +@method_decorator(login_required, name="dispatch") +class Discover(View): + """preview of recently reviewed books""" + + def get(self, request): + """tiled book activity page""" + data = { + "register_form": forms.RegisterForm(), + "request_form": forms.InviteRequestForm(), + "books": helpers.get_landing_books(), + } + return TemplateResponse(request, "landing/landing.html", data) diff --git a/bookwyrm/views/helpers.py b/bookwyrm/views/helpers.py index 42aa48f0e..f757cec95 100644 --- a/bookwyrm/views/helpers.py +++ b/bookwyrm/views/helpers.py @@ -162,8 +162,8 @@ def is_blocked(viewer, user): return False -def get_discover_books(): - """list of books for the discover page""" +def get_landing_books(): + """list of books for the landing page""" return list( set( models.Edition.objects.filter( diff --git a/bookwyrm/views/landing.py b/bookwyrm/views/landing.py index 1361935ee..6f480b70f 100644 --- a/bookwyrm/views/landing.py +++ b/bookwyrm/views/landing.py @@ -13,22 +13,22 @@ class About(View): def get(self, request): """more information about the instance""" - return TemplateResponse(request, "discover/about.html") + return TemplateResponse(request, "landing/about.html") class Home(View): - """discover page or home feed depending on auth""" + """landing page or home feed depending on auth""" def get(self, request): """this is the same as the feed on the home tab""" if request.user.is_authenticated: feed_view = Feed.as_view() return feed_view(request, "home") - discover_view = Discover.as_view() - return discover_view(request) + landing_view = Landing.as_view() + return landing_view(request) -class Discover(View): +class Landing(View): """preview of recently reviewed books""" def get(self, request): @@ -36,6 +36,6 @@ class Discover(View): data = { "register_form": forms.RegisterForm(), "request_form": forms.InviteRequestForm(), - "books": helpers.get_discover_books(), + "books": helpers.get_landing_books(), } - return TemplateResponse(request, "discover/discover.html", data) + return TemplateResponse(request, "landing/landing.html", data) From b5153f3df12a96010fc35c852a47a0a6f0956876 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 7 Aug 2021 12:33:45 -0700 Subject: [PATCH 36/75] WIP --- bookwyrm/templates/discover/discover.html | 54 +++++++++++++++++++++ bookwyrm/templates/discover/large-book.html | 38 +++++++++++++++ bookwyrm/templates/discover/small-book.html | 41 ++++++++++++++++ bookwyrm/templates/landing/large-book.html | 2 +- bookwyrm/templates/landing/small-book.html | 2 +- bookwyrm/views/discover.py | 25 +++++++--- 6 files changed, 154 insertions(+), 8 deletions(-) create mode 100644 bookwyrm/templates/discover/discover.html create mode 100644 bookwyrm/templates/discover/large-book.html create mode 100644 bookwyrm/templates/discover/small-book.html diff --git a/bookwyrm/templates/discover/discover.html b/bookwyrm/templates/discover/discover.html new file mode 100644 index 000000000..0a419e51b --- /dev/null +++ b/bookwyrm/templates/discover/discover.html @@ -0,0 +1,54 @@ +{% extends "layout.html" %} +{% load i18n %} + +{% block title %}{% trans "Discover" %}{% endblock %} + +{% block content %} + +
+

{% trans "Discover" %}

+
+ +
+
+
+
+ {% include 'discover/large-book.html' with status=large.0 %} +
+
+
+
+
+ {% include 'discover/small-book.html' with status=small.0 %} +
+
+
+
+ {% include 'discover/small-book.html' with status=small.1 %} +
+
+
+
+
+
+
+
+ {% include 'discover/small-book.html' with status=small.2 %} +
+
+
+
+ {% include 'discover/small-book.html' with status=small.3 %} +
+
+
+
+
+ {% include 'discover/large-book.html' with status=large.1 %} +
+
+
+
+ + +{% endblock %} diff --git a/bookwyrm/templates/discover/large-book.html b/bookwyrm/templates/discover/large-book.html new file mode 100644 index 000000000..b273d4318 --- /dev/null +++ b/bookwyrm/templates/discover/large-book.html @@ -0,0 +1,38 @@ +{% load bookwyrm_tags %} +{% load markdown %} +{% load i18n %} + +{% if book %} + {% with book=book %} +
+
+ {% include 'snippets/book_cover.html' with cover_class='is-w-l-mobile is-w-auto-tablet' %} + + {% include 'snippets/stars.html' with rating=book|rating:request.user %} +
+ + +
+

+ {{ book.title }} +

+ + {% if book.authors %} +

+ {% trans "by" %} + {% include 'snippets/authors.html' with limit=3 %} +

+ {% endif %} + + {% if book|book_description %} +
+ {{ book|book_description|to_markdown|safe|truncatewords_html:50 }} +
+ {% endif %} +
+
+ {% endwith %} +{% endif %} diff --git a/bookwyrm/templates/discover/small-book.html b/bookwyrm/templates/discover/small-book.html new file mode 100644 index 000000000..052a540cf --- /dev/null +++ b/bookwyrm/templates/discover/small-book.html @@ -0,0 +1,41 @@ +{% load bookwyrm_tags %} +{% load utilities %} +{% load i18n %} + +{% if status %} + {% with book=status.book %} + + {% include 'snippets/book_cover.html' with cover_class='is-w-l-mobile is-h-l-tablet is-w-auto align to-b to-l' %} + + + {% include 'snippets/stars.html' with rating=book|rating:request.user %} + +

+ {{ book.title }} +

+ + {% if book.authors %} +

+ {% trans "by" %} + {% include 'snippets/authors.html' with limit=3 %} +

+ {% endif %} + + + + {% endwith %} +{% endif %} diff --git a/bookwyrm/templates/landing/large-book.html b/bookwyrm/templates/landing/large-book.html index 93026991e..b273d4318 100644 --- a/bookwyrm/templates/landing/large-book.html +++ b/bookwyrm/templates/landing/large-book.html @@ -23,7 +23,7 @@ {% if book.authors %}

{% trans "by" %} - {% include 'snippets/authors.html' %} + {% include 'snippets/authors.html' with limit=3 %}

{% endif %} diff --git a/bookwyrm/templates/landing/small-book.html b/bookwyrm/templates/landing/small-book.html index 3f7cbecc3..2ca505d94 100644 --- a/bookwyrm/templates/landing/small-book.html +++ b/bookwyrm/templates/landing/small-book.html @@ -16,7 +16,7 @@ {% if book.authors %}

{% trans "by" %} - {% include 'snippets/authors.html' %} + {% include 'snippets/authors.html' with limit=3 %}

{% endif %} {% endwith %} diff --git a/bookwyrm/views/discover.py b/bookwyrm/views/discover.py index 9bef6974d..685a4ded7 100644 --- a/bookwyrm/views/discover.py +++ b/bookwyrm/views/discover.py @@ -1,11 +1,14 @@ """ What's up locally """ from django.contrib.auth.decorators import login_required +from django.core.paginator import Paginator +from django.db.models import Q from django.template.response import TemplateResponse from django.utils.decorators import method_decorator from django.views import View -from bookwyrm import forms -from . import helpers +from bookwyrm import models +from bookwyrm.settings import PAGE_LENGTH +from .helpers import privacy_filter # pylint: disable= no-self-use @@ -15,9 +18,19 @@ class Discover(View): def get(self, request): """tiled book activity page""" + activities = privacy_filter( + request.user, + models.Status.objects.select_subclasses().filter( + Q(comment__isnull=False) + | Q(review__isnull=False) + | Q(quotation__isnull=False), + user__local=True + ), + #privacy_levels=["public"] + ) + #paginated = Paginator(activities, PAGE_LENGTH) data = { - "register_form": forms.RegisterForm(), - "request_form": forms.InviteRequestForm(), - "books": helpers.get_landing_books(), + "large": activities.filter(~Q(review__isnull=True, review__content=None))[:2], + "small": activities.filter(~Q(content=None))[:4], } - return TemplateResponse(request, "landing/landing.html", data) + return TemplateResponse(request, "discover/discover.html", data) From 06c5ae06a6aec5422d830a43dd85db0e1734ec52 Mon Sep 17 00:00:00 2001 From: Fabien Basmaison Date: Sat, 7 Aug 2021 21:47:30 +0200 Subject: [PATCH 37/75] [french] Compile French locale. --- locale/fr_FR/LC_MESSAGES/django.mo | Bin 45471 -> 46960 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/locale/fr_FR/LC_MESSAGES/django.mo b/locale/fr_FR/LC_MESSAGES/django.mo index f8ade2a391ba574da54afa6f45e1bf1ad55f9372..98bc29095737fda2d84bcd909167dd90097fb8e7 100644 GIT binary patch delta 14975 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 Sa}roL_b-fR+$^^^NCW_!G=i!C From e3cbf306847b55cdc04875b335f11271f6857143 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 7 Aug 2021 14:38:19 -0700 Subject: [PATCH 38/75] Local discovery view --- bookwyrm/templates/discover/discover.html | 87 +++++++++++++------ bookwyrm/templates/discover/large-book.html | 66 ++++++++++---- bookwyrm/templates/discover/small-book.html | 43 +++++---- .../templates/snippets/follow_button.html | 20 ++++- bookwyrm/views/discover.py | 18 ++-- 5 files changed, 166 insertions(+), 68 deletions(-) diff --git a/bookwyrm/templates/discover/discover.html b/bookwyrm/templates/discover/discover.html index 0a419e51b..01ef21869 100644 --- a/bookwyrm/templates/discover/discover.html +++ b/bookwyrm/templates/discover/discover.html @@ -5,50 +5,85 @@ {% block content %} -
-

{% trans "Discover" %}

-
+
+
+

{% trans "Discover" %}

+

+ {% blocktrans trimmed with site_name=site.name %} + See what's new in the local {{ site_name }} community + {% endblocktrans %} +

+
-
-
-
+
+
- {% include 'discover/large-book.html' with status=large.0 %} + {% include 'discover/large-book.html' with status=large_activities.0 %}
-
-
+
+
+ {% include 'discover/large-book.html' with status=large_activities.1 %} +
+
+
+ +
+
+
- {% include 'discover/small-book.html' with status=small.0 %} + {% include 'discover/large-book.html' with status=large_activities.2 %}
-
+
+
+
+ {% include 'discover/small-book.html' with status=small_activities.0 %} +
+
+
+
+ {% include 'discover/small-book.html' with status=small_activities.1 %} +
+
+
+
+
+
+
+
+ {% include 'discover/small-book.html' with status=small_activities.2 %} +
+
+
+
+ {% include 'discover/small-book.html' with status=small_activities.3 %} +
+
+
+
- {% include 'discover/small-book.html' with status=small.1 %} + {% include 'discover/large-book.html' with status=large_activities.3 %}
-
-
-
-
- {% include 'discover/small-book.html' with status=small.2 %} -
-
-
-
- {% include 'discover/small-book.html' with status=small.3 %} -
+ +
+
+
+ {% include 'discover/large-book.html' with status=large_activities.4 %}
-
+
- {% include 'discover/large-book.html' with status=large.1 %} + {% include 'discover/large-book.html' with status=large_activities.5 %}
- +
+ {% include 'snippets/pagination.html' with page=large_activities %} +
{% endblock %} diff --git a/bookwyrm/templates/discover/large-book.html b/bookwyrm/templates/discover/large-book.html index b273d4318..81620be1c 100644 --- a/bookwyrm/templates/discover/large-book.html +++ b/bookwyrm/templates/discover/large-book.html @@ -1,37 +1,67 @@ {% load bookwyrm_tags %} -{% load markdown %} {% load i18n %} -{% if book %} - {% with book=book %} +{% if status %} + {% with book=status.book %}
-
+
{% include 'snippets/book_cover.html' with cover_class='is-w-l-mobile is-w-auto-tablet' %} {% include 'snippets/stars.html' with rating=book|rating:request.user %} -
- - -
-

+

{{ book.title }}

{% if book.authors %} -

- {% trans "by" %} - {% include 'snippets/authors.html' with limit=3 %} -

+

+ {% trans "by" %} + {% include 'snippets/authors.html' with limit=3 %} +

{% endif %} - {% if book|book_description %} -
- {{ book|book_description|to_markdown|safe|truncatewords_html:50 }} -
- {% endif %} + {% include 'snippets/shelve_button/shelve_button.html' %} +
+ +
+
+ +
+

+ + {{ status.user.display_name }} + + + {% if status.status_type == 'GeneratedNote' %} + {{ status.content|safe }} + {% elif status.status_type == 'Rating' %} + {% trans "rated" %} + {% elif status.status_type == 'Review' %} + {% trans "reviewed" %} + {% elif status.status_type == 'Comment' %} + {% trans "commented on" %} + {% elif status.status_type == 'Quotation' %} + {% trans "quoted" %} + {% endif %} + + {{ book.title }} +

+
+
+ +
+ {% include 'snippets/follow_button.html' with user=status.user show_username=True minimal=True %} +
+ +
+ {% include "snippets/status/content_status.html" with hide_book=True %} +
{% endwith %} diff --git a/bookwyrm/templates/discover/small-book.html b/bookwyrm/templates/discover/small-book.html index 052a540cf..1318c8bdc 100644 --- a/bookwyrm/templates/discover/small-book.html +++ b/bookwyrm/templates/discover/small-book.html @@ -5,23 +5,14 @@ {% if status %} {% with book=status.book %} - {% include 'snippets/book_cover.html' with cover_class='is-w-l-mobile is-h-l-tablet is-w-auto align to-b to-l' %} + {% include 'snippets/book_cover.html' with cover_class='is-w-l-mobile is-w-auto align to-b to-l' %} - {% include 'snippets/stars.html' with rating=book|rating:request.user %} +
+ {% include 'snippets/shelve_button/shelve_button.html' %} +
-

- {{ book.title }} -

- - {% if book.authors %} -

- {% trans "by" %} - {% include 'snippets/authors.html' with limit=3 %} -

- {% endif %} - -
+
-

+

{{ status.user.display_name }} + + {% if status.status_type == 'GeneratedNote' %} + {{ status.content|safe }} + {% elif status.status_type == 'Rating' %} + {% trans "rated" %} + {% elif status.status_type == 'Review' %} + {% trans "reviewed" %} + {% elif status.status_type == 'Comment' %} + {% trans "commented on" %} + {% elif status.status_type == 'Quotation' %} + {% trans "quoted" %} + {% endif %} + + {{ book.title }}

+ {% if status.rating %} +

+ {% include 'snippets/stars.html' with rating=status.rating %} +

+ {% endif %}
+
+ {% include 'snippets/follow_button.html' with user=status.user show_username=True minimal=True %} +
{% endwith %} {% endif %} diff --git a/bookwyrm/templates/snippets/follow_button.html b/bookwyrm/templates/snippets/follow_button.html index 0cbe6b8cd..8cafad7f9 100644 --- a/bookwyrm/templates/snippets/follow_button.html +++ b/bookwyrm/templates/snippets/follow_button.html @@ -9,15 +9,29 @@ {% csrf_token %} - +
diff --git a/bookwyrm/views/discover.py b/bookwyrm/views/discover.py index 685a4ded7..0b1fae2b5 100644 --- a/bookwyrm/views/discover.py +++ b/bookwyrm/views/discover.py @@ -7,7 +7,6 @@ from django.utils.decorators import method_decorator from django.views import View from bookwyrm import models -from bookwyrm.settings import PAGE_LENGTH from .helpers import privacy_filter @@ -24,13 +23,20 @@ class Discover(View): Q(comment__isnull=False) | Q(review__isnull=False) | Q(quotation__isnull=False), - user__local=True + user__local=True, ), - #privacy_levels=["public"] + privacy_levels=["public"], ) - #paginated = Paginator(activities, PAGE_LENGTH) + large_activities = Paginator( + activities.filter(~Q(content=None), ~Q(content="")), 6 + ) + small_activities = Paginator( + activities.filter(Q(content=None) | Q(content="")), 4 + ) + + page = request.GET.get("page") data = { - "large": activities.filter(~Q(review__isnull=True, review__content=None))[:2], - "small": activities.filter(~Q(content=None))[:4], + "large_activities": large_activities.get_page(page), + "small_activities": small_activities.get_page(page), } return TemplateResponse(request, "discover/discover.html", data) From 2eb37663b6a032aac0b2bf227c4e3f8230cf71f6 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 7 Aug 2021 14:46:33 -0700 Subject: [PATCH 39/75] Adds mock to inbox test --- bookwyrm/tests/views/inbox/test_inbox_create.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bookwyrm/tests/views/inbox/test_inbox_create.py b/bookwyrm/tests/views/inbox/test_inbox_create.py index f93354bfb..6e8917238 100644 --- a/bookwyrm/tests/views/inbox/test_inbox_create.py +++ b/bookwyrm/tests/views/inbox/test_inbox_create.py @@ -47,7 +47,8 @@ class InboxCreate(TestCase): } models.SiteSettings.objects.create() - def test_create_status(self, _): + @patch("bookwyrm.activitystreams.ActivityStream.add_status") + def test_create_status(self, *_): """the "it justs works" mode""" datafile = pathlib.Path(__file__).parent.joinpath( "../../data/ap_quotation.json" From 760bd5a63fb51671f945bcb2f614eca41240d574 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 7 Aug 2021 15:10:09 -0700 Subject: [PATCH 40/75] Fixes reference to landing page books --- bookwyrm/management/commands/populate_streams.py | 2 +- bookwyrm/views/invite.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bookwyrm/management/commands/populate_streams.py b/bookwyrm/management/commands/populate_streams.py index f8aa21a52..37559f082 100644 --- a/bookwyrm/management/commands/populate_streams.py +++ b/bookwyrm/management/commands/populate_streams.py @@ -8,7 +8,7 @@ def populate_streams(): users = models.User.objects.filter( local=True, is_active=True, - ) + ).order_by("last_active_date") for user in users: for stream in activitystreams.streams.values(): stream.populate_streams(user) diff --git a/bookwyrm/views/invite.py b/bookwyrm/views/invite.py index 3b9fd17c5..005d57cf8 100644 --- a/bookwyrm/views/invite.py +++ b/bookwyrm/views/invite.py @@ -170,9 +170,9 @@ class InviteRequest(View): data = { "request_form": form, "request_received": received, - "books": helpers.get_discover_books(), + "books": helpers.get_landing_books(), } - return TemplateResponse(request, "discover/discover.html", data) + return TemplateResponse(request, "landing/landing.html", data) @require_POST From 1006096cd06cc861c1ad5e0283f699f75f9869df Mon Sep 17 00:00:00 2001 From: Justin Abrahms Date: Sat, 7 Aug 2021 15:40:50 -0700 Subject: [PATCH 41/75] Close the span tag for an author. --- bookwyrm/templates/snippets/authors.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/templates/snippets/authors.html b/bookwyrm/templates/snippets/authors.html index 5584417d9..81aaa138b 100644 --- a/bookwyrm/templates/snippets/authors.html +++ b/bookwyrm/templates/snippets/authors.html @@ -19,7 +19,7 @@ itemtype="https://schema.org/Thing" >{{ author.name }}{% if not forloop.last %}, {% elif remainder_count > 0 %}, {% blocktrans trimmed count counter=remainder_count %} + >{{ author.name }}{% if not forloop.last %}, {% elif remainder_count > 0 %}, {% blocktrans trimmed count counter=remainder_count %} and {{ remainder_count_display }} other {% plural %} and {{ remainder_count_display }} others From 650a6037a29abb2c47e0084fc91c29594fe61f7b Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 7 Aug 2021 15:51:53 -0700 Subject: [PATCH 42/75] Trims status text --- bookwyrm/templates/discover/large-book.html | 9 +++++++-- bookwyrm/templates/snippets/trimmed_text.html | 7 ++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/bookwyrm/templates/discover/large-book.html b/bookwyrm/templates/discover/large-book.html index 81620be1c..fdea582d8 100644 --- a/bookwyrm/templates/discover/large-book.html +++ b/bookwyrm/templates/discover/large-book.html @@ -1,5 +1,6 @@ {% load bookwyrm_tags %} {% load i18n %} +{% load status_display %} {% if status %} {% with book=status.book %} @@ -59,9 +60,13 @@ {% include 'snippets/follow_button.html' with user=status.user show_username=True minimal=True %}
-
- {% include "snippets/status/content_status.html" with hide_book=True %} +
+ {% include "snippets/status/content_status.html" with hide_book=True trim_length=100 hide_more=True %}
+ + {% trans "View status" %} + +
{% endwith %} diff --git a/bookwyrm/templates/snippets/trimmed_text.html b/bookwyrm/templates/snippets/trimmed_text.html index cfffe0551..f6174a192 100644 --- a/bookwyrm/templates/snippets/trimmed_text.html +++ b/bookwyrm/templates/snippets/trimmed_text.html @@ -3,20 +3,24 @@ {% load i18n %} {% with 0|uuid as uuid %} +{% firstof trim_length 150 as trim_length %} {% if full %} {% with full|to_markdown|safe as full %} - {% with full|to_markdown|safe|truncatewords_html:150 as trimmed %} + {% with full|to_markdown|safe|truncatewords_html:trim_length as trimmed %} {% if not no_trim and trimmed != full %}
{{ trimmed }}
+ {% if not hide_more %} {% trans "Show more" as button_text %} {% include 'snippets/toggle/open_button.html' with text=button_text controls_text="full" controls_uid=uuid class="is-small" %} + {% endif %}
+ {% if not hide_more %}