|
@@ -161,40 +161,55 @@ class Book(LongPlayScrobblableMixin):
|
|
return reverse("books:book_detail", kwargs={"slug": self.uuid})
|
|
return reverse("books:book_detail", kwargs={"slug": self.uuid})
|
|
|
|
|
|
@classmethod
|
|
@classmethod
|
|
- def get_from_google(cls, title: str, overwrite: bool = False):
|
|
|
|
|
|
+ def find_or_create(cls, title: str, enrich: bool = False, commit: bool = True):
|
|
|
|
+ """Given a title, get a Book instance.
|
|
|
|
+
|
|
|
|
+ If the book is not already in our database, or overwrite is True,
|
|
|
|
+ this method will enrich the Book with data from Google.
|
|
|
|
+
|
|
|
|
+ By default this method will also save the data back to the model. If you'd
|
|
|
|
+ like to batch create, use commit=False and you'll get an unsaved but enriched
|
|
|
|
+ instance back which you can then save at your convenience."""
|
|
|
|
+ # TODO use either a Google Books id identifier or author name like for tracks
|
|
book, created = cls.objects.get_or_create(title=title)
|
|
book, created = cls.objects.get_or_create(title=title)
|
|
- if not created and not overwrite:
|
|
|
|
|
|
+ if not created:
|
|
|
|
+ logger.info("Found exact match for book by title", extra={"title": title})
|
|
|
|
+
|
|
|
|
+ if not enrich:
|
|
|
|
+ logger.info("Found book by title, but not enriching", extra={"title": title})
|
|
return book
|
|
return book
|
|
|
|
|
|
book_dict = lookup_book_from_google(title)
|
|
book_dict = lookup_book_from_google(title)
|
|
|
|
|
|
- if created or overwrite:
|
|
|
|
- author_list = []
|
|
|
|
- authors = book_dict.pop("authors")
|
|
|
|
- cover_url = book_dict.pop("cover_url")
|
|
|
|
- try:
|
|
|
|
- genres = book_dict.pop("generes")
|
|
|
|
- except:
|
|
|
|
- genres = []
|
|
|
|
-
|
|
|
|
- if authors:
|
|
|
|
- for author_str in authors:
|
|
|
|
- if author_str:
|
|
|
|
- author, a_created = Author.objects.get_or_create(
|
|
|
|
- name=author_str
|
|
|
|
- )
|
|
|
|
- author_list.append(author)
|
|
|
|
- if a_created:
|
|
|
|
- # TODO enrich author
|
|
|
|
- ...
|
|
|
|
|
|
+ author_list = []
|
|
|
|
+ authors = book_dict.pop("authors")
|
|
|
|
+ cover_url = book_dict.pop("cover_url")
|
|
|
|
+ try:
|
|
|
|
+ genres = book_dict.pop("generes")
|
|
|
|
+ except:
|
|
|
|
+ genres = []
|
|
|
|
+
|
|
|
|
+ if authors:
|
|
|
|
+ for author_str in authors:
|
|
|
|
+ if author_str:
|
|
|
|
+ author, a_created = Author.objects.get_or_create(
|
|
|
|
+ name=author_str
|
|
|
|
+ )
|
|
|
|
+ author_list.append(author)
|
|
|
|
+ if a_created:
|
|
|
|
+ # TODO enrich author
|
|
|
|
+ ...
|
|
|
|
|
|
- for k, v in book_dict.items():
|
|
|
|
- setattr(book, k, v)
|
|
|
|
|
|
+ for k, v in book_dict.items():
|
|
|
|
+ setattr(book, k, v)
|
|
|
|
+
|
|
|
|
+ if commit:
|
|
book.save()
|
|
book.save()
|
|
|
|
|
|
book.save_image_from_url(cover_url)
|
|
book.save_image_from_url(cover_url)
|
|
book.genre.add(*genres)
|
|
book.genre.add(*genres)
|
|
book.authors.add(*author_list)
|
|
book.authors.add(*author_list)
|
|
|
|
+
|
|
return book
|
|
return book
|
|
|
|
|
|
def save_image_from_url(self, url: str, force_update: bool = False):
|
|
def save_image_from_url(self, url: str, force_update: bool = False):
|
|
@@ -378,27 +393,6 @@ class Book(LongPlayScrobblableMixin):
|
|
progress = int((last_scrobble.last_page_read / self.pages) * 100)
|
|
progress = int((last_scrobble.last_page_read / self.pages) * 100)
|
|
return progress
|
|
return progress
|
|
|
|
|
|
- @classmethod
|
|
|
|
- def find_or_create(cls, lookup_id: str, author: str = "") -> "Book":
|
|
|
|
- book = cls.objects.filter(openlibrary_id=lookup_id).first()
|
|
|
|
-
|
|
|
|
- if not book:
|
|
|
|
- data = lookup_book_from_openlibrary(lookup_id, author)
|
|
|
|
-
|
|
|
|
- if not data:
|
|
|
|
- logger.error(
|
|
|
|
- f"No book found on openlibrary, or in our database for {lookup_id}"
|
|
|
|
- )
|
|
|
|
- return book
|
|
|
|
-
|
|
|
|
- book, book_created = cls.objects.get_or_create(
|
|
|
|
- isbn_13=data["isbn"]
|
|
|
|
- )
|
|
|
|
- if book_created:
|
|
|
|
- book.fix_metadata(data=data)
|
|
|
|
-
|
|
|
|
- return book
|
|
|
|
-
|
|
|
|
|
|
|
|
class Paper(LongPlayScrobblableMixin):
|
|
class Paper(LongPlayScrobblableMixin):
|
|
"""Keeps track of Academic Papers"""
|
|
"""Keeps track of Academic Papers"""
|