コード例 #1
0
def handle_create(activity):
    ''' someone did something, good on them '''
    if activity['object'].get('type') not in \
            ['Note', 'Comment', 'Quotation', 'Review', 'GeneratedNote']:
        # if it's an article or unknown type, ignore it
        return

    user = get_or_create_remote_user(activity['actor'])
    if user.local:
        # we really oughtn't even be sending in this case
        return

    # deduplicate incoming activities
    status_id = activity['object']['id']
    if models.Status.objects.filter(remote_id=status_id).count():
        return

    status = status_builder.create_status(activity['object'])
    if not status:
        return

    # create a notification if this is a reply
    if status.reply_parent and status.reply_parent.user.local:
        status_builder.create_notification(
            status.reply_parent.user,
            'REPLY',
            related_user=status.user,
            related_status=status,
        )
コード例 #2
0
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 Exception as e:  # pylint: disable=broad-except
                logger.exception(e)
                item.fail_reason = 'Error loading book'
                item.save()
                continue

            if item.book:
                item.save()
                results.append(item)

                # shelves book and handles reviews
                outgoing.handle_imported_book(job.user, item,
                                              job.include_reviews, job.privacy)
            else:
                item.fail_reason = 'Could not find a match for book'
                item.save()
    finally:
        create_notification(job.user, 'IMPORT', related_import=job)
コード例 #3
0
ファイル: incoming.py プロジェクト: dana-ross/bookwyrm
def handle_create(activity):
    ''' someone did something, good on them '''
    # deduplicate incoming activities
    status_id = activity['object']['id']
    if models.Status.objects.filter(remote_id=status_id).count():
        return

    serializer = activitypub.activity_objects[activity['type']]
    status = serializer(**activity)
    try:
        model = models.activity_models[activity.type]
    except KeyError:
        # not a type of status we are prepared to deserialize
        return

    if activity.type == 'Note':
        reply = models.Status.objects.filter(
            remote_id=activity.inReplyTo).first()
        if not reply:
            return

    activity.to_model(model)
    # create a notification if this is a reply
    if status.reply_parent and status.reply_parent.user.local:
        status_builder.create_notification(
            status.reply_parent.user,
            'REPLY',
            related_user=status.user,
            related_status=status,
        )
コード例 #4
0
def handle_boost(activity):
    ''' someone gave us a boost! '''
    boost = activitypub.Boost(**activity).to_model(models.Boost)

    if not boost.user.local:
        status_builder.create_notification(
            boost.boosted_status.user,
            'BOOST',
            related_user=boost.user,
            related_status=boost.boosted_status,
        )
コード例 #5
0
ファイル: incoming.py プロジェクト: dana-ross/bookwyrm
def handle_favorite(activity):
    ''' approval of your good good post '''
    fav = activitypub.Like(**activity)

    fav = fav.to_model(models.Favorite)
    if fav.user.local:
        return

    status_builder.create_notification(
        fav.status.user,
        'FAVORITE',
        related_user=fav.user,
        related_status=fav.status,
    )
コード例 #6
0
ファイル: incoming.py プロジェクト: dana-ross/bookwyrm
def handle_boost(activity):
    ''' someone gave us a boost! '''
    try:
        boost = activitypub.Boost(**activity).to_model(models.Boost)
    except activitypub.ActivitySerializerError:
        # this probably just means we tried to boost an unknown status
        return

    if not boost.user.local:
        status_builder.create_notification(
            boost.boosted_status.user,
            'BOOST',
            related_user=boost.user,
            related_status=boost.boosted_status,
        )
コード例 #7
0
def handle_favorite(activity):
    ''' approval of your good good post '''
    fav = activitypub.Like(**activity)

    liker = get_or_create_remote_user(activity['actor'])
    if liker.local:
        return

    fav = fav.to_model(models.Favorite)

    status_builder.create_notification(
        fav.status.user,
        'FAVORITE',
        related_user=liker,
        related_status=fav.status,
    )
コード例 #8
0
ファイル: outgoing.py プロジェクト: hartsick/bookwyrm
def handle_favorite(user, status):
    ''' a user likes a status '''
    try:
        favorite = models.Favorite.objects.create(status=status, user=user)
    except IntegrityError:
        # you already fav'ed that
        return

    fav_activity = favorite.to_activity()
    broadcast(user,
              fav_activity,
              privacy='direct',
              direct_recipients=[status.user])
    create_notification(status.user,
                        'FAVORITE',
                        related_user=user,
                        related_status=status)
