Esempio n. 1
0
    def get_objects(self, handle):
        """
        Get the collection of user Follows
        """
        user = current_app.db.fetch(
            self.user_url(handle=handle))

        return vocab.OrderedCollection([
            vocab.Follow({
                "@id": follow.id,
                "actor": user,
                "object": follow.object
            }) for follow in user.follow_collection])
Esempio n. 2
0
def inbox_get(handle=None):
    """
    think of this as the "Home" feed on mastodon. returns all Objects
    addressed to the user. this should require authentication
    """
    u = find_user(handle)
    items = list(mongo.db.posts.find({'to': u['@id']}, {'_id': False}).sort('published', -1))

    resp = vocab.OrderedCollection(
        u['inbox'],
        totalItems=len(items),
        orderedItems=items)

    return Response(json.dumps(resp.json()), headers=content_headers(u))
Esempio n. 3
0
def feed_get(handle):
    """
    per AP spec, returns a reverse-chronological OrderedCollection of
    items in the outbox, pending privacy settings
    """
    print('feed get')
    u = find_user(handle)

    items = list(mongo.db.posts.find({'object.attributedTo': u['@id']}, {'_id': False}).sort('published', -1))

    resp = vocab.OrderedCollection(
        u['outbox'],
        totalItems=len(items),
        orderedItems=items)

    return Response(json.dumps(resp.json()), headers=content_headers(u))
Esempio n. 4
0
def inbox(handle):
    if request.method == 'GET':
        """
        think of this as the "Home" feed on mastodon. returns all Objects
        addressed to the user. this should require authentication
        """
        u = find_user(handle)
        items = list(
            mongo.db.posts.find({
                'to': u['@id']
            }, {
                '_id': False
            }).sort('published', -1))

        resp = vocab.OrderedCollection(u['inbox'],
                                       totalItems=len(items),
                                       orderedItems=items)

        return Response(resp, headers=content_headers(find_user(handle)))

    if request.method == 'POST':
        """
        deduplicates requests, and adds them to the database. in some cases
        (e.g. Follow requests) it automatically responds, pending fuller API
        and UI implementation
        """
        print('inbox post')
        u = find_user(handle)
        r = core.ASObj(request.get_json())

        if 'Create' in r.types:
            # this needs more stuff, like creating a user if necessary
            if mongo.db.posts.find({'@id': r['@id']}) is not None:
                try:
                    r.update(dict(origin=request.environ['HTTP_ORIGIN']))
                    mongo.db.posts.insert_one(r)
                    return Response(status=201)
                except:
                    return Response(status=500)
        elif 'Update' in r.types:
            if 'Actor' in r.types:
                time = get_time()
                r['updated'] = time
                try:
                    mongo.db.users.find_one_and_replace({'@id': r['@id']},
                                                        r.json(),
                                                        {'upsert': True})
                    return Response(status=201)
                except:
                    return Response(status=500)
            elif ('Object' or 'Activity') in r.types:
                try:
                    mongo.db.posts.find_one_and_replace({'@id': r['@id']},
                                                        r.json(),
                                                        {'upsert': True})
                    return Response(status=201)
                except:
                    return Response(status=500)
        elif 'Delete' in r.types:
            time = get_time()
            tombstone = vocab.Tombstone(r['@id'],
                                        published=r['published'],
                                        updated=time,
                                        deleted=time)
            if 'Actor' in r.types:
                try:
                    mongo.db.users.find_one_and_replace({'@id': r['@id']},
                                                        tombstone.json())
                    return Response(status=201)
                except:
                    return Response(status=500)
            elif ('Object' or 'Activity') in r.types:
                try:
                    mongo.db.posts.find_one_and_replace({'@id': r['@id']},
                                                        tombstone.json())
                    return Response(status=201)
                except:
                    return Response(status=500)
            return Response(status=501)
        elif 'Follow' in r.types:
            if u.get('followers_coll'):
                if u['followers_coll'].get('actor'):
                    return 400

            mongo.db.users.update_one(
                {'id': u['@id']}, {'$push': {
                    'followers_coll': r['actor']
                }},
                upsert=True)
            to = requests.get(r['actor'],
                              headers=accept_headers(u)).json()['inbox']
            accept = vocab.accept(to=to, object=r.get_json()).json()
            headers = content_headers(u)

            try:
                requests.post(to, json=accept, headers=headers)
                return Response(status=201)
            except:
                return Response(status=500)
        elif 'Accept' in r.types:
            print('received Accept')
            try:
                mongo.db.users.update_one(
                    {'id': u['@id']},
                    {'$push': {
                        'following_coll': r['object']['actor']
                    }},
                    upsert=True)
                return Response(status=201)
            except:
                return Response(status=501)
        elif 'Reject' in r.types:
            return Response(status=200)
        elif 'Add' in r.types:
            return Response(status=501)
        elif 'Remove' in r.types:
            return Response(status=501)
        elif 'Like' in r.types:
            try:
                mongo.db.posts.update_one(
                    {'id': r['object']},
                    {'$push': {
                        'object.liked_coll': r['actor']
                    }},
                    upsert=True)
                return Response(status=201)
            except:
                return Response(status=500)
        elif 'Announce' in r.types:
            try:
                mongo.db.posts.update_one(
                    {'id': r['object']},
                    {'$push': {
                        'object.shared_coll': r['actor']
                    }},
                    upsert=True)
                return Response(status=201)
            except:
                return Response(status=500)
        elif 'Undo' in r.types:
            # this requires maybe a lot of stuff for implementing?
            # i'll think about it later
            return Response(status=501)
        else:
            print('other type')
            print(r)
        abort(400)
