kopia lustrzana https://github.com/snarfed/bridgy-fed
rodzic
da6288972a
commit
2279db46fc
|
@ -259,3 +259,62 @@ def undo_follow(undo_unwrapped):
|
|||
logger.warning(f'No Follower found for {user_domain} {follower}')
|
||||
|
||||
# TODO send webmention with 410 of u-follow
|
||||
|
||||
|
||||
# TODO: unify with following_collection
|
||||
@app.get(f'/<regex("{common.DOMAIN_RE}"):domain>/followers')
|
||||
@flask_util.cached(cache, CACHE_TIME)
|
||||
def followers_collection(domain):
|
||||
"""ActivityPub Followers collection.
|
||||
|
||||
https://www.w3.org/TR/activitypub/#followers
|
||||
https://www.w3.org/TR/activitypub/#collections
|
||||
https://www.w3.org/TR/activitystreams-core/#paging
|
||||
"""
|
||||
if not User.get_by_id(domain):
|
||||
return f'User {domain} not found', 404
|
||||
|
||||
logger.info(f"Counting {domain}'s followers")
|
||||
count = Follower.query(
|
||||
Follower.status == 'active',
|
||||
Follower.dest == domain,
|
||||
).count()
|
||||
|
||||
ret = {
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
'summary': f"{domain}'s followers",
|
||||
'type': 'Collection',
|
||||
'totalItems': count,
|
||||
'items': [], # TODO
|
||||
}
|
||||
logger.info(f'Returning {json_dumps(ret, indent=2)}')
|
||||
return ret
|
||||
|
||||
|
||||
@app.get(f'/<regex("{common.DOMAIN_RE}"):domain>/following')
|
||||
@flask_util.cached(cache, CACHE_TIME)
|
||||
def following_collection(domain):
|
||||
"""ActivityPub Following collection.
|
||||
|
||||
https://www.w3.org/TR/activitypub/#following
|
||||
https://www.w3.org/TR/activitypub/#collections
|
||||
https://www.w3.org/TR/activitystreams-core/#paging
|
||||
"""
|
||||
if not User.get_by_id(domain):
|
||||
return f'User {domain} not found', 404
|
||||
|
||||
logger.info(f"Counting {domain}'s following")
|
||||
count = Follower.query(
|
||||
Follower.status == 'active',
|
||||
Follower.src == domain,
|
||||
).count()
|
||||
|
||||
ret = {
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
'summary': f"{domain}'s following",
|
||||
'type': 'Collection',
|
||||
'totalItems': count,
|
||||
'items': [], # TODO
|
||||
}
|
||||
logger.info(f'Returning {json_dumps(ret, indent=2)}')
|
||||
return ret
|
||||
|
|
3
pages.py
3
pages.py
|
@ -99,8 +99,6 @@ def user(domain):
|
|||
|
||||
@app.get(f'/user/<regex("{common.DOMAIN_RE}"):domain>/followers')
|
||||
def followers(domain):
|
||||
# TODO:
|
||||
# pull more info from last_follow, eg name, profile picture, url
|
||||
# unify with following
|
||||
if not User.get_by_id(domain):
|
||||
return render_template('user_not_found.html', domain=domain), 404
|
||||
|
@ -116,7 +114,6 @@ def followers(domain):
|
|||
f.handle = re.sub(r'^https?://(.+)/(users/|@)(.+)$', r'@\3@\1', f.src)
|
||||
if f.last_follow:
|
||||
last_follow = json_loads(f.last_follow)
|
||||
print('@', last_follow)
|
||||
actor = last_follow.get('actor', {})
|
||||
f.name = actor.get('name') or ''
|
||||
f.picture = actor.get('icon', {}).get('url')
|
||||
|
|
|
@ -520,3 +520,78 @@ class ActivityPubTest(testutil.TestCase):
|
|||
self.assertEqual('in', activity.direction)
|
||||
self.assertEqual('activitypub', activity.protocol)
|
||||
self.assertEqual('ignored', activity.status)
|
||||
|
||||
def test_followers_collection_unknown_user(self, *args):
|
||||
resp = self.client.get('/foo.com/followers')
|
||||
self.assertEqual(404, resp.status_code)
|
||||
|
||||
def test_followers_collection(self, *args):
|
||||
User.get_or_create('foo.com')
|
||||
|
||||
resp = self.client.get('/foo.com/followers')
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertEqual({
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
'summary': "foo.com's followers",
|
||||
'type': 'Collection',
|
||||
'totalItems': 0,
|
||||
'items': [],
|
||||
}, resp.json)
|
||||
|
||||
Follower.get_or_create('foo.com', 'bar.com')
|
||||
Follower.get_or_create('http://other/actor', 'foo.com')
|
||||
Follower.get_or_create('foo.com', 'baz.com')
|
||||
Follower.get_or_create('foo.com', 'baj.com', status='inactive')
|
||||
|
||||
resp = self.client.get('/foo.com/followers')
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertEqual({
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
'summary': "foo.com's followers",
|
||||
'type': 'Collection',
|
||||
'totalItems': 2,
|
||||
'items': [],
|
||||
# TODO
|
||||
# {
|
||||
# 'type': 'Create',
|
||||
# 'actor': 'http://www.test.example/sally',
|
||||
# 'object': 'http://example.org/foo',
|
||||
# },
|
||||
# {
|
||||
# 'type': 'Like',
|
||||
# 'actor': 'http://www.test.example/joe',
|
||||
# 'object': 'http://example.org/foo',
|
||||
# }],
|
||||
}, resp.json)
|
||||
|
||||
def test_following_collection_unknown_user(self, *args):
|
||||
resp = self.client.get('/foo.com/following')
|
||||
self.assertEqual(404, resp.status_code)
|
||||
|
||||
def test_following_collection(self, *args):
|
||||
User.get_or_create('foo.com')
|
||||
|
||||
resp = self.client.get('/foo.com/following')
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertEqual({
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
'summary': "foo.com's following",
|
||||
'type': 'Collection',
|
||||
'totalItems': 0,
|
||||
'items': [],
|
||||
}, resp.json)
|
||||
|
||||
Follower.get_or_create('bar.com', 'foo.com')
|
||||
Follower.get_or_create('foo.com', 'http://other/actor')
|
||||
Follower.get_or_create('baz.com', 'foo.com')
|
||||
Follower.get_or_create('baj.com', 'foo.com', status='inactive')
|
||||
|
||||
resp = self.client.get('/foo.com/following')
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertEqual({
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
'summary': "foo.com's following",
|
||||
'type': 'Collection',
|
||||
'totalItems': 2,
|
||||
'items': [],
|
||||
}, resp.json)
|
||||
|
|
Ładowanie…
Reference in New Issue