|
@@ -26,7 +26,7 @@ from scrobbles.mixins import (
|
|
|
from scrobbles.utils import get_scrobbles_for_media
|
|
from scrobbles.utils import get_scrobbles_for_media
|
|
|
from taggit.managers import TaggableManager
|
|
from taggit.managers import TaggableManager
|
|
|
from thefuzz import fuzz
|
|
from thefuzz import fuzz
|
|
|
-from vrobbler.apps.books.comicvine import (
|
|
|
|
|
|
|
+from vrobbler.apps.books.sources.comicvine import (
|
|
|
ComicVineClient,
|
|
ComicVineClient,
|
|
|
lookup_comic_from_comicvine,
|
|
lookup_comic_from_comicvine,
|
|
|
)
|
|
)
|
|
@@ -135,6 +135,7 @@ class Book(LongPlayScrobblableMixin):
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
title = models.CharField(max_length=255)
|
|
title = models.CharField(max_length=255)
|
|
|
|
|
+ original_title = models.CharField(max_length=255, **BNULL)
|
|
|
authors = models.ManyToManyField(Author, blank=True)
|
|
authors = models.ManyToManyField(Author, blank=True)
|
|
|
koreader_data_by_hash = models.JSONField(**BNULL)
|
|
koreader_data_by_hash = models.JSONField(**BNULL)
|
|
|
isbn_13 = models.CharField(max_length=255, **BNULL)
|
|
isbn_13 = models.CharField(max_length=255, **BNULL)
|
|
@@ -145,6 +146,11 @@ class Book(LongPlayScrobblableMixin):
|
|
|
publish_date = models.DateField(**BNULL)
|
|
publish_date = models.DateField(**BNULL)
|
|
|
publisher = models.CharField(max_length=255, **BNULL)
|
|
publisher = models.CharField(max_length=255, **BNULL)
|
|
|
first_sentence = models.TextField(**BNULL)
|
|
first_sentence = models.TextField(**BNULL)
|
|
|
|
|
+ # ComicVine
|
|
|
|
|
+ comicvine_id = models.CharField(max_length=255, **BNULL)
|
|
|
|
|
+ issue_number = models.IntegerField(max_length=5, **BNULL)
|
|
|
|
|
+ volume_number = models.IntegerField(max_length=5, **BNULL)
|
|
|
|
|
+ # OpenLibrary
|
|
|
openlibrary_id = models.CharField(max_length=255, **BNULL)
|
|
openlibrary_id = models.CharField(max_length=255, **BNULL)
|
|
|
cover = models.ImageField(upload_to="books/covers/", **BNULL)
|
|
cover = models.ImageField(upload_to="books/covers/", **BNULL)
|
|
|
cover_small = ImageSpecField(
|
|
cover_small = ImageSpecField(
|
|
@@ -188,6 +194,43 @@ class Book(LongPlayScrobblableMixin):
|
|
|
def get_absolute_url(self):
|
|
def get_absolute_url(self):
|
|
|
return reverse("books:book_detail", kwargs={"slug": self.uuid})
|
|
return reverse("books:book_detail", kwargs={"slug": self.uuid})
|
|
|
|
|
|
|
|
|
|
+ @classmethod
|
|
|
|
|
+ def get_from_comicvine(cls, title: str, overwrite: bool = False, force_new: bool =False) -> "Book":
|
|
|
|
|
+ book, created = cls.objects.get_or_create(title=title)
|
|
|
|
|
+ if not created and not overwrite and not force_new:
|
|
|
|
|
+ book, created = cls.objects.get_or_create(original_title=title)
|
|
|
|
|
+ logger.info("Found comic by original title, use force_new=True to override")
|
|
|
|
|
+ return book
|
|
|
|
|
+
|
|
|
|
|
+ book_dict = lookup_comic_from_comicvine(title)
|
|
|
|
|
+
|
|
|
|
|
+ if created or overwrite:
|
|
|
|
|
+ author_list = []
|
|
|
|
|
+ author_dicts = book_dict.pop("author_dicts")
|
|
|
|
|
+ if author_dicts:
|
|
|
|
|
+ for author_dict in author_dicts:
|
|
|
|
|
+ if author_dict.get("authorId"):
|
|
|
|
|
+ author, a_created = Author.objects.get_or_create(
|
|
|
|
|
+ semantic_id=author_dict.get("authorId")
|
|
|
|
|
+ )
|
|
|
|
|
+ author_list.append(author)
|
|
|
|
|
+ if a_created:
|
|
|
|
|
+ author.name = author_dict.get("name")
|
|
|
|
|
+ author.save()
|
|
|
|
|
+ # TODO enrich author?
|
|
|
|
|
+ ...
|
|
|
|
|
+
|
|
|
|
|
+ for k, v in book_dict.items():
|
|
|
|
|
+ setattr(book, k, v)
|
|
|
|
|
+ book.save()
|
|
|
|
|
+
|
|
|
|
|
+ if author_list:
|
|
|
|
|
+ book.authors.add(*author_list)
|
|
|
|
|
+ genres = book_dict.pop("genres", [])
|
|
|
|
|
+ if genres:
|
|
|
|
|
+ book.genre.add(*genres)
|
|
|
|
|
+ return book
|
|
|
|
|
+
|
|
|
@classmethod
|
|
@classmethod
|
|
|
def find_or_create(
|
|
def find_or_create(
|
|
|
cls, title: str, enrich: bool = False, commit: bool = True
|
|
cls, title: str, enrich: bool = False, commit: bool = True
|
|
@@ -215,6 +258,8 @@ class Book(LongPlayScrobblableMixin):
|
|
|
return book
|
|
return book
|
|
|
|
|
|
|
|
book_dict = lookup_book_from_google(title)
|
|
book_dict = lookup_book_from_google(title)
|
|
|
|
|
+ if not book_dict or book_dict.get("isbn_10"):
|
|
|
|
|
+ book_dict = lookup_comic_from_comicvine(title)
|
|
|
|
|
|
|
|
author_list = []
|
|
author_list = []
|
|
|
authors = book_dict.pop("authors")
|
|
authors = book_dict.pop("authors")
|