Bug fixes and absolute ids

This commit is contained in:
Mouse Reeve 2020-02-17 17:53:40 -08:00
parent 3e434077f9
commit b6964dd8aa
8 changed files with 37 additions and 29 deletions

View file

@ -8,7 +8,6 @@ from uuid import uuid4
from fedireads import models from fedireads import models
from fedireads.openlibrary import get_or_create_book from fedireads.openlibrary import get_or_create_book
from fedireads.sanitize_html import InputHtmlParser from fedireads.sanitize_html import InputHtmlParser
from fedireads.settings import DOMAIN
def create_review(user, possible_book, name, content, rating): def create_review(user, possible_book, name, content, rating):
@ -54,6 +53,16 @@ def create_status(user, content, reply_parent=None, mention_books=None):
return status return status
def get_review_json(review):
''' fedireads json for book reviews '''
status = get_status_json(review)
status['inReplyTo'] = review.book.absolute_id
status['fedireadsType'] = review.status_type,
status['name'] = review.name
status['rating'] = review.rating
return status
def get_status_json(status): def get_status_json(status):
''' create activitypub json for a status ''' ''' create activitypub json for a status '''
user = status.user user = status.user
@ -67,11 +76,10 @@ def get_status_json(status):
'attributedTo': user.actor, 'attributedTo': user.actor,
# TODO: assuming all posts are public -- should check privacy db field # TODO: assuming all posts are public -- should check privacy db field
'to': ['https://www.w3.org/ns/activitystreams#Public'], 'to': ['https://www.w3.org/ns/activitystreams#Public'],
'cc': ['https://%s/user/%s/followers' % (DOMAIN, user.localname)], 'cc': ['%s/followers' % user.absolute_id],
'sensitive': status.sensitive, 'sensitive': status.sensitive,
'content': status.content, 'content': status.content,
'type': status.activity_type, 'type': status.activity_type,
'fedireadsType': status.status_type,
'attachment': [], # TODO: the book cover 'attachment': [], # TODO: the book cover
'replies': { 'replies': {
'id': '%s/replies' % uri, 'id': '%s/replies' % uri,
@ -85,11 +93,6 @@ def get_status_json(status):
} }
} }
if status.status_type == 'Review':
status_json['name'] = status.name,
status_json['rating'] = status.rating
status_json['fedireadsType'] = status.status_type
return status_json return status_json
@ -112,7 +115,7 @@ def get_create_json(user, status_json):
'object': status_json, 'object': status_json,
'signature': { 'signature': {
'type': 'RsaSignature2017', 'type': 'RsaSignature2017',
'creator': 'https://%s/user/%s#main-key' % (DOMAIN, user.localname), 'creator': '%s#main-key' % user.absolute_id,
'created': status_json['published'], 'created': status_json['published'],
'signatureValue': b64encode(signed_message).decode('utf8'), 'signatureValue': b64encode(signed_message).decode('utf8'),
} }
@ -146,8 +149,7 @@ def get_add_remove_json(user, book, shelf, action='Add'):
'target': { 'target': {
'type': 'Collection', 'type': 'Collection',
'name': shelf.name, 'name': shelf.name,
'id': 'https://%s/user/%s/shelf/%s' % \ 'id': shelf.absolute_id,
(DOMAIN, user.localname, shelf.identifier)
} }
} }

View file

@ -11,7 +11,7 @@ import requests
from fedireads import models from fedireads import models
from fedireads import outgoing from fedireads import outgoing
from fedireads.activity import create_review, create_status from fedireads.activity import create_review, create_status, get_status_json
from fedireads.remote_user import get_or_create_remote_user from fedireads.remote_user import get_or_create_remote_user
@ -151,7 +151,7 @@ def get_status(request, username, status_id):
if user != status.user: if user != status.user:
return HttpResponseNotFound() return HttpResponseNotFound()
return JsonResponse(status.activity) return JsonResponse(get_status_json(status))
@csrf_exempt @csrf_exempt

View file

@ -18,6 +18,13 @@ class Shelf(FedireadsModel):
through_fields=('shelf', 'book') through_fields=('shelf', 'book')
) )
@property
def absolute_id(self):
''' use shelf identifier as absolute id '''
base_path = self.user.absolute_id
model_name = type(self).__name__.lower()
return '%s/%s/%s' % (base_path, model_name, self.identifier)
class Meta: class Meta:
unique_together = ('user', 'identifier') unique_together = ('user', 'identifier')
@ -61,8 +68,8 @@ class Book(FedireadsModel):
def absolute_id(self): def absolute_id(self):
''' constructs the absolute reference to any db object ''' ''' constructs the absolute reference to any db object '''
base_path = 'https://%s' % DOMAIN base_path = 'https://%s' % DOMAIN
model_name = self.__name__.lower() model_name = type(self).__name__.lower()
return '%s/%s/%d' % (base_path, model_name, self.openlibrary_key) return '%s/%s/%s' % (base_path, model_name, self.openlibrary_key)
class Author(FedireadsModel): class Author(FedireadsModel):

View file

