From 530198adea8c136d3506e59b879b0d38ae66952f Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 17 Dec 2020 12:46:05 -0800 Subject: [PATCH] Serialize alt text of images --- bookwyrm/models/book.py | 6 ++++-- bookwyrm/models/fields.py | 22 ++++++++++++++++++---- bookwyrm/models/status.py | 6 +++--- bookwyrm/models/user.py | 8 +++++++- bookwyrm/templates/snippets/avatar.html | 2 +- bookwyrm/tests/models/test_book_model.py | 2 +- 6 files changed, 34 insertions(+), 12 deletions(-) diff --git a/bookwyrm/models/book.py b/bookwyrm/models/book.py index c28f0a23..b20cb6ef 100644 --- a/bookwyrm/models/book.py +++ b/bookwyrm/models/book.py @@ -52,7 +52,8 @@ class Book(ActivitypubMixin, BookWyrmModel): authors = fields.ManyToManyField('Author') # preformatted authorship string for search and easier display author_text = models.CharField(max_length=255, blank=True, null=True) - cover = fields.ImageField(upload_to='covers/', blank=True, null=True) + cover = fields.ImageField( + upload_to='covers/', blank=True, null=True, alt_field='alt_text') first_published_date = fields.DateTimeField(blank=True, null=True) published_date = fields.DateTimeField(blank=True, null=True) @@ -62,13 +63,14 @@ class Book(ActivitypubMixin, BookWyrmModel): def edition_info(self): ''' properties of this edition, as a string ''' items = [ - self.physical_format if isinstance(self, models.Edition) else None, + self.physical_format, self.languages[0] + ' language' if self.languages and \ self.languages[0] != 'English' else None, str(self.published_date.year) if self.published_date else None, ] return ', '.join(i for i in items if i) + @property def alt_text(self): ''' image alt test ''' return '%s cover (%s)' % (self.title, self.edition_info) diff --git a/bookwyrm/models/fields.py b/bookwyrm/models/fields.py index 52933715..e2ccc1ba 100644 --- a/bookwyrm/models/fields.py +++ b/bookwyrm/models/fields.py @@ -295,18 +295,22 @@ class TagField(ManyToManyField): return items -def image_serializer(value): +def image_serializer(value, alt): ''' helper for serializing images ''' if value and hasattr(value, 'url'): url = value.url else: return None url = 'https://%s%s' % (DOMAIN, url) - return activitypub.Image(url=url) + return activitypub.Image(url=url, name=alt) class ImageField(ActivitypubFieldMixin, models.ImageField): ''' activitypub-aware image field ''' + def __init__(self, *args, alt_field=None, **kwargs): + self.alt_field = alt_field + super().__init__(*args, **kwargs) + # pylint: disable=arguments-differ def set_field_from_activity(self, instance, data, save=True): ''' helper function for assinging a value to the field ''' @@ -316,9 +320,19 @@ class ImageField(ActivitypubFieldMixin, models.ImageField): return getattr(instance, self.name).save(*formatted, save=save) + def set_activity_from_field(self, activity, instance): + value = getattr(instance, self.name) + if value is None: + return + alt_text = getattr(instance, self.alt_field) + formatted = self.field_to_activity(value, alt_text) - def field_to_activity(self, value): - return image_serializer(value) + key = self.get_activitypub_field() + activity[key] = formatted + + + def field_to_activity(self, value, alt=None): + return image_serializer(value, alt) def field_from_activity(self, value): diff --git a/bookwyrm/models/status.py b/bookwyrm/models/status.py index 49fbad55..b358554c 100644 --- a/bookwyrm/models/status.py +++ b/bookwyrm/models/status.py @@ -86,11 +86,11 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel): activity['name'] = self.pure_name activity['type'] = self.pure_type activity['attachment'] = [ - image_serializer(b.cover) for b in self.mention_books.all() \ - if b.cover] + image_serializer(b.cover, b.alt_text) \ + for b in self.mention_books.all()[:4] if b.cover] if hasattr(self, 'book'): activity['attachment'].append( - image_serializer(self.book.cover) + image_serializer(self.book.cover, self.book.alt_text) ) return activity diff --git a/bookwyrm/models/user.py b/bookwyrm/models/user.py index 9d66eb5c..d5db9949 100644 --- a/bookwyrm/models/user.py +++ b/bookwyrm/models/user.py @@ -53,7 +53,8 @@ class User(OrderedCollectionPageMixin, AbstractUser): # name is your display name, which you can change at will name = fields.CharField(max_length=100, default='') avatar = fields.ImageField( - upload_to='avatars/', blank=True, null=True, activitypub_field='icon') + upload_to='avatars/', blank=True, null=True, + activitypub_field='icon', alt_field='alt_text') followers = fields.ManyToManyField( 'self', link_only=True, @@ -90,6 +91,11 @@ class User(OrderedCollectionPageMixin, AbstractUser): last_active_date = models.DateTimeField(auto_now=True) manually_approves_followers = fields.BooleanField(default=False) + @property + def alt_text(self): + ''' alt text with username ''' + return 'avatar for %s' % (self.localname or self.username) + @property def display_name(self): ''' show the cleanest version of the user's name possible ''' diff --git a/bookwyrm/templates/snippets/avatar.html b/bookwyrm/templates/snippets/avatar.html index da4b5fd2..ca49075c 100644 --- a/bookwyrm/templates/snippets/avatar.html +++ b/bookwyrm/templates/snippets/avatar.html @@ -1,3 +1,3 @@ {% load bookwyrm_tags %} -avatar for {{ user|username }} +{{ user.alt_text }} diff --git a/bookwyrm/tests/models/test_book_model.py b/bookwyrm/tests/models/test_book_model.py index 76c9829e..e8b31084 100644 --- a/bookwyrm/tests/models/test_book_model.py +++ b/bookwyrm/tests/models/test_book_model.py @@ -62,7 +62,7 @@ class Book(TestCase): def test_get_edition_info(self): ''' text slug about an edition ''' - book = models.Book.object.create(title='Test Edition') + book = models.Book.objects.create(title='Test Edition') self.assertEqual(book.edition_info, '') book.physical_format = 'worm'