mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2025-01-23 15:38:08 +00:00
initial work to add 'Move' activity
This commit is contained in:
parent
e5f8e4babc
commit
e7ba6a3141
6 changed files with 121 additions and 1 deletions
|
@ -19,6 +19,7 @@ from .verbs import Create, Delete, Undo, Update
|
||||||
from .verbs import Follow, Accept, Reject, Block
|
from .verbs import Follow, Accept, Reject, Block
|
||||||
from .verbs import Add, Remove
|
from .verbs import Add, Remove
|
||||||
from .verbs import Announce, Like
|
from .verbs import Announce, Like
|
||||||
|
from .verbs import Move
|
||||||
|
|
||||||
# this creates a list of all the Activity types that we can serialize,
|
# this creates a list of all the Activity types that we can serialize,
|
||||||
# so when an Activity comes in from outside, we can check if it's known
|
# so when an Activity comes in from outside, we can check if it's known
|
||||||
|
|
|
@ -231,3 +231,28 @@ class Announce(Verb):
|
||||||
def action(self, allow_external_connections=True):
|
def action(self, allow_external_connections=True):
|
||||||
"""boost"""
|
"""boost"""
|
||||||
self.to_model(allow_external_connections=allow_external_connections)
|
self.to_model(allow_external_connections=allow_external_connections)
|
||||||
|
|
||||||
|
@dataclass(init=False)
|
||||||
|
class Move(Verb):
|
||||||
|
"""a user moving an object"""
|
||||||
|
|
||||||
|
# note the spec example for target and origin is an object but
|
||||||
|
# Mastodon uses a URI string and TBH this makes more sense
|
||||||
|
# Is there a way we can account for either format?
|
||||||
|
|
||||||
|
object: str
|
||||||
|
type: str = "Move"
|
||||||
|
target: str
|
||||||
|
origin: str
|
||||||
|
|
||||||
|
def action(self, allow_external_connections=True):
|
||||||
|
"""move"""
|
||||||
|
|
||||||
|
# we need to work out whether the object is a user or something else.
|
||||||
|
|
||||||
|
object_is_user = True # TODO!
|
||||||
|
|
||||||
|
if object_is_user:
|
||||||
|
self.to_model(object_is_user=True allow_external_connections=allow_external_connections)
|
||||||
|
else:
|
||||||
|
self.to_model(object_is_user=False allow_external_connections=allow_external_connections)
|
50
bookwyrm/models/move.py
Normal file
50
bookwyrm/models/move.py
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
""" move an object including migrating a user account """
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
from bookwyrm import activitypub
|
||||||
|
from .activitypub_mixin import ActivityMixin
|
||||||
|
from .base_model import BookWyrmModel
|
||||||
|
from . import fields
|
||||||
|
from .status import Status
|
||||||
|
|
||||||
|
|
||||||
|
class Move(ActivityMixin, BookWyrmModel):
|
||||||
|
"""migrating an activitypub user account"""
|
||||||
|
|
||||||
|
user = fields.ForeignKey(
|
||||||
|
"User", on_delete=models.PROTECT, activitypub_field="actor"
|
||||||
|
)
|
||||||
|
|
||||||
|
# TODO: can we just use the abstract class here?
|
||||||
|
activitypub_object = fields.ForeignKey(
|
||||||
|
"BookWyrmModel", on_delete=models.PROTECT,
|
||||||
|
activitypub_field="object",
|
||||||
|
blank=True,
|
||||||
|
null=True
|
||||||
|
)
|
||||||
|
|
||||||
|
target = fields.CharField(
|
||||||
|
max_length=255, blank=True, null=True, deduplication_field=True
|
||||||
|
)
|
||||||
|
|
||||||
|
origin = fields.CharField(
|
||||||
|
max_length=255, blank=True, null=True, deduplication_field=True
|
||||||
|
)
|
||||||
|
|
||||||
|
activity_serializer = activitypub.Move
|
||||||
|
|
||||||
|
# pylint: disable=unused-argument
|
||||||
|
@classmethod
|
||||||
|
def ignore_activity(cls, activity, allow_external_connections=True):
|
||||||
|
"""don't bother with incoming moves of unknown objects"""
|
||||||
|
# TODO how do we check this for any conceivable object?
|
||||||
|
pass
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
"""update user active time"""
|
||||||
|
self.user.update_active_date()
|
||||||
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
|
# Ok what else? We can trigger a notification for followers of a user who sends a `Move` for themselves
|
||||||
|
# What about when a book is merged (i.e. moved from one id into another)? We could use that to send out a message
|
||||||
|
# to other Bookwyrm instances to update their remote_id for the book, but ...how do we trigger any action?
|
|
@ -40,11 +40,14 @@ class Notification(BookWyrmModel):
|
||||||
GROUP_NAME = "GROUP_NAME"
|
GROUP_NAME = "GROUP_NAME"
|
||||||
GROUP_DESCRIPTION = "GROUP_DESCRIPTION"
|
GROUP_DESCRIPTION = "GROUP_DESCRIPTION"
|
||||||
|
|
||||||
|
# Migrations
|
||||||
|
MOVE = "MOVE"
|
||||||
|
|
||||||
# pylint: disable=line-too-long
|
# pylint: disable=line-too-long
|
||||||
NotificationType = models.TextChoices(
|
NotificationType = models.TextChoices(
|
||||||
# there has got be a better way to do this
|
# there has got be a better way to do this
|
||||||
"NotificationType",
|
"NotificationType",
|
||||||
f"{FAVORITE} {REPLY} {MENTION} {TAG} {FOLLOW} {FOLLOW_REQUEST} {BOOST} {IMPORT} {ADD} {REPORT} {LINK_DOMAIN} {INVITE} {ACCEPT} {JOIN} {LEAVE} {REMOVE} {GROUP_PRIVACY} {GROUP_NAME} {GROUP_DESCRIPTION}",
|
f"{FAVORITE} {REPLY} {MENTION} {TAG} {FOLLOW} {FOLLOW_REQUEST} {BOOST} {IMPORT} {ADD} {REPORT} {LINK_DOMAIN} {INVITE} {ACCEPT} {JOIN} {LEAVE} {REMOVE} {GROUP_PRIVACY} {GROUP_NAME} {GROUP_DESCRIPTION} {MOVE}",
|
||||||
)
|
)
|
||||||
|
|
||||||
user = models.ForeignKey("User", on_delete=models.CASCADE)
|
user = models.ForeignKey("User", on_delete=models.CASCADE)
|
||||||
|
@ -326,3 +329,14 @@ def notify_user_on_follow(sender, instance, created, *args, **kwargs):
|
||||||
notification_type=Notification.FOLLOW,
|
notification_type=Notification.FOLLOW,
|
||||||
read=False,
|
read=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@receiver(models.signals.post_save, sender=Move)
|
||||||
|
# pylint: disable=unused-argument
|
||||||
|
def notify_on_move(sender, instance, *args, **kwargs):
|
||||||
|
"""someone moved something"""
|
||||||
|
Notification.notify(
|
||||||
|
instance.status.user,
|
||||||
|
instance.user,
|
||||||
|
related_object=instance.object,
|
||||||
|
notification_type=Notification.MOVE,
|
||||||
|
)
|
|
@ -35,4 +35,6 @@
|
||||||
{% include 'notifications/items/update.html' %}
|
{% include 'notifications/items/update.html' %}
|
||||||
{% elif notification.notification_type == 'GROUP_DESCRIPTION' %}
|
{% elif notification.notification_type == 'GROUP_DESCRIPTION' %}
|
||||||
{% include 'notifications/items/update.html' %}
|
{% include 'notifications/items/update.html' %}
|
||||||
|
{% elif notification.notification_type == 'MOVE' %}
|
||||||
|
{% include 'notifications/items/move.html' %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
28
bookwyrm/templates/notifications/items/move.html
Normal file
28
bookwyrm/templates/notifications/items/move.html
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
{% extends 'notifications/items/layout.html' %}
|
||||||
|
|
||||||
|
{% load i18n %}
|
||||||
|
{% load utilities %}
|
||||||
|
|
||||||
|
{% block primary_link %}{% spaceless %}
|
||||||
|
{{ notification.related_object.local_path }}
|
||||||
|
{% endspaceless %}{% endblock %}
|
||||||
|
|
||||||
|
{% block icon %}
|
||||||
|
<span class="icon icon-local"></span>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block description %}
|
||||||
|
<!--
|
||||||
|
TODO: a user has a 'name' but not everything does, notably a book.
|
||||||
|
On the other hand, maybe we don't need to notify anyone if a book
|
||||||
|
is moved, just update the remote_id?
|
||||||
|
-->
|
||||||
|
{% blocktrans trimmed with object_name=notification.related_object.name object_path=notification.related_object.local_path %}
|
||||||
|
<a href="{{ related_user_link }}">{{ related_user }}</a>
|
||||||
|
moved {{ object_name }}
|
||||||
|
"<a href="{{ object_path }}">{{ object_name }}</a>"
|
||||||
|
{% endblocktrans %}
|
||||||
|
|
||||||
|
<!-- TODO maybe put a brief context message here for migrated user accounts? -->
|
||||||
|
|
||||||
|
{% endblock %}
|
Loading…
Reference in a new issue