@ -38,7 +38,7 @@ class User(AbstractUser):
@property @property
def absolute_id(self): def absolute_id(self):
''' users are identified by their username, so overriding this prop ''' ''' users are identified by their username, so overriding this prop '''
model_name = type(self).__name__ model_name = type(self).__name__.lower()
return 'https://%s/%s/%s' % (DOMAIN, model_name, self.localname) return 'https://%s/%s/%s' % (DOMAIN, model_name, self.localname)
@ -61,10 +61,10 @@ def execute_before_save(sender, instance, *args, **kwargs):
# populate fields for local users # populate fields for local users
instance.localname = instance.username instance.localname = instance.username
instance.username = '%s@%s' % (instance.username, DOMAIN) instance.username = '%s@%s' % (instance.username, DOMAIN)
instance.actor = 'https://%s/user/%s' % (DOMAIN, instance.localname) instance.actor = instance.absolute_id
instance.inbox = 'https://%s/user/%s/inbox' % (DOMAIN, instance.localname) instance.inbox = '%s/inbox' % instance.absolute_id
instance.shared_inbox = 'https://%s/inbox' % DOMAIN instance.shared_inbox = 'https://%s/inbox' % DOMAIN
instance.outbox = 'https://%s/user/%s/outbox' % (DOMAIN, instance.localname) instance.outbox = '%s/outbox' % instance.absolute_id
if not instance.private_key: if not instance.private_key:
random_generator = Random.new().read random_generator = Random.new().read
key = RSA.generate(1024, random_generator) key = RSA.generate(1024, random_generator)

View file

@ -6,7 +6,8 @@ from urllib.parse import urlencode
from uuid import uuid4 from uuid import uuid4
from fedireads import models from fedireads import models
from fedireads.activity import create_review, create_status, get_status_json from fedireads.activity import create_review, create_status
from fedireads.activity import get_status_json, get_review_json
from fedireads.activity import get_add_json, get_remove_json, get_create_json from fedireads.activity import get_add_json, get_remove_json, get_create_json
from fedireads.remote_user import get_or_create_remote_user from fedireads.remote_user import get_or_create_remote_user
from fedireads.broadcast import get_recipients, broadcast from fedireads.broadcast import get_recipients, broadcast
@ -112,7 +113,7 @@ def handle_outgoing_accept(user, to_follow, activity):
to_follow.followers.add(user) to_follow.followers.add(user)
activity = { activity = {
'@context': 'https://www.w3.org/ns/activitystreams', '@context': 'https://www.w3.org/ns/activitystreams',
'id': 'https://%s/%s#accepts/follows/' % (DOMAIN, to_follow.localname), 'id': '%s#accepts/follows/' % to_follow.absolute_id,
'type': 'Accept', 'type': 'Accept',
'actor': to_follow.actor, 'actor': to_follow.actor,
'object': activity, 'object': activity,
@ -169,9 +170,7 @@ def handle_review(user, book, name, content, rating):
# validated and saves the review in the database so it has an id # validated and saves the review in the database so it has an id
review = create_review(user, book, name, content, rating) review = create_review(user, book, name, content, rating)
#book_path = 'https://%s/book/%s' % (DOMAIN, review.book.openlibrary_key) review_activity = get_review_json(review)
review_activity = get_status_json(review)
create_activity = get_create_json(user, review_activity) create_activity = get_create_json(user, review_activity)
recipients = get_recipients(user, 'public') recipients = get_recipients(user, 'public')

View file

@ -92,7 +92,7 @@
<img src="/images/{{ book.cover }}" class="book-cover small"> <img src="/images/{{ book.cover }}" class="book-cover small">
</td> </td>
<td> <td>
<a href="{{ book.openlibrary_key }}">{{ book.data.title }}</a> <a href="/book/{{ book.openlibrary_key }}">{{ book.data.title }}</a>
</td> </td>
<td> <td>
{{ book.authors.first.data.name }} {{ book.authors.first.data.name }}

View file

@ -17,14 +17,14 @@ urlpatterns = [
re_path(r'^user/(?P<username>\w+)/followers/?$', incoming.get_followers), re_path(r'^user/(?P<username>\w+)/followers/?$', incoming.get_followers),
re_path(r'^user/(?P<username>\w+)/following/?$', incoming.get_following), re_path(r'^user/(?P<username>\w+)/following/?$', incoming.get_following),
re_path( re_path(
r'^user/(?P<username>\w+)/status/(?P<status_id>\d+)/?$', r'^user/(?P<username>\w+)/(status|review)/(?P<status_id>\d+)/?$',
incoming.get_status incoming.get_status
), ),
re_path( re_path(
r'^user/(?P<username>\w+)/status/(?P<status_id>\d+)/activity/?$', r'^user/(?P<username>\w+)/(status|review)/(?P<status_id>\d+)/activity/?$',
incoming.get_status incoming.get_status
), ),
re_path(r'^user/(?P<username>\w+)/status/?$', incoming.get_following), re_path(r'^user/(?P<username>\w+)/(status|review)/?$', incoming.get_following),
# TODO: shelves need pages in the UI and for their activitypub Collection # TODO: shelves need pages in the UI and for their activitypub Collection
# .well-known endpoints # .well-known endpoints

View file

@ -13,7 +13,7 @@ class FedireadsModel(models.Model):
base_path = 'https://%s' % DOMAIN base_path = 'https://%s' % DOMAIN
if self.user: if self.user:
base_path = self.user.absolute_id base_path = self.user.absolute_id
model_name = type(self).__name__ model_name = type(self).__name__.lower()
return '%s/%s/%d' % (base_path, model_name, self.id) return '%s/%s/%d' % (base_path, model_name, self.id)
class Meta: class Meta: