|
@@ -36,6 +36,7 @@ from vrobbler.apps.books.locg import (
|
|
|
lookup_comic_writer_by_locg_slug,
|
|
|
)
|
|
|
from vrobbler.apps.books.sources.google import lookup_book_from_google
|
|
|
+from vrobbler.apps.books.sources.semantic import lookup_paper_from_semantic
|
|
|
from vrobbler.apps.scrobbles.dataclasses import BookLogData
|
|
|
|
|
|
COMICVINE_API_KEY = getattr(settings, "COMICVINE_API_KEY", "")
|
|
@@ -64,22 +65,27 @@ class Author(TimeStampedModel):
|
|
|
)
|
|
|
bio = models.TextField(**BNULL)
|
|
|
wikipedia_url = models.CharField(max_length=255, **BNULL)
|
|
|
- isni = models.CharField(max_length=255, **BNULL)
|
|
|
- locg_slug = models.CharField(max_length=255, **BNULL)
|
|
|
wikidata_id = models.CharField(max_length=255, **BNULL)
|
|
|
+ isni = models.CharField(max_length=255, **BNULL)
|
|
|
goodreads_id = models.CharField(max_length=255, **BNULL)
|
|
|
- librarything_id = models.CharField(max_length=255, **BNULL)
|
|
|
comicvine_data = models.JSONField(**BNULL)
|
|
|
- amazon_id = models.CharField(max_length=255, **BNULL)
|
|
|
+
|
|
|
+ semantic_id = models.CharField(max_length=50, **BNULL)
|
|
|
|
|
|
def __str__(self):
|
|
|
return f"{self.name}"
|
|
|
|
|
|
- def fix_metadata(self, data_dict: dict = {}):
|
|
|
- if not data_dict and self.openlibrary_id:
|
|
|
- data_dict = lookup_author_from_openlibrary(self.openlibrary_id)
|
|
|
+ def enrich_from_semantic(self, overwrite=False):
|
|
|
+ ...
|
|
|
+
|
|
|
+ def enrich_from_google_books(self, overwrite=False):
|
|
|
+ ...
|
|
|
+
|
|
|
+ def enrich_from_openlibrary(self, overwrite=False):
|
|
|
+ data_dict = lookup_author_from_openlibrary(self.openlibrary_id)
|
|
|
|
|
|
if not data_dict or not data_dict.get("name"):
|
|
|
+ logger.warning("Could not find author on openlibrary")
|
|
|
return
|
|
|
|
|
|
headshot_url = data_dict.pop("author_headshot_url", "")
|
|
@@ -160,26 +166,32 @@ class Book(LongPlayScrobblableMixin):
|
|
|
if not created and not overwrite:
|
|
|
return book
|
|
|
|
|
|
- bdict, authors, cover, genres = lookup_book_from_google(
|
|
|
- title
|
|
|
- ).as_dict_with_authors_cover_and_genres()
|
|
|
+ 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")
|
|
|
+ genres = book_dict.pop("generes")
|
|
|
+
|
|
|
if authors:
|
|
|
for author_str in authors:
|
|
|
if author_str:
|
|
|
- author_list.append(
|
|
|
- Author.objects.get_or_create(name=author_str)[0]
|
|
|
+ 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 bdict.items():
|
|
|
+ for k, v in book_dict.items():
|
|
|
setattr(book, k, v)
|
|
|
- book.save()
|
|
|
+ book.save()
|
|
|
|
|
|
- book.save_image_from_url(cover)
|
|
|
- book.genre.add(*genres)
|
|
|
- book.authors.add(*author_list)
|
|
|
+ book.save_image_from_url(cover_url)
|
|
|
+ book.genre.add(*genres)
|
|
|
+ book.authors.add(*author_list)
|
|
|
return book
|
|
|
|
|
|
def save_image_from_url(self, url: str, force_update: bool = False):
|
|
@@ -474,3 +486,68 @@ class Page(TimeStampedModel):
|
|
|
seconds=self.duration_seconds
|
|
|
)
|
|
|
self.save(update_fields=["end_time"])
|
|
|
+
|
|
|
+
|
|
|
+class Paper(LongPlayScrobblableMixin):
|
|
|
+ """Keeps track of Academic Papers"""
|
|
|
+
|
|
|
+ COMPLETION_PERCENT = getattr(settings, "PAPER_COMPLETION_PERCENT", 60)
|
|
|
+ AVG_PAGE_READING_SECONDS = getattr(
|
|
|
+ settings, "AVERAGE_PAGE_READING_SECONDS", 60
|
|
|
+ )
|
|
|
+
|
|
|
+ title = models.CharField(max_length=255)
|
|
|
+ semantic_title = models.CharField(max_length=255, **BNULL)
|
|
|
+ authors = models.ManyToManyField(Author, blank=True)
|
|
|
+ koreader_data_by_hash = models.JSONField(**BNULL)
|
|
|
+ arxiv_id = models.CharField(max_length=50, **BNULL)
|
|
|
+ semantic_id = models.CharField(max_length=50, **BNULL)
|
|
|
+ arxiv_id = models.CharField(max_length=50, **BNULL)
|
|
|
+ corpus_id = models.CharField(max_length=50, **BNULL)
|
|
|
+ doi_id = models.CharField(max_length=50, **BNULL)
|
|
|
+ pages = models.IntegerField(**BNULL)
|
|
|
+ language = models.CharField(max_length=4, **BNULL)
|
|
|
+ first_publish_year = models.IntegerField(**BNULL)
|
|
|
+ publish_date = models.DateField(**BNULL)
|
|
|
+ journal = models.CharField(max_length=255, **BNULL)
|
|
|
+ journal_volume = models.CharField(max_length=50, **BNULL)
|
|
|
+ abstract = models.TextField(**BNULL)
|
|
|
+ tldr = models.CharField(max_length=255, **BNULL)
|
|
|
+ openaccess_pdf_url = models.CharField(max_length=255, **BNULL)
|
|
|
+
|
|
|
+ genre = TaggableManager(through=ObjectWithGenres)
|
|
|
+
|
|
|
+ @classmethod
|
|
|
+ def get_from_semantic(cls, title: str, overwrite: bool = False) -> "Paper":
|
|
|
+ paper, created = cls.objects.get_or_create(title=title)
|
|
|
+ if not created and not overwrite:
|
|
|
+ return paper
|
|
|
+
|
|
|
+ paper_dict = lookup_paper_from_semantic(title)
|
|
|
+
|
|
|
+ if created or overwrite:
|
|
|
+ author_list = []
|
|
|
+ author_dicts = paper_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 paper_dict.items():
|
|
|
+ setattr(paper, k, v)
|
|
|
+ paper.save()
|
|
|
+
|
|
|
+ if author_list:
|
|
|
+ paper.authors.add(*author_list)
|
|
|
+ genres = paper_dict.pop("genres", [])
|
|
|
+ if genres:
|
|
|
+ paper.genre.add(*genres)
|
|
|
+ return paper
|