コード例 #9
0
ファイル: outgoing.py プロジェクト: hartsick/bookwyrm
def handle_boost(user, status):
    ''' a user wishes to boost a status '''
    if models.Boost.objects.filter(boosted_status=status, user=user).exists():
        # you already boosted that.
        return
    boost = models.Boost.objects.create(
        boosted_status=status,
        user=user,
    )
    boost.save()

    boost_activity = boost.to_activity()
    broadcast(user, boost_activity)

    create_notification(status.user,
                        'BOOST',
                        related_user=user,
                        related_status=status)
コード例 #10
0
def handle_follow(activity):
    ''' someone wants to follow a local user '''
    # figure out who they want to follow -- not using get_or_create because
    # we only care if you want to follow local users
    try:
        to_follow = models.User.objects.get(remote_id=activity['object'])
    except models.User.DoesNotExist:
        # some rando, who cares
        return
    if not to_follow.local:
        # just ignore follow alerts about other servers. maybe they should be
        # handled. maybe they shouldn't be sent at all.
        return

    # figure out who the actor is
    actor = get_or_create_remote_user(activity['actor'])
    try:
        relationship = models.UserFollowRequest.objects.create(
            user_subject=actor,
            user_object=to_follow,
            remote_id=activity['id']
        )
    except django.db.utils.IntegrityError as err:
        if err.__cause__.diag.constraint_name != 'userfollowrequest_unique':
            raise
        relationship = models.UserFollowRequest.objects.get(
            remote_id=activity['id']
        )
        # send the accept normally for a duplicate request

    if not to_follow.manually_approves_followers:
        status_builder.create_notification(
            to_follow,
            'FOLLOW',
            related_user=actor
        )
        outgoing.handle_accept(relationship)
    else:
        # Accept will be triggered manually
        status_builder.create_notification(
            to_follow,
            'FOLLOW_REQUEST',
            related_user=actor
        )
コード例 #11
0
ファイル: incoming.py プロジェクト: dana-ross/bookwyrm
def handle_follow(activity):
    ''' someone wants to follow a local user '''
    try:
        relationship = activitypub.Follow(**activity).to_model(
            models.UserFollowRequest)
    except django.db.utils.IntegrityError as err:
        if err.__cause__.diag.constraint_name != 'userfollowrequest_unique':
            raise
        relationship = models.UserFollowRequest.objects.get(
            remote_id=activity['id'])
        # send the accept normally for a duplicate request

    manually_approves = relationship.user_object.manually_approves_followers

    status_builder.create_notification(
        relationship.user_object,
        'FOLLOW_REQUEST' if manually_approves else 'FOLLOW',
        related_user=relationship.user_subject)
    if not manually_approves:
        outgoing.handle_accept(relationship)
コード例 #12
0
ファイル: outgoing.py プロジェクト: SHSauler/bookwyrm
def handle_status(user, form):
    ''' generic handler for statuses '''
    status = form.save()

    # inspect the text for user tags
    text = status.content
    matches = re.finditer(regex.username, text)
    for match in matches:
        username = match.group().strip().split('@')[1:]
        if len(username) == 1:
            # this looks like a local user (@user), fill in the domain
            username.append(DOMAIN)
        username = '******'.join(username)

        mention_user = handle_remote_webfinger(username)
        if not mention_user:
            # we can ignore users we don't know about
            continue
        # add them to status mentions fk
        status.mention_users.add(mention_user)
        # create notification if the mentioned user is local
        if mention_user.local:
            create_notification(mention_user,
                                'MENTION',
                                related_user=user,
                                related_status=status)
    status.save()

    # notify reply parent or tagged users
    if status.reply_parent and status.reply_parent.user.local:
        create_notification(status.reply_parent.user,
                            'REPLY',
                            related_user=user,
                            related_status=status)

    broadcast(user, status.to_create_activity(user), software='bookwyrm')

    # re-format the activity for non-bookwyrm servers
    if hasattr(status, 'pure_activity_serializer'):
        remote_activity = status.to_create_activity(user, pure=True)
        broadcast(user, remote_activity, software='other')
コード例 #13
0
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)

                # shelves book and handles reviews
                outgoing.handle_imported_book(job.user, item,
                                              job.include_reviews, job.privacy)
            else:
                item.fail_reason = "Could not find a match for book"
                item.save()
    finally:
        create_notification(job.user, 'IMPORT', related_import=job)