From c3c22022f604ec1c934aaf60d4536beaebfdc7be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adeodato=20Sim=C3=B3?= Date: Mon, 9 Oct 2023 20:54:06 -0300 Subject: [PATCH 01/28] Check for punctuation before checking for wrapping parenthesis This allows to parse `(URL).` correctly, which was not detected as URL before. --- bookwyrm/tests/views/test_status.py | 9 +++++++++ bookwyrm/views/status.py | 12 +++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/bookwyrm/tests/views/test_status.py b/bookwyrm/tests/views/test_status.py index 33bd8b53a..6e630a370 100644 --- a/bookwyrm/tests/views/test_status.py +++ b/bookwyrm/tests/views/test_status.py @@ -436,6 +436,15 @@ http://www.fish.com/""" f'www.fish.com/.', ) + def test_format_links_punctuation_parens(self, *_): + """ignore trailing punctuation and brackets combined""" + # Period at the end, wrapped in brackets. + url = "http://www.fish.com" + self.assertEqual( + views.status.format_links(f"({url})."), + f'(www.fish.com).', + ) + def test_format_links_special_chars(self, *_): """find and format urls into a tags""" url = "https://archive.org/details/dli.granth.72113/page/n25/mode/2up" diff --git a/bookwyrm/views/status.py b/bookwyrm/views/status.py index 7a0517b01..196db4eb9 100644 --- a/bookwyrm/views/status.py +++ b/bookwyrm/views/status.py @@ -304,17 +304,19 @@ def format_links(content): for potential_link in split_content: if not potential_link: continue + + # FIXME: allow for multiple punctuation characters, e.g. `...` and `!?`. + ends_with_punctuation = _ends_with_punctuation(potential_link) + if ends_with_punctuation: + punctuation_glyph = potential_link[-1] + potential_link = potential_link[0:-1] + wrapped = _wrapped(potential_link) if wrapped: wrapper_close = potential_link[-1] formatted_content += potential_link[0] potential_link = potential_link[1:-1] - ends_with_punctuation = _ends_with_punctuation(potential_link) - if ends_with_punctuation: - punctuation_glyph = potential_link[-1] - potential_link = potential_link[0:-1] - try: # raises an error on anything that's not a valid link validator(potential_link) From 0043329cc189ec23390101a9e9055ed592a8db4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adeodato=20Sim=C3=B3?= Date: Mon, 9 Oct 2023 21:01:34 -0300 Subject: [PATCH 02/28] Simplify literals in _wrapped --- bookwyrm/views/status.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/views/status.py b/bookwyrm/views/status.py index 196db4eb9..bb8f6ac17 100644 --- a/bookwyrm/views/status.py +++ b/bookwyrm/views/status.py @@ -344,7 +344,7 @@ def format_links(content): def _wrapped(text): """check if a line of text is wrapped""" - wrappers = [("(", ")"), ("[", "]"), ("{", "}")] + wrappers = ["()", "[]", "{}"] for wrapper in wrappers: if text[0] == wrapper[0] and text[-1] == wrapper[-1]: return True From 17d741039c95e1a00272e3ed6ed1d3d219218daf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adeodato=20Sim=C3=B3?= Date: Mon, 9 Oct 2023 21:33:35 -0300 Subject: [PATCH 03/28] Remove duplicate test (Test case already part of test_format_links_simple_url.) --- bookwyrm/tests/views/test_status.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/bookwyrm/tests/views/test_status.py b/bookwyrm/tests/views/test_status.py index 6e630a370..42e83c5b8 100644 --- a/bookwyrm/tests/views/test_status.py +++ b/bookwyrm/tests/views/test_status.py @@ -420,14 +420,6 @@ http://www.fish.com/""" 'okay\n\nwww.fish.com/', ) - def test_format_links_parens(self, *_): - """find and format urls into a tags""" - url = "http://www.fish.com/" - self.assertEqual( - views.status.format_links(f"({url})"), - f'(www.fish.com/)', - ) - def test_format_links_punctuation(self, *_): """don’t take trailing punctuation into account pls""" url = "http://www.fish.com/" From 22554f85adbcd40cbdff0061f0ae4b40d2cebdcb Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 2 Nov 2023 14:37:14 -0700 Subject: [PATCH 04/28] Updates tour to reflect changes in #2201 --- bookwyrm/templates/guided_tour/home.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bookwyrm/templates/guided_tour/home.html b/bookwyrm/templates/guided_tour/home.html index be8d095af..250449153 100644 --- a/bookwyrm/templates/guided_tour/home.html +++ b/bookwyrm/templates/guided_tour/home.html @@ -99,7 +99,7 @@ homeTour.addSteps([ ], }, { - text: "{% trans 'Use the Feed, Lists and Discover links to discover the latest news from your feed, lists of books by topic, and the latest happenings on this Bookwyrm server!' %}", + text: "{% trans 'Use the Feed, Discover, and Your Books links to discover the latest news from your feed, the latest happenings on this Bookwyrm server, and see your catalogued books!' %}", title: "{% trans 'Navigation Bar' %}", attachTo: { element: checkResponsiveState('#tour-navbar-start'), @@ -197,7 +197,7 @@ homeTour.addSteps([ ], }, { - text: `{% trans "Your profile, books, direct messages, and settings can be accessed by clicking on your name in the menu here." %}

{% trans "Try selecting Profile from the drop down menu to continue the tour." %}

`, + text: `{% trans "Your profile, user directory, direct messages, and settings can be accessed by clicking on your name in the menu here." %}

{% trans "Try selecting Profile from the drop down menu to continue the tour." %}

