diff --git a/catalog/book/models.py b/catalog/book/models.py index a10a6bc7..3741c3a7 100644 --- a/catalog/book/models.py +++ b/catalog/book/models.py @@ -112,6 +112,16 @@ EDITION_LOCALIZED_SUBTITLE_SCHEMA = { class Edition(Item): if TYPE_CHECKING: works: "models.ManyToManyField[Work, Edition]" + + class BookFormat(models.TextChoices): + PAPERBACK = "paperback", _("Paperback") + HARDCOVER = "hardcover", _("Hardcover") + EBOOK = "ebook", _("eBook") + AUDIOBOOK = "audiobook", _("Audiobook") + GRAPHICNOVEL = "graphicnovel", _("GraphicNovel") + WEB = "web", _("Web Fiction") + OTHER = "other", _("Other") + category = ItemCategory.Book url_path = "book" @@ -127,6 +137,7 @@ class Edition(Item): # "title", # "subtitle", "author", + "format", "pub_house", "pub_year", "pub_month", @@ -171,6 +182,12 @@ class Edition(Item): blank=True, default=list, ) + format = jsondata.CharField( + _("book format"), + blank=True, + max_length=100, + choices=BookFormat.choices, + ) language = LanguageListField() pub_house = jsondata.CharField( _("publishing house"), null=True, blank=True, max_length=500 diff --git a/catalog/book/tests.py b/catalog/book/tests.py index 6dcb7261..10081847 100644 --- a/catalog/book/tests.py +++ b/catalog/book/tests.py @@ -167,6 +167,7 @@ class GoodreadsTestCase(TestCase): self.assertEqual(resource.id_value, "77566") self.assertNotEqual(resource.cover, "/media/item/default.svg") self.assertEqual(edition.isbn, "9780553283686") + self.assertEqual(edition.format, "papberback") self.assertEqual(edition.display_title, "Hyperion") edition.delete() @@ -290,6 +291,7 @@ class BooksTWTestCase(TestCase): self.assertEqual(site.resource.id_type, IdType.BooksTW) self.assertEqual(site.resource.id_value, "0010947886") self.assertEqual(site.resource.item.isbn, "9786263152236") + self.assertEqual(site.resource.item.format, "paperback") self.assertEqual( site.resource.item.display_title, "阿拉伯人三千年:從民族、部落、語言、文化、宗教到帝國,綜覽阿拉伯世界的崛起、衰落與再興", @@ -329,6 +331,7 @@ class DoubanBookTestCase(TestCase): self.assertEqual(site.resource.id_type, IdType.DoubanBook) self.assertEqual(site.resource.id_value, "35902899") self.assertEqual(site.resource.item.isbn, "9781847498571") + self.assertEqual(site.resource.item.format, "paperback") self.assertEqual(site.resource.item.display_title, "1984 Nineteen Eighty-Four") @use_local_response diff --git a/catalog/book/utils.py b/catalog/book/utils.py index 41c5eb3b..2a9bc0f8 100644 --- a/catalog/book/utils.py +++ b/catalog/book/utils.py @@ -62,3 +62,23 @@ def detect_isbn_asin(s: str) -> tuple[IdType, str] | tuple[None, None]: if is_asin(n): return IdType.ASIN, n return None, None + + +def binding_to_format(binding: str | None): + from .models import Edition + + if not binding: + return None + if re.search(r"(Audio|Audible|音频)", binding, flags=re.IGNORECASE): + return Edition.BookFormat.AUDIOBOOK + if re.search( + r"(pub|ebook|e-book|kindle|electronic|电子)", binding, flags=re.IGNORECASE + ): + return Edition.BookFormat.HARDCOVER + if re.search(r"(web|网)", binding, flags=re.IGNORECASE): + return Edition.BookFormat.WEB + if re.search(r"(精|Hard)", binding, flags=re.IGNORECASE): + return Edition.BookFormat.HARDCOVER + if re.search(r"(平|Paper|Soft)", binding, flags=re.IGNORECASE): + return Edition.BookFormat.PAPERBACK + return None diff --git a/catalog/sites/bookstw.py b/catalog/sites/bookstw.py index c85284fc..6049f0f2 100644 --- a/catalog/sites/bookstw.py +++ b/catalog/sites/bookstw.py @@ -131,6 +131,7 @@ class BooksTW(AbstractSite): "pub_year": pub_year, "pub_month": pub_month, "binding": binding, + "format": binding_to_format(str(binding)) if binding else None, "price": price, "pages": pages, "isbn": isbn, diff --git a/catalog/sites/douban_book.py b/catalog/sites/douban_book.py index fe7aa7a5..8ff4c9de 100644 --- a/catalog/sites/douban_book.py +++ b/catalog/sites/douban_book.py @@ -199,6 +199,7 @@ class DoubanBook(AbstractSite): "pub_year": pub_year, "pub_month": pub_month, "binding": binding, + "format": binding_to_format(binding), "price": price, "pages": pages, "isbn": isbn, diff --git a/catalog/sites/goodreads.py b/catalog/sites/goodreads.py index 8baeb17a..891fec1d 100644 --- a/catalog/sites/goodreads.py +++ b/catalog/sites/goodreads.py @@ -7,7 +7,7 @@ from django.utils.timezone import make_aware from lxml import html from catalog.book.models import Edition, Work -from catalog.book.utils import detect_isbn_asin +from catalog.book.utils import binding_to_format, detect_isbn_asin from catalog.common import * from common.models.lang import detect_language from journal.models.renderers import html_to_text @@ -95,6 +95,7 @@ class Goodreads(AbstractSite): ids[t] = n data["pages"] = b["details"].get("numPages") data["binding"] = b["details"].get("format") + data["format"] = binding_to_format(b["details"].get("format")) data["pub_house"] = b["details"].get("publisher") if b["details"].get("publicationTime"): dt = make_aware( diff --git a/catalog/templates/edition.html b/catalog/templates/edition.html index bcdd09a1..53998099 100644 --- a/catalog/templates/edition.html +++ b/catalog/templates/edition.html @@ -21,6 +21,13 @@
{% include '_people.html' with people=item.author role='author' max=5 %}
{% include '_people.html' with people=item.translator role='translator' max=5 %}
+
+
+ {% if item.format %} + {% trans 'book format' %}: {{ item.get_format_display }} + {% endif %} +
+
{% if item.pub_house %} {% trans 'publishing house' %}: {{ item.pub_house }}