kopia lustrzana https://github.com/snarfed/bridgy-fed
rodzic
db2668ffab
commit
579f55d965
|
@ -883,6 +883,8 @@ def follower_collection(id, collection):
|
|||
* https://www.w3.org/TR/activitypub/#followers
|
||||
* https://www.w3.org/TR/activitypub/#collections
|
||||
* https://www.w3.org/TR/activitystreams-core/#paging
|
||||
|
||||
TODO: unify page generation with outbox()
|
||||
"""
|
||||
protocol = Protocol.for_request(fed='web')
|
||||
assert protocol
|
||||
|
@ -932,6 +934,10 @@ def follower_collection(id, collection):
|
|||
@app.get(f'/<regex("{DOMAIN_RE}"):id>/outbox')
|
||||
@flask_util.cached(cache, CACHE_TIME)
|
||||
def outbox(id):
|
||||
"""Serves a user's AP outbox.
|
||||
|
||||
TODO: unify page generation with follower_collection()
|
||||
"""
|
||||
protocol = Protocol.for_request(fed='web')
|
||||
if not protocol:
|
||||
error(f"Couldn't determine protocol", status=404)
|
||||
|
@ -941,18 +947,34 @@ def outbox(id):
|
|||
error(f'User {id} not found', status=404)
|
||||
|
||||
query = Object.query(Object.users == g.user.key)
|
||||
objects, before, after = fetch_objects(query, by=Object.updated, user=g.user)
|
||||
objects, new_before, new_after = fetch_objects(query, by=Object.updated,
|
||||
user=g.user)
|
||||
|
||||
# page
|
||||
page = {
|
||||
'type': 'CollectionPage',
|
||||
'partOf': request.base_url,
|
||||
'items': util.trim_nulls([ActivityPub.convert(obj) for obj in objects]),
|
||||
}
|
||||
if new_before:
|
||||
page['next'] = f'{request.base_url}?before={new_before}'
|
||||
if new_after:
|
||||
page['prev'] = f'{request.base_url}?after={new_after}'
|
||||
|
||||
if 'before' in request.args or 'after' in request.args:
|
||||
page.update({
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
'id': request.url,
|
||||
})
|
||||
logger.info(f'Returning {json_dumps(page, indent=2)}')
|
||||
return page, {'Content-Type': as2.CONTENT_TYPE}
|
||||
|
||||
# collection
|
||||
return {
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
'id': request.url,
|
||||
'summary': f"{id}'s outbox",
|
||||
'type': 'OrderedCollection',
|
||||
# TODO. needs to handle deleted
|
||||
# 'totalItems': query.count(),
|
||||
'first': {
|
||||
'type': 'CollectionPage',
|
||||
'partOf': request.base_url,
|
||||
'items': [ActivityPub.convert(obj) for obj in objects],
|
||||
},
|
||||
'summary': f"{id}'s outbox",
|
||||
'totalItems': query.count(),
|
||||
'first': page,
|
||||
}, {'Content-Type': as2.CONTENT_TYPE}
|
||||
|
|
|
@ -1568,6 +1568,7 @@ class ActivityPubTest(TestCase):
|
|||
'id': 'https://fa.brid.gy/ap/fake:foo/outbox',
|
||||
'summary': "fake:foo's outbox",
|
||||
'type': 'OrderedCollection',
|
||||
'totalItems': 0,
|
||||
'first': {
|
||||
'type': 'CollectionPage',
|
||||
'partOf': 'https://fa.brid.gy/ap/fake:foo/outbox',
|
||||
|
@ -1575,26 +1576,55 @@ class ActivityPubTest(TestCase):
|
|||
},
|
||||
}, resp.json)
|
||||
|
||||
def store_outbox_objects(self, user):
|
||||
for i, obj in enumerate([REPLY, MENTION, LIKE, DELETE]):
|
||||
self.store_object(id=obj['id'], users=[user.key], as2=obj)
|
||||
|
||||
@patch('models.PAGE_SIZE', 2)
|
||||
def test_outbox_fake_objects(self, *_):
|
||||
user = self.make_user('fake:foo', cls=Fake)
|
||||
for i, obj in enumerate([REPLY, MENTION, LIKE, DELETE]):
|
||||
self.store_object(id=str(i), users=[user.key], as2=obj)
|
||||
self.store_outbox_objects(user)
|
||||
|
||||
resp = self.client.get(f'/ap/fake:foo/outbox',
|
||||
base_url='https://fa.brid.gy')
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
after = Object.get_by_id(LIKE['id']).updated.isoformat()
|
||||
self.assertEqual({
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
'id': 'https://fa.brid.gy/ap/fake:foo/outbox',
|
||||
'summary': "fake:foo's outbox",
|
||||
'type': 'OrderedCollection',
|
||||
'totalItems': 4,
|
||||
'first': {
|
||||
'type': 'CollectionPage',
|
||||
'partOf': 'https://fa.brid.gy/ap/fake:foo/outbox',
|
||||
'items': [DELETE, LIKE, MENTION, REPLY],
|
||||
'items': [DELETE, LIKE],
|
||||
'next': f'https://fa.brid.gy/ap/fake:foo/outbox?before={after}',
|
||||
},
|
||||
}, resp.json)
|
||||
|
||||
@patch('models.PAGE_SIZE', 2)
|
||||
def test_outbox_fake_objects_page(self, *_):
|
||||
user = self.make_user('fake:foo', cls=Fake)
|
||||
self.store_outbox_objects(user)
|
||||
|
||||
after = datetime(1900, 1, 1).isoformat()
|
||||
resp = self.client.get(f'/ap/fake:foo/outbox?after={after}',
|
||||
base_url='https://fa.brid.gy')
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
prev = Object.get_by_id(MENTION['id']).updated.isoformat()
|
||||
self.assertEqual({
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
'id': f'https://fa.brid.gy/ap/fake:foo/outbox?after={after}',
|
||||
'type': 'CollectionPage',
|
||||
'partOf': 'https://fa.brid.gy/ap/fake:foo/outbox',
|
||||
'prev': f'https://fa.brid.gy/ap/fake:foo/outbox?after={prev}',
|
||||
'next': f'https://fa.brid.gy/ap/fake:foo/outbox?before={after}',
|
||||
'items': [MENTION, REPLY],
|
||||
}, resp.json)
|
||||
|
||||
def test_outbox_web_empty(self, *_):
|
||||
resp = self.client.get(f'/user.com/outbox')
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
@ -1603,6 +1633,7 @@ class ActivityPubTest(TestCase):
|
|||
'id': 'http://localhost/user.com/outbox',
|
||||
'summary': "user.com's outbox",
|
||||
'type': 'OrderedCollection',
|
||||
'totalItems': 0,
|
||||
'first': {
|
||||
'type': 'CollectionPage',
|
||||
'partOf': 'http://localhost/user.com/outbox',
|
||||
|
|
Ładowanie…
Reference in New Issue