12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- import logging
- import requests
- from books.openlibrary import lookup_book_from_openlibrary
- from django.conf import settings
- from django.contrib.auth import get_user_model
- from django.core.files.base import ContentFile
- from django.db import models
- from django.urls import reverse
- from django_extensions.db.models import TimeStampedModel
- from scrobbles.mixins import ScrobblableMixin
- from scrobbles.utils import get_scrobbles_for_media
- logger = logging.getLogger(__name__)
- User = get_user_model()
- BNULL = {"blank": True, "null": True}
- class Author(TimeStampedModel):
- name = models.CharField(max_length=255)
- openlibrary_id = models.CharField(max_length=255, **BNULL)
- def __str__(self):
- return f"{self.name}"
- def fix_metadata(self):
- logger.warn("Not implemented yet")
- class Book(ScrobblableMixin):
- COMPLETION_PERCENT = getattr(settings, "BOOK_COMPLETION_PERCENT", 95)
- title = models.CharField(max_length=255)
- authors = models.ManyToManyField(Author)
- goodreads_id = models.CharField(max_length=255, **BNULL)
- koreader_id = models.IntegerField(**BNULL)
- koreader_authors = models.CharField(max_length=255, **BNULL)
- koreader_md5 = models.CharField(max_length=255, **BNULL)
- isbn = models.CharField(max_length=255, **BNULL)
- pages = models.IntegerField(**BNULL)
- language = models.CharField(max_length=4, **BNULL)
- first_publish_year = models.IntegerField(**BNULL)
- author_name = models.CharField(max_length=255, **BNULL)
- author_openlibrary_id = models.CharField(max_length=255, **BNULL)
- openlibrary_id = models.CharField(max_length=255, **BNULL)
- cover = models.ImageField(upload_to="books/covers/", **BNULL)
- def __str__(self):
- return f"{self.title} by {self.author}"
- def fix_metadata(self, force_update=False):
- if not self.openlibrary_id or force_update:
- book_dict = lookup_book_from_openlibrary(self.title, self.author)
- cover_url = book_dict.pop("cover_url")
- Book.objects.filter(pk=self.id).update(**book_dict)
- r = requests.get(cover_url)
- if r.status_code == 200:
- fname = f"{self.title}_{self.uuid}.jpg"
- self.cover.save(fname, ContentFile(r.content), save=True)
- self.save()
- @property
- def author(self):
- return self.authors.first()
- def get_absolute_url(self):
- return reverse("books:book_detail", kwargs={"slug": self.uuid})
- @property
- def pages_for_completion(self) -> int:
- if not self.pages:
- logger.warn(f"{self} has no pages, no completion percentage")
- return 0
- return int(self.pages * (self.COMPLETION_PERCENT / 100))
- def progress_for_user(self, user_id: int) -> int:
- """Used to keep track of whether the book is complete or not"""
- user = User.objects.get(id=user_id)
- last_scrobble = get_scrobbles_for_media(self, user).last()
- return int((last_scrobble.book_pages_read / self.pages) * 100)
- @classmethod
- def find_or_create(cls, data_dict: dict) -> "Game":
- from books.utils import get_or_create_book
- return get_or_create_book(
- data_dict.get("title"), data_dict.get("author")
- )
|