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}')
|
logger.warning(f'No Follower found for {user_domain} {follower}')
|
||||||
|
|
||||||
# TODO send webmention with 410 of u-follow
|
# 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')
|
@app.get(f'/user/<regex("{common.DOMAIN_RE}"):domain>/followers')
|
||||||
def followers(domain):
|
def followers(domain):
|
||||||
# TODO:
|
|
||||||
# pull more info from last_follow, eg name, profile picture, url
|
|
||||||
# unify with following
|
# unify with following
|
||||||
if not User.get_by_id(domain):
|
if not User.get_by_id(domain):
|
||||||
return render_template('user_not_found.html', domain=domain), 404
|
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)
|
f.handle = re.sub(r'^https?://(.+)/(users/|@)(.+)$', r'@\3@\1', f.src)
|
||||||
if f.last_follow:
|
if f.last_follow:
|
||||||
last_follow = json_loads(f.last_follow)
|
last_follow = json_loads(f.last_follow)
|
||||||
print('@', last_follow)
|
|
||||||
actor = last_follow.get('actor', {})
|
actor = last_follow.get('actor', {})
|
||||||
f.name = actor.get('name') or ''
|
f.name = actor.get('name') or ''
|
||||||
f.picture = actor.get('icon', {}).get('url')
|
f.picture = actor.get('icon', {}).get('url')
|
||||||
|
|
|
@ -520,3 +520,78 @@ class ActivityPubTest(testutil.TestCase):
|
||||||
self.assertEqual('in', activity.direction)
|
self.assertEqual('in', activity.direction)
|
||||||
self.assertEqual('activitypub', activity.protocol)
|
self.assertEqual('activitypub', activity.protocol)
|
||||||
self.assertEqual('ignored', activity.status)
|
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