`, title: "{% trans 'Profile and settings menu' %}", attachTo: { element: checkResponsiveState('#navbar-dropdown'), From e1217f20542df1fdab10f95a96b539f58a953a5f Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 2 Nov 2023 15:04:03 -0700 Subject: [PATCH 05/28] Don't show notification for user follow request if the user is inactive --- bookwyrm/templates/notifications/item.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bookwyrm/templates/notifications/item.html b/bookwyrm/templates/notifications/item.html index bac7dc61f..7e7f0da27 100644 --- a/bookwyrm/templates/notifications/item.html +++ b/bookwyrm/templates/notifications/item.html @@ -10,7 +10,9 @@ {% elif notification.notification_type == 'FOLLOW' %} {% include 'notifications/items/follow.html' %} {% elif notification.notification_type == 'FOLLOW_REQUEST' %} - {% include 'notifications/items/follow_request.html' %} + {% if notification.related_users.0.is_active %} + {% include 'notifications/items/follow_request.html' %} + {% endif %} {% elif notification.notification_type == 'IMPORT' %} {% include 'notifications/items/import.html' %} {% elif notification.notification_type == 'ADD' %} From 285c513211da7fef58c6f333ec80ea6566ecebc6 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 2 Nov 2023 19:01:40 -0700 Subject: [PATCH 06/28] Adds test for invalid isbns and handle isbns with dashes --- bookwyrm/isbn/isbn.py | 7 ++++++- bookwyrm/tests/test_isbn.py | 7 +++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/bookwyrm/isbn/isbn.py b/bookwyrm/isbn/isbn.py index 4cc7f47dd..56062ff7b 100644 --- a/bookwyrm/isbn/isbn.py +++ b/bookwyrm/isbn/isbn.py @@ -40,7 +40,12 @@ class IsbnHyphenator: self.__element_tree = ElementTree.parse(self.__range_file_path) gs1_prefix = isbn_13[:3] - reg_group = self.__find_reg_group(isbn_13, gs1_prefix) + try: + reg_group = self.__find_reg_group(isbn_13, gs1_prefix) + except ValueError: + # if the reg groups are invalid, just return the original isbn + return isbn_13 + if reg_group is None: return isbn_13 # failed to hyphenate diff --git a/bookwyrm/tests/test_isbn.py b/bookwyrm/tests/test_isbn.py index b528e9210..5486c7151 100644 --- a/bookwyrm/tests/test_isbn.py +++ b/bookwyrm/tests/test_isbn.py @@ -29,3 +29,10 @@ class TestISBN(TestCase): self.assertEqual(hyphenator.hyphenate("9786769533251"), "9786769533251") # 979-8 (United States) 2300000-3499999 (unassigned) self.assertEqual(hyphenator.hyphenate("9798311111111"), "9798311111111") + + def test_isbn_hyphenation_invalid_data(self): + """Make sure not to throw an error when a bad ISBN is found""" + # no action taken + self.assertEqual(hyphenator.hyphenate("978-0-4633461-1-2"), "978-0-4633461-1-2") + self.assertEqual(hyphenator.hyphenate("9-0-4633461-1-2"), "9-0-4633461-1-2") + self.assertEqual(hyphenator.hyphenate("90463346112"), "90463346112") From f839038c8f4d364f0951c38205b93731f8ebb3ef Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 2 Nov 2023 19:12:17 -0700 Subject: [PATCH 07/28] Add test for normalizing isbns in book model Turns out this was actually working as expected --- bookwyrm/models/book.py | 9 +++++++-- bookwyrm/tests/models/test_book_model.py | 6 +++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/bookwyrm/models/book.py b/bookwyrm/models/book.py index 9e05c03af..ac317f644 100644 --- a/bookwyrm/models/book.py +++ b/bookwyrm/models/book.py @@ -366,9 +366,9 @@ class Edition(Book): # normalize isbn format if self.isbn_10: - self.isbn_10 = re.sub(r"[^0-9X]", "", self.isbn_10) + self.isbn_10 = normalize_isbn(self.isbn_10) if self.isbn_13: - self.isbn_13 = re.sub(r"[^0-9X]", "", self.isbn_13) + self.isbn_10 = normalize_isbn(self.isbn_13) # set rank self.edition_rank = self.get_rank() @@ -463,6 +463,11 @@ def isbn_13_to_10(isbn_13): return converted + str(checkdigit) +def normalize_isbn(isbn): + """Remove unexpected characters from ISBN 10 or 13""" + return re.sub(r"[^0-9X]", "", isbn) + + # pylint: disable=unused-argument @receiver(models.signals.post_save, sender=Edition) def preview_image(instance, *args, **kwargs): diff --git a/bookwyrm/tests/models/test_book_model.py b/bookwyrm/tests/models/test_book_model.py index 8122e9505..4347efcb6 100644 --- a/bookwyrm/tests/models/test_book_model.py +++ b/bookwyrm/tests/models/test_book_model.py @@ -11,7 +11,7 @@ from django.test import TestCase from django.utils import timezone from bookwyrm import models, settings -from bookwyrm.models.book import isbn_10_to_13, isbn_13_to_10 +from bookwyrm.models.book import isbn_10_to_13, isbn_13_to_10, normalize_isbn from bookwyrm.settings import ENABLE_THUMBNAIL_GENERATION @@ -72,6 +72,10 @@ class Book(TestCase): isbn_10 = isbn_13_to_10(isbn_13) self.assertEqual(isbn_10, "178816167X") + def test_normalize_isbn(self): + """Remove misc characters from ISBNs""" + self.assertEqual(normalize_isbn("978-0-4633461-1-2"), "9780463346112") + def test_get_edition_info(self): """text slug about an edition""" book = models.Edition.objects.create(title="Test Edition") From 116a838eef7cacb8c79f67e6083d53e1625d49a8 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 2 Nov 2023 19:37:58 -0700 Subject: [PATCH 08/28] Fixes typo that confuses isbn 10 and 13 --- bookwyrm/models/book.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/models/book.py b/bookwyrm/models/book.py index ac317f644..e5941136f 100644 --- a/bookwyrm/models/book.py +++ b/bookwyrm/models/book.py @@ -368,7 +368,7 @@ class Edition(Book): if self.isbn_10: self.isbn_10 = normalize_isbn(self.isbn_10) if self.isbn_13: - self.isbn_10 = normalize_isbn(self.isbn_13) + self.isbn_13 = normalize_isbn(self.isbn_13) # set rank self.edition_rank = self.get_rank() From 294788aa1ae2f10ffeae188177dfb96e9291a6d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adeodato=20Sim=C3=B3?= Date: Mon, 9 Oct 2023 21:41:22 -0300 Subject: [PATCH 09/28] format_links: refactor; support multiple punctuation --- bookwyrm/tests/views/test_status.py | 4 ++ bookwyrm/views/status.py | 71 ++++++++++------------------- 2 files changed, 28 insertions(+), 47 deletions(-) diff --git a/bookwyrm/tests/views/test_status.py b/bookwyrm/tests/views/test_status.py index 42e83c5b8..33c8f0e41 100644 --- a/bookwyrm/tests/views/test_status.py +++ b/bookwyrm/tests/views/test_status.py @@ -427,6 +427,10 @@ http://www.fish.com/""" views.status.format_links(f"{url}."), f'www.fish.com/.', ) + self.assertEqual( + views.status.format_links(f"{url}!?!"), + f'www.fish.com/!?!', + ) def test_format_links_punctuation_parens(self, *_): """ignore trailing punctuation and brackets combined""" diff --git a/bookwyrm/views/status.py b/bookwyrm/views/status.py index bb8f6ac17..4c1d049df 100644 --- a/bookwyrm/views/status.py +++ b/bookwyrm/views/status.py @@ -1,7 +1,6 @@ """ what are we here for if not for posting """ import re import logging -from urllib.parse import urlparse from django.contrib.auth.decorators import login_required from django.core.validators import URLValidator @@ -297,67 +296,45 @@ def find_or_create_hashtags(content): def format_links(content): """detect and format links""" - validator = URLValidator() - formatted_content = "" + validator = URLValidator(["http", "https"]) + schema_re = re.compile(r"\bhttps?://") split_content = re.split(r"(\s+)", content) - for potential_link in split_content: - if not potential_link: + for i, potential_link in enumerate(split_content): + if not schema_re.search(potential_link): continue - # FIXME: allow for multiple punctuation characters, e.g. `...` and `!?`. - ends_with_punctuation = _ends_with_punctuation(potential_link) - if ends_with_punctuation: - punctuation_glyph = potential_link[-1] - potential_link = potential_link[0:-1] - - wrapped = _wrapped(potential_link) - if wrapped: - wrapper_close = potential_link[-1] - formatted_content += potential_link[0] - potential_link = potential_link[1:-1] - + # Strip surrounding brackets and trailing punctuation. + prefix, potential_link, suffix = _unwrap(potential_link) try: # raises an error on anything that's not a valid link validator(potential_link) # use everything but the scheme in the presentation of the link - url = urlparse(potential_link) - link = url.netloc + url.path + url.params - if url.query != "": - link += "?" + url.query - if url.fragment != "": - link += "#" + url.fragment - - formatted_content += f'{link}' + link = schema_re.sub("", potential_link) + split_content[i] = f'{prefix}{link}{suffix}' except (ValidationError, UnicodeError): - formatted_content += potential_link + pass - if wrapped: - formatted_content += wrapper_close - - if ends_with_punctuation: - formatted_content += punctuation_glyph - - return formatted_content + return "".join(split_content) -def _wrapped(text): - """check if a line of text is wrapped""" - wrappers = ["()", "[]", "{}"] - for wrapper in wrappers: +def _unwrap(text): + """split surrounding brackets and trailing punctuation from a string of text""" + punct = re.compile(r'([.,;:!?"’”»]+)\Z') + prefix = suffix = "" + + if punct.search(text): + # Move punctuation to suffix segment. + text, suffix, _ = punct.split(text) + + for wrapper in ("()", "[]", "{}"): if text[0] == wrapper[0] and text[-1] == wrapper[-1]: - return True - return False + # Split out wrapping chars. + suffix = text[-1] + suffix + prefix, text = text[:1], text[1:-1] - -def _ends_with_punctuation(text): - """check if a line of text ends with a punctuation glyph""" - glyphs = [".", ",", ";", ":", "!", "?", "”", "’", '"', "»"] - for glyph in glyphs: - if text[-1] == glyph: - return True - return False + return prefix, text, suffix def to_markdown(content): From 7d13cbb10b45a8599e12aa9c379e1617d6e76f27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adeodato=20Sim=C3=B3?= Date: Thu, 2 Nov 2023 21:27:55 -0300 Subject: [PATCH 10/28] Add failing tests for reported bugs in format_links() --- bookwyrm/tests/views/test_status.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/bookwyrm/tests/views/test_status.py b/bookwyrm/tests/views/test_status.py index 33c8f0e41..67e1f6d76 100644 --- a/bookwyrm/tests/views/test_status.py +++ b/bookwyrm/tests/views/test_status.py @@ -469,6 +469,13 @@ http://www.fish.com/""" views.status.format_links(url), f'{url[8:]}' ) + def test_format_links_ignore_non_urls(self, *_): + """formating links should leave plain text untouced""" + text_elision = "> “The distinction is significant.” [...]" # bookwyrm#2993 + text_quoteparens = "some kind of gene-editing technology (?)" # bookwyrm#3049 + self.assertEqual(views.status.format_links(text_elision), text_elision) + self.assertEqual(views.status.format_links(text_quoteparens), text_quoteparens) + def test_format_mentions_with_at_symbol_links(self, *_): """A link with an @username shouldn't treat the username as a mention""" content = "a link to https://example.com/user/@mouse" From 954a02126eb21ca230319cd8ff62adf04d962de9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adeodato=20Sim=C3=B3?= Date: Thu, 2 Nov 2023 21:59:34 -0300 Subject: [PATCH 11/28] format_links: parse punctuation inside brackets Also, consolidate all punctuation tests into a single table-driven one. --- bookwyrm/tests/views/test_status.py | 37 ++++++++++++++--------------- bookwyrm/views/status.py | 6 +++++ 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/bookwyrm/tests/views/test_status.py b/bookwyrm/tests/views/test_status.py index 67e1f6d76..424698130 100644 --- a/bookwyrm/tests/views/test_status.py +++ b/bookwyrm/tests/views/test_status.py @@ -421,25 +421,24 @@ http://www.fish.com/""" ) def test_format_links_punctuation(self, *_): - """don’t take trailing punctuation into account pls""" - url = "http://www.fish.com/" - self.assertEqual( - views.status.format_links(f"{url}."), - f'www.fish.com/.', - ) - self.assertEqual( - views.status.format_links(f"{url}!?!"), - f'www.fish.com/!?!', - ) - - def test_format_links_punctuation_parens(self, *_): - """ignore trailing punctuation and brackets combined""" - # Period at the end, wrapped in brackets. - url = "http://www.fish.com" - self.assertEqual( - views.status.format_links(f"({url})."), - f'(www.fish.com).', - ) + """test many combinations of brackets, URLs, and punctuation""" + url = "https://bookwyrm.social" + html = f'bookwyrm.social' + test_table = [ + ("punct", f"text and {url}.", f"text and {html}."), + ("multi_punct", f"text, then {url}?...", f"text, then {html}?..."), + ("bracket_punct", f"here ({url}).", f"here ({html})."), + ("punct_bracket", f"there [{url}?]", f"there [{html}?]"), + ("punct_bracket_punct", f"not here? ({url}!).", f"not here? ({html}!)."), + ( + "multi_punct_bracket", + f"not there ({url}...);", + f"not there ({html}...);", + ), + ] + for desc, text, output in test_table: + with self.subTest(desc=desc): + self.assertEqual(views.status.format_links(text), output) def test_format_links_special_chars(self, *_): """find and format urls into a tags""" diff --git a/bookwyrm/views/status.py b/bookwyrm/views/status.py index 4c1d049df..8dab11a27 100644 --- a/bookwyrm/views/status.py +++ b/bookwyrm/views/status.py @@ -333,6 +333,12 @@ def _unwrap(text): # Split out wrapping chars. suffix = text[-1] + suffix prefix, text = text[:1], text[1:-1] + break # Nested wrappers not supported atm. + + if punct.search(text): + # Move inner punctuation to suffix segment. + text, inner_punct, _ = punct.split(text) + suffix = inner_punct + suffix return prefix, text, suffix From afad39bf80265f74de100cf3550924a7916d02a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adeodato=20Sim=C3=B3?= Date: Fri, 3 Nov 2023 19:31:03 -0300 Subject: [PATCH 12/28] Use $ instead of \Z for end of string They're identical here, since re.M is not used, and the better-known should be used, for readability. --- bookwyrm/views/status.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/views/status.py b/bookwyrm/views/status.py index 8dab11a27..34b62d0b4 100644 --- a/bookwyrm/views/status.py +++ b/bookwyrm/views/status.py @@ -321,7 +321,7 @@ def format_links(content): def _unwrap(text): """split surrounding brackets and trailing punctuation from a string of text""" - punct = re.compile(r'([.,;:!?"’”»]+)\Z') + punct = re.compile(r'([.,;:!?"’”»]+)$') prefix = suffix = "" if punct.search(text): From 7104e775d8bf0307766354369df6b5725d5431bd Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 5 Nov 2023 06:36:43 -0800 Subject: [PATCH 13/28] Updates working of header tour --- bookwyrm/templates/guided_tour/home.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/templates/guided_tour/home.html b/bookwyrm/templates/guided_tour/home.html index 250449153..a464206ef 100644 --- a/bookwyrm/templates/guided_tour/home.html +++ b/bookwyrm/templates/guided_tour/home.html @@ -99,7 +99,7 @@ homeTour.addSteps([ ], }, { - text: "{% trans 'Use the Feed, Discover, and Your Books links to discover the latest news from your feed, the latest happenings on this Bookwyrm server, and see your catalogued books!' %}", + text: "{% trans 'Use the Lists, Discover, and Your Books links to discover reading suggestions and the latest happenings on this server, or to see your catalogued books!' %}", title: "{% trans 'Navigation Bar' %}", attachTo: { element: checkResponsiveState('#tour-navbar-start'), From 10e0f2224aab59b41410725ca9c7691f95302073 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 5 Nov 2023 06:44:39 -0800 Subject: [PATCH 14/28] Adds a couple more tests for find_existing --- .../tests/models/test_activitypub_mixin.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/bookwyrm/tests/models/test_activitypub_mixin.py b/bookwyrm/tests/models/test_activitypub_mixin.py index a465c2c12..645a6546b 100644 --- a/bookwyrm/tests/models/test_activitypub_mixin.py +++ b/bookwyrm/tests/models/test_activitypub_mixin.py @@ -119,6 +119,25 @@ class ActivitypubMixins(TestCase): result = models.Edition.find_existing({"openlibraryKey": "OL1234"}) self.assertEqual(result, book) + def test_find_existing_with_id(self, *_): + """make sure that an "id" field won't produce a match""" + book = models.Edition.objects.create(title="Test edition") + + result = models.Edition.find_existing({"id": book.id}) + self.assertIsNone(result) + + def test_find_existing_with_id_and_match(self, *_): + """make sure that an "id" field won't produce a match""" + book = models.Edition.objects.create(title="Test edition") + matching_book = models.Edition.objects.create( + title="Another test edition", openlibrary_key="OL1234" + ) + + result = models.Edition.find_existing( + {"id": book.id, "openlibraryKey": "OL1234"} + ) + self.assertEqual(result, matching_book) + def test_get_recipients_public_object(self, *_): """determines the recipients for an object's broadcast""" MockSelf = namedtuple("Self", ("privacy")) From 93a7dd9cf3ee3b67982ab63965050c67ee2bc829 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 5 Nov 2023 07:50:28 -0800 Subject: [PATCH 15/28] Erase user data and statuses on account deletion --- bookwyrm/models/user.py | 24 ++++++++++++++- bookwyrm/tests/models/test_user_model.py | 38 ++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/bookwyrm/models/user.py b/bookwyrm/models/user.py index c152cf445..625a7d289 100644 --- a/bookwyrm/models/user.py +++ b/bookwyrm/models/user.py @@ -1,6 +1,7 @@ """ database schema for user data """ import re from urllib.parse import urlparse +from uuid import uuid4 from django.apps import apps from django.contrib.auth.models import AbstractUser @@ -394,10 +395,31 @@ class User(OrderedCollectionPageMixin, AbstractUser): """We don't actually delete the database entry""" # pylint: disable=attribute-defined-outside-init self.is_active = False - self.avatar = "" + self.allow_reactivation = False + + self.erase_user_data() + self.erase_user_statuses() + # skip the logic in this class's save() super().save(*args, **kwargs) + def erase_user_data(self): + """Wipe a user's custom data""" + # mangle email address + self.email = f"{uuid4()}@deleted.user" + + # erase data fields + self.avatar = "" + self.preview_image = "" + self.summary = None + self.name = None + self.favorites.set([]) + + def erase_user_statuses(self): + """Wipe the data on all the user's statuses""" + for status in self.status_set.all(): + status.delete() + def deactivate(self): """Disable the user but allow them to reactivate""" # pylint: disable=attribute-defined-outside-init diff --git a/bookwyrm/tests/models/test_user_model.py b/bookwyrm/tests/models/test_user_model.py index 838dd2e49..de39d5467 100644 --- a/bookwyrm/tests/models/test_user_model.py +++ b/bookwyrm/tests/models/test_user_model.py @@ -26,6 +26,7 @@ class User(TestCase): local=True, localname="mouse", name="hi", + summary="a summary", bookwyrm_user=False, ) self.another_user = models.User.objects.create_user( @@ -218,19 +219,52 @@ class User(TestCase): @patch("bookwyrm.suggested_users.remove_user_task.delay") def test_delete_user(self, _): - """deactivate a user""" + """permanently delete a user""" self.assertTrue(self.user.is_active) + self.assertEqual(self.user.name, "hi") + self.assertEqual(self.user.summary, "a summary") + self.assertEqual(self.user.email, "mouse@mouse.mouse") with patch( "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" - ) as broadcast_mock: + ) as broadcast_mock, patch( + "bookwyrm.models.user.User.erase_user_statuses" + ) as erase_statuses_mock: self.user.delete() + self.assertEqual(erase_statuses_mock.call_count, 1) + + # make sure the deletion is broadcast self.assertEqual(broadcast_mock.call_count, 1) activity = json.loads(broadcast_mock.call_args[1]["args"][1]) self.assertEqual(activity["type"], "Delete") self.assertEqual(activity["object"], self.user.remote_id) + + self.user.refresh_from_db() + + # the user's account data should be deleted + self.assertIsNone(self.user.name) + self.assertIsNone(self.user.summary) + self.assertNotEqual(self.user.email, "mouse@mouse.mouse") self.assertFalse(self.user.is_active) + @patch("bookwyrm.suggested_users.remove_user_task.delay") + @patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") + @patch("bookwyrm.activitystreams.add_status_task.delay") + @patch("bookwyrm.activitystreams.remove_status_task.delay") + def test_delete_user_erase_statuses(self, *_): + """erase user statuses when user is deleted""" + status = models.Status.objects.create(user=self.user, content="hello") + self.assertFalse(status.deleted) + self.assertIsNotNone(status.content) + self.assertIsNone(status.deleted_date) + + self.user.delete() + status.refresh_from_db() + + self.assertTrue(status.deleted) + self.assertIsNone(status.content) + self.assertIsNotNone(status.deleted_date) + def test_admins_no_admins(self): """list of admins""" result = models.User.admins() From 5e42afd85a94c5a7ab6d216533acd5f06c14f54a Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 5 Nov 2023 08:10:03 -0800 Subject: [PATCH 16/28] Pass args and kwargs through status deletion --- bookwyrm/models/status.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/models/status.py b/bookwyrm/models/status.py index 11646431b..cc44fe2bf 100644 --- a/bookwyrm/models/status.py +++ b/bookwyrm/models/status.py @@ -102,7 +102,7 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel): if hasattr(self, "quotation"): self.quotation = None # pylint: disable=attribute-defined-outside-init self.deleted_date = timezone.now() - self.save() + self.save(*args, **kwargs) @property def recipients(self): From 61caeed5a3bcf9508524963489896488b52f7ef2 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 5 Nov 2023 08:51:42 -0800 Subject: [PATCH 17/28] Adds migration and more tests --- .../migrations/0183_auto_20231105_1607.py | 25 ++++++++ bookwyrm/models/user.py | 27 ++++++++- bookwyrm/tests/models/test_user_model.py | 57 +++++++++++++++++++ 3 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 bookwyrm/migrations/0183_auto_20231105_1607.py diff --git a/bookwyrm/migrations/0183_auto_20231105_1607.py b/bookwyrm/migrations/0183_auto_20231105_1607.py new file mode 100644 index 000000000..390b56a9f --- /dev/null +++ b/bookwyrm/migrations/0183_auto_20231105_1607.py @@ -0,0 +1,25 @@ +# Generated by Django 3.2.20 on 2023-11-05 16:07 + +from django.db import migrations +from bookwyrm.models import User + + +def erase_deleted_user_data(apps, schema_editor): + """Retroactively clear user data""" + for user in User.get_permanently_deleted_users(): + user.erase_user_data() + user.save(broadcast=False) + user.erase_user_statuses(broadcast=False) + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0182_auto_20231027_1122"), + ] + + operations = [ + migrations.RunPython( + erase_deleted_user_data, reverse_code=migrations.RunPython.noop + ) + ] diff --git a/bookwyrm/models/user.py b/bookwyrm/models/user.py index 625a7d289..017db31d3 100644 --- a/bookwyrm/models/user.py +++ b/bookwyrm/models/user.py @@ -8,7 +8,7 @@ from django.contrib.auth.models import AbstractUser from django.contrib.postgres.fields import ArrayField, CICharField from django.core.exceptions import PermissionDenied, ObjectDoesNotExist from django.dispatch import receiver -from django.db import models, transaction +from django.db import models, transaction, IntegrityError from django.utils import timezone from django.utils.translation import gettext_lazy as _ from model_utils import FieldTracker @@ -263,6 +263,13 @@ class User(OrderedCollectionPageMixin, AbstractUser): is_active=True, ).distinct() + @classmethod + def get_permanently_deleted_users(cls): + return cls.objects.filter( + is_active=False, + deactivation_reason__in=["self_deletion", "moderator_deletion"], + ).distinct() + def update_active_date(self): """this user is here! they are doing things!""" self.last_active_date = timezone.now() @@ -415,10 +422,24 @@ class User(OrderedCollectionPageMixin, AbstractUser): self.name = None self.favorites.set([]) - def erase_user_statuses(self): + def erase_user_statuses(self, broadcast=True): """Wipe the data on all the user's statuses""" + # safety valve: make sure the user is deleted + if not self.is_permanently_deleted: + raise IntegrityError( + "Attempted to delete statuses for improperly deleted user" + ) + for status in self.status_set.all(): - status.delete() + status.delete(broadcast=broadcast) + + @property + def is_permanently_deleted(self): + """is this user inactive, or really truly deleted?""" + return not self.is_active and self.deactivation_reason in [ + "self_deletion", + "moderator_deletion", + ] def deactivate(self): """Disable the user but allow them to reactivate""" diff --git a/bookwyrm/tests/models/test_user_model.py b/bookwyrm/tests/models/test_user_model.py index de39d5467..47db1bc9a 100644 --- a/bookwyrm/tests/models/test_user_model.py +++ b/bookwyrm/tests/models/test_user_model.py @@ -2,6 +2,7 @@ import json from unittest.mock import patch from django.contrib.auth.models import Group +from django.db import IntegrityError from django.test import TestCase import responses @@ -265,6 +266,25 @@ class User(TestCase): self.assertIsNone(status.content) self.assertIsNotNone(status.deleted_date) + @patch("bookwyrm.suggested_users.remove_user_task.delay") + @patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") + @patch("bookwyrm.activitystreams.add_status_task.delay") + def test_delete_user_erase_statuses(self, *_): + """erase user statuses when user is deleted""" + status = models.Status.objects.create(user=self.user, content="hello") + self.assertFalse(status.deleted) + self.assertIsNotNone(status.content) + self.assertIsNone(status.deleted_date) + + self.user.deactivate() + with self.assertRaises(IntegrityError): + self.user.erase_user_statuses() + + status.refresh_from_db() + self.assertFalse(status.deleted) + self.assertIsNotNone(status.content) + self.assertIsNone(status.deleted_date) + def test_admins_no_admins(self): """list of admins""" result = models.User.admins() @@ -302,3 +322,40 @@ class User(TestCase): results = models.User.admins() self.assertEqual(results.count(), 1) self.assertEqual(results.first(), self.user) + + def test_get_permanently_deleted_users(self): + + with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch( + "bookwyrm.activitystreams.populate_stream_task.delay" + ), patch("bookwyrm.lists_stream.populate_lists_task.delay"): + active_user = models.User.objects.create_user( + f"activeuser@{DOMAIN}", + "activeuser@activeuser.activeuser", + "activeuserword", + local=True, + localname="active", + ) + deleted_user = models.User.objects.create_user( + f"deleteduser@{DOMAIN}", + "deleteduser@deleteduser.deleteduser", + "deleteduserword", + local=True, + localname="deleted", + is_active=False, + deactivation_reason="self_deletion", + ) + inactive_user = models.User.objects.create_user( + f"inactiveuser@{DOMAIN}", + "inactiveuser@inactiveuser.inactiveuser", + "inactiveuserword", + local=True, + localname="inactive", + is_active=False, + deactivation_reason="self_deactivation", + ) + + deleted_users = models.User.get_permanently_deleted_users() + + self.assertTrue(deleted_users.filter(localname="deleted").exists()) + self.assertFalse(deleted_users.filter(localname="active").exists()) + self.assertFalse(deleted_users.filter(localname="inactive").exists()) From 4de99074566a233cd765c8e41a0e9f5047296ac9 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 5 Nov 2023 09:25:50 -0800 Subject: [PATCH 18/28] Adds migration tests --- .../migrations/0183_auto_20231105_1607.py | 5 +- bookwyrm/models/user.py | 10 +- bookwyrm/tests/migrations/test_0183.py | 126 ++++++++++++++++++ 3 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 bookwyrm/tests/migrations/test_0183.py diff --git a/bookwyrm/migrations/0183_auto_20231105_1607.py b/bookwyrm/migrations/0183_auto_20231105_1607.py index 390b56a9f..2716a0737 100644 --- a/bookwyrm/migrations/0183_auto_20231105_1607.py +++ b/bookwyrm/migrations/0183_auto_20231105_1607.py @@ -8,7 +8,10 @@ def erase_deleted_user_data(apps, schema_editor): """Retroactively clear user data""" for user in User.get_permanently_deleted_users(): user.erase_user_data() - user.save(broadcast=False) + user.save( + broadcast=False, + update_fields=["email", "avatar", "preview_image", "summary", "name"], + ) user.erase_user_statuses(broadcast=False) diff --git a/bookwyrm/models/user.py b/bookwyrm/models/user.py index 017db31d3..43df39291 100644 --- a/bookwyrm/models/user.py +++ b/bookwyrm/models/user.py @@ -408,10 +408,18 @@ class User(OrderedCollectionPageMixin, AbstractUser): self.erase_user_statuses() # skip the logic in this class's save() - super().save(*args, **kwargs) + super().save( + *args, + update_fields=["email", "avatar", "preview_image", "summary", "name"], + **kwargs, + ) def erase_user_data(self): """Wipe a user's custom data""" + if not self.is_permanently_deleted: + raise IntegrityError( + "Attempted to delete user data for improperly deleted user" + ) # mangle email address self.email = f"{uuid4()}@deleted.user" diff --git a/bookwyrm/tests/migrations/test_0183.py b/bookwyrm/tests/migrations/test_0183.py new file mode 100644 index 000000000..8c8f27d5a --- /dev/null +++ b/bookwyrm/tests/migrations/test_0183.py @@ -0,0 +1,126 @@ +""" testing migrations """ +import json +from unittest.mock import patch + +from django.apps import apps +from django.test import TestCase +from django.db.migrations.executor import MigrationExecutor +from django.db import connection +import responses + +from bookwyrm import models +from bookwyrm.management.commands import initdb +from bookwyrm.settings import USE_HTTPS, DOMAIN + +# pylint: disable=missing-class-docstring +# pylint: disable=missing-function-docstring +class EraseDeletedUserDataMigration(TestCase): + + migrate_from = "0182_auto_20231027_1122" + migrate_to = "0183_auto_20231105_1607" + + # pylint: disable=invalid-name + def setUp(self): + with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch( + "bookwyrm.activitystreams.populate_stream_task.delay" + ), patch("bookwyrm.lists_stream.populate_lists_task.delay"): + self.active_user = models.User.objects.create_user( + f"activeuser@{DOMAIN}", + "activeuser@activeuser.activeuser", + "activeuserword", + local=True, + localname="active", + name="a name", + ) + self.inactive_user = models.User.objects.create_user( + f"inactiveuser@{DOMAIN}", + "inactiveuser@inactiveuser.inactiveuser", + "inactiveuserword", + local=True, + localname="inactive", + is_active=False, + deactivation_reason="self_deactivation", + name="name name", + ) + self.deleted_user = models.User.objects.create_user( + f"deleteduser@{DOMAIN}", + "deleteduser@deleteduser.deleteduser", + "deleteduserword", + local=True, + localname="deleted", + is_active=False, + deactivation_reason="self_deletion", + name="cool name", + ) + with patch( + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" + ), patch("bookwyrm.activitystreams.add_status_task.delay"): + self.active_status = models.Status.objects.create( + user=self.active_user, content="don't delete me" + ) + self.inactive_status = models.Status.objects.create( + user=self.inactive_user, content="also don't delete me" + ) + self.deleted_status = models.Status.objects.create( + user=self.deleted_user, content="yes, delete me" + ) + + initdb.init_groups() + initdb.init_permissions() + + assert ( + self.migrate_from and self.migrate_to + ), "TestCase '{}' must define migrate_from and migrate_to properties".format( + type(self).__name__ + ) + self.migrate_from = [("bookwyrm", self.migrate_from)] + self.migrate_to = [("bookwyrm", self.migrate_to)] + executor = MigrationExecutor(connection) + old_apps = executor.loader.project_state(self.migrate_from).apps + + # Reverse to the original migration + executor.migrate(self.migrate_from) + + self.setUpBeforeMigration(old_apps) + + # Run the migration to test + executor = MigrationExecutor(connection) + executor.loader.build_graph() # reload. + with patch("bookwyrm.activitystreams.remove_status_task.delay"): + executor.migrate(self.migrate_to) + + self.apps = executor.loader.project_state(self.migrate_to).apps + + def setUpBeforeMigration(self, apps): + pass + + def test_user_data_deleted(self): + """Make sure that only the right data was deleted""" + self.active_user.refresh_from_db() + self.inactive_user.refresh_from_db() + self.deleted_user.refresh_from_db() + self.active_status.refresh_from_db() + self.inactive_status.refresh_from_db() + self.deleted_status.refresh_from_db() + + self.assertTrue(self.active_user.is_active) + self.assertEqual(self.active_user.name, "a name") + self.assertNotEqual(self.deleted_user.email, "activeuser@activeuser.activeuser") + self.assertFalse(self.active_status.deleted) + self.assertEqual(self.active_status.content, "don't delete me") + + self.assertFalse(self.inactive_user.is_active) + self.assertEqual(self.inactive_user.name, "name name") + self.assertNotEqual( + self.deleted_user.email, "inactiveuser@inactiveuser.inactiveuser" + ) + self.assertFalse(self.inactive_status.deleted) + self.assertEqual(self.inactive_status.content, "also don't delete me") + + self.assertFalse(self.deleted_user.is_active) + self.assertIsNone(self.deleted_user.name) + self.assertNotEqual( + self.deleted_user.email, "deleteduser@deleteduser.deleteduser" + ) + self.assertTrue(self.deleted_status.deleted) + self.assertIsNone(self.deleted_status.content) From 47953c84d7823aaf6102fb85409fd70d53b6e9aa Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 5 Nov 2023 09:49:38 -0800 Subject: [PATCH 19/28] Fixes linting errors Apparently I didn't have a linter working! --- bookwyrm/tests/models/test_user_model.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/bookwyrm/tests/models/test_user_model.py b/bookwyrm/tests/models/test_user_model.py index 47db1bc9a..3576417de 100644 --- a/bookwyrm/tests/models/test_user_model.py +++ b/bookwyrm/tests/models/test_user_model.py @@ -1,5 +1,6 @@ """ testing models """ import json + from unittest.mock import patch from django.contrib.auth.models import Group from django.db import IntegrityError @@ -10,9 +11,11 @@ from bookwyrm import models from bookwyrm.management.commands import initdb from bookwyrm.settings import USE_HTTPS, DOMAIN + # pylint: disable=missing-class-docstring # pylint: disable=missing-function-docstring class User(TestCase): + protocol = "https://" if USE_HTTPS else "http://" # pylint: disable=invalid-name @@ -269,7 +272,7 @@ class User(TestCase): @patch("bookwyrm.suggested_users.remove_user_task.delay") @patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") @patch("bookwyrm.activitystreams.add_status_task.delay") - def test_delete_user_erase_statuses(self, *_): + def test_delete_user_erase_statuses_invalid(self, *_): """erase user statuses when user is deleted""" status = models.Status.objects.create(user=self.user, content="hello") self.assertFalse(status.deleted) @@ -328,14 +331,14 @@ class User(TestCase): with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch( "bookwyrm.activitystreams.populate_stream_task.delay" ), patch("bookwyrm.lists_stream.populate_lists_task.delay"): - active_user = models.User.objects.create_user( + models.User.objects.create_user( f"activeuser@{DOMAIN}", "activeuser@activeuser.activeuser", "activeuserword", local=True, localname="active", ) - deleted_user = models.User.objects.create_user( + models.User.objects.create_user( f"deleteduser@{DOMAIN}", "deleteduser@deleteduser.deleteduser", "deleteduserword", @@ -344,7 +347,7 @@ class User(TestCase): is_active=False, deactivation_reason="self_deletion", ) - inactive_user = models.User.objects.create_user( + models.User.objects.create_user( f"inactiveuser@{DOMAIN}", "inactiveuser@inactiveuser.inactiveuser", "inactiveuserword", From f353b49d36b5778fefdc820f8adf529ce1d2b055 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 5 Nov 2023 09:53:57 -0800 Subject: [PATCH 20/28] Another linting issues --- bookwyrm/models/user.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bookwyrm/models/user.py b/bookwyrm/models/user.py index 43df39291..48f536ed1 100644 --- a/bookwyrm/models/user.py +++ b/bookwyrm/models/user.py @@ -265,6 +265,7 @@ class User(OrderedCollectionPageMixin, AbstractUser): @classmethod def get_permanently_deleted_users(cls): + """a list of users who are permanently deleted""" return cls.objects.filter( is_active=False, deactivation_reason__in=["self_deletion", "moderator_deletion"], From d3668e413db48be6495ff2d8c1f02337158d52f8 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 5 Nov 2023 09:59:49 -0800 Subject: [PATCH 21/28] Removes updates fields that was causing problems --- bookwyrm/models/user.py | 1 - 1 file changed, 1 deletion(-) diff --git a/bookwyrm/models/user.py b/bookwyrm/models/user.py index 48f536ed1..b9e9ae486 100644 --- a/bookwyrm/models/user.py +++ b/bookwyrm/models/user.py @@ -411,7 +411,6 @@ class User(OrderedCollectionPageMixin, AbstractUser): # skip the logic in this class's save() super().save( *args, - update_fields=["email", "avatar", "preview_image", "summary", "name"], **kwargs, ) From c17a2ec55ba18d52c5f83a19e1d30550063151a4 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 5 Nov 2023 10:18:04 -0800 Subject: [PATCH 22/28] Creates snippet for user tag in admin view The existing display wasn't showing the correct colors and was repeating code unnecessarily --- .../templates/settings/users/user_admin.html | 26 +------------------ .../templates/settings/users/user_info.html | 19 +------------- .../templates/snippets/user_active_tag.html | 17 ++++++++++++ .../snippets/user_active_tag_item.html | 19 ++++++++++++++ 4 files changed, 38 insertions(+), 43 deletions(-) create mode 100644 bookwyrm/templates/snippets/user_active_tag.html create mode 100644 bookwyrm/templates/snippets/user_active_tag_item.html diff --git a/bookwyrm/templates/settings/users/user_admin.html b/bookwyrm/templates/settings/users/user_admin.html index a1d93ddd0..cc5c51ba7 100644 --- a/bookwyrm/templates/settings/users/user_admin.html +++ b/bookwyrm/templates/settings/users/user_admin.html @@ -74,31 +74,7 @@ {{ user.created_date }} {{ user.last_active_date }} - {% if user.is_active %} - {% if user.moved_to %} - - {% trans "Moved" %} - {% else %} - - {% trans "Active" %} - {% endif %} - {% elif user.deactivation_reason == "moderator_deletion" or user.deactivation_reason == "self_deletion" %} - - {% trans "Deleted" %} - ({{ user.get_deactivation_reason_display }}) - {% else %} - - {% trans "Inactive" %} - ({{ user.get_deactivation_reason_display }}) - {% endif %} + {% include "snippets/user_active_tag.html" with user=user %} {% if status == "federated" %} diff --git a/bookwyrm/templates/settings/users/user_info.html b/bookwyrm/templates/settings/users/user_info.html index 368045a0d..f35c60db9 100644 --- a/bookwyrm/templates/settings/users/user_info.html +++ b/bookwyrm/templates/settings/users/user_info.html @@ -23,24 +23,7 @@

{% trans "Status" %}

- {% if user.is_active %} - {% if user.moved_to %} -

- {% trans "Moved" %} -

- {% else %} -

- {% trans "Active" %} -

- {% endif %} - {% else %} -

- {% trans "Inactive" %} - {% if user.deactivation_reason %} - ({% trans user.get_deactivation_reason_display %}) - {% endif %} -

- {% endif %} + {% include "snippets/user_active_tag.html" with large=True %}

{% if user.local %} {% trans "Local" %} diff --git a/bookwyrm/templates/snippets/user_active_tag.html b/bookwyrm/templates/snippets/user_active_tag.html new file mode 100644 index 000000000..c3f067b43 --- /dev/null +++ b/bookwyrm/templates/snippets/user_active_tag.html @@ -0,0 +1,17 @@ +{% load i18n %} + +{% if user.is_active %} + {% if user.moved_to %} + {% trans "Moved" as text %} + {% include "snippets/user_active_tag_item.html" with icon="x" text=text level="info" %} + {% else %} + {% trans "Active" as text %} + {% include "snippets/user_active_tag_item.html" with icon="check" text=text level="success" %} + {% endif %} +{% elif user.is_permanently_deleted %} + {% trans "Deleted" as text %} + {% include "snippets/user_active_tag_item.html" with icon="x" text=text level="danger" deactivation_reason=user.get_deactivation_reason_display %} +{% else %} + {% trans "Inactive" as text %} + {% include "snippets/user_active_tag_item.html" with icon="x" text=text level="warning" deactivation_reason=user.get_deactivation_reason_display %} +{% endif %} diff --git a/bookwyrm/templates/snippets/user_active_tag_item.html b/bookwyrm/templates/snippets/user_active_tag_item.html new file mode 100644 index 000000000..e722150f2 --- /dev/null +++ b/bookwyrm/templates/snippets/user_active_tag_item.html @@ -0,0 +1,19 @@ +{% if large %} + +

+ + {{ text }} + {% if deactivation_reason %} + ({{ deactivation_reason }}) + {% endif %} +

+ +{% else %} + + +{{ text }} + +{% endif %} + From 27d99a009412a2b48ebf063f1ba03b5bdd50f714 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 5 Nov 2023 19:47:32 -0800 Subject: [PATCH 23/28] Removes failsafe that was overzealous --- bookwyrm/models/user.py | 18 ++++++------------ .../tests/views/inbox/test_inbox_delete.py | 4 +++- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/bookwyrm/models/user.py b/bookwyrm/models/user.py index b9e9ae486..19006f772 100644 --- a/bookwyrm/models/user.py +++ b/bookwyrm/models/user.py @@ -8,7 +8,7 @@ from django.contrib.auth.models import AbstractUser from django.contrib.postgres.fields import ArrayField, CICharField from django.core.exceptions import PermissionDenied, ObjectDoesNotExist from django.dispatch import receiver -from django.db import models, transaction, IntegrityError +from django.db import models, transaction from django.utils import timezone from django.utils.translation import gettext_lazy as _ from model_utils import FieldTracker @@ -268,7 +268,10 @@ class User(OrderedCollectionPageMixin, AbstractUser): """a list of users who are permanently deleted""" return cls.objects.filter( is_active=False, - deactivation_reason__in=["self_deletion", "moderator_deletion"], + deactivation_reason__in=[ + "self_deletion", + "moderator_deletion", + ], ).distinct() def update_active_date(self): @@ -416,10 +419,6 @@ class User(OrderedCollectionPageMixin, AbstractUser): def erase_user_data(self): """Wipe a user's custom data""" - if not self.is_permanently_deleted: - raise IntegrityError( - "Attempted to delete user data for improperly deleted user" - ) # mangle email address self.email = f"{uuid4()}@deleted.user" @@ -432,12 +431,6 @@ class User(OrderedCollectionPageMixin, AbstractUser): def erase_user_statuses(self, broadcast=True): """Wipe the data on all the user's statuses""" - # safety valve: make sure the user is deleted - if not self.is_permanently_deleted: - raise IntegrityError( - "Attempted to delete statuses for improperly deleted user" - ) - for status in self.status_set.all(): status.delete(broadcast=broadcast) @@ -447,6 +440,7 @@ class User(OrderedCollectionPageMixin, AbstractUser): return not self.is_active and self.deactivation_reason in [ "self_deletion", "moderator_deletion", + "activitypub_deletion", ] def deactivate(self): diff --git a/bookwyrm/tests/views/inbox/test_inbox_delete.py b/bookwyrm/tests/views/inbox/test_inbox_delete.py index 0fb108e22..7b4c12564 100644 --- a/bookwyrm/tests/views/inbox/test_inbox_delete.py +++ b/bookwyrm/tests/views/inbox/test_inbox_delete.py @@ -11,6 +11,7 @@ from bookwyrm import models, views class InboxActivities(TestCase): """inbox tests""" + # pylint: disable=invalid-name def setUp(self): """basic user and book data""" with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch( @@ -97,7 +98,8 @@ class InboxActivities(TestCase): self.assertEqual(models.Notification.objects.get(), notif) @patch("bookwyrm.suggested_users.remove_user_task.delay") - def test_delete_user(self, _): + @patch("bookwyrm.activitystreams.remove_status_task.delay") + def test_delete_user(self, *_): """delete a user""" self.assertTrue(models.User.objects.get(username="rat@example.com").is_active) activity = { From ee6e3ed7eb3ef6be989cd4bd594901d68be7b8a0 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 5 Nov 2023 20:25:51 -0800 Subject: [PATCH 24/28] Adds a database field for is_deleted on user --- .../migrations/0183_auto_20231105_1607.py | 22 +++------ .../migrations/0184_auto_20231106_0421.py | 49 +++++++++++++++++++ bookwyrm/models/user.py | 34 +++++-------- .../templates/snippets/user_active_tag.html | 2 +- .../migrations/{test_0183.py => test_0184.py} | 17 +++---- bookwyrm/tests/models/test_user_model.py | 37 -------------- 6 files changed, 75 insertions(+), 86 deletions(-) create mode 100644 bookwyrm/migrations/0184_auto_20231106_0421.py rename bookwyrm/tests/migrations/{test_0183.py => test_0184.py} (92%) diff --git a/bookwyrm/migrations/0183_auto_20231105_1607.py b/bookwyrm/migrations/0183_auto_20231105_1607.py index 2716a0737..0c8376adc 100644 --- a/bookwyrm/migrations/0183_auto_20231105_1607.py +++ b/bookwyrm/migrations/0183_auto_20231105_1607.py @@ -1,18 +1,6 @@ # Generated by Django 3.2.20 on 2023-11-05 16:07 -from django.db import migrations -from bookwyrm.models import User - - -def erase_deleted_user_data(apps, schema_editor): - """Retroactively clear user data""" - for user in User.get_permanently_deleted_users(): - user.erase_user_data() - user.save( - broadcast=False, - update_fields=["email", "avatar", "preview_image", "summary", "name"], - ) - user.erase_user_statuses(broadcast=False) +from django.db import migrations, models class Migration(migrations.Migration): @@ -22,7 +10,9 @@ class Migration(migrations.Migration): ] operations = [ - migrations.RunPython( - erase_deleted_user_data, reverse_code=migrations.RunPython.noop - ) + migrations.AddField( + model_name="user", + name="is_deleted", + field=models.BooleanField(default=False), + ), ] diff --git a/bookwyrm/migrations/0184_auto_20231106_0421.py b/bookwyrm/migrations/0184_auto_20231106_0421.py new file mode 100644 index 000000000..e8197dea1 --- /dev/null +++ b/bookwyrm/migrations/0184_auto_20231106_0421.py @@ -0,0 +1,49 @@ +# Generated by Django 3.2.20 on 2023-11-06 04:21 + +from django.db import migrations +from bookwyrm.models import User + + +def update_deleted_users(apps, schema_editor): + """Find all the users who are deleted, not just inactive, and set deleted""" + users = apps.get_model("bookwyrm", "User") + db_alias = schema_editor.connection.alias + users.objects.using(db_alias).filter( + is_active=False, + deactivation_reason__in=[ + "self_deletion", + "moderator_deletion", + ], + ).update(is_deleted=True) + + # differente rules for remote users + users.objects.using(db_alias).filter(is_active=False, local=False,).exclude( + deactivation_reason="moderator_deactivation", + ).update(is_deleted=True) + + +def erase_deleted_user_data(apps, schema_editor): + """Retroactively clear user data""" + for user in User.objects.filter(is_deleted=True): + user.erase_user_data() + user.save( + broadcast=False, + update_fields=["email", "avatar", "preview_image", "summary", "name"], + ) + user.erase_user_statuses(broadcast=False) + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0183_auto_20231105_1607"), + ] + + operations = [ + migrations.RunPython( + update_deleted_users, reverse_code=migrations.RunPython.noop + ), + migrations.RunPython( + erase_deleted_user_data, reverse_code=migrations.RunPython.noop + ), + ] diff --git a/bookwyrm/models/user.py b/bookwyrm/models/user.py index 19006f772..75ca1d527 100644 --- a/bookwyrm/models/user.py +++ b/bookwyrm/models/user.py @@ -8,7 +8,7 @@ from django.contrib.auth.models import AbstractUser from django.contrib.postgres.fields import ArrayField, CICharField from django.core.exceptions import PermissionDenied, ObjectDoesNotExist from django.dispatch import receiver -from django.db import models, transaction +from django.db import models, transaction, IntegrityError from django.utils import timezone from django.utils.translation import gettext_lazy as _ from model_utils import FieldTracker @@ -54,6 +54,7 @@ class User(OrderedCollectionPageMixin, AbstractUser): username = fields.UsernameField() email = models.EmailField(unique=True, null=True) + is_deleted = models.BooleanField(default=False) key_pair = fields.OneToOneField( "KeyPair", @@ -263,17 +264,6 @@ class User(OrderedCollectionPageMixin, AbstractUser): is_active=True, ).distinct() - @classmethod - def get_permanently_deleted_users(cls): - """a list of users who are permanently deleted""" - return cls.objects.filter( - is_active=False, - deactivation_reason__in=[ - "self_deletion", - "moderator_deletion", - ], - ).distinct() - def update_active_date(self): """this user is here! they are doing things!""" self.last_active_date = timezone.now() @@ -407,6 +397,7 @@ class User(OrderedCollectionPageMixin, AbstractUser): # pylint: disable=attribute-defined-outside-init self.is_active = False self.allow_reactivation = False + self.is_deleted = True self.erase_user_data() self.erase_user_statuses() @@ -419,6 +410,11 @@ class User(OrderedCollectionPageMixin, AbstractUser): def erase_user_data(self): """Wipe a user's custom data""" + if not self.is_deleted: + raise IntegrityError( + "Trying to erase user data on user that is not deleted" + ) + # mangle email address self.email = f"{uuid4()}@deleted.user" @@ -431,18 +427,14 @@ class User(OrderedCollectionPageMixin, AbstractUser): def erase_user_statuses(self, broadcast=True): """Wipe the data on all the user's statuses""" + if not self.is_deleted: + raise IntegrityError( + "Trying to erase user data on user that is not deleted" + ) + for status in self.status_set.all(): status.delete(broadcast=broadcast) - @property - def is_permanently_deleted(self): - """is this user inactive, or really truly deleted?""" - return not self.is_active and self.deactivation_reason in [ - "self_deletion", - "moderator_deletion", - "activitypub_deletion", - ] - def deactivate(self): """Disable the user but allow them to reactivate""" # pylint: disable=attribute-defined-outside-init diff --git a/bookwyrm/templates/snippets/user_active_tag.html b/bookwyrm/templates/snippets/user_active_tag.html index c3f067b43..1d85ae68b 100644 --- a/bookwyrm/templates/snippets/user_active_tag.html +++ b/bookwyrm/templates/snippets/user_active_tag.html @@ -8,7 +8,7 @@ {% trans "Active" as text %} {% include "snippets/user_active_tag_item.html" with icon="check" text=text level="success" %} {% endif %} -{% elif user.is_permanently_deleted %} +{% elif user.is_deleted %} {% trans "Deleted" as text %} {% include "snippets/user_active_tag_item.html" with icon="x" text=text level="danger" deactivation_reason=user.get_deactivation_reason_display %} {% else %} diff --git a/bookwyrm/tests/migrations/test_0183.py b/bookwyrm/tests/migrations/test_0184.py similarity index 92% rename from bookwyrm/tests/migrations/test_0183.py rename to bookwyrm/tests/migrations/test_0184.py index 8c8f27d5a..4bf1b66c9 100644 --- a/bookwyrm/tests/migrations/test_0183.py +++ b/bookwyrm/tests/migrations/test_0184.py @@ -1,23 +1,20 @@ """ testing migrations """ -import json from unittest.mock import patch -from django.apps import apps from django.test import TestCase from django.db.migrations.executor import MigrationExecutor from django.db import connection -import responses from bookwyrm import models from bookwyrm.management.commands import initdb -from bookwyrm.settings import USE_HTTPS, DOMAIN +from bookwyrm.settings import DOMAIN # pylint: disable=missing-class-docstring # pylint: disable=missing-function-docstring class EraseDeletedUserDataMigration(TestCase): - migrate_from = "0182_auto_20231027_1122" - migrate_to = "0183_auto_20231105_1607" + migrate_from = "0183_auto_20231105_1607" + migrate_to = "0184_auto_20231106_0421" # pylint: disable=invalid-name def setUp(self): @@ -68,11 +65,6 @@ class EraseDeletedUserDataMigration(TestCase): initdb.init_groups() initdb.init_permissions() - assert ( - self.migrate_from and self.migrate_to - ), "TestCase '{}' must define migrate_from and migrate_to properties".format( - type(self).__name__ - ) self.migrate_from = [("bookwyrm", self.migrate_from)] self.migrate_to = [("bookwyrm", self.migrate_to)] executor = MigrationExecutor(connection) @@ -104,12 +96,14 @@ class EraseDeletedUserDataMigration(TestCase): self.deleted_status.refresh_from_db() self.assertTrue(self.active_user.is_active) + self.assertFalse(self.active_user.is_deleted) self.assertEqual(self.active_user.name, "a name") self.assertNotEqual(self.deleted_user.email, "activeuser@activeuser.activeuser") self.assertFalse(self.active_status.deleted) self.assertEqual(self.active_status.content, "don't delete me") self.assertFalse(self.inactive_user.is_active) + self.assertFalse(self.inactive_user.is_deleted) self.assertEqual(self.inactive_user.name, "name name") self.assertNotEqual( self.deleted_user.email, "inactiveuser@inactiveuser.inactiveuser" @@ -118,6 +112,7 @@ class EraseDeletedUserDataMigration(TestCase): self.assertEqual(self.inactive_status.content, "also don't delete me") self.assertFalse(self.deleted_user.is_active) + self.assertTrue(self.deleted_user.is_deleted) self.assertIsNone(self.deleted_user.name) self.assertNotEqual( self.deleted_user.email, "deleteduser@deleteduser.deleteduser" diff --git a/bookwyrm/tests/models/test_user_model.py b/bookwyrm/tests/models/test_user_model.py index 3576417de..30d7918c0 100644 --- a/bookwyrm/tests/models/test_user_model.py +++ b/bookwyrm/tests/models/test_user_model.py @@ -325,40 +325,3 @@ class User(TestCase): results = models.User.admins() self.assertEqual(results.count(), 1) self.assertEqual(results.first(), self.user) - - def test_get_permanently_deleted_users(self): - - with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch( - "bookwyrm.activitystreams.populate_stream_task.delay" - ), patch("bookwyrm.lists_stream.populate_lists_task.delay"): - models.User.objects.create_user( - f"activeuser@{DOMAIN}", - "activeuser@activeuser.activeuser", - "activeuserword", - local=True, - localname="active", - ) - models.User.objects.create_user( - f"deleteduser@{DOMAIN}", - "deleteduser@deleteduser.deleteduser", - "deleteduserword", - local=True, - localname="deleted", - is_active=False, - deactivation_reason="self_deletion", - ) - models.User.objects.create_user( - f"inactiveuser@{DOMAIN}", - "inactiveuser@inactiveuser.inactiveuser", - "inactiveuserword", - local=True, - localname="inactive", - is_active=False, - deactivation_reason="self_deactivation", - ) - - deleted_users = models.User.get_permanently_deleted_users() - - self.assertTrue(deleted_users.filter(localname="deleted").exists()) - self.assertFalse(deleted_users.filter(localname="active").exists()) - self.assertFalse(deleted_users.filter(localname="inactive").exists()) From 2248206a6675a9e8b7451b7a20a0c44c10c4f6e4 Mon Sep 17 00:00:00 2001 From: Hugh Rundle Date: Wed, 8 Nov 2023 18:30:49 +1100 Subject: [PATCH 25/28] fix missing types in BookData file fields activitypub.BookData includes fields for 'files' and 'fileLinks'. This is a problem because BookData is inherited by Book and Author, neither of which have 'files' as a field in the main model. Additionally, Author doesn't have a value for 'file_links'. When serializing to JSON, BookData therefore throws 'TypeError: Object of type _MISSING_TYPE is not JSON serializable' This fixes the problem by removing links and moving fileLinks to activitypub.Book. --- bookwyrm/activitypub/book.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bookwyrm/activitypub/book.py b/bookwyrm/activitypub/book.py index 5db0dc3ac..a53222053 100644 --- a/bookwyrm/activitypub/book.py +++ b/bookwyrm/activitypub/book.py @@ -22,8 +22,6 @@ class BookData(ActivityObject): aasin: Optional[str] = None isfdb: Optional[str] = None lastEditedBy: Optional[str] = None - links: list[str] = field(default_factory=list) - fileLinks: list[str] = field(default_factory=list) # pylint: disable=invalid-name @@ -45,6 +43,8 @@ class Book(BookData): firstPublishedDate: str = "" publishedDate: str = "" + fileLinks: list[str] = field(default_factory=list) + cover: Optional[Document] = None type: str = "Book" From ebcacfc6c50658f39fcc5a50ea72e6c67ae42c9c Mon Sep 17 00:00:00 2001 From: Levi Bard Date: Thu, 9 Nov 2023 12:57:45 +0100 Subject: [PATCH 26/28] Fix `bw-dev initdb` --- bw-dev | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bw-dev b/bw-dev index 57441f013..6769f4bcd 100755 --- a/bw-dev +++ b/bw-dev @@ -91,7 +91,7 @@ case "$CMD" in $DOCKER_COMPOSE run --rm --service-ports web ;; initdb) - initdb "@" + initdb "$@" ;; resetdb) prod_error From 99a9dbe5f4134b76f5e90da7df25f1b0e7210f16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adeodato=20Sim=C3=B3?= Date: Thu, 9 Nov 2023 21:36:05 -0300 Subject: [PATCH 27/28] Create NotificationType as class, not through API This way, we need not list every value again to create the enum. N.B.: enum values are now accessed as `models.NotificationType.FOO`, instead of `models.Notification.FOO`. --- bookwyrm/models/__init__.py | 2 +- bookwyrm/models/antispam.py | 3 +- bookwyrm/models/group.py | 13 +++---- bookwyrm/models/move.py | 5 ++- bookwyrm/models/notification.py | 42 +++++++++++----------- bookwyrm/tests/models/test_notification.py | 24 ++++++------- bookwyrm/views/group.py | 14 +++++--- 7 files changed, 53 insertions(+), 50 deletions(-) diff --git a/bookwyrm/models/__init__.py b/bookwyrm/models/__init__.py index c455c751f..e1c862f2b 100644 --- a/bookwyrm/models/__init__.py +++ b/bookwyrm/models/__init__.py @@ -34,7 +34,7 @@ from .site import PasswordReset, InviteRequest from .announcement import Announcement from .antispam import EmailBlocklist, IPBlocklist, AutoMod, automod_task -from .notification import Notification +from .notification import Notification, NotificationType from .hashtag import Hashtag diff --git a/bookwyrm/models/antispam.py b/bookwyrm/models/antispam.py index 94d978ec4..1067cbf1d 100644 --- a/bookwyrm/models/antispam.py +++ b/bookwyrm/models/antispam.py @@ -10,6 +10,7 @@ from django.utils.translation import gettext_lazy as _ from bookwyrm.tasks import app, MISC from .base_model import BookWyrmModel +from .notification import NotificationType from .user import User @@ -80,7 +81,7 @@ def automod_task(): with transaction.atomic(): for admin in admins: notification, _ = notification_model.objects.get_or_create( - user=admin, notification_type=notification_model.REPORT, read=False + user=admin, notification_type=NotificationType.REPORT, read=False ) notification.related_reports.set(reports) diff --git a/bookwyrm/models/group.py b/bookwyrm/models/group.py index 003b23d02..d02b56ab1 100644 --- a/bookwyrm/models/group.py +++ b/bookwyrm/models/group.py @@ -1,5 +1,4 @@ """ do book related things with other users """ -from django.apps import apps from django.db import models, IntegrityError, transaction from django.db.models import Q from bookwyrm.settings import DOMAIN @@ -143,26 +142,28 @@ class GroupMemberInvitation(models.Model): @transaction.atomic def accept(self): """turn this request into the real deal""" + # pylint: disable-next=import-outside-toplevel + from .notification import Notification, NotificationType # circular dependency + GroupMember.from_request(self) - model = apps.get_model("bookwyrm.Notification", require_ready=True) # tell the group owner - model.notify( + Notification.notify( self.group.user, self.user, related_group=self.group, - notification_type=model.ACCEPT, + notification_type=NotificationType.ACCEPT, ) # let the other members know about it for membership in self.group.memberships.all(): member = membership.user if member not in (self.user, self.group.user): - model.notify( + Notification.notify( member, self.user, related_group=self.group, - notification_type=model.JOIN, + notification_type=NotificationType.JOIN, ) def reject(self): diff --git a/bookwyrm/models/move.py b/bookwyrm/models/move.py index a5bf9d76d..d6d8ef78f 100644 --- a/bookwyrm/models/move.py +++ b/bookwyrm/models/move.py @@ -6,7 +6,7 @@ from bookwyrm import activitypub from .activitypub_mixin import ActivityMixin from .base_model import BookWyrmModel from . import fields -from .notification import Notification +from .notification import Notification, NotificationType class Move(ActivityMixin, BookWyrmModel): @@ -49,7 +49,6 @@ class MoveUser(Move): # only allow if the source is listed in the target's alsoKnownAs if self.user in self.target.also_known_as.all(): - self.user.also_known_as.add(self.target.id) self.user.update_active_date() self.user.moved_to = self.target.remote_id @@ -65,7 +64,7 @@ class MoveUser(Move): for follower in self.user.followers.all(): if follower.local: Notification.notify( - follower, self.user, notification_type=Notification.MOVE + follower, self.user, notification_type=NotificationType.MOVE ) else: diff --git a/bookwyrm/models/notification.py b/bookwyrm/models/notification.py index 093c25c65..46b88f5e5 100644 --- a/bookwyrm/models/notification.py +++ b/bookwyrm/models/notification.py @@ -6,7 +6,7 @@ from . import Boost, Favorite, GroupMemberInvitation, ImportJob, LinkDomain from . import ListItem, Report, Status, User, UserFollowRequest -class Notification(BookWyrmModel): +class NotificationType(models.TextChoices): """you've been tagged, liked, followed, etc""" # Status interactions @@ -43,12 +43,9 @@ class Notification(BookWyrmModel): # Migrations MOVE = "MOVE" - # pylint: disable=line-too-long - NotificationType = models.TextChoices( - # there has got be a better way to do this - "NotificationType", - f"{FAVORITE} {REPLY} {MENTION} {TAG} {FOLLOW} {FOLLOW_REQUEST} {BOOST} {IMPORT} {ADD} {REPORT} {LINK_DOMAIN} {INVITE} {ACCEPT} {JOIN} {LEAVE} {REMOVE} {GROUP_PRIVACY} {GROUP_NAME} {GROUP_DESCRIPTION} {MOVE}", - ) + +class Notification(BookWyrmModel): + """a notification object""" user = models.ForeignKey("User", on_delete=models.CASCADE) read = models.BooleanField(default=False) @@ -93,11 +90,11 @@ class Notification(BookWyrmModel): user=user, related_users=related_user, related_list_items__book_list=list_item.book_list, - notification_type=Notification.ADD, + notification_type=NotificationType.ADD, ).first() if not notification: notification = cls.objects.create( - user=user, notification_type=Notification.ADD + user=user, notification_type=NotificationType.ADD ) notification.related_users.add(related_user) notification.related_list_items.add(list_item) @@ -124,7 +121,7 @@ def notify_on_fav(sender, instance, *args, **kwargs): instance.status.user, instance.user, related_status=instance.status, - notification_type=Notification.FAVORITE, + notification_type=NotificationType.FAVORITE, ) @@ -138,7 +135,7 @@ def notify_on_unfav(sender, instance, *args, **kwargs): instance.status.user, instance.user, related_status=instance.status, - notification_type=Notification.FAVORITE, + notification_type=NotificationType.FAVORITE, ) @@ -163,7 +160,7 @@ def notify_user_on_mention(sender, instance, *args, **kwargs): instance.reply_parent.user, instance.user, related_status=instance, - notification_type=Notification.REPLY, + notification_type=NotificationType.REPLY, ) for mention_user in instance.mention_users.all(): @@ -175,7 +172,7 @@ def notify_user_on_mention(sender, instance, *args, **kwargs): Notification.notify( mention_user, instance.user, - notification_type=Notification.MENTION, + notification_type=NotificationType.MENTION, related_status=instance, ) @@ -194,7 +191,7 @@ def notify_user_on_boost(sender, instance, *args, **kwargs): instance.boosted_status.user, instance.user, related_status=instance.boosted_status, - notification_type=Notification.BOOST, + notification_type=NotificationType.BOOST, ) @@ -206,7 +203,7 @@ def notify_user_on_unboost(sender, instance, *args, **kwargs): instance.boosted_status.user, instance.user, related_status=instance.boosted_status, - notification_type=Notification.BOOST, + notification_type=NotificationType.BOOST, ) @@ -221,7 +218,7 @@ def notify_user_on_import_complete( return Notification.objects.get_or_create( user=instance.user, - notification_type=Notification.IMPORT, + notification_type=NotificationType.IMPORT, related_import=instance, ) @@ -240,7 +237,7 @@ def notify_admins_on_report(sender, instance, created, *args, **kwargs): for admin in admins: notification, _ = Notification.objects.get_or_create( user=admin, - notification_type=Notification.REPORT, + notification_type=NotificationType.REPORT, read=False, ) notification.related_reports.add(instance) @@ -260,7 +257,7 @@ def notify_admins_on_link_domain(sender, instance, created, *args, **kwargs): for admin in admins: notification, _ = Notification.objects.get_or_create( user=admin, - notification_type=Notification.LINK_DOMAIN, + notification_type=NotificationType.LINK_DOMAIN, read=False, ) notification.related_link_domains.add(instance) @@ -274,7 +271,7 @@ def notify_user_on_group_invite(sender, instance, *args, **kwargs): instance.user, instance.group.user, related_group=instance.group, - notification_type=Notification.INVITE, + notification_type=NotificationType.INVITE, ) @@ -312,11 +309,12 @@ def notify_user_on_follow(sender, instance, created, *args, **kwargs): notification = Notification.objects.filter( user=instance.user_object, related_users=instance.user_subject, - notification_type=Notification.FOLLOW_REQUEST, + notification_type=NotificationType.FOLLOW_REQUEST, ).first() if not notification: notification = Notification.objects.create( - user=instance.user_object, notification_type=Notification.FOLLOW_REQUEST + user=instance.user_object, + notification_type=NotificationType.FOLLOW_REQUEST, ) notification.related_users.set([instance.user_subject]) notification.read = False @@ -326,6 +324,6 @@ def notify_user_on_follow(sender, instance, created, *args, **kwargs): Notification.notify( instance.user_object, instance.user_subject, - notification_type=Notification.FOLLOW, + notification_type=NotificationType.FOLLOW, read=False, ) diff --git a/bookwyrm/tests/models/test_notification.py b/bookwyrm/tests/models/test_notification.py index 0e4fe91c7..1c412e1b4 100644 --- a/bookwyrm/tests/models/test_notification.py +++ b/bookwyrm/tests/models/test_notification.py @@ -43,7 +43,7 @@ class Notification(TestCase): def test_notification(self): """New notifications are unread""" notification = models.Notification.objects.create( - user=self.local_user, notification_type=models.Notification.FAVORITE + user=self.local_user, notification_type=models.NotificationType.FAVORITE ) self.assertFalse(notification.read) @@ -52,7 +52,7 @@ class Notification(TestCase): models.Notification.notify( self.local_user, self.remote_user, - notification_type=models.Notification.FAVORITE, + notification_type=models.NotificationType.FAVORITE, ) self.assertTrue(models.Notification.objects.exists()) @@ -61,7 +61,7 @@ class Notification(TestCase): models.Notification.notify( self.local_user, self.remote_user, - notification_type=models.Notification.FAVORITE, + notification_type=models.NotificationType.FAVORITE, ) self.assertEqual(models.Notification.objects.count(), 1) notification = models.Notification.objects.get() @@ -70,7 +70,7 @@ class Notification(TestCase): models.Notification.notify( self.local_user, self.another_user, - notification_type=models.Notification.FAVORITE, + notification_type=models.NotificationType.FAVORITE, ) self.assertEqual(models.Notification.objects.count(), 1) notification.refresh_from_db() @@ -92,7 +92,7 @@ class Notification(TestCase): models.Notification.notify( self.remote_user, self.local_user, - notification_type=models.Notification.FAVORITE, + notification_type=models.NotificationType.FAVORITE, ) self.assertFalse(models.Notification.objects.exists()) @@ -101,7 +101,7 @@ class Notification(TestCase): models.Notification.notify( self.local_user, self.local_user, - notification_type=models.Notification.FAVORITE, + notification_type=models.NotificationType.FAVORITE, ) self.assertFalse(models.Notification.objects.exists()) @@ -154,14 +154,14 @@ class Notification(TestCase): models.Notification.notify( self.local_user, self.remote_user, - notification_type=models.Notification.FAVORITE, + notification_type=models.NotificationType.FAVORITE, ) self.assertTrue(models.Notification.objects.exists()) models.Notification.unnotify( self.local_user, self.remote_user, - notification_type=models.Notification.FAVORITE, + notification_type=models.NotificationType.FAVORITE, ) self.assertFalse(models.Notification.objects.exists()) @@ -170,25 +170,25 @@ class Notification(TestCase): models.Notification.notify( self.local_user, self.remote_user, - notification_type=models.Notification.FAVORITE, + notification_type=models.NotificationType.FAVORITE, ) models.Notification.notify( self.local_user, self.another_user, - notification_type=models.Notification.FAVORITE, + notification_type=models.NotificationType.FAVORITE, ) self.assertTrue(models.Notification.objects.exists()) models.Notification.unnotify( self.local_user, self.remote_user, - notification_type=models.Notification.FAVORITE, + notification_type=models.NotificationType.FAVORITE, ) self.assertTrue(models.Notification.objects.exists()) models.Notification.unnotify( self.local_user, self.another_user, - notification_type=models.Notification.FAVORITE, + notification_type=models.NotificationType.FAVORITE, ) self.assertFalse(models.Notification.objects.exists()) diff --git a/bookwyrm/views/group.py b/bookwyrm/views/group.py index 1ccfd6849..5ac4954e8 100644 --- a/bookwyrm/views/group.py +++ b/bookwyrm/views/group.py @@ -13,9 +13,11 @@ from django.contrib.postgres.search import TrigramSimilarity from django.db.models.functions import Greatest from bookwyrm import forms, models +from bookwyrm.models import NotificationType from bookwyrm.suggested_users import suggested_users from .helpers import get_user_from_username, maybe_redirect_local_path + # pylint: disable=no-self-use class Group(View): """group page""" @@ -59,11 +61,11 @@ class Group(View): model = apps.get_model("bookwyrm.Notification", require_ready=True) for field in form.changed_data: notification_type = ( - model.GROUP_PRIVACY + NotificationType.GROUP_PRIVACY if field == "privacy" - else model.GROUP_NAME + else NotificationType.GROUP_NAME if field == "name" - else model.GROUP_DESCRIPTION + else NotificationType.GROUP_DESCRIPTION if field == "description" else None ) @@ -251,7 +253,9 @@ def remove_member(request): memberships = models.GroupMember.objects.filter(group=group) model = apps.get_model("bookwyrm.Notification", require_ready=True) - notification_type = model.LEAVE if user == request.user else model.REMOVE + notification_type = ( + NotificationType.LEAVE if user == request.user else NotificationType.REMOVE + ) # let the other members know about it for membership in memberships: member = membership.user @@ -264,7 +268,7 @@ def remove_member(request): ) # let the user (now ex-member) know as well, if they were removed - if notification_type == model.REMOVE: + if notification_type == NotificationType.REMOVE: model.notify( user, None, related_group=group, notification_type=notification_type ) From 891b72c79cba74327804e15dda97c24c271d9a3f Mon Sep 17 00:00:00 2001 From: Hugh Rundle Date: Mon, 13 Nov 2023 21:14:03 +1100 Subject: [PATCH 28/28] update user export file to use ActivityPub objects where possible. (#3109) * add more context to user export page * fix BookData fields wrong for files * use to_activity and to_model where possible * fixes for import and export - use AP JSON where possible - minor template wording updates * import fixes and updates tests * minor cleanup * remove todo for mastodon --- bookwyrm/activitypub/book.py | 4 +- bookwyrm/models/bookwyrm_export_job.py | 238 +++++----- bookwyrm/models/bookwyrm_import_job.py | 436 +++++++----------- bookwyrm/models/notification.py | 2 - bookwyrm/templates/import/import_user.html | 2 +- .../templates/preferences/export-user.html | 1 + .../tests/data/bookwyrm_account_export.tar.gz | Bin 161361 -> 104793 bytes bookwyrm/tests/data/user_import.json | 399 ++++++++++++++++ .../tests/models/test_bookwyrm_export_job.py | 62 ++- .../tests/models/test_bookwyrm_import_job.py | 190 +++----- 10 files changed, 800 insertions(+), 534 deletions(-) create mode 100644 bookwyrm/tests/data/user_import.json diff --git a/bookwyrm/activitypub/book.py b/bookwyrm/activitypub/book.py index 5db0dc3ac..a53222053 100644 --- a/bookwyrm/activitypub/book.py +++ b/bookwyrm/activitypub/book.py @@ -22,8 +22,6 @@ class BookData(ActivityObject): aasin: Optional[str] = None isfdb: Optional[str] = None lastEditedBy: Optional[str] = None - links: list[str] = field(default_factory=list) - fileLinks: list[str] = field(default_factory=list) # pylint: disable=invalid-name @@ -45,6 +43,8 @@ class Book(BookData): firstPublishedDate: str = "" publishedDate: str = "" + fileLinks: list[str] = field(default_factory=list) + cover: Optional[Document] = None type: str = "Book" diff --git a/bookwyrm/models/bookwyrm_export_job.py b/bookwyrm/models/bookwyrm_export_job.py index 80912b9e3..1f6085e0c 100644 --- a/bookwyrm/models/bookwyrm_export_job.py +++ b/bookwyrm/models/bookwyrm_export_job.py @@ -1,5 +1,6 @@ """Export user account to tar.gz file for import into another Bookwyrm instance""" +import dataclasses import logging from uuid import uuid4 @@ -8,12 +9,11 @@ from django.db.models import Q from django.core.serializers.json import DjangoJSONEncoder from django.core.files.base import ContentFile -from bookwyrm.models import AnnualGoal, ReadThrough, ShelfBook, Shelf, List, ListItem +from bookwyrm.models import AnnualGoal, ReadThrough, ShelfBook, List, ListItem from bookwyrm.models import Review, Comment, Quotation -from bookwyrm.models import Edition, Book +from bookwyrm.models import Edition from bookwyrm.models import UserFollows, User, UserBlocks from bookwyrm.models.job import ParentJob, ParentTask -from bookwyrm.settings import DOMAIN from bookwyrm.tasks import app, IMPORTS from bookwyrm.utils.tar import BookwyrmTarFile @@ -63,7 +63,7 @@ def tar_export(json_data: str, user, file): if getattr(user, "avatar", False): tar.add_image(user.avatar, filename="avatar") - editions, books = get_books_for_user(user) # pylint: disable=unused-variable + editions = get_books_for_user(user) for book in editions: if getattr(book, "cover", False): tar.add_image(book.cover) @@ -71,138 +71,162 @@ def tar_export(json_data: str, user, file): file.close() -def json_export(user): # pylint: disable=too-many-locals, too-many-statements +def json_export( + user, +): # pylint: disable=too-many-locals, too-many-statements, too-many-branches """Generate an export for a user""" - # user - exported_user = {} + + # User as AP object + exported_user = user.to_activity() + # I don't love this but it prevents a JSON encoding error + # when there is no user image + if isinstance( + exported_user["icon"], + dataclasses._MISSING_TYPE, # pylint: disable=protected-access + ): + exported_user["icon"] = {} + else: + # change the URL to be relative to the JSON file + file_type = exported_user["icon"]["url"].rsplit(".", maxsplit=1)[-1] + filename = f"avatar.{file_type}" + exported_user["icon"]["url"] = filename + + # Additional settings - can't be serialized as AP vals = [ - "username", - "name", - "summary", - "manually_approves_followers", - "hide_follows", "show_goal", - "show_suggested_users", - "discoverable", "preferred_timezone", "default_post_privacy", + "show_suggested_users", ] + exported_user["settings"] = {} for k in vals: - exported_user[k] = getattr(user, k) + exported_user["settings"][k] = getattr(user, k) - if getattr(user, "avatar", False): - exported_user["avatar"] = f'https://{DOMAIN}{getattr(user, "avatar").url}' - - # reading goals + # Reading goals - can't be serialized as AP reading_goals = AnnualGoal.objects.filter(user=user).distinct() - goals_list = [] - # TODO: either error checking should be more sophisticated - # or maybe we don't need this try/except - try: - for goal in reading_goals: - goals_list.append( - {"goal": goal.goal, "year": goal.year, "privacy": goal.privacy} - ) - except Exception: # pylint: disable=broad-except - pass + exported_user["goals"] = [] + for goal in reading_goals: + exported_user["goals"].append( + {"goal": goal.goal, "year": goal.year, "privacy": goal.privacy} + ) - try: - readthroughs = ReadThrough.objects.filter(user=user).distinct().values() - readthroughs = list(readthroughs) - except Exception: # pylint: disable=broad-except - readthroughs = [] + # Reading history - can't be serialized as AP + readthroughs = ReadThrough.objects.filter(user=user).distinct().values() + readthroughs = list(readthroughs) - # books - editions, books = get_books_for_user(user) - final_books = [] + # Books + editions = get_books_for_user(user) + exported_user["books"] = [] + + for edition in editions: + book = {} + book["work"] = edition.parent_work.to_activity() + book["edition"] = edition.to_activity() + + if book["edition"].get("cover"): + # change the URL to be relative to the JSON file + filename = book["edition"]["cover"]["url"].rsplit("/", maxsplit=1)[-1] + book["edition"]["cover"]["url"] = f"covers/{filename}" - for book in books.values(): - edition = editions.filter(id=book["id"]) - book["edition"] = edition.values()[0] # authors - book["authors"] = list(edition.first().authors.all().values()) - # readthroughs + book["authors"] = [] + for author in edition.authors.all(): + book["authors"].append(author.to_activity()) + + # Shelves this book is on + # Every ShelfItem is this book so we don't other serializing + book["shelves"] = [] + shelf_books = ( + ShelfBook.objects.select_related("shelf") + .filter(user=user, book=edition) + .distinct() + ) + + for shelfbook in shelf_books: + book["shelves"].append(shelfbook.shelf.to_activity()) + + # Lists and ListItems + # ListItems include "notes" and "approved" so we need them + # even though we know it's this book + book["lists"] = [] + list_items = ListItem.objects.filter(book=edition, user=user).distinct() + + for item in list_items: + list_info = item.book_list.to_activity() + list_info[ + "privacy" + ] = item.book_list.privacy # this isn't serialized so we add it + list_info["list_item"] = item.to_activity() + book["lists"].append(list_info) + + # Statuses + # Can't use select_subclasses here because + # we need to filter on the "book" value, + # which is not available on an ordinary Status + for status in ["comments", "quotations", "reviews"]: + book[status] = [] + + comments = Comment.objects.filter(user=user, book=edition).all() + for status in comments: + obj = status.to_activity() + obj["progress"] = status.progress + obj["progress_mode"] = status.progress_mode + book["comments"].append(obj) + + quotes = Quotation.objects.filter(user=user, book=edition).all() + for status in quotes: + obj = status.to_activity() + obj["position"] = status.position + obj["endposition"] = status.endposition + obj["position_mode"] = status.position_mode + book["quotations"].append(obj) + + reviews = Review.objects.filter(user=user, book=edition).all() + for status in reviews: + obj = status.to_activity() + book["reviews"].append(obj) + + # readthroughs can't be serialized to activity book_readthroughs = ( - ReadThrough.objects.filter(user=user, book=book["id"]).distinct().values() + ReadThrough.objects.filter(user=user, book=edition).distinct().values() ) book["readthroughs"] = list(book_readthroughs) - # shelves - shelf_books = ShelfBook.objects.filter(user=user, book=book["id"]).distinct() - shelves_from_books = Shelf.objects.filter(shelfbook__in=shelf_books, user=user) - - book["shelves"] = list(shelves_from_books.values()) - book["shelf_books"] = {} - - for shelf in shelves_from_books: - shelf_contents = ShelfBook.objects.filter(user=user, shelf=shelf).distinct() - - book["shelf_books"][shelf.identifier] = list(shelf_contents.values()) - - # book lists - book_lists = List.objects.filter(books__in=[book["id"]], user=user).distinct() - book["lists"] = list(book_lists.values()) - book["list_items"] = {} - for blist in book_lists: - list_items = ListItem.objects.filter(book_list=blist).distinct() - book["list_items"][blist.name] = list(list_items.values()) - - # reviews - reviews = Review.objects.filter(user=user, book=book["id"]).distinct() - - book["reviews"] = list(reviews.values()) - - # comments - comments = Comment.objects.filter(user=user, book=book["id"]).distinct() - - book["comments"] = list(comments.values()) - - # quotes - quotes = Quotation.objects.filter(user=user, book=book["id"]).distinct() - - book["quotes"] = list(quotes.values()) # append everything - final_books.append(book) + exported_user["books"].append(book) - # saved book lists + # saved book lists - just the remote id saved_lists = List.objects.filter(id__in=user.saved_lists.all()).distinct() - saved_lists = [l.remote_id for l in saved_lists] + exported_user["saved_lists"] = [l.remote_id for l in saved_lists] - # follows + # follows - just the remote id follows = UserFollows.objects.filter(user_subject=user).distinct() following = User.objects.filter(userfollows_user_object__in=follows).distinct() - follows = [f.remote_id for f in following] + exported_user["follows"] = [f.remote_id for f in following] - # blocks + # blocks - just the remote id blocks = UserBlocks.objects.filter(user_subject=user).distinct() blocking = User.objects.filter(userblocks_user_object__in=blocks).distinct() - blocks = [b.remote_id for b in blocking] + exported_user["blocks"] = [b.remote_id for b in blocking] - data = { - "user": exported_user, - "goals": goals_list, - "books": final_books, - "saved_lists": saved_lists, - "follows": follows, - "blocked_users": blocks, - } - - return DjangoJSONEncoder().encode(data) + return DjangoJSONEncoder().encode(exported_user) def get_books_for_user(user): - """Get all the books and editions related to a user - :returns: tuple of editions, books - """ + """Get all the books and editions related to a user""" - editions = Edition.objects.filter( - Q(shelves__user=user) - | Q(readthrough__user=user) - | Q(review__user=user) - | Q(list__user=user) - | Q(comment__user=user) - | Q(quotation__user=user) - ).distinct() - books = Book.objects.filter(id__in=editions).distinct() - return editions, books + editions = ( + Edition.objects.select_related("parent_work") + .filter( + Q(shelves__user=user) + | Q(readthrough__user=user) + | Q(review__user=user) + | Q(list__user=user) + | Q(comment__user=user) + | Q(quotation__user=user) + ) + .distinct() + ) + + return editions diff --git a/bookwyrm/models/bookwyrm_import_job.py b/bookwyrm/models/bookwyrm_import_job.py index 16dad1bfc..461f2cf0f 100644 --- a/bookwyrm/models/bookwyrm_import_job.py +++ b/bookwyrm/models/bookwyrm_import_job.py @@ -1,13 +1,11 @@ """Import a user from another Bookwyrm instance""" -from functools import reduce import json import logging -import operator from django.db.models import FileField, JSONField, CharField -from django.db.models import Q -from django.utils.dateparse import parse_datetime +from django.utils import timezone +from django.utils.html import strip_tags from django.contrib.postgres.fields import ArrayField as DjangoArrayField from bookwyrm import activitypub @@ -47,9 +45,9 @@ def start_import_task(**kwargs): job.import_data = json.loads(tar.read("archive.json").decode("utf-8")) if "include_user_profile" in job.required: - update_user_profile(job.user, tar, job.import_data.get("user")) + update_user_profile(job.user, tar, job.import_data) if "include_user_settings" in job.required: - update_user_settings(job.user, job.import_data.get("user")) + update_user_settings(job.user, job.import_data) if "include_goals" in job.required: update_goals(job.user, job.import_data.get("goals")) if "include_saved_lists" in job.required: @@ -57,7 +55,7 @@ def start_import_task(**kwargs): if "include_follows" in job.required: upsert_follows(job.user, job.import_data.get("follows")) if "include_blocks" in job.required: - upsert_user_blocks(job.user, job.import_data.get("blocked_users")) + upsert_user_blocks(job.user, job.import_data.get("blocks")) process_books(job, tar) @@ -70,10 +68,12 @@ def start_import_task(**kwargs): def process_books(job, tar): - """process user import data related to books""" + """ + Process user import data related to books + We always import the books even if not assigning + them to shelves, lists etc + """ - # create the books. We need to merge Book and Edition instances - # and also check whether these books already exist in the DB books = job.import_data.get("books") for data in books: @@ -85,308 +85,193 @@ def process_books(job, tar): if "include_readthroughs" in job.required: upsert_readthroughs(data.get("readthroughs"), job.user, book.id) - if "include_reviews" in job.required: - get_or_create_statuses( - job.user, models.Review, data.get("reviews"), book.id - ) - if "include_comments" in job.required: - get_or_create_statuses( - job.user, models.Comment, data.get("comments"), book.id + upsert_statuses( + job.user, models.Comment, data.get("comments"), book.remote_id + ) + if "include_quotations" in job.required: + upsert_statuses( + job.user, models.Quotation, data.get("quotations"), book.remote_id ) - if "include_quotes" in job.required: - get_or_create_statuses( - job.user, models.Quotation, data.get("quotes"), book.id + if "include_reviews" in job.required: + upsert_statuses( + job.user, models.Review, data.get("reviews"), book.remote_id ) + if "include_lists" in job.required: - upsert_lists(job.user, data.get("lists"), data.get("list_items"), book.id) + upsert_lists(job.user, data.get("lists"), book.id) def get_or_create_edition(book_data, tar): - """Take a JSON string of book and edition data, - find or create the edition in the database and + """Take a JSON string of work and edition data, + find or create the edition and work in the database and return an edition instance""" - cover_path = book_data.get( - "cover", None - ) # we use this further down but need to assign a var before cleaning - - clean_book = clean_values(book_data) - book = clean_book.copy() # don't mutate the original book data - - # prefer edition values only if they are not null - edition = clean_values(book["edition"]) - for key in edition.keys(): - if key not in book.keys() or ( - key in book.keys() and (edition[key] not in [None, ""]) - ): - book[key] = edition[key] - - existing = find_existing(models.Edition, book) + edition = book_data.get("edition") + existing = models.Edition.find_existing(edition) if existing: return existing - # the book is not in the local database, so we have to do this the hard way - local_authors = get_or_create_authors(book["authors"]) + # make sure we have the authors in the local DB + # replace the old author ids in the edition JSON + edition["authors"] = [] + for author in book_data.get("authors"): + parsed_author = activitypub.parse(author) + instance = parsed_author.to_model( + model=models.Author, save=True, overwrite=True + ) - # get rid of everything that's not strictly in a Book - # or is many-to-many so can't be set directly - associated_values = [ - "edition", - "authors", - "readthroughs", - "shelves", - "shelf_books", - "lists", - "list_items", - "reviews", - "comments", - "quotes", - ] + edition["authors"].append(instance.remote_id) - for val in associated_values: - del book[val] + # we will add the cover later from the tar + # don't try to load it from the old server + cover = edition.get("cover", {}) + cover_path = cover.get("url", None) + edition["cover"] = {} - # now we can save the book as an Edition - new_book = models.Edition.objects.create(**book) - new_book.authors.set(local_authors) # now we can add authors with set() + # first we need the parent work to exist + work = book_data.get("work") + work["editions"] = [] + parsed_work = activitypub.parse(work) + work_instance = parsed_work.to_model(model=models.Work, save=True, overwrite=True) - # get cover from original book_data because we lost it in clean_values + # now we have a work we can add it to the edition + # and create the edition model instance + edition["work"] = work_instance.remote_id + parsed_edition = activitypub.parse(edition) + book = parsed_edition.to_model(model=models.Edition, save=True, overwrite=True) + + # set the cover image from the tar if cover_path: - tar.write_image_to_file(cover_path, new_book.cover) + tar.write_image_to_file(cover_path, book.cover) - # NOTE: clean_values removes "last_edited_by" - # because it's a user ID from the old database - # if this is required, bookwyrm_export_job will - # need to bring in the user who edited it. - - # create parent - work = models.Work.objects.create(title=book["title"]) - work.authors.set(local_authors) - new_book.parent_work = work - - new_book.save(broadcast=False) - return new_book - - -def clean_values(data): - """clean values we don't want when creating new instances""" - - values = [ - "id", - "pk", - "remote_id", - "cover", - "preview_image", - "last_edited_by", - "last_edited_by_id", - "user", - "book_list", - "shelf_book", - "parent_work_id", - ] - - common = data.keys() & values - new_data = data - for val in common: - del new_data[val] - return new_data - - -def find_existing(cls, data): - """Given a book or author, find any existing model instances""" - - identifiers = [ - "openlibrary_key", - "inventaire_id", - "librarything_key", - "goodreads_key", - "asin", - "isfdb", - "isbn_10", - "isbn_13", - "oclc_number", - "origin_id", - "viaf", - "wikipedia_link", - "isni", - "gutenberg_id", - ] - - match_fields = [] - for i in identifiers: - if data.get(i) not in [None, ""]: - match_fields.append({i: data.get(i)}) - - if len(match_fields) > 0: - match = cls.objects.filter(reduce(operator.or_, (Q(**f) for f in match_fields))) - return match.first() - return None - - -def get_or_create_authors(data): - """Take a JSON string of authors find or create the authors - in the database and return a list of author instances""" - - authors = [] - for author in data: - clean = clean_values(author) - existing = find_existing(models.Author, clean) - if existing: - authors.append(existing) - else: - new = models.Author.objects.create(**clean) - authors.append(new) - return authors + return book def upsert_readthroughs(data, user, book_id): - """Take a JSON string of readthroughs, find or create the - instances in the database and return a list of saved instances""" + """Take a JSON string of readthroughs and + find or create the instances in the database""" - for read_thru in data: - start_date = ( - parse_datetime(read_thru["start_date"]) - if read_thru["start_date"] is not None - else None - ) - finish_date = ( - parse_datetime(read_thru["finish_date"]) - if read_thru["finish_date"] is not None - else None - ) - stopped_date = ( - parse_datetime(read_thru["stopped_date"]) - if read_thru["stopped_date"] is not None - else None - ) - readthrough = { - "user": user, - "book": models.Edition.objects.get(id=book_id), - "progress": read_thru["progress"], - "progress_mode": read_thru["progress_mode"], - "start_date": start_date, - "finish_date": finish_date, - "stopped_date": stopped_date, - "is_active": read_thru["is_active"], - } + for read_through in data: - existing = models.ReadThrough.objects.filter(**readthrough).exists() + obj = {} + keys = [ + "progress_mode", + "start_date", + "finish_date", + "stopped_date", + "is_active", + ] + for key in keys: + obj[key] = read_through[key] + obj["user_id"] = user.id + obj["book_id"] = book_id + + existing = models.ReadThrough.objects.filter(**obj).first() if not existing: - models.ReadThrough.objects.create(**readthrough) + models.ReadThrough.objects.create(**obj) -def get_or_create_statuses(user, cls, data, book_id): +def upsert_statuses(user, cls, data, book_remote_id): """Take a JSON string of a status and find or create the instances in the database""" - for book_status in data: + for status in data: - keys = [ - "content", - "raw_content", - "content_warning", - "privacy", - "sensitive", - "published_date", - "reading_status", - "name", - "rating", - "quote", - "raw_quote", + # update ids and remove replies + status["attributedTo"] = user.remote_id + status["to"] = update_followers_address(user, status["to"]) + status["cc"] = update_followers_address(user, status["cc"]) + status[ + "replies" + ] = {} # this parses incorrectly but we can't set it without knowing the new id + status["inReplyToBook"] = book_remote_id + + # save new status or do update it if it already exists + parsed = activitypub.parse(status) + instance = parsed.to_model(model=cls, save=True, overwrite=True) + + print(instance.id, instance.privacy) + + for val in [ "progress", "progress_mode", "position", + "endposition", "position_mode", - ] - common = book_status.keys() & keys - status = {k: book_status[k] for k in common} - status["published_date"] = parse_datetime(book_status["published_date"]) - if "rating" in common: - status["rating"] = float(book_status["rating"]) - book = models.Edition.objects.get(id=book_id) - exists = cls.objects.filter(**status, book=book, user=user).exists() - if not exists: - cls.objects.create(**status, book=book, user=user) + ]: + if status.get(val): + print(val, status[val]) + instance.val = status[val] + instance.save() -def upsert_lists(user, lists, items, book_id): - """Take a list and ListItems as JSON and - create DB entries if they don't already exist""" +def upsert_lists(user, lists, book_id): + """Take a list of objects each containing + a list and list item as AP objects + + Because we are creating new IDs we can't assume the id + will exist or be accurate, so we only use to_model for + adding new items after checking whether they exist . + + """ book = models.Edition.objects.get(id=book_id) - for lst in lists: - book_list = models.List.objects.filter(name=lst["name"], user=user).first() - if not book_list: - book_list = models.List.objects.create( + for blist in lists: + booklist = models.List.objects.filter(name=blist["name"], user=user).first() + if not booklist: + + blist["owner"] = user.remote_id + parsed = activitypub.parse(blist) + booklist = parsed.to_model(model=models.List, save=True, overwrite=True) + + booklist.privacy = blist["privacy"] + booklist.save() + + item = models.ListItem.objects.filter(book=book, book_list=booklist).exists() + if not item: + count = booklist.books.count() + models.ListItem.objects.create( + book=book, + book_list=booklist, user=user, - name=lst["name"], - description=lst["description"], - curation=lst["curation"], - privacy=lst["privacy"], + notes=blist["list_item"]["notes"], + approved=blist["list_item"]["approved"], + order=count + 1, ) - # If the list exists but the ListItem doesn't don't try to add it - # with the same order as an existing item - count = models.ListItem.objects.filter(book_list=book_list).count() - - for i in items[lst["name"]]: - if not models.ListItem.objects.filter( - book=book, book_list=book_list, user=user - ).exists(): - models.ListItem.objects.create( - book=book, - book_list=book_list, - user=user, - notes=i["notes"], - order=i["order"] + count, - ) - def upsert_shelves(book, user, book_data): - """Take shelf and ShelfBooks JSON objects and create + """Take shelf JSON objects and create DB entries if they don't already exist""" shelves = book_data["shelves"] - for shelf in shelves: + book_shelf = models.Shelf.objects.filter(name=shelf["name"], user=user).first() + if not book_shelf: - book_shelf = models.Shelf.objects.create( - name=shelf["name"], - user=user, - identifier=shelf["identifier"], - description=shelf["description"], - editable=shelf["editable"], - privacy=shelf["privacy"], + book_shelf = models.Shelf.objects.create(name=shelf["name"], user=user) + + # add the book as a ShelfBook if needed + if not models.ShelfBook.objects.filter( + book=book, shelf=book_shelf, user=user + ).exists(): + models.ShelfBook.objects.create( + book=book, shelf=book_shelf, user=user, shelved_date=timezone.now() ) - for shelfbook in book_data["shelf_books"][book_shelf.identifier]: - - shelved_date = parse_datetime(shelfbook["shelved_date"]) - - if not models.ShelfBook.objects.filter( - book=book, shelf=book_shelf, user=user - ).exists(): - models.ShelfBook.objects.create( - book=book, - shelf=book_shelf, - user=user, - shelved_date=shelved_date, - ) - def update_user_profile(user, tar, data): """update the user's profile from import data""" - name = data.get("name") - username = data.get("username").split("@")[0] + name = data.get("name", None) + username = data.get("preferredUsername") user.name = name if name else username - user.summary = data.get("summary") + user.summary = strip_tags(data.get("summary", None)) user.save(update_fields=["name", "summary"]) - - if data.get("avatar") is not None: + if data["icon"].get("url"): avatar_filename = next(filter(lambda n: n.startswith("avatar"), tar.getnames())) tar.write_image_to_file(avatar_filename, user.avatar) @@ -394,18 +279,28 @@ def update_user_profile(user, tar, data): def update_user_settings(user, data): """update the user's settings from import data""" - update_fields = [ - "manually_approves_followers", - "hide_follows", - "show_goal", - "show_suggested_users", - "discoverable", - "preferred_timezone", - "default_post_privacy", + update_fields = ["manually_approves_followers", "hide_follows", "discoverable"] + + ap_fields = [ + ("manuallyApprovesFollowers", "manually_approves_followers"), + ("hideFollows", "hide_follows"), + ("discoverable", "discoverable"), ] - for field in update_fields: - setattr(user, field, data[field]) + for (ap_field, bw_field) in ap_fields: + setattr(user, bw_field, data[ap_field]) + + bw_fields = [ + "show_goal", + "show_suggested_users", + "default_post_privacy", + "preferred_timezone", + ] + + for field in bw_fields: + update_fields.append(field) + setattr(user, field, data["settings"][field]) + user.save(update_fields=update_fields) @@ -421,7 +316,7 @@ def update_goals(user, data): """update the user's goals from import data""" for goal in data: - # edit the existing goal if there is one instead of making a new one + # edit the existing goal if there is one existing = models.AnnualGoal.objects.filter( year=goal["year"], user=user ).first() @@ -513,3 +408,14 @@ def upsert_user_blocks_task(job_id): return upsert_user_blocks( parent_job.user, parent_job.import_data.get("blocked_users") ) + + +def update_followers_address(user, field): + """statuses to or cc followers need to have the followers + address updated to the new local user""" + + for i, audience in enumerate(field): + if audience.rsplit("/")[-1] == "followers": + field[i] = user.followers_url + + return field diff --git a/bookwyrm/models/notification.py b/bookwyrm/models/notification.py index e0aefea0a..f9cbee8d8 100644 --- a/bookwyrm/models/notification.py +++ b/bookwyrm/models/notification.py @@ -261,9 +261,7 @@ def notify_user_on_user_export_complete( """we exported your user details! aren't you proud of us""" update_fields = update_fields or [] if not instance.complete or "complete" not in update_fields: - print("RETURNING", instance.status) return - print("NOTIFYING") Notification.objects.create( user=instance.user, notification_type=Notification.USER_EXPORT, diff --git a/bookwyrm/templates/import/import_user.html b/bookwyrm/templates/import/import_user.html index 29081df00..681ed6756 100644 --- a/bookwyrm/templates/import/import_user.html +++ b/bookwyrm/templates/import/import_user.html @@ -132,7 +132,7 @@ {% trans "Book reviews" %}
{% endblocktrans %} diff --git a/bookwyrm/tests/data/bookwyrm_account_export.tar.gz b/bookwyrm/tests/data/bookwyrm_account_export.tar.gz index 7612db57ed6897816af33a834ec7e19694efe592..34cee6bc001a7d834d45506100a98c1b01bcefa2 100644 GIT binary patch literal 104793 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 *QYZ41$Xu+whN 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 -s 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 IXaLXx0HeG@zW@LL diff --git a/bookwyrm/tests/data/user_import.json b/bookwyrm/tests/data/user_import.json new file mode 100644 index 000000000..0318ddfeb --- /dev/null +++ b/bookwyrm/tests/data/user_import.json @@ -0,0 +1,399 @@ +{ + "id": "https://www.example.com/user/rat", + "type": "Person", + "preferredUsername": "rat", + "inbox": "https://www.example.com/user/rat/inbox", + "publicKey": { + "id": "https://www.example.com/user/rat/#main-key", + "owner": "https://www.example.com/user/rat", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nzzzz\n-----END PUBLIC KEY-----" + }, + "followers": "https://www.example.com/user/rat/followers", + "following": "https://www.example.com/user/rat/following", + "outbox": "https://www.example.com/user/rat/outbox", + "endpoints": { + "sharedInbox": "https://www.example.com/inbox" + }, + "name": "Rat", + "summary": "

I love to make soup in Paris and eat pizza in New York

", + "icon": { + "type": "Document", + "url": "avatar.png", + "name": "avatar for rat", + "@context": "https://www.w3.org/ns/activitystreams" + }, + "bookwyrmUser": true, + "manuallyApprovesFollowers": true, + "discoverable": false, + "hideFollows": true, + "alsoKnownAs": [], + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1", + { + "manuallyApprovesFollowers": "as:manuallyApprovesFollowers", + "schema": "http://schema.org#", + "PropertyValue": "schema:PropertyValue", + "value": "schema:value", + "alsoKnownAs": { + "@id": "as:alsoKnownAs", + "@type": "@id" + }, + "movedTo": { + "@id": "as:movedTo", + "@type": "@id" + } + } + ], + "settings": { + "show_goal": false, + "preferred_timezone": "Australia/Adelaide", + "default_post_privacy": "followers", + "show_suggested_users": false + }, + "goals": [ + { + "goal": 12, + "year": 2023, + "privacy": "followers" + } + ], + "books": [ + { + "work": { + "id": "https://www.example.com/book/1", + "type": "Work", + "title": "Seeing Like a State", + "description": "

Examines how (sometimes quasi-) authoritarian high-modernist planning fails to deliver the goods, be they increased resources for the state or a better life for the people.

", + "languages": [ "English" ], + "series": "", + "seriesNumber": "", + "subjects": [], + "subjectPlaces": [], + "authors": [ + "https://www.example.com/author/1" + ], + "firstPublishedDate": "", + "publishedDate": "1998-03-30T00:00:00Z", + "fileLinks": [], + "lccn": "", + "editions": [ + "https://www.example.com/book/2" + ], + "@context": "https://www.w3.org/ns/activitystreams" + }, + "edition": { + "id": "https://www.example.com/book/2", + "type": "Edition", + "openlibraryKey": "OL680025M", + "title": "Seeking Like A State", + "sortTitle": "seeing like a state", + "subtitle": "", + "description": "

Examines how (sometimes quasi-) authoritarian high-modernist planning fails to deliver the goods, be they increased resources for the state or a better life for the people.

", + "languages": ["English"], + "series": "", + "seriesNumber": "", + "subjects": [], + "subjectPlaces": [], + "authors": [ + "https://www.example.com/author/1" + ], + "firstPublishedDate": "", + "publishedDate": "", + "fileLinks": [], + "cover": { + "type": "Document", + "url": "covers/d273d638-191d-4ebf-b213-3c60dbf010fe.jpeg", + "name": "James C. Scott: Seeing like a state", + "@context": "https://www.w3.org/ns/activitystreams" + }, + "work": "https://www.example.com/book/1", + "isbn10": "", + "isbn13": "9780300070163", + "oclcNumber": "", + "physicalFormat": "", + "physicalFormatDetail": "", + "publishers": [], + "editionRank": 4, + "@context": "https://www.w3.org/ns/activitystreams" + }, + "authors": [ + { + "id": "https://www.example.com/author/1", + "type": "Author", + "name": "James C. Scott", + "aliases": [ + "James Campbell Scott", + "\u30b8\u30a7\u30fc\u30e0\u30ba\u30fbC. \u30b9\u30b3\u30c3\u30c8", + "\u30b8\u30a7\u30fc\u30e0\u30ba\u30fbC\u30fb\u30b9\u30b3\u30c3\u30c8", + "\u062c\u06cc\u0645\u0632 \u0633\u06cc. \u0627\u0633\u06a9\u0627\u062a", + "Jim Scott", + "\u062c\u064a\u0645\u0633 \u0633\u0643\u0648\u062a", + "James C. Scott", + "\u0414\u0436\u0435\u0439\u043c\u0441 \u0421\u043a\u043e\u0442\u0442", + "\u30b8\u30a7\u30fc\u30e0\u30b9\u30fbC \u30b9\u30b3\u30c3\u30c8", + "James Cameron Scott" + ], + "bio": "

American political scientist and anthropologist

", + "wikipediaLink": "https://en.wikipedia.org/wiki/James_C._Scott", + "website": "", + "@context": "https://www.w3.org/ns/activitystreams" + } + ], + "shelves": [ + { + "id": "https://www.example.com/user/rat/books/read", + "type": "Shelf", + "totalItems": 1, + "first": "https://www.example.com/user/rat/books/read?page=1", + "last": "https://www.example.com/user/rat/books/read?page=1", + "name": "Read", + "owner": "https://www.example.com/user/rat", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "cc": [ + "https://www.example.com/user/rat/followers" + ], + "@context": "https://www.w3.org/ns/activitystreams" + }, + { + "id": "https://www.example.com/user/rat/books/to-read", + "type": "Shelf", + "totalItems": 1, + "first": "https://www.example.com/user/rat/books/to-read?page=1", + "last": "https://www.example.com/user/rat/books/to-read?page=1", + "name": "To Read", + "owner": "https://www.example.com/user/rat", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "cc": [ + "https://www.example.com/user/rat/followers" + ], + "@context": "https://www.w3.org/ns/activitystreams" + } + ], + "lists": [ + { + "id": "https://www.example.com/list/2", + "type": "BookList", + "totalItems": 1, + "first": "https://www.example.com/list/2?page=1", + "last": "https://www.example.com/list/2?page=1", + "name": "my list of books", + "owner": "https://www.example.com/user/rat", + "to": [ + "https://www.example.com/user/rat/followers" + ], + "cc": [], + "summary": "Here is a description of my list", + "curation": "closed", + "@context": "https://www.w3.org/ns/activitystreams", + "privacy": "followers", + "list_item": { + "id": "https://www.example.com/user/rat/listitem/3", + "type": "ListItem", + "actor": "https://www.example.com/user/rat", + "book": "https://www.example.com/book/2", + "notes": "

It's fun.

", + "approved": true, + "order": 1, + "@context": "https://www.w3.org/ns/activitystreams" + } + } + ], + "comments": [], + "quotations": [], + "reviews": [ + { + "id": "https://www.example.com/user/rat/review/7", + "type": "Review", + "published": "2023-08-14T04:09:18.343+00:00", + "attributedTo": "https://www.example.com//user/rat", + "content": "

I like it

", + "to": [ + "https://your.domain.here/user/rat/followers" + ], + "cc": [], + "replies": { + "id": "https://www.example.com/user/rat/review/7/replies", + "type": "OrderedCollection", + "totalItems": 0, + "first": "https://www.example.com/user/rat/review/7/replies?page=1", + "last": "https://www.example.com/user/rat/review/7/replies?page=1", + "@context": "https://www.w3.org/ns/activitystreams" + }, + "summary": "Here's a spoiler alert", + "tag": [], + "attachment": [], + "sensitive": true, + "inReplyToBook": "https://www.example.com/book/6", + "name": "great book", + "rating": 5.0, + "@context": "https://www.w3.org/ns/activitystreams", + "progress": 23, + "progress_mode": "PG" + } + ], + "readthroughs": [ + { + "id": 1, + "created_date": "2023-08-14T04:00:27.544Z", + "updated_date": "2023-08-14T04:00:27.546Z", + "remote_id": "https://www.example.com/user/rat/readthrough/1", + "user_id": 1, + "book_id": 4880, + "progress": null, + "progress_mode": "PG", + "start_date": "2018-01-01T00:00:00Z", + "finish_date": "2023-08-13T00:00:00Z", + "stopped_date": null, + "is_active": false + } + ] + }, + { + "work": { + "id": "https://www.example.com/book/3", + "type": "Work", + "title": "Sand Talk: How Indigenous Thinking Can Save the World", + "description": "", + "languages": [], + "series": "", + "seriesNumber": "", + "subjects": [], + "subjectPlaces": [], + "authors": [ + "https://www.example.com/author/2" + ], + "firstPublishedDate": "", + "publishedDate": "", + "fileLinks": [], + "lccn": "", + "openlibraryKey": "OL28216445M", + "editions": [ + "https://www.example.com/book/4" + ], + "@context": "https://www.w3.org/ns/activitystreams" + }, + "edition": { + "id": "https://www.example.com/book/4", + "type": "Edition", + "title": "Sand Talk", + "sortTitle": "sand talk", + "subtitle": "How Indigenous Thinking Can Save the World", + "description": "", + "languages": [], + "series": "", + "seriesNumber": "", + "subjects": [], + "subjectPlaces": [], + "authors": [ + "https://www.example.com/author/2" + ], + "firstPublishedDate": "", + "publishedDate": "", + "fileLinks": [], + "cover": { + "type": "Document", + "url": "covers/6a553a08-2641-42a1-baa4-960df9edbbfc.jpeg", + "name": "Tyson Yunkaporta - Sand Talk", + "@context": "https://www.w3.org/ns/activitystreams" + }, + "work": "https://www.example.com/book/3", + "isbn10": "", + "isbn13": "9780062975645", + "oclcNumber": "", + "inventaireId": "isbn:9780062975645", + "physicalFormat": "paperback", + "physicalFormatDetail": "", + "publishers": [], + "editionRank": 5, + "@context": "https://www.w3.org/ns/activitystreams" + }, + "authors": [ + { + "id": "https://www.example.com/author/2", + "type": "Author", + "name": "Tyson Yunkaporta", + "aliases": [], + "bio": "", + "wikipediaLink": "", + "website": "", + "@context": "https://www.w3.org/ns/activitystreams" + } + ], + "shelves": [], + "lists": [], + "comments": [ + { + "id": "https://www.example.com/user/rat/comment/4", + "type": "Comment", + "published": "2023-08-14T04:48:18.746+00:00", + "attributedTo": "https://www.example.com/user/rat", + "content": "

this is a comment about an amazing book

", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "cc": [ + "https://www.example.com/user/rat/followers" + ], + "replies": { + "id": "https://www.example.com/user/rat/comment/4/replies", + "type": "OrderedCollection", + "totalItems": 0, + "first": "https://www.example.com/user/rat/comment/4/replies?page=1", + "last": "https://www.example.com/user/rat/comment/4/replies?page=1", + "@context": "https://www.w3.org/ns/activitystreams" + }, + "tag": [], + "attachment": [], + "sensitive": false, + "inReplyToBook": "https://www.example.com/book/4", + "readingStatus": null, + "@context": "https://www.w3.org/ns/activitystreams" + } + ], + "quotations": [ + { + "id": "https://www.example.com/user/rat/quotation/2", + "type": "Quotation", + "published": "2023-11-12T04:29:38.370305+00:00", + "attributedTo": "https://www.example.com/user/rat", + "content": "

not actually from this book lol

", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "cc": [ + "https://www.example.com/user/rat/followers" + ], + "replies": { + "id": "https://www.example.com/user/rat/quotation/2/replies", + "type": "OrderedCollection", + "totalItems": 0, + "first": "https://www.example.com/user/rat/quotation/2/replies?page=1", + "last": "https://www.example.com/user/rat/quotation/2/replies?page=1", + "@context": "https://www.w3.org/ns/activitystreams" + }, + "tag": [], + "attachment": [], + "sensitive": false, + "summary": "spoiler ahead!", + "inReplyToBook": "https://www.example.com/book/2", + "quote": "

To be or not to be

", + "@context": "https://www.w3.org/ns/activitystreams" + } + ], + "reviews": [], + "readthroughs": [] + } + ], + "saved_lists": [ + "https://local.lists/9999" + ], + "follows": [ + "https://your.domain.here/user/rat" + ], + "blocks": ["https://your.domain.here/user/badger"] +} \ No newline at end of file diff --git a/bookwyrm/tests/models/test_bookwyrm_export_job.py b/bookwyrm/tests/models/test_bookwyrm_export_job.py index d3e81a161..b5f2520a9 100644 --- a/bookwyrm/tests/models/test_bookwyrm_export_job.py +++ b/bookwyrm/tests/models/test_bookwyrm_export_job.py @@ -144,17 +144,19 @@ class BookwyrmExport(TestCase): def test_json_export_user_settings(self): """Test the json export function for basic user info""" data = export_job.json_export(self.local_user) - user_data = json.loads(data)["user"] - self.assertEqual(user_data["username"], "mouse") + user_data = json.loads(data) + self.assertEqual(user_data["preferredUsername"], "mouse") self.assertEqual(user_data["name"], "Mouse") - self.assertEqual(user_data["summary"], "I'm a real bookmouse") - self.assertEqual(user_data["manually_approves_followers"], False) - self.assertEqual(user_data["hide_follows"], False) - self.assertEqual(user_data["show_goal"], False) - self.assertEqual(user_data["show_suggested_users"], False) + self.assertEqual(user_data["summary"], "

I'm a real bookmouse

") + self.assertEqual(user_data["manuallyApprovesFollowers"], False) + self.assertEqual(user_data["hideFollows"], False) self.assertEqual(user_data["discoverable"], True) - self.assertEqual(user_data["preferred_timezone"], "America/Los Angeles") - self.assertEqual(user_data["default_post_privacy"], "followers") + self.assertEqual(user_data["settings"]["show_goal"], False) + self.assertEqual(user_data["settings"]["show_suggested_users"], False) + self.assertEqual( + user_data["settings"]["preferred_timezone"], "America/Los Angeles" + ) + self.assertEqual(user_data["settings"]["default_post_privacy"], "followers") def test_json_export_extended_user_data(self): """Test the json export function for other non-book user info""" @@ -175,10 +177,8 @@ class BookwyrmExport(TestCase): self.assertEqual(len(json_data["follows"]), 1) self.assertEqual(json_data["follows"][0], "https://your.domain.here/user/rat") # blocked users - self.assertEqual(len(json_data["blocked_users"]), 1) - self.assertEqual( - json_data["blocked_users"][0], "https://your.domain.here/user/badger" - ) + self.assertEqual(len(json_data["blocks"]), 1) + self.assertEqual(json_data["blocks"][0], "https://your.domain.here/user/badger") def test_json_export_books(self): """Test the json export function for extended user info""" @@ -188,46 +188,44 @@ class BookwyrmExport(TestCase): start_date = json_data["books"][0]["readthroughs"][0]["start_date"] self.assertEqual(len(json_data["books"]), 1) - self.assertEqual(json_data["books"][0]["title"], "Example Edition") + self.assertEqual(json_data["books"][0]["edition"]["title"], "Example Edition") self.assertEqual(len(json_data["books"][0]["authors"]), 1) self.assertEqual(json_data["books"][0]["authors"][0]["name"], "Sam Zhu") + self.assertEqual( f'"{start_date}"', DjangoJSONEncoder().encode(self.readthrough_start) ) - self.assertEqual(json_data["books"][0]["shelves"][0]["identifier"], "read") - self.assertEqual( - json_data["books"][0]["shelf_books"]["read"][0]["book_id"], self.edition.id - ) + + self.assertEqual(json_data["books"][0]["shelves"][0]["name"], "Read") self.assertEqual(len(json_data["books"][0]["lists"]), 1) self.assertEqual(json_data["books"][0]["lists"][0]["name"], "My excellent list") - self.assertEqual(len(json_data["books"][0]["list_items"]), 1) self.assertEqual( - json_data["books"][0]["list_items"]["My excellent list"][0]["book_id"], + json_data["books"][0]["lists"][0]["list_item"]["book"], + self.edition.remote_id, self.edition.id, ) self.assertEqual(len(json_data["books"][0]["reviews"]), 1) self.assertEqual(len(json_data["books"][0]["comments"]), 1) - self.assertEqual(len(json_data["books"][0]["quotes"]), 1) + self.assertEqual(len(json_data["books"][0]["quotations"]), 1) self.assertEqual(json_data["books"][0]["reviews"][0]["name"], "my review") - self.assertEqual(json_data["books"][0]["reviews"][0]["content"], "awesome") - self.assertEqual(json_data["books"][0]["reviews"][0]["rating"], "5.00") + self.assertEqual( + json_data["books"][0]["reviews"][0]["content"], "

awesome

" + ) + self.assertEqual(json_data["books"][0]["reviews"][0]["rating"], 5.0) - self.assertEqual(json_data["books"][0]["comments"][0]["content"], "ok so far") + self.assertEqual( + json_data["books"][0]["comments"][0]["content"], "

ok so far

" + ) self.assertEqual(json_data["books"][0]["comments"][0]["progress"], 15) self.assertEqual(json_data["books"][0]["comments"][0]["progress_mode"], "PG") self.assertEqual( - json_data["books"][0]["quotes"][0]["content"], "check this out" + json_data["books"][0]["quotations"][0]["content"], "

check this out

" ) self.assertEqual( - json_data["books"][0]["quotes"][0]["quote"], "A rose by any other name" + json_data["books"][0]["quotations"][0]["quote"], + "

A rose by any other name

", ) - - def test_tar_export(self): - """test the tar export function""" - - # TODO - pass # pylint: disable=unnecessary-pass diff --git a/bookwyrm/tests/models/test_bookwyrm_import_job.py b/bookwyrm/tests/models/test_bookwyrm_import_job.py index 5a41e5607..3f72f7205 100644 --- a/bookwyrm/tests/models/test_bookwyrm_import_job.py +++ b/bookwyrm/tests/models/test_bookwyrm_import_job.py @@ -53,57 +53,62 @@ class BookwyrmImport(TestCase): # pylint: disable=too-many-public-methods localname="badger", ) - self.work = models.Work.objects.create(title="Test Book") + self.work = models.Work.objects.create(title="Sand Talk") self.book = models.Edition.objects.create( - title="Test Book", + title="Sand Talk", remote_id="https://example.com/book/1234", openlibrary_key="OL28216445M", + inventaire_id="isbn:9780062975645", + isbn_13="9780062975645", parent_work=self.work, ) + self.json_file = pathlib.Path(__file__).parent.joinpath( + "../data/user_import.json" + ) + + with open(self.json_file, "r", encoding="utf-8") as jsonfile: + self.json_data = json.loads(jsonfile.read()) + self.archive_file = pathlib.Path(__file__).parent.joinpath( "../data/bookwyrm_account_export.tar.gz" ) - with open(self.archive_file, "rb") as fileobj: - with BookwyrmTarFile.open(mode="r:gz", fileobj=fileobj) as tarfile: - self.import_data = json.loads( - tarfile.read("archive.json").decode("utf-8") - ) def test_update_user_profile(self): """Test update the user's profile from import data""" with patch("bookwyrm.suggested_users.remove_user_task.delay"), patch( "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" - ): + ), patch("bookwyrm.suggested_users.rerank_user_task.delay"): with open(self.archive_file, "rb") as fileobj: with BookwyrmTarFile.open(mode="r:gz", fileobj=fileobj) as tarfile: models.bookwyrm_import_job.update_user_profile( - self.local_user, tarfile, self.import_data.get("user") + self.local_user, tarfile, self.json_data ) - self.local_user.refresh_from_db() - self.assertEqual( - self.local_user.username, "mouse" - ) # username should not change - self.assertEqual(self.local_user.name, "Rat") - self.assertEqual( - self.local_user.summary, - "I love to make soup in Paris and eat pizza in New York", - ) + self.local_user.refresh_from_db() + + self.assertEqual( + self.local_user.username, "mouse" + ) # username should not change + self.assertEqual(self.local_user.name, "Rat") + self.assertEqual( + self.local_user.summary, + "I love to make soup in Paris and eat pizza in New York", + ) def test_update_user_settings(self): """Test updating the user's settings from import data""" with patch("bookwyrm.suggested_users.remove_user_task.delay"), patch( "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" - ): + ), patch("bookwyrm.suggested_users.rerank_user_task.delay"): models.bookwyrm_import_job.update_user_settings( - self.local_user, self.import_data.get("user") + self.local_user, self.json_data ) self.local_user.refresh_from_db() @@ -125,11 +130,11 @@ class BookwyrmImport(TestCase): # pylint: disable=too-many-public-methods privacy="public", ) + goals = [{"goal": 12, "year": 2023, "privacy": "followers"}] + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): - models.bookwyrm_import_job.update_goals( - self.local_user, self.import_data.get("goals") - ) + models.bookwyrm_import_job.update_goals(self.local_user, goals) self.local_user.refresh_from_db() goal = models.AnnualGoal.objects.get() @@ -198,7 +203,7 @@ class BookwyrmImport(TestCase): # pylint: disable=too-many-public-methods "bookwyrm.lists_stream.add_user_lists_task.delay" ), patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): models.bookwyrm_import_job.upsert_follows( - self.local_user, self.import_data.get("follows") + self.local_user, self.json_data.get("follows") ) after_follow = models.UserFollows.objects.filter( @@ -223,7 +228,7 @@ class BookwyrmImport(TestCase): # pylint: disable=too-many-public-methods "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" ): models.bookwyrm_import_job.upsert_user_blocks( - self.local_user, self.import_data.get("blocked_users") + self.local_user, self.json_data.get("blocks") ) blocked_after = models.UserBlocks.objects.filter( @@ -234,19 +239,6 @@ class BookwyrmImport(TestCase): # pylint: disable=too-many-public-methods ).exists() self.assertTrue(blocked_after) - def test_get_or_create_authors(self): - """Test taking a JSON string of authors find or create the authors - in the database and returning a list of author instances""" - - author_exists = models.Author.objects.filter(isni="0000000108973024").exists() - self.assertFalse(author_exists) - - authors = self.import_data.get("books")[0]["authors"] - bookwyrm_import_job.get_or_create_authors(authors) - - author = models.Author.objects.get(isni="0000000108973024") - self.assertEqual(author.name, "James C. Scott") - def test_get_or_create_edition_existing(self): """Test take a JSON string of books and editions, find or create the editions in the database and @@ -258,7 +250,7 @@ class BookwyrmImport(TestCase): # pylint: disable=too-many-public-methods with BookwyrmTarFile.open(mode="r:gz", fileobj=fileobj) as tarfile: bookwyrm_import_job.get_or_create_edition( - self.import_data["books"][1], tarfile + self.json_data["books"][1], tarfile ) # Sand Talk self.assertEqual(models.Edition.objects.count(), 1) @@ -272,53 +264,13 @@ class BookwyrmImport(TestCase): # pylint: disable=too-many-public-methods with open(self.archive_file, "rb") as fileobj: with BookwyrmTarFile.open(mode="r:gz", fileobj=fileobj) as tarfile: + bookwyrm_import_job.get_or_create_edition( - self.import_data["books"][0], tarfile + self.json_data["books"][0], tarfile ) # Seeing like a state - self.assertTrue( - models.Edition.objects.filter(isbn_13="9780300070163").exists() - ) - self.assertEqual(models.Edition.objects.count(), 2) - - def test_clean_values(self): - """test clean values we don't want when creating new instances""" - - author = self.import_data.get("books")[0]["authors"][0] - edition = self.import_data.get("books")[0]["edition"] - - cleaned_author = bookwyrm_import_job.clean_values(author) - cleaned_edition = bookwyrm_import_job.clean_values(edition) - - self.assertEqual(cleaned_author["name"], "James C. Scott") - self.assertEqual(cleaned_author.get("id"), None) - self.assertEqual(cleaned_author.get("remote_id"), None) - self.assertEqual(cleaned_author.get("last_edited_by"), None) - self.assertEqual(cleaned_author.get("last_edited_by_id"), None) - - self.assertEqual(cleaned_edition.get("title"), "Seeing Like a State") - self.assertEqual(cleaned_edition.get("id"), None) - self.assertEqual(cleaned_edition.get("remote_id"), None) - self.assertEqual(cleaned_edition.get("last_edited_by"), None) - self.assertEqual(cleaned_edition.get("last_edited_by_id"), None) - self.assertEqual(cleaned_edition.get("cover"), None) - self.assertEqual(cleaned_edition.get("preview_image "), None) - self.assertEqual(cleaned_edition.get("user"), None) - self.assertEqual(cleaned_edition.get("book_list"), None) - self.assertEqual(cleaned_edition.get("shelf_book"), None) - - def test_find_existing(self): - """Given a book or author, find any existing model instances""" - - self.assertEqual(models.Book.objects.count(), 2) # includes Work - self.assertEqual(models.Edition.objects.count(), 1) - self.assertEqual(models.Edition.objects.first().title, "Test Book") - self.assertEqual(models.Edition.objects.first().openlibrary_key, "OL28216445M") - - existing = bookwyrm_import_job.find_existing( - models.Edition, {"openlibrary_key": "OL28216445M", "isbn_10": None} - ) - self.assertEqual(existing.title, "Test Book") + self.assertTrue(models.Edition.objects.filter(isbn_13="9780300070163").exists()) + self.assertEqual(models.Edition.objects.count(), 2) def test_upsert_readthroughs(self): """Test take a JSON string of readthroughs, find or create the @@ -332,7 +284,7 @@ class BookwyrmImport(TestCase): # pylint: disable=too-many-public-methods "remote_id": "https://example.com/mouse/readthrough/1", "user_id": 1, "book_id": 1234, - "progress": None, + "progress": 23, "progress_mode": "PG", "start_date": "2022-12-31T13:30:00Z", "finish_date": "2023-08-23T14:30:00Z", @@ -355,19 +307,20 @@ class BookwyrmImport(TestCase): # pylint: disable=too-many-public-methods self.assertEqual(models.ReadThrough.objects.first().book_id, self.book.id) self.assertEqual(models.ReadThrough.objects.first().user, self.local_user) - def test_get_or_create_review_status(self): + def test_get_or_create_review(self): """Test get_or_create_review_status with a review""" self.assertEqual(models.Review.objects.filter(user=self.local_user).count(), 0) - reviews = self.import_data["books"][0]["reviews"] + reviews = self.json_data["books"][0]["reviews"] with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): - bookwyrm_import_job.get_or_create_statuses( - self.local_user, models.Review, reviews, self.book.id + bookwyrm_import_job.upsert_statuses( + self.local_user, models.Review, reviews, self.book.remote_id ) + self.assertEqual(models.Review.objects.filter(user=self.local_user).count(), 1) self.assertEqual( - models.Review.objects.filter(book=self.book).first().raw_content, - "I like it", + models.Review.objects.filter(book=self.book).first().content, + "

I like it

", ) self.assertEqual( models.Review.objects.filter(book=self.book).first().content_warning, @@ -376,10 +329,6 @@ class BookwyrmImport(TestCase): # pylint: disable=too-many-public-methods self.assertEqual( models.Review.objects.filter(book=self.book).first().sensitive, True ) - self.assertEqual( - models.Review.objects.filter(book=self.book).first().published_date, - parse_datetime("2023-08-14T04:09:18.343Z"), - ) self.assertEqual( models.Review.objects.filter(book=self.book).first().name, "great book" ) @@ -387,19 +336,23 @@ class BookwyrmImport(TestCase): # pylint: disable=too-many-public-methods models.Review.objects.filter(book=self.book).first().rating, 5.00 ) - def test_get_or_create_comment_status(self): + self.assertEqual( + models.Review.objects.filter(book=self.book).first().privacy, "followers" + ) + + def test_get_or_create_comment(self): """Test get_or_create_review_status with a comment""" self.assertEqual(models.Comment.objects.filter(user=self.local_user).count(), 0) - comments = self.import_data["books"][1]["comments"] + comments = self.json_data["books"][1]["comments"] with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): - bookwyrm_import_job.get_or_create_statuses( - self.local_user, models.Comment, comments, self.book.id + bookwyrm_import_job.upsert_statuses( + self.local_user, models.Comment, comments, self.book.remote_id ) self.assertEqual(models.Comment.objects.filter(user=self.local_user).count(), 1) self.assertEqual( - models.Comment.objects.filter(book=self.book).first().raw_content, - "this is a comment about an amazing book", + models.Comment.objects.filter(book=self.book).first().content, + "

this is a comment about an amazing book

", ) self.assertEqual( models.Comment.objects.filter(book=self.book).first().content_warning, None @@ -407,56 +360,45 @@ class BookwyrmImport(TestCase): # pylint: disable=too-many-public-methods self.assertEqual( models.Comment.objects.filter(book=self.book).first().sensitive, False ) - self.assertEqual( - models.Comment.objects.filter(book=self.book).first().published_date, - parse_datetime("2023-08-14T04:48:18.746Z"), - ) self.assertEqual( models.Comment.objects.filter(book=self.book).first().progress_mode, "PG" ) - def test_get_or_create_comment_quote(self): + def test_get_or_create_quote(self): """Test get_or_create_review_status with a quote""" self.assertEqual( models.Quotation.objects.filter(user=self.local_user).count(), 0 ) - quotes = self.import_data["books"][1]["quotes"] + quotes = self.json_data["books"][1]["quotations"] with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): - bookwyrm_import_job.get_or_create_statuses( - self.local_user, models.Quotation, quotes, self.book.id + bookwyrm_import_job.upsert_statuses( + self.local_user, models.Quotation, quotes, self.book.remote_id ) self.assertEqual( models.Quotation.objects.filter(user=self.local_user).count(), 1 ) self.assertEqual( - models.Quotation.objects.filter(book=self.book).first().raw_content, - "not actually from this book lol", + models.Quotation.objects.filter(book=self.book).first().content, + "

not actually from this book lol

", ) self.assertEqual( models.Quotation.objects.filter(book=self.book).first().content_warning, "spoiler ahead!", ) self.assertEqual( - models.Quotation.objects.filter(book=self.book).first().raw_quote, - "To be or not to be", - ) - self.assertEqual( - models.Quotation.objects.filter(book=self.book).first().published_date, - parse_datetime("2023-08-14T04:48:50.207Z"), + models.Quotation.objects.filter(book=self.book).first().quote, + "

To be or not to be

", ) self.assertEqual( models.Quotation.objects.filter(book=self.book).first().position_mode, "PG" ) - self.assertEqual( - models.Quotation.objects.filter(book=self.book).first().position, 1 - ) def test_upsert_list_existing(self): """Take a list and ListItems as JSON and create DB entries if they don't already exist""" - book_data = self.import_data["books"][0] + book_data = self.json_data["books"][0] other_book = models.Edition.objects.create( title="Another Book", remote_id="https://example.com/book/9876" @@ -488,7 +430,6 @@ class BookwyrmImport(TestCase): # pylint: disable=too-many-public-methods bookwyrm_import_job.upsert_lists( self.local_user, book_data["lists"], - book_data["list_items"], other_book.id, ) @@ -505,7 +446,7 @@ class BookwyrmImport(TestCase): # pylint: disable=too-many-public-methods """Take a list and ListItems as JSON and create DB entries if they don't already exist""" - book_data = self.import_data["books"][0] + book_data = self.json_data["books"][0] self.assertEqual(models.List.objects.filter(user=self.local_user).count(), 0) self.assertFalse(models.ListItem.objects.filter(book=self.book.id).exists()) @@ -516,7 +457,6 @@ class BookwyrmImport(TestCase): # pylint: disable=too-many-public-methods bookwyrm_import_job.upsert_lists( self.local_user, book_data["lists"], - book_data["list_items"], self.book.id, ) @@ -542,7 +482,7 @@ class BookwyrmImport(TestCase): # pylint: disable=too-many-public-methods book=self.book, shelf=shelf, user=self.local_user ) - book_data = self.import_data["books"][0] + book_data = self.json_data["books"][0] with patch("bookwyrm.activitystreams.add_book_statuses_task.delay"), patch( "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" ): @@ -560,7 +500,7 @@ class BookwyrmImport(TestCase): # pylint: disable=too-many-public-methods models.ShelfBook.objects.filter(user=self.local_user.id).count(), 0 ) - book_data = self.import_data["books"][0] + book_data = self.json_data["books"][0] with patch("bookwyrm.activitystreams.add_book_statuses_task.delay"), patch( "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"