From 3a4a194160f72f75e0924505d9454ea261706c40 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 3 May 2020 18:56:29 -0700 Subject: [PATCH] Path to update books --- fedireads/books_manager.py | 4 +- fedireads/connectors/abstract_connector.py | 2 +- fedireads/connectors/openlibrary.py | 2 +- fedireads/connectors/self_connector.py | 1 - fedireads/incoming.py | 19 ++++++++- .../migrations/0037_auto_20200504_0049.py | 21 ---------- .../migrations/0037_auto_20200504_0154.py | 41 +++++++++++++++++++ fedireads/models/book.py | 7 ++-- init_db.py | 4 +- 9 files changed, 68 insertions(+), 33 deletions(-) delete mode 100644 fedireads/migrations/0037_auto_20200504_0049.py create mode 100644 fedireads/migrations/0037_auto_20200504_0154.py diff --git a/fedireads/books_manager.py b/fedireads/books_manager.py index 6f0d78cb..fe00aa7d 100644 --- a/fedireads/books_manager.py +++ b/fedireads/books_manager.py @@ -57,10 +57,10 @@ def first_search_result(query): return None -def update_book(book): +def update_book(book, data=None): ''' re-sync with the original data source ''' connector = load_connector(book.connector) - connector.update_book(book) + connector.update_book(book, data=data) def get_connectors(): diff --git a/fedireads/connectors/abstract_connector.py b/fedireads/connectors/abstract_connector.py index fb28c3fc..bb3df27c 100644 --- a/fedireads/connectors/abstract_connector.py +++ b/fedireads/connectors/abstract_connector.py @@ -57,7 +57,7 @@ class AbstractConnector(ABC): @abstractmethod - def update_book(self, book_obj): + def update_book(self, book_obj, data=None): ''' sync a book with the canonical remote copy ''' # return book model obj diff --git a/fedireads/connectors/openlibrary.py b/fedireads/connectors/openlibrary.py index 72be68fd..1f3b3e43 100644 --- a/fedireads/connectors/openlibrary.py +++ b/fedireads/connectors/openlibrary.py @@ -140,7 +140,7 @@ class Connector(AbstractConnector): return book - def update_book(self, book): + def update_book(self, book, data=None): ''' load new data ''' if not book.sync and not book.sync_cover: return diff --git a/fedireads/connectors/self_connector.py b/fedireads/connectors/self_connector.py index a91e8207..f1d5b24b 100644 --- a/fedireads/connectors/self_connector.py +++ b/fedireads/connectors/self_connector.py @@ -23,7 +23,6 @@ class Connector(AbstractConnector): SearchVector('isbn_10', weight='A') +\ SearchVector('openlibrary_key', weight='B') +\ SearchVector('goodreads_key', weight='B') +\ - SearchVector('source_url', weight='B') +\ SearchVector('asin', weight='B') +\ SearchVector('oclc_number', weight='B') +\ SearchVector('description', weight='C') +\ diff --git a/fedireads/incoming.py b/fedireads/incoming.py index 74218fbb..62fd3d43 100644 --- a/fedireads/incoming.py +++ b/fedireads/incoming.py @@ -10,7 +10,7 @@ from django.http import HttpResponseBadRequest, HttpResponseNotFound from django.views.decorators.csrf import csrf_exempt import requests -from fedireads import models, outgoing +from fedireads import books_manager, models, outgoing from fedireads import status as status_builder from fedireads.remote_user import get_or_create_remote_user from fedireads.tasks import app @@ -63,7 +63,7 @@ def shared_inbox(request): }, 'Update': { 'Person': None,# TODO: handle_update_user - 'Document': None# TODO: handle_update_book + 'Document': handle_update_book, }, } activity_type = activity['type'] @@ -320,3 +320,18 @@ def handle_tag(activity): if not user.local: book = activity['target']['id'].split('/')[-1] status_builder.create_tag(user, book, activity['object']['name']) + + +@app.task +def handle_update_book(activity): + ''' a remote instance changed a book (Document) ''' + document = activity['object'] + # check if we have their copy and care about their updates + book = models.Book.objects.select_subclasses().filter( + remote_id=document['url'], + sync=True, + ).first() + if not book: + return + + books_manager.update_book(book, data=document) diff --git a/fedireads/migrations/0037_auto_20200504_0049.py b/fedireads/migrations/0037_auto_20200504_0049.py deleted file mode 100644 index 039fac6e..00000000 --- a/fedireads/migrations/0037_auto_20200504_0049.py +++ /dev/null @@ -1,21 +0,0 @@ -# Generated by Django 3.0.3 on 2020-05-04 00:49 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('fedireads', '0036_auto_20200503_2007'), - ] - - operations = [ - migrations.RemoveField( - model_name='author', - name='fedireads_key', - ), - migrations.RemoveField( - model_name='book', - name='fedireads_key', - ), - ] diff --git a/fedireads/migrations/0037_auto_20200504_0154.py b/fedireads/migrations/0037_auto_20200504_0154.py new file mode 100644 index 00000000..5807580d --- /dev/null +++ b/fedireads/migrations/0037_auto_20200504_0154.py @@ -0,0 +1,41 @@ +# Generated by Django 3.0.3 on 2020-05-04 01:54 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('fedireads', '0036_auto_20200503_2007'), + ] + + operations = [ + migrations.RemoveField( + model_name='author', + name='fedireads_key', + ), + migrations.RemoveField( + model_name='book', + name='fedireads_key', + ), + migrations.RemoveField( + model_name='book', + name='source_url', + ), + migrations.AddField( + model_name='author', + name='last_sync_date', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + migrations.AddField( + model_name='author', + name='sync', + field=models.BooleanField(default=True), + ), + migrations.AddField( + model_name='book', + name='remote_id', + field=models.CharField(max_length=255, null=True), + ), + ] diff --git a/fedireads/models/book.py b/fedireads/models/book.py index 3e6e6c1e..d7944984 100644 --- a/fedireads/models/book.py +++ b/fedireads/models/book.py @@ -1,6 +1,4 @@ ''' database schema for books and shelves ''' -from uuid import uuid4 - from django.utils import timezone from django.db import models from model_utils.managers import InheritanceManager @@ -50,6 +48,7 @@ class Connector(FedireadsModel): class Book(FedireadsModel): ''' a generic book, which can mean either an edition or a work ''' + remote_id = models.CharField(max_length=255, null=True) # these identifiers apply to both works and editions openlibrary_key = models.CharField(max_length=255, blank=True, null=True) librarything_key = models.CharField(max_length=255, blank=True, null=True) @@ -57,7 +56,6 @@ class Book(FedireadsModel): misc_identifiers = JSONField(null=True) # info about where the data comes from and where/if to sync - source_url = models.CharField(max_length=255, unique=True, null=True) sync = models.BooleanField(default=True) sync_cover = models.BooleanField(default=True) last_sync_date = models.DateTimeField(default=timezone.now) @@ -130,6 +128,7 @@ class Edition(Book): ''' an edition of a book ''' # default -> this is what gets displayed for a work default = models.BooleanField(default=False) + # these identifiers only apply to editions, not works isbn_10 = models.CharField(max_length=255, blank=True, null=True) isbn_13 = models.CharField(max_length=255, blank=True, null=True) @@ -152,6 +151,8 @@ class Edition(Book): class Author(FedireadsModel): ''' copy of an author from OL ''' openlibrary_key = models.CharField(max_length=255, blank=True, null=True) + sync = models.BooleanField(default=True) + last_sync_date = models.DateTimeField(default=timezone.now) wikipedia_link = models.CharField(max_length=255, blank=True, null=True) # idk probably other keys would be useful here? born = models.DateTimeField(blank=True, null=True) diff --git a/init_db.py b/init_db.py index 2b6a09ac..62e0d571 100644 --- a/init_db.py +++ b/init_db.py @@ -36,5 +36,5 @@ Connector.objects.create( ) -get_or_create_book('OL1715344W') -get_or_create_book('OL102749W') +get_or_create_book('OL1715344W', key='openlibrary_key', connector_id=1) +get_or_create_book('OL102749W', key='openlibrary_key', connector_id=1)