Esempio n. 5
0
def feed(handle):
    if request.method == 'GET':
        """
        per AP spec, returns a reverse-chronological OrderedCollection of
        items in the outbox, pending privacy settings
        """
        print('feed get')
        u = find_user(handle)

        items = list(
            mongo.db.posts.find({
                'object.attributedTo': u['@id']
            }, {
                '_id': False
            }).sort('published', -1))

        resp = vocab.OrderedCollection(u['outbox'],
                                       totalItems=len(items),
                                       orderedItems=items)

        return Response(json.dumps(resp.json()), headers=content_headers(u))

    if request.method == 'POST':
        """
        adds objects that it receives to mongodb and sends them along
        to appropriate Actor inboxes
        """
        r = core.ASObj(request.get_json(), vocab.BasicEnv)
        u = find_user(handle)

        # if it's a note it turns it into a Create object
        if 'Note' in r.types:
            obj = r.get_json()
            r = vocab.Create(obj['@id'] + '/activity',
                             actor=u['@id'],
                             published=obj['published'],
                             to=obj['to'],
                             bto=obj['bto'],
                             cc=obj['cc'],
                             bcc=obj['bcc'],
                             audience=obj['audience'],
                             obj=obj)

        if 'Create' in r.types:
            mongo.db.users.update({'acct': u['acct']},
                                  {'$inc': {
                                      'metrics.post_count': 1
                                  }})
        elif 'Update' in r.types:
            return Response(status=501)
        elif 'Delete' in r.types:
            return Response(status=501)
        elif 'Follow' in r.types:
            return Response(status=501)
        elif 'Accept' in r.types:
            return Response(status=501)
        elif 'Reject' in r.types:
            return Response(status=501)
        elif 'Add' in r.types:
            return Response(status=501)
        elif 'Remove' in r.types:
            return Response(status=501)
        elif 'Like' in r.types:
            if u['acct'] not in mongo.db.posts.find(
                {'@id': r['object']['@id']})['likes']:
                try:
                    mongo.db.posts.update({'@id': r['object']['@id']},
                                          {'$push': {
                                              'likes': u['acct']
                                          }})
                    return Response(status=201)
                except:
                    return Response(status=500)
        elif 'Announce' in r.types:
            return Response(status=501)
        elif 'Undo' in r.types:
            return Response(status=501)

        recipients = []
        r = r.json()

        for group in ['to', 'bto', 'cc', 'bcc', 'audience']:
            addresses = r.get(group, [])
            recipients.extend(addresses)

        for address in addresses:
            requests.post(address, json=r, headers=content_headers(u))
        try:
            mongo.db.posts.insert_one(r)
            return Response(status=201)
        except:
            return Response(status=500)