Merge pull request #512 from mouse-reeve/edition-order

Edition order
This commit is contained in:
Mouse Reeve 2021-01-11 14:50:26 -08:00 committed by GitHub
commit ad9008ada8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 92 additions and 12 deletions

View file

@ -41,6 +41,7 @@ class Edition(Book):
pages: int = None
physicalFormat: str = ''
publishers: List[str] = field(default_factory=lambda: [])
editionRank: int = 0
type: str = 'Edition'

View file

@ -7,7 +7,11 @@ class Connector(AbstractMinimalConnector):
''' this is basically just for search '''
def get_or_create_book(self, remote_id):
return activitypub.resolve_remote_id(models.Edition, remote_id)
edition = activitypub.resolve_remote_id(models.Edition, remote_id)
work = edition.parent_work
work.default_edition = work.get_default_edition()
work.save()
return edition
def parse_search_data(self, data):
return data

View file

@ -0,0 +1,27 @@
# Generated by Django 3.0.7 on 2021-01-11 17:18
import bookwyrm.models.fields
from django.db import migrations
def set_rank(app_registry, schema_editor):
db_alias = schema_editor.connection.alias
books = app_registry.get_model('bookwyrm', 'Edition')
for book in books.objects.using(db_alias):
book.edition_rank = book.get_rank
book.save()
class Migration(migrations.Migration):
dependencies = [
('bookwyrm', '0034_importjob_complete'),
]
operations = [
migrations.AddField(
model_name='edition',
name='edition_rank',
field=bookwyrm.models.fields.IntegerField(default=0),
),
migrations.RunPython(set_rank),
]

View file

@ -52,10 +52,11 @@ def execute_after_save(sender, instance, created, *args, **kwargs):
instance.save()
def unfurl_related_field(related_field):
def unfurl_related_field(related_field, sort_field=None):
''' load reverse lookups (like public key owner or Status attachment '''
if hasattr(related_field, 'all'):
return [unfurl_related_field(i) for i in related_field.all()]
return [unfurl_related_field(i) for i in related_field.order_by(
sort_field).all()]
if related_field.reverse_unfurl:
return related_field.field_to_activity()
return related_field.remote_id
@ -145,11 +146,11 @@ class ActivitypubMixin:
if hasattr(self, 'serialize_reverse_fields'):
# for example, editions of a work
for model_field_name, activity_field_name in \
for model_field_name, activity_field_name, sort_field in \
self.serialize_reverse_fields:
related_field = getattr(self, model_field_name)
activity[activity_field_name] = \
unfurl_related_field(related_field)
unfurl_related_field(related_field, sort_field)
if not activity.get('id'):
activity['id'] = self.get_remote_id()

View file

@ -122,20 +122,29 @@ class Work(OrderedCollectionPageMixin, Book):
load_remote=False
)
def save(self, *args, **kwargs):
''' set some fields on the edition object '''
# set rank
for edition in self.editions.all():
edition.save()
return super().save(*args, **kwargs)
def get_default_edition(self):
''' in case the default edition is not set '''
return self.default_edition or self.editions.first()
return self.default_edition or self.editions.order_by(
'-edition_rank'
).first()
def to_edition_list(self, **kwargs):
''' an ordered collection of editions '''
return self.to_ordered_collection(
self.editions.order_by('-updated_date').all(),
self.editions.order_by('-edition_rank').all(),
remote_id='%s/editions' % self.remote_id,
**kwargs
)
activity_serializer = activitypub.Work
serialize_reverse_fields = [('editions', 'editions')]
serialize_reverse_fields = [('editions', 'editions', '-edition_rank')]
deserialize_reverse_fields = [('editions', 'editions')]
@ -164,17 +173,39 @@ class Edition(Book):
parent_work = fields.ForeignKey(
'Work', on_delete=models.PROTECT, null=True,
related_name='editions', activitypub_field='work')
edition_rank = fields.IntegerField(default=0)
activity_serializer = activitypub.Edition
name_field = 'title'
@property
def get_rank(self):
''' calculate how complete the data is on this edition '''
if self.parent_work and self.parent_work.default_edition == self:
# default edition has the highest rank
return 20
rank = 0
rank += int(bool(self.cover)) * 3
rank += int(bool(self.isbn_13))
rank += int(bool(self.isbn_10))
rank += int(bool(self.oclc_number))
rank += int(bool(self.pages))
rank += int(bool(self.physical_format))
rank += int(bool(self.description))
# max rank is 9
return rank
def save(self, *args, **kwargs):
''' calculate isbn 10/13 '''
''' set some fields on the edition object '''
# calculate isbn 10/13
if self.isbn_13 and self.isbn_13[:3] == '978' and not self.isbn_10:
self.isbn_10 = isbn_13_to_10(self.isbn_13)
if self.isbn_10 and not self.isbn_13:
self.isbn_13 = isbn_10_to_13(self.isbn_10)
# set rank
self.edition_rank = self.get_rank
return super().save(*args, **kwargs)

View file

@ -47,7 +47,7 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel):
objects = InheritanceManager()
activity_serializer = activitypub.Note
serialize_reverse_fields = [('attachments', 'attachment')]
serialize_reverse_fields = [('attachments', 'attachment', 'id')]
deserialize_reverse_fields = [('attachments', 'attachment')]
@classmethod

View file

@ -200,7 +200,7 @@ class KeyPair(ActivitypubMixin, BookWyrmModel):
blank=True, null=True, activitypub_field='publicKeyPem')
activity_serializer = activitypub.PublicKey
serialize_reverse_fields = [('owner', 'owner')]
serialize_reverse_fields = [('owner', 'owner', 'id')]
def get_remote_id(self):
# self.owner is set by the OneToOneField on User

View file

@ -82,3 +82,19 @@ class Book(TestCase):
self.assertEqual(book.edition_info, 'worm, Glorbish language, 2020')
self.assertEqual(
book.alt_text, 'Test Edition cover (worm, Glorbish language, 2020)')
def test_get_rank(self):
''' sets the data quality index for the book '''
# basic rank
self.assertEqual(self.first_edition.edition_rank, 0)
self.first_edition.description = 'hi'
self.first_edition.save()
self.assertEqual(self.first_edition.edition_rank, 1)
# default edition
self.work.default_edition = self.first_edition
self.work.save()
self.first_edition.refresh_from_db()
self.assertEqual(self.first_edition.edition_rank, 20)

View file

@ -736,7 +736,7 @@ def editions_page(request, book_id):
data = {
'title': 'Editions of %s' % work.title,
'editions': work.editions.all(),
'editions': work.editions.order_by('-edition_rank').all(),
'work': work,
}
return TemplateResponse(request, 'editions.html', data)