mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-11-26 11:31:08 +00:00
Isfdb ID for books and authors (#2482)
* New ID: Audible ASIN Audible belongs to Amazon BUT they do not share the same IDs. The Audible ASIN of an audiobook is never the same as the Amazon ASIN. Yeah, I know, Amazon is great. The fact that the ASIN is a good distinction for different works and editions bothers me more than I will ever be willing to admint. * New ID "ISFDB" Internet Speculative Ficiton Database ID for books and authors. Links to the entry if set. * Added aasin to test Added aasin to test * the answer expects more emptxy fields...
This commit is contained in:
parent
0e2b88ad0c
commit
ac8b060d58
15 changed files with 150 additions and 4 deletions
|
@ -19,6 +19,8 @@ class BookData(ActivityObject):
|
|||
viaf: str = None
|
||||
wikidata: str = None
|
||||
asin: str = None
|
||||
aasin: str = None
|
||||
isfdb: str = None
|
||||
lastEditedBy: str = None
|
||||
links: List[str] = field(default_factory=lambda: [])
|
||||
fileLinks: List[str] = field(default_factory=lambda: [])
|
||||
|
|
|
@ -21,6 +21,7 @@ class AuthorForm(CustomForm):
|
|||
"inventaire_id",
|
||||
"librarything_key",
|
||||
"goodreads_key",
|
||||
"isfdb",
|
||||
"isni",
|
||||
]
|
||||
widgets = {
|
||||
|
|
|
@ -89,6 +89,8 @@ class EditionForm(CustomForm):
|
|||
attrs={"aria-describedby": "desc_oclc_number"}
|
||||
),
|
||||
"ASIN": forms.TextInput(attrs={"aria-describedby": "desc_ASIN"}),
|
||||
"AASIN": forms.TextInput(attrs={"aria-describedby": "desc_AASIN"}),
|
||||
"isfdb": forms.TextInput(attrs={"aria-describedby": "desc_isfdb"}),
|
||||
}
|
||||
|
||||
|
||||
|
|
28
bookwyrm/migrations/0168_auto_20221205_1701.py
Normal file
28
bookwyrm/migrations/0168_auto_20221205_1701.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Generated by Django 3.2.16 on 2022-12-05 17:01
|
||||
|
||||
import bookwyrm.models.fields
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("bookwyrm", "0167_auto_20221125_1900"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="author",
|
||||
name="aasin",
|
||||
field=bookwyrm.models.fields.CharField(
|
||||
blank=True, max_length=255, null=True
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="book",
|
||||
name="aasin",
|
||||
field=bookwyrm.models.fields.CharField(
|
||||
blank=True, max_length=255, null=True
|
||||
),
|
||||
),
|
||||
]
|
28
bookwyrm/migrations/0169_auto_20221206_0902.py
Normal file
28
bookwyrm/migrations/0169_auto_20221206_0902.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Generated by Django 3.2.16 on 2022-12-06 09:02
|
||||
|
||||
import bookwyrm.models.fields
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("bookwyrm", "0168_auto_20221205_1701"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="author",
|
||||
name="isfdb",
|
||||
field=bookwyrm.models.fields.CharField(
|
||||
blank=True, max_length=255, null=True
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="book",
|
||||
name="isfdb",
|
||||
field=bookwyrm.models.fields.CharField(
|
||||
blank=True, max_length=255, null=True
|
||||
),
|
||||
),
|
||||
]
|
|
@ -24,6 +24,9 @@ class Author(BookDataModel):
|
|||
gutenberg_id = fields.CharField(
|
||||
max_length=255, blank=True, null=True, deduplication_field=True
|
||||
)
|
||||
isfdb = fields.CharField(
|
||||
max_length=255, blank=True, null=True, deduplication_field=True
|
||||
)
|
||||
# idk probably other keys would be useful here?
|
||||
born = fields.DateTimeField(blank=True, null=True)
|
||||
died = fields.DateTimeField(blank=True, null=True)
|
||||
|
@ -60,6 +63,11 @@ class Author(BookDataModel):
|
|||
"""generate the url from the openlibrary id"""
|
||||
return f"https://openlibrary.org/authors/{self.openlibrary_key}"
|
||||
|
||||
@property
|
||||
def isfdb_link(self):
|
||||
"""generate the url from the isni id"""
|
||||
return f"https://www.isfdb.org/cgi-bin/ea.cgi?{self.isfdb}"
|
||||
|
||||
def get_remote_id(self):
|
||||
"""editions and works both use "book" instead of model_name"""
|
||||
return f"https://{DOMAIN}/author/{self.id}"
|
||||
|
|
|
@ -55,6 +55,12 @@ class BookDataModel(ObjectMixin, BookWyrmModel):
|
|||
asin = fields.CharField(
|
||||
max_length=255, blank=True, null=True, deduplication_field=True
|
||||
)
|
||||
aasin = fields.CharField(
|
||||
max_length=255, blank=True, null=True, deduplication_field=True
|
||||
)
|
||||
isfdb = fields.CharField(
|
||||
max_length=255, blank=True, null=True, deduplication_field=True
|
||||
)
|
||||
search_vector = SearchVectorField(null=True)
|
||||
|
||||
last_edited_by = fields.ForeignKey(
|
||||
|
@ -73,6 +79,11 @@ class BookDataModel(ObjectMixin, BookWyrmModel):
|
|||
"""generate the url from the inventaire id"""
|
||||
return f"https://inventaire.io/entity/{self.inventaire_id}"
|
||||
|
||||
@property
|
||||
def isfdb_link(self):
|
||||
"""generate the url from the isfdb id"""
|
||||
return f"https://www.isfdb.org/cgi-bin/title.cgi?{self.isfdb}"
|
||||
|
||||
class Meta:
|
||||
"""can't initialize this model, that wouldn't make sense"""
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
<meta itemprop="name" content="{{ author.name }}">
|
||||
|
||||
{% firstof author.aliases author.born author.died as details %}
|
||||
{% firstof author.wikipedia_link author.openlibrary_key author.inventaire_id author.isni as links %}
|
||||
{% firstof author.wikipedia_link author.openlibrary_key author.inventaire_id author.isni author.isfdb as links %}
|
||||
{% if details or links %}
|
||||
<div class="column is-3">
|
||||
{% if details %}
|
||||
|
@ -81,6 +81,14 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if author.isfdb %}
|
||||
<div class="mt-1">
|
||||
<a itemprop="sameAs" href="{{ author.isfdb_link }}" rel="nofollow noopener noreferrer" target="_blank">
|
||||
{% trans "View on ISFDB" %}
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% trans "Load data" as button_text %}
|
||||
{% if author.openlibrary_key %}
|
||||
<div class="mt-1 is-flex">
|
||||
|
@ -128,6 +136,14 @@
|
|||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if author.isfdb %}
|
||||
<div>
|
||||
<a itemprop="sameAs" href="https://www.isfdb.org/cgi-bin/ea.cgi?{{ author.isfdb }}" target="_blank" rel="nofollow noopener noreferrer">
|
||||
{% trans "View ISFDB entry" %}
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
|
|
@ -101,6 +101,13 @@
|
|||
{% include 'snippets/form_errors.html' with errors_list=form.goodreads_key.errors id="desc_goodreads_key" %}
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label" for="id_isfdb">{% trans "ISFDB:" %}</label>
|
||||
{{ form.isfdb }}
|
||||
|
||||
{% include 'snippets/form_errors.html' with errors_list=form.isfdb.errors id="desc_isfdb" %}
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label" for="id_isni">{% trans "ISNI:" %}</label>
|
||||
{{ form.isni }}
|
||||
|
|
|
@ -158,6 +158,13 @@
|
|||
{% endif %}
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if book.isfdb %}
|
||||
<p>
|
||||
<a href="{{ book.isfdb_link }}" target="_blank" rel="nofollow noopener noreferrer">
|
||||
{% trans "View on ISFDB" %}
|
||||
</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
</section>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{% spaceless %}
|
||||
{% load i18n %}
|
||||
|
||||
{% if book.isbn_13 or book.oclc_number or book.asin %}
|
||||
{% if book.isbn_13 or book.oclc_number or book.asin or book.aasin or book.isfdb %}
|
||||
<dl>
|
||||
{% if book.isbn_13 %}
|
||||
<div class="is-flex">
|
||||
|
@ -23,6 +23,21 @@
|
|||
<dd>{{ book.asin }}</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if book.aasin %}
|
||||
<div class="is-flex">
|
||||
<dt class="mr-1">{% trans "Audible ASIN:" %}</dt>
|
||||
<dd>{{ book.aasin }}</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if book.isfdb %}
|
||||
<div class="is-flex">
|
||||
<dt class="mr-1">{% trans "ISFDB ID:" %}</dt>
|
||||
<dd>{{ book.isfdb }}</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if book.goodreads_key %}
|
||||
<div class="is-flex">
|
||||
<dt class="mr-1">{% trans "Goodreads:" %}</dt>
|
||||
|
|
|
@ -353,6 +353,24 @@
|
|||
|
||||
{% include 'snippets/form_errors.html' with errors_list=form.ASIN.errors id="desc_ASIN" %}
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label" for="id_aasin">
|
||||
{% trans "Audible ASIN:" %}
|
||||
</label>
|
||||
{{ form.aasin }}
|
||||
|
||||
{% include 'snippets/form_errors.html' with errors_list=form.AASIN.errors id="desc_AASIN" %}
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label" for="id_isfdb">
|
||||
{% trans "ISFDB ID:" %}
|
||||
</label>
|
||||
{{ form.isfdb }}
|
||||
|
||||
{% include 'snippets/form_errors.html' with errors_list=form.isfdb.errors id="desc_isfdb" %}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
"openlibrary_key": "OL29486417M",
|
||||
"librarything_key": null,
|
||||
"goodreads_key": null,
|
||||
"isfdb": null,
|
||||
"attachment": [
|
||||
{
|
||||
"url": "https://bookwyrm.social/images/covers/50202953._SX318_.jpg",
|
||||
|
|
|
@ -63,7 +63,7 @@ class ExportViews(TestCase):
|
|||
# pylint: disable=line-too-long
|
||||
self.assertEqual(
|
||||
result[0],
|
||||
b"title,author_text,remote_id,openlibrary_key,inventaire_id,librarything_key,goodreads_key,bnf_id,viaf,wikidata,asin,isbn_10,isbn_13,oclc_number,rating,review_name,review_cw,review_content\r\n",
|
||||
b"title,author_text,remote_id,openlibrary_key,inventaire_id,librarything_key,goodreads_key,bnf_id,viaf,wikidata,asin,aasin,isfdb,isbn_10,isbn_13,oclc_number,rating,review_name,review_cw,review_content\r\n",
|
||||
)
|
||||
expected = f"Test Book,,{self.book.remote_id},,,,,beep,,,,123456789X,9781234567890,,,,,\r\n"
|
||||
expected = f"Test Book,,{self.book.remote_id},,,,,beep,,,,,,123456789X,9781234567890,,,,,\r\n"
|
||||
self.assertEqual(result[1].decode("utf-8"), expected)
|
||||
|
|
|
@ -49,6 +49,8 @@ class Editions(View):
|
|||
"isbn_13",
|
||||
"oclc_number",
|
||||
"asin",
|
||||
"aasin",
|
||||
"isfdb",
|
||||
]
|
||||
search_filter_entries = [
|
||||
{f"{f}__icontains": query} for f in searchable_fields
|
||||
|
|
Loading…
Reference in a new issue