From 0b34b6cd968f1ec687f13f5e16b5b7ee9f65ed9a Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 6 Nov 2020 14:51:29 -0800 Subject: [PATCH] Updates code for loading remote statuses --- bookwyrm/incoming.py | 24 +----------------------- bookwyrm/remote_user.py | 13 ++++++++----- bookwyrm/status.py | 33 ++++++++++++++++++++++++++++++++- celerywyrm/celery.py | 1 + 4 files changed, 42 insertions(+), 29 deletions(-) diff --git a/bookwyrm/incoming.py b/bookwyrm/incoming.py index 134c54845..5b231ceb6 100644 --- a/bookwyrm/incoming.py +++ b/bookwyrm/incoming.py @@ -217,29 +217,7 @@ def handle_create(activity): # we really oughtn't even be sending in this case return - # render the json into an activity object - serializer = activitypub.activity_objects[activity['object']['type']] - activity = serializer(**activity['object']) - - # ignore notes that aren't replies to known statuses - if activity.type == 'Note': - reply = models.Status.objects.filter( - remote_id=activity.inReplyTo - ).first() - if not reply: - return - - # look up books - book_urls = [] - if hasattr(activity, 'inReplyToBook'): - book_urls.append(activity.inReplyToBook) - if hasattr(activity, 'tag'): - book_urls += [t['href'] for t in activity.tag if t['type'] == 'Book'] - for remote_id in book_urls: - books_manager.get_or_create_book(remote_id) - - model = models.activity_models[activity.type] - status = activity.to_model(model) + status = status_builder.create_status(activity['object']) # create a notification if this is a reply if status.reply_parent and status.reply_parent.user.local: diff --git a/bookwyrm/remote_user.py b/bookwyrm/remote_user.py index 372f97a8c..b3408c712 100644 --- a/bookwyrm/remote_user.py +++ b/bookwyrm/remote_user.py @@ -7,6 +7,8 @@ from django.core.files.base import ContentFile from django.db import transaction from bookwyrm import activitypub, models +from bookwyrm import status as status_builder +from bookwyrm.tasks import app def get_or_create_remote_user(actor): @@ -29,7 +31,7 @@ def get_or_create_remote_user(actor): user.avatar.save(*avatar) if user.bookwyrm_user: - get_remote_reviews(user) + get_remote_reviews.delay(user.id) return user @@ -78,8 +80,10 @@ def get_avatar(data): return [image_name, image_content] -def get_remote_reviews(user): +@app.task +def get_remote_reviews(user_id): ''' ingest reviews by a new remote bookwyrm user ''' + user = models.User.objects.get(id=user_id) outbox_page = user.outbox + '?page=true' response = requests.get( outbox_page, @@ -87,9 +91,8 @@ def get_remote_reviews(user): ) data = response.json() # TODO: pagination? - for status in data['orderedItems']: - if status.get('bookwyrmType') == 'Review': - activitypub.Review(**status).to_model(models.Review) + for activity in data['orderedItems']: + status_builder.create_status(activity) def get_or_create_remote_server(domain): diff --git a/bookwyrm/status.py b/bookwyrm/status.py index c8c01c990..73e6d5526 100644 --- a/bookwyrm/status.py +++ b/bookwyrm/status.py @@ -2,7 +2,7 @@ from datetime import datetime from django.db import IntegrityError -from bookwyrm import models +from bookwyrm import activitypub, books_manager, models from bookwyrm.books_manager import get_or_create_book from bookwyrm.sanitize_html import InputHtmlParser @@ -14,6 +14,37 @@ def delete_status(status): status.save() +def create_status(activity): + ''' unfortunately, it's not QUITE as simple as deserialiing it ''' + # render the json into an activity object + serializer = activitypub.activity_objects[activity['type']] + activity = serializer(**activity) + try: + model = models.activity_models[activity.type] + except KeyError: + # not a type of status we are prepared to deserialize + return None + + # ignore notes that aren't replies to known statuses + if activity.type == 'Note': + reply = models.Status.objects.filter( + remote_id=activity.inReplyTo + ).first() + if not reply: + return None + + # look up books + book_urls = [] + if hasattr(activity, 'inReplyToBook'): + book_urls.append(activity.inReplyToBook) + if hasattr(activity, 'tag'): + book_urls += [t['href'] for t in activity.tag if t['type'] == 'Book'] + for remote_id in book_urls: + books_manager.get_or_create_book(remote_id) + + return activity.to_model(model) + + def create_generated_note(user, content, mention_books=None, privacy='public'): ''' a note created by the app about user activity ''' # sanitize input html diff --git a/celerywyrm/celery.py b/celerywyrm/celery.py index 28b4a2005..361b76ec3 100644 --- a/celerywyrm/celery.py +++ b/celerywyrm/celery.py @@ -24,3 +24,4 @@ app.autodiscover_tasks(['bookwyrm'], related_name='books_manager') app.autodiscover_tasks(['bookwyrm'], related_name='emailing') app.autodiscover_tasks(['bookwyrm'], related_name='goodreads_import') app.autodiscover_tasks(['bookwyrm'], related_name='incoming') +app.autodiscover_tasks(['bookwyrm'], related_name='remote_user')