From 2d875b5575c580f1da2c40051c6952992f52e8c8 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 5 Dec 2021 12:28:17 -0800 Subject: [PATCH 01/15] Add link properties for remotes --- bookwyrm/models/author.py | 12 ++++++++++++ bookwyrm/models/book.py | 10 ++++++++++ bookwyrm/templates/author/author.html | 10 +++++----- bookwyrm/templates/book/book.html | 4 ++-- bookwyrm/templatetags/utilities.py | 8 -------- 5 files changed, 29 insertions(+), 15 deletions(-) diff --git a/bookwyrm/models/author.py b/bookwyrm/models/author.py index 6c29ac05..ce0d027c 100644 --- a/bookwyrm/models/author.py +++ b/bookwyrm/models/author.py @@ -1,4 +1,5 @@ """ database schema for info about authors """ +import re from django.contrib.postgres.indexes import GinIndex from django.db import models @@ -33,6 +34,17 @@ class Author(BookDataModel): ) bio = fields.HtmlField(null=True, blank=True) + @property + def isni_link(self): + """generate the url from the isni id""" + clean_isni = re.sub(r"\s", "", self.isni) + return f"https://insi.org/isni/{clean_isni}" + + @property + def openlibrary_link(self): + """generate the url from the openlibrary id""" + return f"https://openlibrary.org/authors/{self.openlibrary_key}" + def get_remote_id(self): """editions and works both use "book" instead of model_name""" return f"https://{DOMAIN}/author/{self.id}" diff --git a/bookwyrm/models/book.py b/bookwyrm/models/book.py index d97a1b8a..0a551bf2 100644 --- a/bookwyrm/models/book.py +++ b/bookwyrm/models/book.py @@ -52,6 +52,16 @@ class BookDataModel(ObjectMixin, BookWyrmModel): null=True, ) + @property + def openlibrary_link(self): + """generate the url from the openlibrary id""" + return f"https://openlibrary.org/books/{self.openlibrary_key}" + + @property + def inventaire_link(self): + """generate the url from the inventaire id""" + return f"https://inventaire.io/entity/{self.inventaire_id}" + class Meta: """can't initialize this model, that wouldn't make sense""" diff --git a/bookwyrm/templates/author/author.html b/bookwyrm/templates/author/author.html index b066c6ca..fb682176 100644 --- a/bookwyrm/templates/author/author.html +++ b/bookwyrm/templates/author/author.html @@ -66,23 +66,23 @@ {% if author.isni %}

- + {% trans "View ISNI record" %}

{% endif %} {% if author.openlibrary_key %} -

- +

+ {% trans "View on OpenLibrary" %}

{% endif %} {% if author.inventaire_id %} -

- +

+ {% trans "View on Inventaire" %}

diff --git a/bookwyrm/templates/book/book.html b/bookwyrm/templates/book/book.html index 7d4df76f..cbca31b5 100644 --- a/bookwyrm/templates/book/book.html +++ b/bookwyrm/templates/book/book.html @@ -91,10 +91,10 @@ {% endwith %} {% if book.openlibrary_key %} -

{% trans "View on OpenLibrary" %}

+

{% trans "View on OpenLibrary" %}

{% endif %} {% if book.inventaire_id %} -

{% trans "View on Inventaire" %}

+

{% trans "View on Inventaire" %}

