bookwyrm/bookwyrm/activitypub/note.py

140 lines
3.5 KiB
Python
Raw Permalink Normal View History

2021-03-08 16:49:10 +00:00
""" note serializer and children thereof """
from dataclasses import dataclass, field
from typing import Dict, List
import re
2021-02-16 17:35:00 +00:00
from django.apps import apps
from django.db import IntegrityError, transaction
from .base_activity import ActivityObject, ActivitySerializerError, Link
2021-04-15 23:35:04 +00:00
from .image import Document
2021-03-08 16:49:10 +00:00
2020-10-08 19:32:45 +00:00
@dataclass(init=False)
class Tombstone(ActivityObject):
2021-04-26 16:15:42 +00:00
"""the placeholder for a deleted status"""
2021-03-08 16:49:10 +00:00
type: str = "Tombstone"
2020-10-08 19:32:45 +00:00
2021-03-08 17:54:02 +00:00
def to_model(self, *args, **kwargs): # pylint: disable=unused-argument
2021-04-26 16:15:42 +00:00
"""this should never really get serialized, just searched for"""
2021-03-08 17:54:02 +00:00
model = apps.get_model("bookwyrm.Status")
2021-02-16 17:35:00 +00:00
return model.find_existing_by_remote_id(self.id)
2020-10-08 19:32:45 +00:00
2021-06-18 21:29:24 +00:00
# pylint: disable=invalid-name
@dataclass(init=False)
class Note(ActivityObject):
2021-04-26 16:15:42 +00:00
"""Note activity"""
2021-03-08 16:49:10 +00:00
published: str
attributedTo: str
2021-03-08 16:49:10 +00:00
content: str = ""
2020-11-30 22:24:31 +00:00
to: List[str] = field(default_factory=lambda: [])
cc: List[str] = field(default_factory=lambda: [])
replies: Dict = field(default_factory=lambda: {})
inReplyTo: str = None
summary: str = None
tag: List[Link] = field(default_factory=lambda: [])
2021-04-15 23:35:04 +00:00
attachment: List[Document] = field(default_factory=lambda: [])
sensitive: bool = False
updated: str = None
2021-03-08 16:49:10 +00:00
type: str = "Note"
# pylint: disable=too-many-arguments
def to_model(
self,
model=None,
instance=None,
allow_create=True,
save=True,
overwrite=True,
allow_external_connections=True,
):
instance = super().to_model(
model, instance, allow_create, save, overwrite, allow_external_connections
)
if instance is None:
return instance
# Replace links to hashtags in content with local URLs
changed_content = False
for hashtag in instance.mention_hashtags.all():
updated_content = re.sub(
rf'(<a href=")[^"]*(" data-mention="hashtag">{hashtag.name}</a>)',
rf"\1{hashtag.remote_id}\2",
instance.content,
flags=re.IGNORECASE,
)
if instance.content != updated_content:
instance.content = updated_content
changed_content = True
if not save or not changed_content:
return instance
with transaction.atomic():
try:
instance.save(broadcast=False, update_fields=["content"])
except IntegrityError as e:
raise ActivitySerializerError(e)
return instance
@dataclass(init=False)
class Article(Note):
2021-04-26 16:15:42 +00:00
"""what's an article except a note with more fields"""
2021-03-08 16:49:10 +00:00
name: str
2021-03-08 16:49:10 +00:00
type: str = "Article"
@dataclass(init=False)
class GeneratedNote(Note):
2021-04-26 16:15:42 +00:00
"""just a re-typed note"""
2021-03-08 16:49:10 +00:00
type: str = "GeneratedNote"
2021-06-18 21:29:24 +00:00
# pylint: disable=invalid-name
@dataclass(init=False)
class Comment(Note):
2021-04-26 16:15:42 +00:00
"""like a note but with a book"""
2021-03-08 16:49:10 +00:00
inReplyToBook: str
2021-08-16 20:59:15 +00:00
readingStatus: str = None
progress: int = None
progressMode: str = None
2021-03-08 16:49:10 +00:00
type: str = "Comment"
@dataclass(init=False)
class Quotation(Comment):
2021-04-26 16:15:42 +00:00
"""a quote and commentary on a book"""
2021-03-08 17:48:25 +00:00
quote: str
2021-09-05 23:00:40 +00:00
position: int = None
positionMode: str = None
2021-03-08 17:48:25 +00:00
type: str = "Quotation"
@dataclass(init=False)
class Review(Comment):
2021-04-26 16:15:42 +00:00
"""a full book review"""
2021-03-08 16:49:10 +00:00
2020-12-17 21:21:21 +00:00
name: str = None
rating: int = None
2021-03-08 16:49:10 +00:00
type: str = "Review"
@dataclass(init=False)
class Rating(Comment):
2021-04-26 16:15:42 +00:00
"""just a star rating"""
2021-03-08 16:49:10 +00:00
rating: int
content: str = None
2021-04-29 22:16:51 +00:00
name: str = None # not used, but the model inherits from Review
2021-03-08 17:48:25 +00:00
type: str = "Rating"