kopia lustrzana https://github.com/snarfed/bridgy-fed
Protocol.receive: automatically send to ATProto PDS if user has ATProto enabled
for #999pull/1020/head
rodzic
c608ecaa36
commit
515be28cdd
33
protocol.py
33
protocol.py
|
@ -402,6 +402,17 @@ class Protocol:
|
|||
if owner:
|
||||
return cls.key_for(owner)
|
||||
|
||||
@classmethod
|
||||
def bot_user_id(cls):
|
||||
"""Returns the Web user id for the bot user for this protocol.
|
||||
|
||||
For example, ``'bsky.brid.gy'`` for ATProto.
|
||||
|
||||
Returns:
|
||||
str:
|
||||
"""
|
||||
return f'{cls.ABBREV}{SUPERDOMAIN}'
|
||||
|
||||
@classmethod
|
||||
def create_for(cls, user):
|
||||
"""Creates a copy user in this protocol.
|
||||
|
@ -1020,8 +1031,8 @@ class Protocol:
|
|||
obj (models.Object): activity to deliver
|
||||
from_user (models.User): user (actor) this activity is from
|
||||
"""
|
||||
# find delivery targets
|
||||
targets = from_cls.targets(obj) # maps Target to Object or None
|
||||
# find delivery targets. maps Target to Object or None
|
||||
targets = from_cls.targets(obj, from_user=from_user)
|
||||
|
||||
if not targets:
|
||||
obj.status = 'ignored'
|
||||
|
@ -1050,13 +1061,14 @@ class Protocol:
|
|||
return 'OK', 202
|
||||
|
||||
@classmethod
|
||||
def targets(cls, obj):
|
||||
def targets(cls, obj, from_user):
|
||||
"""Collects the targets to send a :class:`models.Object` to.
|
||||
|
||||
Targets are both objects - original posts, events, etc - and actors.
|
||||
|
||||
Args:
|
||||
obj (models.Object)
|
||||
from_user (User)
|
||||
|
||||
Returns:
|
||||
dict: maps :class:`models.Target` to original (in response to)
|
||||
|
@ -1192,6 +1204,21 @@ class Protocol:
|
|||
if feed_obj:
|
||||
feed_obj.put()
|
||||
|
||||
# include ATProto if this user is enabled there.
|
||||
# TODO: abstract across protocols. maybe with this, below
|
||||
# targets.update({
|
||||
# Target(protocol=proto.LABEL,
|
||||
# uri=proto.target_for(proto.bot_user_id())): None
|
||||
# for proto in PROTOCOLS
|
||||
# if proto and proto.HAS_COPIES
|
||||
# })
|
||||
|
||||
if 'atproto' in from_user.enabled_protocols:
|
||||
from atproto import ATProto
|
||||
targets.setdefault(Target(protocol=ATProto.LABEL, uri=ATProto.PDS_URL),
|
||||
None)
|
||||
logger.info(f'user has ATProto enabled, added target {ATProto.PDS_URL}')
|
||||
|
||||
# de-dupe targets, discard same-domain
|
||||
# maps string target URL to (Target, Object) tuple
|
||||
candidates = {t.uri: (t, obj) for t, obj in targets.items()}
|
||||
|
|
|
@ -147,7 +147,7 @@ def run():
|
|||
obj.put()
|
||||
|
||||
|
||||
targets = list(user.targets(obj).keys())
|
||||
targets = list(user.targets(obj, from_user=user).keys())
|
||||
|
||||
if from_proto != ActivityPub:
|
||||
targets += [Target(protocol='activitypub', uri=t)
|
||||
|
|
|
@ -443,14 +443,14 @@ class ProtocolTest(TestCase):
|
|||
self.assertCountEqual([
|
||||
Target(protocol='fake', uri='fake:post:target'),
|
||||
Target(protocol='atproto', uri='https://atproto.brid.gy'),
|
||||
], Protocol.targets(obj).keys())
|
||||
], Protocol.targets(obj, from_user=user).keys())
|
||||
|
||||
def test_targets_composite_inreplyto(self):
|
||||
Fake.fetchable['fake:post'] = {
|
||||
'objectType': 'note',
|
||||
}
|
||||
self.assertEqual({Target(protocol='fake', uri='fake:post:target')},
|
||||
OtherFake.targets(Object(our_as1={
|
||||
|
||||
obj = Object(our_as1={
|
||||
'objectType': 'activity',
|
||||
'verb': 'post',
|
||||
'object': {
|
||||
|
@ -461,7 +461,10 @@ class ProtocolTest(TestCase):
|
|||
'url': 'http://foo',
|
||||
},
|
||||
},
|
||||
})).keys())
|
||||
})
|
||||
|
||||
self.assertEqual({Target(protocol='fake', uri='fake:post:target')},
|
||||
OtherFake.targets(obj, from_user=self.user).keys())
|
||||
|
||||
def test_translate_ids_follow(self):
|
||||
self.assert_equals({
|
||||
|
@ -681,6 +684,24 @@ class ProtocolReceiveTest(TestCase):
|
|||
|
||||
self.assertEqual([(obj.key.id(), 'shared:target')], Fake.sent)
|
||||
|
||||
@patch.object(ATProto, 'send', return_value=True)
|
||||
def test_create_post_user_enabled_copy_protocol_adds_pds_target(self, mock_send):
|
||||
self.user.enabled_protocols = ['atproto']
|
||||
self.user.put()
|
||||
|
||||
post_as1 = {
|
||||
'id': 'fake:post',
|
||||
'objectType': 'note',
|
||||
'author': 'fake:user',
|
||||
}
|
||||
obj = self.store_object(id='fake:post', our_as1=post_as1)
|
||||
|
||||
self.assertEqual(('OK', 202), Fake.receive_as1(post_as1))
|
||||
|
||||
[obj, url], _ = mock_send.call_args
|
||||
self.assertEqual('fake:post#bridgy-fed-create', obj.key.id())
|
||||
self.assertEqual(ATProto.PDS_URL, url)
|
||||
|
||||
def test_create_post_use_instead(self):
|
||||
self.make_user('fake:not-this', cls=Fake, use_instead=self.user.key, obj_mf2={
|
||||
'type': ['h-card'],
|
||||
|
|
Ładowanie…
Reference in New Issue