From 5c99f142f9cf58f639c0bcbab95a3f01d3436942 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 15 Dec 2021 17:10:59 -0800 Subject: [PATCH] Serialize links for books --- bookwyrm/activitypub/base_activity.py | 48 ++++++++++++++++----------- bookwyrm/activitypub/person.py | 5 +++ bookwyrm/models/book.py | 7 +++- bookwyrm/models/link.py | 6 +++- bookwyrm/models/user.py | 9 +---- 5 files changed, 45 insertions(+), 30 deletions(-) diff --git a/bookwyrm/activitypub/base_activity.py b/bookwyrm/activitypub/base_activity.py index 7429dbe6..f1b3ad18 100644 --- a/bookwyrm/activitypub/base_activity.py +++ b/bookwyrm/activitypub/base_activity.py @@ -20,23 +20,6 @@ class ActivityEncoder(JSONEncoder): return o.__dict__ -@dataclass -class Link: - """for tagging a book in a status""" - - href: str - name: str - mediaType: str = None - type: str = "Link" - - -@dataclass -class Mention(Link): - """a subtype of Link for mentioning an actor""" - - type: str = "Mention" - - @dataclass # pylint: disable=invalid-name class Signature: @@ -199,8 +182,9 @@ class ActivityObject: ) return instance - def serialize(self): + def serialize(self, **kwargs): """convert to dictionary with context attr""" + omit = kwargs.get("omit", ()) data = self.__dict__.copy() # recursively serialize for (k, v) in data.items(): @@ -209,8 +193,9 @@ class ActivityObject: data[k] = v.serialize() except TypeError: pass - data = {k: v for (k, v) in data.items() if v is not None} - data["@context"] = "https://www.w3.org/ns/activitystreams" + data = {k: v for (k, v) in data.items() if v is not None and k not in omit} + if "@context" not in omit: + data["@context"] = "https://www.w3.org/ns/activitystreams" return data @@ -305,3 +290,26 @@ def resolve_remote_id( # if we're refreshing, "result" will be set and we'll update it return item.to_model(model=model, instance=result, save=save) + + +@dataclass(init=False) +class Link(ActivityObject): + """for tagging a book in a status""" + + href: str + name: str + mediaType: str = None + id: str = None + type: str = "Link" + + def serialize(self, **kwargs): + """remove fields""" + omit = ("id", "type", "@context") + return super().serialize(omit=omit) + + +@dataclass(init=False) +class Mention(Link): + """a subtype of Link for mentioning an actor""" + + type: str = "Mention" diff --git a/bookwyrm/activitypub/person.py b/bookwyrm/activitypub/person.py index 174ead61..576e7f9a 100644 --- a/bookwyrm/activitypub/person.py +++ b/bookwyrm/activitypub/person.py @@ -15,6 +15,11 @@ class PublicKey(ActivityObject): publicKeyPem: str type: str = "PublicKey" + def serialize(self, **kwargs): + """remove fields""" + omit = ("type", "@context") + return super().serialize(omit=omit) + # pylint: disable=invalid-name @dataclass(init=False) diff --git a/bookwyrm/models/book.py b/bookwyrm/models/book.py index cb811a12..c850f78b 100644 --- a/bookwyrm/models/book.py +++ b/bookwyrm/models/book.py @@ -234,7 +234,10 @@ class Work(OrderedCollectionPageMixin, Book): ) activity_serializer = activitypub.Work - serialize_reverse_fields = [("editions", "editions", "-edition_rank")] + serialize_reverse_fields = [ + ("editions", "editions", "-edition_rank"), + ("file_links", "fileLinks", "-created_date"), + ] deserialize_reverse_fields = [("editions", "editions"), ("file_links", "fileLinks")] @@ -289,6 +292,8 @@ class Edition(Book): activity_serializer = activitypub.Edition name_field = "title" + serialize_reverse_fields = [("file_links", "fileLinks", "-created_date")] + deserialize_reverse_fields = [("file_links", "fileLinks")] def get_rank(self): """calculate how complete the data is on this edition""" diff --git a/bookwyrm/models/link.py b/bookwyrm/models/link.py index 9c0d3222..8693775b 100644 --- a/bookwyrm/models/link.py +++ b/bookwyrm/models/link.py @@ -23,11 +23,15 @@ class Link(ActivitypubMixin, BookWyrmModel): del kwargs["broadcast"] return super().save(*args, **kwargs) + def to_activity(self, omit=(), **kwargs): + """we don't need ALL the fields""" + return super().to_activity(omit=("@context", "id"), **kwargs) + class FileLink(Link): """a link to a file""" - book = fields.ForeignKey( + book = models.ForeignKey( "Book", on_delete=models.CASCADE, related_name="file_links", null=True ) filetype = fields.CharField(max_length=5, activitypub_field="mediaType") diff --git a/bookwyrm/models/user.py b/bookwyrm/models/user.py index 4d98f5c5..e13ccd03 100644 --- a/bookwyrm/models/user.py +++ b/bookwyrm/models/user.py @@ -344,6 +344,7 @@ class User(OrderedCollectionPageMixin, AbstractUser): def delete(self, *args, **kwargs): """deactivate rather than delete a user""" + # pylint: disable=attribute-defined-outside-init self.is_active = False # skip the logic in this class's save() super().save(*args, **kwargs) @@ -404,14 +405,6 @@ class KeyPair(ActivitypubMixin, BookWyrmModel): self.private_key, self.public_key = create_key_pair() return super().save(*args, **kwargs) - def to_activity(self, **kwargs): - """override default AP serializer to add context object - idk if this is the best way to go about this""" - activity_object = super().to_activity(**kwargs) - del activity_object["@context"] - del activity_object["type"] - return activity_object - class AnnualGoal(BookWyrmModel): """set a goal for how many books you read in a year"""