Merge pull request #1636 from bookwyrm-social/missing-covers

Fixes checking if image fields are already set
This commit is contained in:
Mouse Reeve 2021-11-28 09:34:49 -08:00 committed by GitHub
commit 1fed22b27e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 150 additions and 8 deletions

View file

@ -296,7 +296,7 @@ class ManyToManyField(ActivitypubFieldMixin, models.ManyToManyField):
super().__init__(*args, **kwargs)
def set_field_from_activity(self, instance, data, overwrite=True):
"""helper function for assinging a value to the field"""
"""helper function for assigning a value to the field"""
if not overwrite and getattr(instance, self.name).exists():
return False
@ -398,7 +398,11 @@ class ImageField(ActivitypubFieldMixin, models.ImageField):
if formatted is None or formatted is MISSING:
return False
if not overwrite and hasattr(instance, self.name):
if (
not overwrite
and hasattr(instance, self.name)
and getattr(instance, self.name)
):
return False
getattr(instance, self.name).save(*formatted, save=save)

View file

@ -19,7 +19,7 @@ from django.utils import timezone
from bookwyrm import activitypub
from bookwyrm.activitypub.base_activity import ActivityObject
from bookwyrm.models import fields, User, Status
from bookwyrm.models import fields, User, Status, Edition
from bookwyrm.models.base_model import BookWyrmModel
from bookwyrm.models.activitypub_mixin import ActivitypubMixin
from bookwyrm.settings import DOMAIN
@ -215,7 +215,7 @@ class ModelFields(TestCase):
"rat", "rat@rat.rat", "ratword", local=True, localname="rat"
)
public = "https://www.w3.org/ns/activitystreams#Public"
followers = "%s/followers" % user.remote_id
followers = f"{user.remote_id}/followers"
instance = fields.PrivacyField()
instance.name = "privacy_field"
@ -409,11 +409,10 @@ class ModelFields(TestCase):
"""loadin' a list of items from Links"""
# TODO
@responses.activate
@patch("bookwyrm.models.activitypub_mixin.ObjectMixin.broadcast")
@patch("bookwyrm.suggested_users.remove_user_task.delay")
def test_image_field(self, *_):
"""storing images"""
def test_image_field_to_activity(self, *_):
"""serialize an image field to activitypub"""
user = User.objects.create_user(
"mouse", "mouse@mouse.mouse", "mouseword", local=True, localname="mouse"
)
@ -437,16 +436,155 @@ class ModelFields(TestCase):
self.assertEqual(output.name, "")
self.assertEqual(output.type, "Document")
@responses.activate
def test_image_field_from_activity(self, *_):
"""load an image from activitypub"""
image_file = pathlib.Path(__file__).parent.joinpath(
"../../static/images/default_avi.jpg"
)
image = Image.open(image_file)
output = BytesIO()
image.save(output, format=image.format)
instance = fields.ImageField()
responses.add(
responses.GET,
"http://www.example.com/image.jpg",
body=user.avatar.file.read(),
body=image.tobytes(),
status=200,
)
loaded_image = instance.field_from_activity("http://www.example.com/image.jpg")
self.assertIsInstance(loaded_image, list)
self.assertIsInstance(loaded_image[1], ContentFile)
@responses.activate
def test_image_field_set_field_from_activity(self, *_):
"""update a model instance from an activitypub object"""
image_file = pathlib.Path(__file__).parent.joinpath(
"../../static/images/default_avi.jpg"
)
image = Image.open(image_file)
output = BytesIO()
image.save(output, format=image.format)
instance = fields.ImageField(activitypub_field="cover", name="cover")
responses.add(
responses.GET,
"http://www.example.com/image.jpg",
body=image.tobytes(),
status=200,
)
book = Edition.objects.create(title="hello")
MockActivity = namedtuple("MockActivity", ("cover"))
mock_activity = MockActivity("http://www.example.com/image.jpg")
instance.set_field_from_activity(book, mock_activity)
self.assertIsNotNone(book.cover.name)
self.assertEqual(book.cover.size, 43200)
@responses.activate
def test_image_field_set_field_from_activity_no_overwrite_no_cover(self, *_):
"""update a model instance from an activitypub object"""
image_file = pathlib.Path(__file__).parent.joinpath(
"../../static/images/default_avi.jpg"
)
image = Image.open(image_file)
output = BytesIO()
image.save(output, format=image.format)
instance = fields.ImageField(activitypub_field="cover", name="cover")
responses.add(
responses.GET,
"http://www.example.com/image.jpg",
body=image.tobytes(),
status=200,
)
book = Edition.objects.create(title="hello")
MockActivity = namedtuple("MockActivity", ("cover"))
mock_activity = MockActivity("http://www.example.com/image.jpg")
instance.set_field_from_activity(book, mock_activity, overwrite=False)
self.assertIsNotNone(book.cover.name)
self.assertEqual(book.cover.size, 43200)
@responses.activate
def test_image_field_set_field_from_activity_no_overwrite_with_cover(self, *_):
"""update a model instance from an activitypub object"""
image_file = pathlib.Path(__file__).parent.joinpath(
"../../static/images/default_avi.jpg"
)
image = Image.open(image_file)
output = BytesIO()
image.save(output, format=image.format)
another_image_file = pathlib.Path(__file__).parent.joinpath(
"../../static/images/logo.png"
)
another_image = Image.open(another_image_file)
another_output = BytesIO()
another_image.save(another_output, format=another_image.format)
instance = fields.ImageField(activitypub_field="cover", name="cover")
responses.add(
responses.GET,
"http://www.example.com/image.jpg",
body=another_image.tobytes(),
status=200,
)
book = Edition.objects.create(title="hello")
book.cover.save("test.jpg", ContentFile(output.getvalue()))
self.assertEqual(book.cover.size, 2136)
MockActivity = namedtuple("MockActivity", ("cover"))
mock_activity = MockActivity("http://www.example.com/image.jpg")
instance.set_field_from_activity(book, mock_activity, overwrite=False)
# same cover as before
self.assertEqual(book.cover.size, 2136)
@responses.activate
def test_image_field_set_field_from_activity_with_overwrite_with_cover(self, *_):
"""update a model instance from an activitypub object"""
image_file = pathlib.Path(__file__).parent.joinpath(
"../../static/images/default_avi.jpg"
)
image = Image.open(image_file)
output = BytesIO()
image.save(output, format=image.format)
book = Edition.objects.create(title="hello")
book.cover.save("test.jpg", ContentFile(output.getvalue()))
self.assertEqual(book.cover.size, 2136)
another_image_file = pathlib.Path(__file__).parent.joinpath(
"../../static/images/logo.png"
)
another_image = Image.open(another_image_file)
another_output = BytesIO()
another_image.save(another_output, format=another_image.format)
instance = fields.ImageField(activitypub_field="cover", name="cover")
responses.add(
responses.GET,
"http://www.example.com/image.jpg",
body=another_image.tobytes(),
status=200,
)
MockActivity = namedtuple("MockActivity", ("cover"))
mock_activity = MockActivity("http://www.example.com/image.jpg")
instance.set_field_from_activity(book, mock_activity, overwrite=True)
# new cover
self.assertIsNotNone(book.cover.name)
self.assertEqual(book.cover.size, 376800)
def test_datetime_field(self, *_):
"""this one is pretty simple, it just has to use isoformat"""
instance = fields.DateTimeField()