From 06ff795df1ed1659b53c92a9b3cabb06aa5cd4e6 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 28 Mar 2020 16:30:54 -0700 Subject: [PATCH] Periodically update books Fixes #21 --- fedireads/books_manager.py | 5 +++++ fedireads/connectors/abstract_connector.py | 2 ++ fedireads/connectors/fedireads_connector.py | 16 +++++++++------- fedireads/connectors/openlibrary.py | 17 ++++++++++------- fedireads/routine_book_tasks.py | 16 ++++++++++++++++ 5 files changed, 42 insertions(+), 14 deletions(-) create mode 100644 fedireads/routine_book_tasks.py diff --git a/fedireads/books_manager.py b/fedireads/books_manager.py index bedcad7bd..d59a28bda 100644 --- a/fedireads/books_manager.py +++ b/fedireads/books_manager.py @@ -23,6 +23,11 @@ def search(query): connector = get_connector() return connector.search(query) +def update_book(book): + ''' re-sync with the original data source ''' + connector = get_connector(book) + connector.update_book(book) + def get_connector(book=None): ''' pick a book data connector ''' diff --git a/fedireads/connectors/abstract_connector.py b/fedireads/connectors/abstract_connector.py index 8a4dd40c0..daccb6098 100644 --- a/fedireads/connectors/abstract_connector.py +++ b/fedireads/connectors/abstract_connector.py @@ -58,6 +58,8 @@ class AbstractConnector(ABC): def update_from_mappings(obj, data, mappings): ''' assign data to model with mappings ''' noop = lambda x: x + mappings['authors'] = ('', noop) + mappings['parent_work'] = ('', noop) for (key, value) in data.items(): formatter = None if key in mappings: diff --git a/fedireads/connectors/fedireads_connector.py b/fedireads/connectors/fedireads_connector.py index df619c372..8fc6e2708 100644 --- a/fedireads/connectors/fedireads_connector.py +++ b/fedireads/connectors/fedireads_connector.py @@ -42,6 +42,10 @@ class Connector(AbstractConnector): # no book was found, so we start creating a new one book = models.Book(fedireads_key=fedireads_key) + + def update_book(self, book): + ''' add remote data to a local book ''' + fedireads_key = book.fedireads_key response = requests.get( '%s/%s' % (self.base_url, fedireads_key), headers={ @@ -60,8 +64,10 @@ class Connector(AbstractConnector): } book = update_from_mappings(book, data, mappings) - book.source_url = response.url - book.connector = self.connector + if not book.source_url: + book.source_url = response.url + if not book.connector: + book.connector = self.connector book.save() if data.get('parent_work'): @@ -74,7 +80,7 @@ class Connector(AbstractConnector): author_id = author_id.split('/')[-1] book.authors.add(self.get_or_create_author(author_id)) - if data.get('covers') and len(data['covers']): + if book.sync_cover and data.get('covers') and len(data['covers']): book.cover.save(*self.get_cover(data['covers'][0]), save=True) return book @@ -115,10 +121,6 @@ class Connector(AbstractConnector): return [image_name, image_content] - def update_book(self, book_obj): - pass - - def get_date(date_string): ''' helper function to try to interpret dates ''' try: diff --git a/fedireads/connectors/openlibrary.py b/fedireads/connectors/openlibrary.py index ac8974e51..fb4f57612 100644 --- a/fedireads/connectors/openlibrary.py +++ b/fedireads/connectors/openlibrary.py @@ -58,7 +58,12 @@ class Connector(AbstractConnector): except ObjectDoesNotExist: # no book was found, so we start creating a new one book = model(openlibrary_key=olkey) + self.update_book(book) + + def update_book(self, book): + ''' query openlibrary for data on a book ''' + olkey = book.openlibrary_key # load the book json from openlibrary.org response = requests.get('%s/works/%s.json' % (self.url, olkey)) if not response.ok: @@ -81,8 +86,10 @@ class Connector(AbstractConnector): if 'goodreads' in data['identifiers']: book.goodreads_key = data['identifiers']['goodreads'] - book.source_url = response.url - book.connector = self.connector + if not book.source_url: + book.source_url = response.url + if not book.connector: + book.connector = self.connector book.save() # this book sure as heck better be an edition @@ -101,7 +108,7 @@ class Connector(AbstractConnector): author_id = author_id.split('/')[-1] book.authors.add(self.get_or_create_author(author_id)) - if data.get('covers') and len(data['covers']): + if book.sync_cover and data.get('covers') and len(data['covers']): book.cover.save(*self.get_cover(data['covers'][0]), save=True) return book @@ -149,10 +156,6 @@ class Connector(AbstractConnector): return [image_name, image_content] - def update_book(self, book_obj): - pass - - def get_date(date_string): ''' helper function to try to interpret dates ''' formats = [ diff --git a/fedireads/routine_book_tasks.py b/fedireads/routine_book_tasks.py new file mode 100644 index 000000000..ac710be76 --- /dev/null +++ b/fedireads/routine_book_tasks.py @@ -0,0 +1,16 @@ +''' Routine tasks for keeping your library tidy ''' +from datetime import datetime, timedelta +from fedireads import books_manager +from fedireads import models + +def sync_book_data(): + ''' update books with any changes to their canonical source ''' + expiry = datetime.now() - timedelta(days=1) + books = models.Book.objects.filter( + sync=True, + last_sync_date__lte=expiry + ).all() + for book in books: + # TODO: create background tasks + books_manager.update_book(book) +