{% endif %} diff --git a/bookwyrm/templatetags/utilities.py b/bookwyrm/templatetags/utilities.py index 5cc25fed..2246fab1 100644 --- a/bookwyrm/templatetags/utilities.py +++ b/bookwyrm/templatetags/utilities.py @@ -5,7 +5,6 @@ from uuid import uuid4 from django import template from django.utils.safestring import mark_safe from django.utils.translation import gettext_lazy as _ -from django.template.defaultfilters import stringfilter from django.templatetags.static import static @@ -98,10 +97,3 @@ def get_isni(existing, author, autoescape=True): f'' ) return "" - - -@register.filter(name="remove_spaces") -@stringfilter -def remove_spaces(arg): - """Removes spaces from argument passed in""" - return re.sub(r"\s", "", str(arg)) From b824841cb333d1624b49de06613ac324549a2a96 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 5 Dec 2021 12:37:19 -0800 Subject: [PATCH 02/15] Adds update logic to connectors --- bookwyrm/connectors/abstract_connector.py | 36 ++++++++++++++++++----- bookwyrm/connectors/inventaire.py | 2 ++ bookwyrm/connectors/openlibrary.py | 2 ++ 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/bookwyrm/connectors/abstract_connector.py b/bookwyrm/connectors/abstract_connector.py index c032986d..97ac9249 100644 --- a/bookwyrm/connectors/abstract_connector.py +++ b/bookwyrm/connectors/abstract_connector.py @@ -111,7 +111,7 @@ class AbstractConnector(AbstractMinimalConnector): return existing.default_edition return existing - # load the json + # load the json data from the remote data source data = self.get_book_data(remote_id) if self.is_work_data(data): try: @@ -150,23 +150,32 @@ class AbstractConnector(AbstractMinimalConnector): """this allows connectors to override the default behavior""" return get_data(remote_id) - def create_edition_from_data(self, work, edition_data): + def create_edition_from_data(self, work, edition_data, instance=None): """if we already have the work, we're ready""" mapped_data = dict_from_mappings(edition_data, self.book_mappings) mapped_data["work"] = work.remote_id edition_activity = activitypub.Edition(**mapped_data) - edition = edition_activity.to_model(model=models.Edition, overwrite=False) - edition.connector = self.connector - edition.save() + edition = edition_activity.to_model( + model=models.Edition, overwrite=False, instance=instance + ) + + # if we're updating an existing instance, we don't need to load authors + if instance: + return edition + + if not edition.connector: + edition.connector = self.connector + edition.save(broadcast=False, update_fields=["connector"]) for author in self.get_authors_from_data(edition_data): edition.authors.add(author) + # use the authors from the work if none are found for the edition if not edition.authors.exists() and work.authors.exists(): edition.authors.set(work.authors.all()) return edition - def get_or_create_author(self, remote_id): + def get_or_create_author(self, remote_id, instance=None): """load that author""" existing = models.Author.find_existing_by_remote_id(remote_id) if existing: @@ -181,7 +190,20 @@ class AbstractConnector(AbstractMinimalConnector): return None # this will dedupe - return activity.to_model(model=models.Author, overwrite=False) + return activity.to_model( + model=models.Author, overwrite=False, instance=instance + ) + + def update_author_from_remote(self, obj): + """load the remote data from this connector and add it to an existing author""" + remote_id = obj.getattr(self, "generated_remote_link_field") + return self.get_or_create_author(remote_id, instance=obj) + + def update_book_from_remote(self, obj): + """load the remote data from this connector and add it to an existing book""" + remote_id = obj.getattr(self, "generated_remote_link_field") + data = self.get_book_data(remote_id) + return self.create_edition_from_data(obj.parent_work, data, instance=obj) @abstractmethod def is_work_data(self, data): diff --git a/bookwyrm/connectors/inventaire.py b/bookwyrm/connectors/inventaire.py index e9f53856..bc5b3f68 100644 --- a/bookwyrm/connectors/inventaire.py +++ b/bookwyrm/connectors/inventaire.py @@ -11,6 +11,8 @@ from .connector_manager import ConnectorException class Connector(AbstractConnector): """instantiate a connector for inventaire""" + generated_remote_link_field = "inventaire_link" + def __init__(self, identifier): super().__init__(identifier) diff --git a/bookwyrm/connectors/openlibrary.py b/bookwyrm/connectors/openlibrary.py index b8afc7ca..225174c8 100644 --- a/bookwyrm/connectors/openlibrary.py +++ b/bookwyrm/connectors/openlibrary.py @@ -12,6 +12,8 @@ from .openlibrary_languages import languages class Connector(AbstractConnector): """instantiate a connector for OL""" + generated_remote_link_field = "openlibrary_link" + def __init__(self, identifier): super().__init__(identifier) From 113eda33e9cf5281b8c1aa406634f76658ae0ed9 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 5 Dec 2021 12:47:43 -0800 Subject: [PATCH 03/15] Adds update views --- bookwyrm/views/author.py | 18 ++++++++++++++++++ bookwyrm/views/books/books.py | 16 ++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/bookwyrm/views/author.py b/bookwyrm/views/author.py index 0c8e3e05..fdf86cd4 100644 --- a/bookwyrm/views/author.py +++ b/bookwyrm/views/author.py @@ -6,9 +6,11 @@ from django.shortcuts import get_object_or_404, redirect from django.template.response import TemplateResponse from django.utils.decorators import method_decorator from django.views import View +from django.views.decorators.http import require_POST from bookwyrm import forms, models from bookwyrm.activitypub import ActivitypubResponse +from bookwyrm.connectors import connector_manager from bookwyrm.settings import PAGE_LENGTH from bookwyrm.views.helpers import is_api_request @@ -73,3 +75,19 @@ class EditAuthor(View): author = form.save() return redirect(f"/author/{author.id}") + + +@login_required +@require_POST +@permission_required("bookwyrm.edit_book", raise_exception=True) +# pylint: disable=unused-argument +def update_author_from_remote(request, connector_identifier, author_id): + """load the remote data for this author""" + connector = connector_manager.load_connector( + get_object_or_404(models.Connector, identifier=connector_identifier) + ) + author = get_object_or_404(models.Book.objects.select_subclasses(), id=author_id) + + connector.update_author_from_remote(author) + + return redirect("author", author.id) diff --git a/bookwyrm/views/books/books.py b/bookwyrm/views/books/books.py index e495da3e..f7166749 100644 --- a/bookwyrm/views/books/books.py +++ b/bookwyrm/views/books/books.py @@ -178,3 +178,19 @@ def resolve_book(request): book = connector.get_or_create_book(remote_id) return redirect("book", book.id) + + +@login_required +@require_POST +@permission_required("bookwyrm.edit_book", raise_exception=True) +# pylint: disable=unused-argument +def update_book_from_remote(request, connector_identifier, book_id): + """load the remote data for this book""" + connector = connector_manager.load_connector( + get_object_or_404(models.Connector, identifier=connector_identifier) + ) + book = get_object_or_404(models.Book.objects.select_subclasses(), id=book_id) + + connector.update_book_from_remote(book) + + return redirect("book", book.id) From d7e4e6aa1e45a9bdd8c55eba449d06b4ff4f422f Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 5 Dec 2021 13:02:42 -0800 Subject: [PATCH 04/15] Adds openlibrary update for book --- bookwyrm/connectors/abstract_connector.py | 4 ++-- bookwyrm/templates/author/author.html | 6 ++++++ bookwyrm/templates/book/book.html | 8 +++++++- bookwyrm/urls.py | 9 +++++++-- bookwyrm/views/__init__.py | 1 + bookwyrm/views/author.py | 2 +- bookwyrm/views/books/books.py | 2 +- 7 files changed, 25 insertions(+), 7 deletions(-) diff --git a/bookwyrm/connectors/abstract_connector.py b/bookwyrm/connectors/abstract_connector.py index 97ac9249..48d2b4cb 100644 --- a/bookwyrm/connectors/abstract_connector.py +++ b/bookwyrm/connectors/abstract_connector.py @@ -196,12 +196,12 @@ class AbstractConnector(AbstractMinimalConnector): def update_author_from_remote(self, obj): """load the remote data from this connector and add it to an existing author""" - remote_id = obj.getattr(self, "generated_remote_link_field") + remote_id = getattr(obj, getattr(self, "generated_remote_link_field")) return self.get_or_create_author(remote_id, instance=obj) def update_book_from_remote(self, obj): """load the remote data from this connector and add it to an existing book""" - remote_id = obj.getattr(self, "generated_remote_link_field") + remote_id = getattr(obj, getattr(self, "generated_remote_link_field")) data = self.get_book_data(remote_id) return self.create_edition_from_data(obj.parent_work, data, instance=obj) diff --git a/bookwyrm/templates/author/author.html b/bookwyrm/templates/author/author.html index fb682176..c2355955 100644 --- a/bookwyrm/templates/author/author.html +++ b/bookwyrm/templates/author/author.html @@ -77,6 +77,9 @@ {% trans "View on OpenLibrary" %} + {% if request.user.is_authenticated and perms.bookwyrm.edit_book %} + + {% endif %}

{% endif %} @@ -85,6 +88,9 @@ {% trans "View on Inventaire" %} + {% if request.user.is_authenticated and perms.bookwyrm.edit_book %} + + {% endif %}

{% endif %} diff --git a/bookwyrm/templates/book/book.html b/bookwyrm/templates/book/book.html index cbca31b5..3a7b1cbc 100644 --- a/bookwyrm/templates/book/book.html +++ b/bookwyrm/templates/book/book.html @@ -91,7 +91,13 @@ {% endwith %} {% if book.openlibrary_key %} -

{% trans "View on OpenLibrary" %}

+

+ {% trans "View on OpenLibrary" %} +

+ {% csrf_token %} + +
+

{% endif %} {% if book.inventaire_id %}

{% trans "View on Inventaire" %}

diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py index 514bb7e6..697028b7 100644 --- a/bookwyrm/urls.py +++ b/bookwyrm/urls.py @@ -422,8 +422,13 @@ urlpatterns = [ r"^upload-cover/(?P\d+)/?$", views.upload_cover, name="upload-cover" ), re_path(r"^add-description/(?P\d+)/?$", views.add_description), - re_path(r"^resolve-book/?$", views.resolve_book), - re_path(r"^switch-edition/?$", views.switch_edition), + re_path(r"^resolve-book/?$", views.resolve_book, name="resolve-book"), + re_path(r"^switch-edition/?$", views.switch_edition, name="switch-edition"), + re_path( + rf"{BOOK_PATH}/update/(?P[\w\.]+)?$", + views.update_book_from_remote, + name="book-update-remote" + ), # isbn re_path(r"^isbn/(?P\d+)(.json)?/?$", views.Isbn.as_view()), # author diff --git a/bookwyrm/views/__init__.py b/bookwyrm/views/__init__.py index d79de424..b399b90a 100644 --- a/bookwyrm/views/__init__.py +++ b/bookwyrm/views/__init__.py @@ -29,6 +29,7 @@ from .preferences.block import Block, unblock # books from .books.books import Book, upload_cover, add_description, resolve_book +from .books.books import update_book_from_remote from .books.edit_book import EditBook, ConfirmEditBook from .books.editions import Editions, switch_edition diff --git a/bookwyrm/views/author.py b/bookwyrm/views/author.py index fdf86cd4..838d1c2b 100644 --- a/bookwyrm/views/author.py +++ b/bookwyrm/views/author.py @@ -81,7 +81,7 @@ class EditAuthor(View): @require_POST @permission_required("bookwyrm.edit_book", raise_exception=True) # pylint: disable=unused-argument -def update_author_from_remote(request, connector_identifier, author_id): +def update_author_from_remote(request, author_id, connector_identifier): """load the remote data for this author""" connector = connector_manager.load_connector( get_object_or_404(models.Connector, identifier=connector_identifier) diff --git a/bookwyrm/views/books/books.py b/bookwyrm/views/books/books.py index f7166749..2d49ae30 100644 --- a/bookwyrm/views/books/books.py +++ b/bookwyrm/views/books/books.py @@ -184,7 +184,7 @@ def resolve_book(request): @require_POST @permission_required("bookwyrm.edit_book", raise_exception=True) # pylint: disable=unused-argument -def update_book_from_remote(request, connector_identifier, book_id): +def update_book_from_remote(request, book_id, connector_identifier): """load the remote data for this book""" connector = connector_manager.load_connector( get_object_or_404(models.Connector, identifier=connector_identifier) From 4085714764af94157e740848f1c90472f0b16e5c Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 5 Dec 2021 13:24:40 -0800 Subject: [PATCH 05/15] Update openlibrary author with ISNI --- bookwyrm/connectors/abstract_connector.py | 7 ++++--- bookwyrm/connectors/openlibrary.py | 8 ++++++++ bookwyrm/models/author.py | 2 +- bookwyrm/templates/author/author.html | 16 +++++++++++----- bookwyrm/templates/book/book.html | 2 ++ bookwyrm/urls.py | 19 +++++++++++++++---- bookwyrm/views/__init__.py | 2 +- bookwyrm/views/author.py | 2 +- 8 files changed, 43 insertions(+), 15 deletions(-) diff --git a/bookwyrm/connectors/abstract_connector.py b/bookwyrm/connectors/abstract_connector.py index 48d2b4cb..4b1f6e58 100644 --- a/bookwyrm/connectors/abstract_connector.py +++ b/bookwyrm/connectors/abstract_connector.py @@ -177,9 +177,10 @@ class AbstractConnector(AbstractMinimalConnector): def get_or_create_author(self, remote_id, instance=None): """load that author""" - existing = models.Author.find_existing_by_remote_id(remote_id) - if existing: - return existing + if not instance: + existing = models.Author.find_existing_by_remote_id(remote_id) + if existing: + return existing data = self.get_book_data(remote_id) diff --git a/bookwyrm/connectors/openlibrary.py b/bookwyrm/connectors/openlibrary.py index 225174c8..c15277f8 100644 --- a/bookwyrm/connectors/openlibrary.py +++ b/bookwyrm/connectors/openlibrary.py @@ -68,6 +68,7 @@ class Connector(AbstractConnector): Mapping("born", remote_field="birth_date"), Mapping("died", remote_field="death_date"), Mapping("bio", formatter=get_description), + Mapping("isni", remote_field="remote_ids", formatter=get_isni), ] def get_book_data(self, remote_id): @@ -226,6 +227,13 @@ def get_languages(language_blob): return langs +def get_isni(remote_ids_blob): + """extract the isni from the remote id data for the author""" + if not remote_ids_blob or not isinstance(remote_ids_blob, dict): + return None + return remote_ids_blob.get("isni") + + def pick_default_edition(options): """favor physical copies with covers in english""" if not options: diff --git a/bookwyrm/models/author.py b/bookwyrm/models/author.py index ce0d027c..5cc11afd 100644 --- a/bookwyrm/models/author.py +++ b/bookwyrm/models/author.py @@ -38,7 +38,7 @@ class Author(BookDataModel): def isni_link(self): """generate the url from the isni id""" clean_isni = re.sub(r"\s", "", self.isni) - return f"https://insi.org/isni/{clean_isni}" + return f"https://isni.org/isni/{clean_isni}" @property def openlibrary_link(self): diff --git a/bookwyrm/templates/author/author.html b/bookwyrm/templates/author/author.html index c2355955..6e93d313 100644 --- a/bookwyrm/templates/author/author.html +++ b/bookwyrm/templates/author/author.html @@ -14,7 +14,7 @@ {% if request.user.is_authenticated and perms.bookwyrm.edit_book %}
- + {% trans "Edit Author" %} @@ -73,23 +73,29 @@ {% endif %} {% if author.openlibrary_key %} -

+

{% trans "View on OpenLibrary" %} {% if request.user.is_authenticated and perms.bookwyrm.edit_book %} - +

+ {% csrf_token %} + +
{% endif %}

{% endif %} {% if author.inventaire_id %} -

+

{% trans "View on Inventaire" %} {% if request.user.is_authenticated and perms.bookwyrm.edit_book %} - +

+ {% csrf_token %} + +
{% endif %}

{% endif %} diff --git a/bookwyrm/templates/book/book.html b/bookwyrm/templates/book/book.html index 3a7b1cbc..cdfbdf98 100644 --- a/bookwyrm/templates/book/book.html +++ b/bookwyrm/templates/book/book.html @@ -93,10 +93,12 @@ {% if book.openlibrary_key %}

{% trans "View on OpenLibrary" %} + {% if request.user.is_authenticated and perms.bookwyrm.edit_book %}

{% csrf_token %}
+ {% endif %}

{% endif %} {% if book.inventaire_id %} diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py index 697028b7..6e53ef2a 100644 --- a/bookwyrm/urls.py +++ b/bookwyrm/urls.py @@ -425,15 +425,26 @@ urlpatterns = [ re_path(r"^resolve-book/?$", views.resolve_book, name="resolve-book"), re_path(r"^switch-edition/?$", views.switch_edition, name="switch-edition"), re_path( - rf"{BOOK_PATH}/update/(?P[\w\.]+)?$", + rf"^{BOOK_PATH}/update/(?P[\w\.]+)?$", views.update_book_from_remote, - name="book-update-remote" + name="book-update-remote", + ), + re_path( + r"^author/(?P\d+)/update/(?P[\w\.]+)?$", + views.update_author_from_remote, + name="author-update-remote", ), # isbn re_path(r"^isbn/(?P\d+)(.json)?/?$", views.Isbn.as_view()), # author - re_path(r"^author/(?P\d+)(.json)?/?$", views.Author.as_view()), - re_path(r"^author/(?P\d+)/edit/?$", views.EditAuthor.as_view()), + re_path( + r"^author/(?P\d+)(.json)?/?$", views.Author.as_view(), name="author" + ), + re_path( + r"^author/(?P\d+)/edit/?$", + views.EditAuthor.as_view(), + name="edit-author", + ), # reading progress re_path(r"^edit-readthrough/?$", views.edit_readthrough, name="edit-readthrough"), re_path(r"^delete-readthrough/?$", views.delete_readthrough), diff --git a/bookwyrm/views/__init__.py b/bookwyrm/views/__init__.py index b399b90a..837b1257 100644 --- a/bookwyrm/views/__init__.py +++ b/bookwyrm/views/__init__.py @@ -55,7 +55,7 @@ from .imports.manually_review import ( ) # misc views -from .author import Author, EditAuthor +from .author import Author, EditAuthor, update_author_from_remote from .directory import Directory from .discover import Discover from .feed import DirectMessage, Feed, Replies, Status diff --git a/bookwyrm/views/author.py b/bookwyrm/views/author.py index 838d1c2b..2acb3b19 100644 --- a/bookwyrm/views/author.py +++ b/bookwyrm/views/author.py @@ -86,7 +86,7 @@ def update_author_from_remote(request, author_id, connector_identifier): connector = connector_manager.load_connector( get_object_or_404(models.Connector, identifier=connector_identifier) ) - author = get_object_or_404(models.Book.objects.select_subclasses(), id=author_id) + author = get_object_or_404(models.Author, id=author_id) connector.update_author_from_remote(author) From 071da7d4fb9d379dab8a703b987e88dfd353ef9a Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 5 Dec 2021 13:38:15 -0800 Subject: [PATCH 06/15] Handle various link generation needs --- bookwyrm/connectors/abstract_connector.py | 8 ++++++-- bookwyrm/connectors/inventaire.py | 7 ++++++- bookwyrm/templates/author/author.html | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/bookwyrm/connectors/abstract_connector.py b/bookwyrm/connectors/abstract_connector.py index 4b1f6e58..bb2bfb6f 100644 --- a/bookwyrm/connectors/abstract_connector.py +++ b/bookwyrm/connectors/abstract_connector.py @@ -195,14 +195,18 @@ class AbstractConnector(AbstractMinimalConnector): model=models.Author, overwrite=False, instance=instance ) + def get_remote_id_from_model(self, obj): + """given the data stored, how can we look this up""" + return getattr(obj, getattr(self, "generated_remote_link_field")) + def update_author_from_remote(self, obj): """load the remote data from this connector and add it to an existing author""" - remote_id = getattr(obj, getattr(self, "generated_remote_link_field")) + remote_id = self.get_remote_id_from_model(obj) return self.get_or_create_author(remote_id, instance=obj) def update_book_from_remote(self, obj): """load the remote data from this connector and add it to an existing book""" - remote_id = getattr(obj, getattr(self, "generated_remote_link_field")) + remote_id = self.get_remote_id_from_model(obj) data = self.get_book_data(remote_id) return self.create_edition_from_data(obj.parent_work, data, instance=obj) diff --git a/bookwyrm/connectors/inventaire.py b/bookwyrm/connectors/inventaire.py index bc5b3f68..45d0546f 100644 --- a/bookwyrm/connectors/inventaire.py +++ b/bookwyrm/connectors/inventaire.py @@ -11,7 +11,7 @@ from .connector_manager import ConnectorException class Connector(AbstractConnector): """instantiate a connector for inventaire""" - generated_remote_link_field = "inventaire_link" + generated_remote_link_field = "inventaire_id" def __init__(self, identifier): super().__init__(identifier) @@ -212,6 +212,11 @@ class Connector(AbstractConnector): return "" return data.get("extract") + def get_remote_id_from_model(self, obj): + """use get_remote_id to figure out the link from a model obj""" + remote_id_value = getattr(obj, self.inventaire_id) + return self.get_remote_id(remote_id_value) + def get_language_code(options, code="en"): """when there are a bunch of translation but we need a single field""" diff --git a/bookwyrm/templates/author/author.html b/bookwyrm/templates/author/author.html index 6e93d313..bf2c8f3f 100644 --- a/bookwyrm/templates/author/author.html +++ b/bookwyrm/templates/author/author.html @@ -92,7 +92,7 @@ {% trans "View on Inventaire" %} {% if request.user.is_authenticated and perms.bookwyrm.edit_book %} -
+ {% csrf_token %}
From 02313f40b8700a7a3c121f94bbdc0d301db16c60 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 5 Dec 2021 13:46:13 -0800 Subject: [PATCH 07/15] Adds update from inventaire link for books --- bookwyrm/connectors/inventaire.py | 2 +- bookwyrm/templates/book/book.html | 10 +++++++++- bookwyrm/urls.py | 4 ++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/bookwyrm/connectors/inventaire.py b/bookwyrm/connectors/inventaire.py index 45d0546f..a9aeb94f 100644 --- a/bookwyrm/connectors/inventaire.py +++ b/bookwyrm/connectors/inventaire.py @@ -214,7 +214,7 @@ class Connector(AbstractConnector): def get_remote_id_from_model(self, obj): """use get_remote_id to figure out the link from a model obj""" - remote_id_value = getattr(obj, self.inventaire_id) + remote_id_value = obj.inventaire_id return self.get_remote_id(remote_id_value) diff --git a/bookwyrm/templates/book/book.html b/bookwyrm/templates/book/book.html index cdfbdf98..6d8ce72b 100644 --- a/bookwyrm/templates/book/book.html +++ b/bookwyrm/templates/book/book.html @@ -102,7 +102,15 @@

{% endif %} {% if book.inventaire_id %} -

{% trans "View on Inventaire" %}

+

+ {% trans "View on Inventaire" %} + {% if request.user.is_authenticated and perms.bookwyrm.edit_book %} +

+ {% csrf_token %} + +
+ {% endif %} +

{% endif %}
diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py index 6e53ef2a..012a9116 100644 --- a/bookwyrm/urls.py +++ b/bookwyrm/urls.py @@ -425,12 +425,12 @@ urlpatterns = [ re_path(r"^resolve-book/?$", views.resolve_book, name="resolve-book"), re_path(r"^switch-edition/?$", views.switch_edition, name="switch-edition"), re_path( - rf"^{BOOK_PATH}/update/(?P[\w\.]+)?$", + rf"{BOOK_PATH}/update/(?P[\w\.]+)/?$", views.update_book_from_remote, name="book-update-remote", ), re_path( - r"^author/(?P\d+)/update/(?P[\w\.]+)?$", + r"^author/(?P\d+)/update/(?P[\w\.]+)/?$", views.update_author_from_remote, name="author-update-remote", ), From 7dbb9b4b26984b0c4b929fffda96dcaf2ce784e2 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 7 Dec 2021 11:23:01 -0800 Subject: [PATCH 08/15] Cleans up styling on author page Better mobile display, trim long text blocks --- bookwyrm/templates/author/author.html | 164 ++++++++++-------- bookwyrm/templates/snippets/trimmed_list.html | 34 ++++ 2 files changed, 123 insertions(+), 75 deletions(-) create mode 100644 bookwyrm/templates/snippets/trimmed_list.html diff --git a/bookwyrm/templates/author/author.html b/bookwyrm/templates/author/author.html index bf2c8f3f..0d7d102d 100644 --- a/bookwyrm/templates/author/author.html +++ b/bookwyrm/templates/author/author.html @@ -23,114 +23,128 @@ -
+
+ {% if author.bio %} +
+ {% include "snippets/trimmed_text.html" with full=author.bio trim_length=200 %} +
+ {% endif %} - {% if author.aliases or author.born or author.died or author.wikipedia_link or author.openlibrary_key or author.inventaire_id or author.isni %} + {% firstof author.aliases author.born author.died as details %} + {% firstof author.wikipedia_link author.openlibrary_key author.inventaire_id author.isni as links %} + {% if details or links %}
-
-
+ {% if details %} +
+

{% trans "Author details" %}

+
{% if author.aliases %} -
+
{% trans "Aliases:" %}
- {% for alias in author.aliases %} -
- {{alias}}{% if not forloop.last %}, {% endif %} -
- {% endfor %} +
+ {% include "snippets/trimmed_list.html" with items=author.aliases itemprop="alternateName" %} +
{% endif %} {% if author.born %} -
+
{% trans "Born:" %}
{{ author.born|naturalday }}
{% endif %} {% if author.died %} -
+
{% trans "Died:" %}
{{ author.died|naturalday }}
{% endif %}
+
+ {% endif %} - {% if author.wikipedia_link %} -

- - {% trans "Wikipedia" %} - -

- {% endif %} - - {% if author.isni %} -

- - {% trans "View ISNI record" %} - -

- {% endif %} - - {% if author.openlibrary_key %} -

- - {% trans "View on OpenLibrary" %} - - {% if request.user.is_authenticated and perms.bookwyrm.edit_book %} -

- {% csrf_token %} - -
+ {% if links %} +
+

{% trans "External links" %}

+
+ {% if author.wikipedia_link %} +

+ + {% trans "Wikipedia" %} + +

{% endif %} -

- {% endif %} - {% if author.inventaire_id %} -

- - {% trans "View on Inventaire" %} - - {% if request.user.is_authenticated and perms.bookwyrm.edit_book %} -

- {% csrf_token %} - -
+ {% if author.isni %} +

+ + {% trans "View ISNI record" %} + +

{% endif %} -

- {% endif %} - {% if author.librarything_key %} -

- - {% trans "View on LibraryThing" %} - -

- {% endif %} + {% if author.openlibrary_key %} +

+ + {% trans "View on OpenLibrary" %} + + {% if request.user.is_authenticated and perms.bookwyrm.edit_book %} +

+ {% csrf_token %} + +
+ {% endif %} +

+ {% endif %} - {% if author.goodreads_key %} -

- - {% trans "View on Goodreads" %} - -

- {% endif %} -
-
- {% endif %} -
- {% if author.bio %} - {{ author.bio|to_markdown|safe }} + {% if author.inventaire_id %} +

+ + {% trans "View on Inventaire" %} + + {% if request.user.is_authenticated and perms.bookwyrm.edit_book %} +

+ {% csrf_token %} + +
+ {% endif %} +

+ {% endif %} + + {% if author.librarything_key %} +

+ + {% trans "View on LibraryThing" %} + +

+ {% endif %} + + {% if author.goodreads_key %} +

+ + {% trans "View on Goodreads" %} + +

+ {% endif %} +
+ {% endif %}
+ {% endif %}
+ +
-

{% blocktrans with name=author.name %}Books by {{ name }}{% endblocktrans %}

+

{% blocktrans with name=author.name %}Books by {{ name }}{% endblocktrans %}

{% for book in books %} -
- {% include 'landing/small-book.html' with book=book %} +
+
+ {% include 'landing/small-book.html' with book=book %} +
{% include 'snippets/shelve_button/shelve_button.html' with book=book %}
{% endfor %} diff --git a/bookwyrm/templates/snippets/trimmed_list.html b/bookwyrm/templates/snippets/trimmed_list.html new file mode 100644 index 00000000..2e5f4595 --- /dev/null +++ b/bookwyrm/templates/snippets/trimmed_list.html @@ -0,0 +1,34 @@ +{% spaceless %} +{% load i18n %} +{% load humanize %} +{% firstof limit 3 as limit %} +{% with subtraction_value='-'|add:limit %} +{% with remainder_count=items|length|add:subtraction_value %} +{% with remainder_count_display=remainder_count|intcomma %} + +
+ + {% for item in items|slice:limit %} + {{ item }}{% if not forloop.last %}, {% elif remainder_count > 0 %}, {% blocktrans trimmed count counter=remainder_count %} + and {{ remainder_count_display }} other + {% plural %} + and {{ remainder_count_display }} others + {% endblocktrans %} + {% endif %} + {% endfor %} + + + {% for item in items|slice:"3:" %} + {{ item }}{% if not forloop.last %}, {% endif %} + {% endfor %} +
+ + +{% endwith %} +{% endwith %} +{% endwith %} +{% endspaceless %} From 4973e0a0103b652e26cc9fcad6271c8f8cadc72f Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 7 Dec 2021 12:30:21 -0800 Subject: [PATCH 09/15] Adds confirm modal for loading data --- bookwyrm/static/css/fonts/icomoon.eot | Bin 10404 -> 10460 bytes bookwyrm/static/css/fonts/icomoon.svg | 1 + bookwyrm/static/css/fonts/icomoon.ttf | Bin 10240 -> 10296 bytes bookwyrm/static/css/fonts/icomoon.woff | Bin 10316 -> 10372 bytes bookwyrm/static/css/vendor/icons.css | 13 +++--- bookwyrm/templates/author/author.html | 46 +++++++++++----------- bookwyrm/templates/author/sync_modal.html | 30 ++++++++++++++ 7 files changed, 63 insertions(+), 27 deletions(-) create mode 100644 bookwyrm/templates/author/sync_modal.html diff --git a/bookwyrm/static/css/fonts/icomoon.eot b/bookwyrm/static/css/fonts/icomoon.eot index 8eba8692fa04b6c1de810e316dadb480c17c633a..7b1f2d9d9f9d3ff8805e56d83c6c2ceba7654a8f 100644 GIT binary patch delta 407 zcmW-d&r1S96vyA}uAzBIODiI9!xRrHU0j2HNuBDpx9FmanjYL-P{_K}K|Hq%1VM*A z7<4cYyhsG~CkPQ`80^KvdiNB$y^&$&&FA}_H{W5J@<4VBA^@AZBPqzSVP8+3Uu^)u z3(ibdRkZgfy#+v4k?RGeqG9zQ8(5u%(#2`Km+m4z0t7R~ypjvd2k?BziM~`s!RZzx z`;HX*I0x(dDr!{}`JH)guekhzOk>Za;V^+9q%EZ+I6t$eI@i2gID1lk15o5|e`oyN$2~pg)Ys z>ACGOxP>YIe5m(q!zwjGNfM=Bp_YKANbBKapSO)B>y2_Nz&;CrWAPn3{6PKz8eMM3 delta 349 zcmcZ;xFnEui3S4$!$ekdmd95FnbnVsQbG z769^R0BMf&oXWIzyP`%Qe*pu7vPDK}Vv3w*pBn>%$_=2rSq4ymgPX;afk73hhe0JH zx1?f@9j7voZvy16$;nSnT*tLz8j$}0$dAZPtSDeG(PIKyre*;YP{>QnO`Yk*`5VZO z09w*kkY8NFzzmdOP=5d<6d0J9&rMEYv}fd+yoAx(GXW?j0(2fT0}BHqgThPEmkKYd zUbelw^@{8N-~a!CvOqmA8D5HmMXy6e8UH^PXAx%>TO~GM%wG&>CIjQ-gBqfnU74Je z6~TI%1+P4g=ePOFz|8{Y-%V6`31Wcg$rn`38MP;KsI8g2LoI?0XfFeU_GT&dLyQ1e C-e1)K diff --git a/bookwyrm/static/css/fonts/icomoon.svg b/bookwyrm/static/css/fonts/icomoon.svg index 82e41329..7dbbe0dc 100644 --- a/bookwyrm/static/css/fonts/icomoon.svg +++ b/bookwyrm/static/css/fonts/icomoon.svg @@ -46,4 +46,5 @@ + \ No newline at end of file diff --git a/bookwyrm/static/css/fonts/icomoon.ttf b/bookwyrm/static/css/fonts/icomoon.ttf index 5bf90a0a7ee19d304097a5d19cec297eb296e1fa..151f2b782e011873be7120240fc65777f3771917 100644 GIT binary patch delta 400 zcmZn&*bz|Az{tSBz|GLWz|3IaAFOZ0FT`#D6xjpB3CX#M1((-OT*JV?CtQ)hZ{{s!_V z04-@N$S*DdIur;rBtY^E%*+=i9g_oi)6<$`oYkfqWAne@#w)vSZ>pt{u~W0uO)!5xI#K1q>!kK+DuDfP96##N5=GUYx&y z{0N{WZ3X$oB|wJ)f%*d=p}@e*d~V_adq%EFjMjz;KoJq3&08`&p AF#rGn diff --git a/bookwyrm/static/css/fonts/icomoon.woff b/bookwyrm/static/css/fonts/icomoon.woff index 6ce6834d5addfd8b1a478d05ec802eded9a45b33..bc08184133a6ada4b7b8e59d5290d6019c817132 100644 GIT binary patch delta 447 zcmX>T&=M$8?(gQtz{mgu8Z8XmVA^7`p@zgn9pQR|0tal-PM@DL53Il^`2vCg~2+Iq}ugL%k0>yfOd=(Jp z;ASz)$StV=ifsV$!FYikr*lqzGEkkLS^`io3WWFX+A%FRu>xqZ+8!WZ0gO$VWbzVo zQ-NZ4fR?v`@Juhx-v#-_B|zT*Er+UO2C|r$FHGiPv}ZJ%?89j75Au*0g8&0F0~^rq z3NJ-pD!iu{eu3v)C%J`C|TJ3Zh?u zW-tQ7OMLTFMki%Yh5rwjA21&P8q2`Ss3-`8Obm<<{yq5D@b7^F;{zs!e;|VyK?DQC z&8ND7@%%Pl8Ms-%{JU3k=YSX>da{SAIit?x2GunzKuLwkI%*MIf}rpL>DAfXrFMuB E0NgKiQUCw| delta 409 zcmZn(JQE;X?(gQtz{mgu8a@o%V0v<)hVbMD4VH;oqV-J4xrqe~42&5-nHmt@>$G=8 zdSWq1>{% trans "External links" %}
{% if author.wikipedia_link %} -

+

{% endif %} {% if author.isni %} -

+

{% endif %} + {% trans "Load data" as button_text %} {% if author.openlibrary_key %} -

- +

+ {% trans "View on OpenLibrary" %} {% if request.user.is_authenticated and perms.bookwyrm.edit_book %} -
- {% csrf_token %} - -
+ {% with controls_text="ol_sync" controls_uid=author.id %} + {% include 'snippets/toggle/toggle_button.html' with text=button_text focus="modal_title_ol_sync" class="is-small" icon_with_text="download" %} + {% include "author/sync_modal.html" with source="opnlibrary.org" source_name="OpenLibrary" %} + {% endwith %} {% endif %} -

+
{% endif %} {% if author.inventaire_id %} -

- +

+ {% trans "View on Inventaire" %} + {% if request.user.is_authenticated and perms.bookwyrm.edit_book %} -
- {% csrf_token %} - -
+ {% with controls_text="iv_sync" controls_uid=author.id %} + {% include 'snippets/toggle/toggle_button.html' with text=button_text focus="modal_title_iv_sync" class="is-small" icon_with_text="download" %} + {% include "author/sync_modal.html" with source="inventaire.io" source_name="Inventaire" %} + {% endwith %} {% endif %} -

+
{% endif %} {% if author.librarything_key %} -

+

{% endif %} {% if author.goodreads_key %} -

+

{% endif %}
diff --git a/bookwyrm/templates/author/sync_modal.html b/bookwyrm/templates/author/sync_modal.html new file mode 100644 index 00000000..a061ada8 --- /dev/null +++ b/bookwyrm/templates/author/sync_modal.html @@ -0,0 +1,30 @@ +{% extends 'components/modal.html' %} +{% load i18n %} + +{% block modal-title %} +{% trans "Load data" %} +{% endblock %} + +{% block modal-form-open %} +
+ {% csrf_token %} +{% endblock %} + +{% block modal-body %} +

+ {% blocktrans trimmed %} + Loading data will connect to {{ source_name }} and check for any metadata about this author which aren't present here. Existing metadata will not be overwritten. + {% endblocktrans %} +

+{% endblock %} + +{% block modal-footer %} + + +{% trans "Cancel" as button_text %} +{% include 'snippets/toggle/toggle_button.html' with text=button_text %} +{% endblock %} + +{% block modal-form-close %}
{% endblock %} From e500f5312589a9c6d1ce8fa8baefad1071a61152 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 7 Dec 2021 12:41:11 -0800 Subject: [PATCH 10/15] Sync button for books --- bookwyrm/templates/author/author.html | 2 +- bookwyrm/templates/book/book.html | 17 +++++++------- bookwyrm/templates/book/sync_modal.html | 30 +++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 bookwyrm/templates/book/sync_modal.html diff --git a/bookwyrm/templates/author/author.html b/bookwyrm/templates/author/author.html index 3fe4b7ab..66ecb062 100644 --- a/bookwyrm/templates/author/author.html +++ b/bookwyrm/templates/author/author.html @@ -94,7 +94,7 @@ {% if request.user.is_authenticated and perms.bookwyrm.edit_book %} {% with controls_text="ol_sync" controls_uid=author.id %} {% include 'snippets/toggle/toggle_button.html' with text=button_text focus="modal_title_ol_sync" class="is-small" icon_with_text="download" %} - {% include "author/sync_modal.html" with source="opnlibrary.org" source_name="OpenLibrary" %} + {% include "author/sync_modal.html" with source="openlibrary.org" source_name="OpenLibrary" %} {% endwith %} {% endif %}
diff --git a/bookwyrm/templates/book/book.html b/bookwyrm/templates/book/book.html index 6d8ce72b..27d061a2 100644 --- a/bookwyrm/templates/book/book.html +++ b/bookwyrm/templates/book/book.html @@ -90,14 +90,15 @@
{% endwith %} + {% trans "Load data" as button_text %} {% if book.openlibrary_key %}

{% trans "View on OpenLibrary" %} {% if request.user.is_authenticated and perms.bookwyrm.edit_book %} -

- {% csrf_token %} - -
+ {% with controls_text="ol_sync" controls_uid=book.id %} + {% include 'snippets/toggle/toggle_button.html' with text=button_text focus="modal_title_ol_sync" class="is-small" icon_with_text="download" %} + {% include "book/sync_modal.html" with source="openlibrary.org" source_name="OpenLibrary" %} + {% endwith %} {% endif %}

{% endif %} @@ -105,10 +106,10 @@

{% trans "View on Inventaire" %} {% if request.user.is_authenticated and perms.bookwyrm.edit_book %} -

- {% csrf_token %} - -
+ {% with controls_text="iv_sync" controls_uid=book.id %} + {% include 'snippets/toggle/toggle_button.html' with text=button_text focus="modal_title_iv_sync" class="is-small" icon_with_text="download" %} + {% include "book/sync_modal.html" with source="inventaire.io" source_name="Inventaire" %} + {% endwith %} {% endif %}

{% endif %} diff --git a/bookwyrm/templates/book/sync_modal.html b/bookwyrm/templates/book/sync_modal.html new file mode 100644 index 00000000..d80bf25f --- /dev/null +++ b/bookwyrm/templates/book/sync_modal.html @@ -0,0 +1,30 @@ +{% extends 'components/modal.html' %} +{% load i18n %} + +{% block modal-title %} +{% trans "Load data" %} +{% endblock %} + +{% block modal-form-open %} +
+ {% csrf_token %} +{% endblock %} + +{% block modal-body %} +

+ {% blocktrans trimmed %} + Loading data will connect to {{ source_name }} and check for any metadata about this book which aren't present here. Existing metadata will not be overwritten. + {% endblocktrans %} +

+{% endblock %} + +{% block modal-footer %} + + +{% trans "Cancel" as button_text %} +{% include 'snippets/toggle/toggle_button.html' with text=button_text %} +{% endblock %} + +{% block modal-form-close %}
{% endblock %} From cf26f48d5c19beb7b949d311f38acd82ff2acc2c Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 7 Dec 2021 13:05:31 -0800 Subject: [PATCH 11/15] Adds view tests --- bookwyrm/tests/views/books/test_book.py | 22 ++++++++++++++++++++++ bookwyrm/tests/views/test_author.py | 23 +++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/bookwyrm/tests/views/books/test_book.py b/bookwyrm/tests/views/books/test_book.py index 561e2192..cb73e381 100644 --- a/bookwyrm/tests/views/books/test_book.py +++ b/bookwyrm/tests/views/books/test_book.py @@ -209,6 +209,28 @@ class BookViews(TestCase): self.assertEqual(self.book.description, "new description hi") self.assertEqual(self.book.last_edited_by, self.local_user) + def test_update_book_from_remote(self): + """call out to sync with remote connector""" + models.Connector.objects.create( + identifier="openlibrary.org", + name="OpenLibrary", + connector_file="openlibrary", + base_url="https://openlibrary.org", + books_url="https://openlibrary.org", + covers_url="https://covers.openlibrary.org", + search_url="https://openlibrary.org/search?q=", + isbn_search_url="https://openlibrary.org/isbn", + ) + self.local_user.groups.add(self.group) + request = self.factory.post("") + request.user = self.local_user + + with patch( + "bookwyrm.connectors.openlibrary.Connector.update_book_from_remote" + ) as mock: + views.update_book_from_remote(request, self.book.id, "openlibrary.org") + self.assertEqual(mock.call_count, 1) + def _setup_cover_url(): """creates cover url mock""" diff --git a/bookwyrm/tests/views/test_author.py b/bookwyrm/tests/views/test_author.py index 32b1565e..03166932 100644 --- a/bookwyrm/tests/views/test_author.py +++ b/bookwyrm/tests/views/test_author.py @@ -148,3 +148,26 @@ class AuthorViews(TestCase): self.assertEqual(author.name, "Test Author") validate_html(resp.render()) self.assertEqual(resp.status_code, 200) + + def test_update_author_from_remote(self): + """call out to sync with remote connector""" + author = models.Author.objects.create(name="Test Author") + models.Connector.objects.create( + identifier="openlibrary.org", + name="OpenLibrary", + connector_file="openlibrary", + base_url="https://openlibrary.org", + books_url="https://openlibrary.org", + covers_url="https://covers.openlibrary.org", + search_url="https://openlibrary.org/search?q=", + isbn_search_url="https://openlibrary.org/isbn", + ) + self.local_user.groups.add(self.group) + request = self.factory.post("") + request.user = self.local_user + + with patch( + "bookwyrm.connectors.openlibrary.Connector.update_author_from_remote" + ) as mock: + views.update_author_from_remote(request, author.id, "openlibrary.org") + self.assertEqual(mock.call_count, 1) From 31883a9f7c3f6ac03fb3832ed43b0680eab35bb1 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 7 Dec 2021 13:08:25 -0800 Subject: [PATCH 12/15] Linting fixes --- bookwyrm/tests/connectors/test_abstract_connector.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/bookwyrm/tests/connectors/test_abstract_connector.py b/bookwyrm/tests/connectors/test_abstract_connector.py index a453f613..0b46d607 100644 --- a/bookwyrm/tests/connectors/test_abstract_connector.py +++ b/bookwyrm/tests/connectors/test_abstract_connector.py @@ -88,7 +88,7 @@ class AbstractConnector(TestCase): """find an existing book by remote/origin id""" self.assertEqual(models.Book.objects.count(), 1) self.assertEqual( - self.book.remote_id, "https://%s/book/%d" % (DOMAIN, self.book.id) + self.book.remote_id, f"https://{DOMAIN}/book/{self.book.id}" ) self.assertEqual(self.book.origin_id, "https://example.com/book/1234") @@ -99,7 +99,7 @@ class AbstractConnector(TestCase): # dedupe by remote id result = self.connector.get_or_create_book( - "https://%s/book/%d" % (DOMAIN, self.book.id) + f"https://{DOMAIN}/book/{self.book.id}" ) self.assertEqual(models.Book.objects.count(), 1) self.assertEqual(result, self.book) @@ -119,7 +119,8 @@ class AbstractConnector(TestCase): @responses.activate def test_get_or_create_author(self): """load an author""" - self.connector.author_mappings = [ # pylint: disable=attribute-defined-outside-init # pylint: disable=attribute-defined-outside-init + # pylint: disable=attribute-defined-outside-init + self.connector.author_mappings = [ Mapping("id"), Mapping("name"), ] From b6071da3fce4255057d6201336d87130391d49a2 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 7 Dec 2021 13:48:22 -0800 Subject: [PATCH 13/15] Connector tests --- .../connectors/test_abstract_connector.py | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/bookwyrm/tests/connectors/test_abstract_connector.py b/bookwyrm/tests/connectors/test_abstract_connector.py index 0b46d607..90e77b79 100644 --- a/bookwyrm/tests/connectors/test_abstract_connector.py +++ b/bookwyrm/tests/connectors/test_abstract_connector.py @@ -40,6 +40,8 @@ class AbstractConnector(TestCase): class TestConnector(abstract_connector.AbstractConnector): """nothing added here""" + generated_remote_link_field = "openlibrary_link" + def format_search_result(self, search_result): return search_result @@ -87,9 +89,7 @@ class AbstractConnector(TestCase): def test_get_or_create_book_existing(self): """find an existing book by remote/origin id""" self.assertEqual(models.Book.objects.count(), 1) - self.assertEqual( - self.book.remote_id, f"https://{DOMAIN}/book/{self.book.id}" - ) + self.assertEqual(self.book.remote_id, f"https://{DOMAIN}/book/{self.book.id}") self.assertEqual(self.book.origin_id, "https://example.com/book/1234") # dedupe by origin id @@ -140,3 +140,26 @@ class AbstractConnector(TestCase): author = models.Author.objects.create(name="Test Author") result = self.connector.get_or_create_author(author.remote_id) self.assertEqual(author, result) + + @responses.activate + def test_update_author_from_remote(self): + """trigger the function that looks up the remote data""" + author = models.Author.objects.create(name="Test", openlibrary_key="OL123A") + # pylint: disable=attribute-defined-outside-init + self.connector.author_mappings = [ + Mapping("id"), + Mapping("name"), + Mapping("isni"), + ] + + responses.add( + responses.GET, + "https://openlibrary.org/authors/OL123A", + json={"id": "https://www.example.com/author", "name": "Beep", "isni": "hi"}, + ) + + self.connector.update_author_from_remote(author) + + author.refresh_from_db() + self.assertEqual(author.name, "Test") + self.assertEqual(author.isni, "hi") From 6ee1a628b0e4c056985fd6e26689bf361289c49d Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 7 Dec 2021 13:53:25 -0800 Subject: [PATCH 14/15] inventaire remote id test --- bookwyrm/tests/connectors/test_inventaire_connector.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/bookwyrm/tests/connectors/test_inventaire_connector.py b/bookwyrm/tests/connectors/test_inventaire_connector.py index 65325d02..55727a60 100644 --- a/bookwyrm/tests/connectors/test_inventaire_connector.py +++ b/bookwyrm/tests/connectors/test_inventaire_connector.py @@ -306,3 +306,11 @@ class Inventaire(TestCase): extract = self.connector.get_description({"enwiki": "test_path"}) self.assertEqual(extract, "hi hi") + + def test_remote_id_from_model(self): + """figure out a url from an id""" + obj = models.Author.objects.create(name="hello", inventaire_id="123") + self.assertEqual( + self.connector.get_remote_id_from_model(obj), + "https://inventaire.io?action=by-uris&uris=123", + ) From 4248c23c49f6e20f33d9acdb5d6b59a03a596c2b Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 7 Dec 2021 13:58:23 -0800 Subject: [PATCH 15/15] Test loading ISNI from openlibrary --- bookwyrm/tests/connectors/test_openlibrary_connector.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bookwyrm/tests/connectors/test_openlibrary_connector.py b/bookwyrm/tests/connectors/test_openlibrary_connector.py index 75a273d6..c05eb1a9 100644 --- a/bookwyrm/tests/connectors/test_openlibrary_connector.py +++ b/bookwyrm/tests/connectors/test_openlibrary_connector.py @@ -98,6 +98,9 @@ class Openlibrary(TestCase): "type": "/type/datetime", "value": "2008-08-31 10:09:33.413686", }, + "remote_ids": { + "isni": "000111", + }, "key": "/authors/OL453734A", "type": {"key": "/type/author"}, "id": 1259965, @@ -110,6 +113,7 @@ class Openlibrary(TestCase): self.assertIsInstance(result, models.Author) self.assertEqual(result.name, "George Elliott") self.assertEqual(result.openlibrary_key, "OL453734A") + self.assertEqual(result.isni, "000111") def test_get_cover_url(self): """formats a url that should contain the cover image"""