示例#1
0
def like_status(status: Status, user: UserProfile) -> None:
    """
        status - the status target of the like - Status
        user - the user liking the post - UserProfile
    """

    r = redis.StrictRedis(host=os.environ.get('REDIS_HOST', 'localhost'))

    NotificationManager(user).create_like_notification(status)

    json_file = json.dumps(status.to_json(), default=str)

    r.publish(f'timeline:{status.user.id}', f'notification {json_file}')
示例#2
0
    def on_post(self, req, resp):

        if req.get_param('media_ids'):
            user = req.context['user']

            status = Status(
                caption=req.get_param('status') or '',
                visibility=bool(req.get_param('visibility')), #False if None
                user=user,
                sensitive=bool(req.get_param('sensitive')),
                remote=False,
                story=bool(req.get_param('is_story'))
            )

            if status.sensitive:
                status.spoliet_text=req.get_param('spoiler_text')

            status.save()

            if  req.get_param('media_ids') != None:
                    for image in req.get_param('media_ids').split(','):
                        m = Media.get_or_none(media_name=image)
                        m.status = status
                        m.save()

            #Increment the number of posts uploaded
            UserProfile.update({UserProfile.statuses_count: UserProfile.statuses_count + 1}).where(UserProfile.id == user.id).execute()
            spread_status(status)
            resp.status = falcon.HTTP_200
            resp.body = json.dumps(status.to_json(),default=str)

        elif req.get_param('in_reply_to_id'):

            replying_to = Status.get_or_none(id=req.get_param('in_reply_to_id'))
            if replying_to:
                status = Status(
                    caption = req.get_param('status'),
                    user = user,
                    remote = False,
                    story = False,
                    in_reply_to = replying_to,
                    sensitive = replying_to.sensitive,
                    spoiler_text = req.get_param('spoiler_text') or replying_to.spoiler_text
                )
            else:
                resp.status = falcon.HTTP_500
                resp.body = json.dumps({"Error": "Replying to bad ID"})
        else:
            resp.status = falcon.HTTP_500
            resp.body = json.dumps({"Error": "No photo attached"})
示例#3
0
def spread_status(status: Status,
                  mentions: List[str],
                  ap_spread: bool = False) -> None:
    """
    Given a status we have to: 

    - Populate users timelines
    - Notifiy mentions
    - Send via AP TODO

    if we are spreading to local follers (for example from a external
    request) the ap_spread should be false but if the local user is the
    one creating the spread tag we should use ap_spread = true

    """
    r = redis.StrictRedis(host=os.environ.get('REDIS_HOST', 'localhost'))
    time = status.created_at.timestamp()

    #Populate all the followers timelines
    json_file = json.dumps(status.to_json(), default=str)
    for follower in status.user.followers():
        TimelineManager(follower).push_home(status)
        # Add it to notifications
        r.publish(f'timeline:{follower.id}', f'update {json_file}')

    #Add id to the own timeline
    TimelineManager(status.user).push_home(status)
    r.publish(f'timeline:{status.user.id}', f'update {json_file}')

    # Notify mentioned people

    remote = []

    # Notify mentions
    for user in mentions:
        # We have two formats: local user and remote user
        # if the user is local the user string is of the from
        # 'username' otherwise is '*****@*****.**'

        #target_user = User.get_or_none(User.username==user)
        target_user = ActivityPubId(user).get_or_create_remote_user()
        if target_user:
            # First we check that there is an user with this username
            # and then we get it's profile
            if not target_user.is_remote:
                NotificationManager(
                    status.user).create_mention_notification(target_user)
            else:
                remote.append(target_user)

    # Spread via AP
    if ap_spread:
        create = generate_create_note(status, remote)

        # Can this be the coolest var in the project?
        # it's just a set of addresses. Here I'm taking care
        # to minimize the number of requests to external actors
        # targeting shared inboxes (like a pro, look at me mom)

        targets_spotted = set()

        remote_followers = (UserProfile.select().join(
            FollowerRelation,
            on=FollowerRelation.user).where((UserProfile.is_remote == True) & (
                FollowerRelation.follows == status.user)))

        for follower in remote_followers:
            if follower.public_inbox:
                targets_spotted.add(follower.public_inbox)
            else:
                targets_spotted.add(follower.uris.inbox)

        # We're ready mike, drop cargo to the target
        print(targets_spotted)
        for inbox in targets_spotted:
            push_to_remote_actor(inbox, create.to_json())