forked from mirrors/bookwyrm
Federating lists and shelves
This commit is contained in:
parent
c7914d1394
commit
e53b4e57fa
8 changed files with 74 additions and 29 deletions
|
@ -1,5 +1,5 @@
|
||||||
''' defines activitypub collections (lists) '''
|
''' defines activitypub collections (lists) '''
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass, field
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from .base_activity import ActivityObject
|
from .base_activity import ActivityObject
|
||||||
|
@ -10,9 +10,12 @@ class OrderedCollection(ActivityObject):
|
||||||
''' structure of an ordered collection activity '''
|
''' structure of an ordered collection activity '''
|
||||||
totalItems: int
|
totalItems: int
|
||||||
first: str
|
first: str
|
||||||
last: str = ''
|
last: str = None
|
||||||
name: str = ''
|
name: str = None
|
||||||
owner: str = ''
|
summary: str = None
|
||||||
|
owner: str = None
|
||||||
|
to: List[str] = field(default_factory=lambda: [])
|
||||||
|
cc: List[str] = field(default_factory=lambda: [])
|
||||||
type: str = 'OrderedCollection'
|
type: str = 'OrderedCollection'
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ class Create(Verb):
|
||||||
''' Create activity '''
|
''' Create activity '''
|
||||||
to: List
|
to: List
|
||||||
cc: List
|
cc: List
|
||||||
signature: Signature
|
signature: Signature = None
|
||||||
type: str = 'Create'
|
type: str = 'Create'
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -161,10 +161,12 @@ class ActivitypubMixin:
|
||||||
''' returns the object wrapped in a Create activity '''
|
''' returns the object wrapped in a Create activity '''
|
||||||
activity_object = self.to_activity(**kwargs)
|
activity_object = self.to_activity(**kwargs)
|
||||||
|
|
||||||
|
signature = None
|
||||||
|
create_id = self.remote_id + '/activity'
|
||||||
|
if 'content' in activity_object:
|
||||||
signer = pkcs1_15.new(RSA.import_key(user.key_pair.private_key))
|
signer = pkcs1_15.new(RSA.import_key(user.key_pair.private_key))
|
||||||
content = activity_object['content']
|
content = activity_object['content']
|
||||||
signed_message = signer.sign(SHA256.new(content.encode('utf8')))
|
signed_message = signer.sign(SHA256.new(content.encode('utf8')))
|
||||||
create_id = self.remote_id + '/activity'
|
|
||||||
|
|
||||||
signature = activitypub.Signature(
|
signature = activitypub.Signature(
|
||||||
creator='%s#main-key' % user.remote_id,
|
creator='%s#main-key' % user.remote_id,
|
||||||
|
|
|
@ -19,12 +19,9 @@ class List(OrderedCollectionMixin, BookWyrmModel):
|
||||||
name = fields.CharField(max_length=100)
|
name = fields.CharField(max_length=100)
|
||||||
user = fields.ForeignKey(
|
user = fields.ForeignKey(
|
||||||
'User', on_delete=models.PROTECT, activitypub_field='owner')
|
'User', on_delete=models.PROTECT, activitypub_field='owner')
|
||||||
description = fields.TextField(blank=True, null=True)
|
description = fields.TextField(
|
||||||
privacy = fields.CharField(
|
blank=True, null=True, activitypub_field='summary')
|
||||||
max_length=255,
|
privacy = fields.PrivacyField()
|
||||||
default='public',
|
|
||||||
choices=fields.PrivacyLevels.choices
|
|
||||||
)
|
|
||||||
curation = fields.CharField(
|
curation = fields.CharField(
|
||||||
max_length=255,
|
max_length=255,
|
||||||
default='closed',
|
default='closed',
|
||||||
|
|
|
@ -15,11 +15,7 @@ class Shelf(OrderedCollectionMixin, BookWyrmModel):
|
||||||
user = fields.ForeignKey(
|
user = fields.ForeignKey(
|
||||||
'User', on_delete=models.PROTECT, activitypub_field='owner')
|
'User', on_delete=models.PROTECT, activitypub_field='owner')
|
||||||
editable = models.BooleanField(default=True)
|
editable = models.BooleanField(default=True)
|
||||||
privacy = fields.CharField(
|
privacy = fields.PrivacyField()
|
||||||
max_length=255,
|
|
||||||
default='public',
|
|
||||||
choices=fields.PrivacyLevels.choices
|
|
||||||
)
|
|
||||||
books = models.ManyToManyField(
|
books = models.ManyToManyField(
|
||||||
'Edition',
|
'Edition',
|
||||||
symmetrical=False,
|
symmetrical=False,
|
||||||
|
|
|
@ -71,10 +71,15 @@ class Goal(View):
|
||||||
broadcast(
|
broadcast(
|
||||||
request.user,
|
request.user,
|
||||||
status.to_create_activity(request.user),
|
status.to_create_activity(request.user),
|
||||||
|
privacy=status.privacy,
|
||||||
software='bookwyrm')
|
software='bookwyrm')
|
||||||
|
|
||||||
# re-format the activity for non-bookwyrm servers
|
# re-format the activity for non-bookwyrm servers
|
||||||
remote_activity = status.to_create_activity(request.user, pure=True)
|
remote_activity = status.to_create_activity(request.user, pure=True)
|
||||||
broadcast(request.user, remote_activity, software='other')
|
broadcast(
|
||||||
|
request.user,
|
||||||
|
remote_activity,
|
||||||
|
privacy=status.privacy,
|
||||||
|
software='other')
|
||||||
|
|
||||||
return redirect(request.headers.get('Referer', '/'))
|
return redirect(request.headers.get('Referer', '/'))
|
||||||
|
|
|
@ -11,6 +11,7 @@ from django.views.decorators.http import require_POST
|
||||||
|
|
||||||
from bookwyrm import forms, models
|
from bookwyrm import forms, models
|
||||||
from bookwyrm.activitypub import ActivitypubResponse
|
from bookwyrm.activitypub import ActivitypubResponse
|
||||||
|
from bookwyrm.broadcast import broadcast
|
||||||
from bookwyrm.connectors import connector_manager
|
from bookwyrm.connectors import connector_manager
|
||||||
from .helpers import is_api_request, object_visible_to_user, privacy_filter
|
from .helpers import is_api_request, object_visible_to_user, privacy_filter
|
||||||
from .helpers import get_user_from_username
|
from .helpers import get_user_from_username
|
||||||
|
@ -48,6 +49,14 @@ class Lists(View):
|
||||||
if not form.is_valid():
|
if not form.is_valid():
|
||||||
return redirect('lists')
|
return redirect('lists')
|
||||||
book_list = form.save()
|
book_list = form.save()
|
||||||
|
|
||||||
|
# let the world know
|
||||||
|
broadcast(
|
||||||
|
request.user,
|
||||||
|
book_list.to_create_activity(request.user),
|
||||||
|
privacy=book_list.privacy,
|
||||||
|
software='bookwyrm'
|
||||||
|
)
|
||||||
return redirect(book_list.local_path)
|
return redirect(book_list.local_path)
|
||||||
|
|
||||||
class UserLists(View):
|
class UserLists(View):
|
||||||
|
@ -128,6 +137,13 @@ class List(View):
|
||||||
if not form.is_valid():
|
if not form.is_valid():
|
||||||
return redirect('list', book_list.id)
|
return redirect('list', book_list.id)
|
||||||
book_list = form.save()
|
book_list = form.save()
|
||||||
|
# let the world know
|
||||||
|
broadcast(
|
||||||
|
request.user,
|
||||||
|
book_list.to_update_activity(request.user),
|
||||||
|
privacy=book_list.privacy,
|
||||||
|
software='bookwyrm'
|
||||||
|
)
|
||||||
return redirect(book_list.local_path)
|
return redirect(book_list.local_path)
|
||||||
|
|
||||||
|
|
||||||
|
@ -161,6 +177,13 @@ class Curate(View):
|
||||||
if approved:
|
if approved:
|
||||||
suggestion.approved = True
|
suggestion.approved = True
|
||||||
suggestion.save()
|
suggestion.save()
|
||||||
|
# let the world know
|
||||||
|
broadcast(
|
||||||
|
request.user,
|
||||||
|
suggestion.to_add_activity(request.user),
|
||||||
|
privacy=book_list.privacy,
|
||||||
|
software='bookwyrm'
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
suggestion.delete()
|
suggestion.delete()
|
||||||
return redirect('list-curate', book_list.id)
|
return redirect('list-curate', book_list.id)
|
||||||
|
@ -177,11 +200,18 @@ def add_book(request, list_id):
|
||||||
# do you have permission to add to the list?
|
# do you have permission to add to the list?
|
||||||
if request.user == book_list.user or book_list.curation == 'open':
|
if request.user == book_list.user or book_list.curation == 'open':
|
||||||
# go ahead and add it
|
# go ahead and add it
|
||||||
models.ListItem.objects.create(
|
item = models.ListItem.objects.create(
|
||||||
book=book,
|
book=book,
|
||||||
book_list=book_list,
|
book_list=book_list,
|
||||||
added_by=request.user,
|
added_by=request.user,
|
||||||
)
|
)
|
||||||
|
# let the world know
|
||||||
|
broadcast(
|
||||||
|
request.user,
|
||||||
|
item.to_add_activity(request.user),
|
||||||
|
privacy=book_list.privacy,
|
||||||
|
software='bookwyrm'
|
||||||
|
)
|
||||||
elif book_list.curation == 'curated':
|
elif book_list.curation == 'curated':
|
||||||
# make a pending entry
|
# make a pending entry
|
||||||
models.ListItem.objects.create(
|
models.ListItem.objects.create(
|
||||||
|
@ -206,5 +236,13 @@ def remove_book(request, list_id):
|
||||||
if not book_list.user == request.user and not item.added_by == request.user:
|
if not book_list.user == request.user and not item.added_by == request.user:
|
||||||
return HttpResponseNotFound()
|
return HttpResponseNotFound()
|
||||||
|
|
||||||
|
activity = item.to_remove_activity(request.user)
|
||||||
item.delete()
|
item.delete()
|
||||||
|
# let the world know
|
||||||
|
broadcast(
|
||||||
|
request.user,
|
||||||
|
activity,
|
||||||
|
privacy=book_list.privacy,
|
||||||
|
software='bookwyrm'
|
||||||
|
)
|
||||||
return redirect('list', list_id)
|
return redirect('list', list_id)
|
||||||
|
|
|
@ -138,7 +138,12 @@ def shelve(request):
|
||||||
pass
|
pass
|
||||||
shelfbook = models.ShelfBook.objects.create(
|
shelfbook = models.ShelfBook.objects.create(
|
||||||
book=book, shelf=desired_shelf, added_by=request.user)
|
book=book, shelf=desired_shelf, added_by=request.user)
|
||||||
broadcast(request.user, shelfbook.to_add_activity(request.user))
|
broadcast(
|
||||||
|
request.user,
|
||||||
|
shelfbook.to_add_activity(request.user),
|
||||||
|
privacy=shelfbook.shelf.privacy,
|
||||||
|
software='bookwyrm'
|
||||||
|
)
|
||||||
|
|
||||||
# post about "want to read" shelves
|
# post about "want to read" shelves
|
||||||
if desired_shelf.identifier == 'to-read':
|
if desired_shelf.identifier == 'to-read':
|
||||||
|
@ -146,7 +151,6 @@ def shelve(request):
|
||||||
request.user,
|
request.user,
|
||||||
desired_shelf,
|
desired_shelf,
|
||||||
book,
|
book,
|
||||||
privacy=desired_shelf.privacy
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return redirect('/')
|
return redirect('/')
|
||||||
|
@ -169,4 +173,4 @@ def handle_unshelve(user, book, shelf):
|
||||||
activity = row.to_remove_activity(user)
|
activity = row.to_remove_activity(user)
|
||||||
row.delete()
|
row.delete()
|
||||||
|
|
||||||
broadcast(user, activity)
|
broadcast(user, activity, privacy=shelf.privacy, software='bookwyrm')
|
||||||
|
|
Loading…
Reference in a new issue