def handle_follow(activity): ''' someone wants to follow a local user ''' # figure out who they want to follow to_follow = models.User.objects.get(actor=activity['object']) # figure out who they are user = get_or_create_remote_user(activity['actor']) try: request = models.UserFollowRequest.objects.create( user_subject=user, user_object=to_follow, relationship_id=activity['id']) except django.db.utils.IntegrityError as err: if err.__cause__.diag.constraint_name != 'userfollowrequest_unique': raise # Duplicate follow request. Not sure what the correct behaviour is, but # just dropping it works for now. We should perhaps generate the # Accept, but then do we need to match the activity id? return if not to_follow.manually_approves_followers: status_builder.create_notification(to_follow, 'FOLLOW', related_user=user) outgoing.handle_accept(user, to_follow, request) else: status_builder.create_notification(to_follow, 'FOLLOW_REQUEST', related_user=user)
def handle_reply(user, review, content): ''' respond to a review or status ''' # validated and saves the comment in the database so it has an id reply = create_status(user, content, reply_parent=review) if reply.reply_parent: create_notification( reply.reply_parent.user, 'REPLY', related_user=user, related_status=reply, ) reply_activity = activitypub.get_status(reply) create_activity = activitypub.get_create(user, reply_activity) broadcast(user, create_activity)
def handle_boost(activity): ''' someone gave us a boost! ''' try: status_id = activity['object'].split('/')[-1] status = models.Status.objects.get(id=status_id) booster = get_or_create_remote_user(activity['actor']) except (models.Status.DoesNotExist, models.User.DoesNotExist): return False if not booster.local: status_builder.create_boost_from_activity(booster, activity) status_builder.create_notification( status.user, 'BOOST', related_user=booster, related_status=status, )
def handle_favorite(activity): ''' approval of your good good post ''' try: status_id = activity['object'].split('/')[-1] status = models.Status.objects.get(id=status_id) liker = get_or_create_remote_user(activity['actor']) except (models.Status.DoesNotExist, models.User.DoesNotExist): return False if not liker.local: status_builder.create_favorite_from_activity(liker, activity) status_builder.create_notification( status.user, 'FAVORITE', related_user=liker, related_status=status, )
def handle_create(activity): ''' someone did something, good on them ''' user = get_or_create_remote_user(activity['actor']) if not 'object' in activity: return HttpResponseBadRequest() if user.local: # we really oughtn't even be sending in this case return if activity['object'].get('fedireadsType') and \ 'inReplyToBook' in activity['object']: try: if activity['object']['fedireadsType'] == 'Review': builder = status_builder.create_review_from_activity elif activity['object']['fedireadsType'] == 'Quotation': builder = status_builder.create_quotation_from_activity else: builder = status_builder.create_comment_from_activity # create the status, it'll throw a valueerror if anything is missing builder(user, activity['object']) except ValueError: return HttpResponseBadRequest() else: # TODO: should only create notes if they are relevent to a book, # so, not every single thing someone posts on mastodon try: status = status_builder.create_status_from_activity( user, activity['object']) if status and status.reply_parent: status_builder.create_notification( status.reply_parent.user, 'REPLY', related_user=status.user, related_status=status, ) except ValueError: return HttpResponseBadRequest()
def import_data(job_id): ''' does the actual lookup work in a celery task ''' job = ImportJob.objects.get(id=job_id) try: results = [] for item in job.items.all(): try: item.resolve() except HTTPError: pass if item.book: item.save() results.append(item) else: item.fail_reason = "Could not match book on OpenLibrary" item.save() status = outgoing.handle_import_books(job.user, results) if status: job.import_status = status job.save() finally: create_notification(job.user, 'IMPORT', related_import=job)
def handle_create(activity): ''' someone did something, good on them ''' user = get_or_create_remote_user(activity['actor']) if user.local: # we really oughtn't even be sending in this case return True if activity['object'].get('fedireadsType') and \ 'inReplyToBook' in activity['object']: if activity['object']['fedireadsType'] == 'Review': builder = status_builder.create_review_from_activity elif activity['object']['fedireadsType'] == 'Quotation': builder = status_builder.create_quotation_from_activity else: builder = status_builder.create_comment_from_activity # create the status, it'll throw a ValueError if anything is missing builder(user, activity['object']) elif activity['object'].get('inReplyTo'): # only create the status if it's in reply to a status we already know if not status_builder.get_status(activity['object']['inReplyTo']): return True status = status_builder.create_status_from_activity( user, activity['object'] ) if status and status.reply_parent: status_builder.create_notification( status.reply_parent.user, 'REPLY', related_user=status.user, related_status=status, ) return True