kopia lustrzana https://github.com/snarfed/bridgy-fed
rodzic
97ffc10f72
commit
a76fe45891
|
@ -500,7 +500,9 @@ class WebmentionTest(testutil.TestCase):
|
|||
)
|
||||
|
||||
def test_update_reply(self, mock_get, mock_post):
|
||||
Object(id='http://a/reply', status='complete', as1='{}').put()
|
||||
# different = copy.deepcopy(self.reply_as1)
|
||||
# different['content'] += ' other'
|
||||
Object(id='http://a/reply', status='complete', as1='{"content": "other"}').put()
|
||||
|
||||
mock_get.side_effect = self.activitypub_gets
|
||||
mock_post.return_value = requests_response('abc xyz')
|
||||
|
@ -513,7 +515,7 @@ class WebmentionTest(testutil.TestCase):
|
|||
|
||||
args, kwargs = mock_post.call_args
|
||||
self.assertEqual(('https://foo.com/inbox',), args)
|
||||
self.assertEqual(self.as2_update, json_loads(kwargs['data']))
|
||||
self.assert_equals(self.as2_update, json_loads(kwargs['data']))
|
||||
|
||||
def test_redo_repost_isnt_update(self, mock_get, mock_post):
|
||||
"""Like and Announce shouldn't use Update, they should just resend as is."""
|
||||
|
@ -530,12 +532,13 @@ class WebmentionTest(testutil.TestCase):
|
|||
|
||||
args, kwargs = mock_post.call_args
|
||||
self.assertEqual(('https://foo.com/inbox',), args)
|
||||
self.assertEqual(self.repost_as2, json_loads(kwargs['data']))
|
||||
self.assert_equals(self.repost_as2, json_loads(kwargs['data']))
|
||||
|
||||
def test_skip_update_if_content_unchanged(self, mock_get, mock_post):
|
||||
"""https://github.com/snarfed/bridgy-fed/issues/78"""
|
||||
Object(id='http://a/reply', status='complete',
|
||||
as1=json_dumps(self.reply_as1)).put()
|
||||
as1=json_dumps(self.reply_as1),
|
||||
ap_delivered=['https://foo.com/inbox']).put()
|
||||
mock_get.side_effect = self.activitypub_gets
|
||||
|
||||
got = self.client.post('/webmention', data={
|
||||
|
@ -717,23 +720,8 @@ class WebmentionTest(testutil.TestCase):
|
|||
},
|
||||
)
|
||||
|
||||
def test_create_post_run_task(self, mock_get, mock_post):
|
||||
mock_get.side_effect = [self.create, self.actor]
|
||||
mock_post.return_value = requests_response('abc xyz')
|
||||
|
||||
# Object(id='https://orig/post', domains=['orig'],
|
||||
# status='complete', mf2=json_dumps(self.create_mf2),
|
||||
# as1=json_dumps(self.create_as1)).put()
|
||||
|
||||
# different_create_mf2 = copy.deepcopy(self.create_mf2)
|
||||
# different_create_mf2['items'][0]['properties']['content'][0]['value'] += ' different'
|
||||
# different_create_as1 = copy.deepcopy(self.create_as1)
|
||||
# different_create_as1['content'] += ' different'
|
||||
# Object(id='https://orig/post', domains=['orig'],
|
||||
# status='complete', source_protocol='activitypub',
|
||||
# mf2=json_dumps(different_create_mf2),
|
||||
# as1=json_dumps(different_create_as1)).put()
|
||||
|
||||
@staticmethod
|
||||
def make_followers():
|
||||
Follower.get_or_create('orig', 'https://mastodon/aaa')
|
||||
Follower.get_or_create('orig', 'https://mastodon/bbb',
|
||||
last_follow=json_dumps({'actor': {
|
||||
|
@ -750,17 +738,6 @@ class WebmentionTest(testutil.TestCase):
|
|||
last_follow=json_dumps({'actor': {
|
||||
'inbox': 'https://inbox',
|
||||
}}))
|
||||
# TODO
|
||||
# # already sent, should be skipped
|
||||
# Follower.get_or_create('orig', 'https://mastodon/eee',
|
||||
# last_follow=json_dumps({'actor': {
|
||||
# 'inbox': 'https://skipped/inbox',
|
||||
# }}))
|
||||
# changed, should still be sent
|
||||
Follower.get_or_create('orig', 'https://mastodon/fff',
|
||||
last_follow=json_dumps({'actor': {
|
||||
'inbox': 'https://updated/inbox',
|
||||
}}))
|
||||
Follower.get_or_create('orig', 'https://mastodon/ggg',
|
||||
status='inactive',
|
||||
last_follow=json_dumps({'actor': {
|
||||
|
@ -772,6 +749,51 @@ class WebmentionTest(testutil.TestCase):
|
|||
'inbox': 'https://inbox',
|
||||
}}))
|
||||
|
||||
def test_create_post_run_task_new(self, mock_get, mock_post):
|
||||
mock_get.side_effect = [self.create, self.actor]
|
||||
mock_post.return_value = requests_response('abc xyz')
|
||||
self.make_followers()
|
||||
|
||||
got = self.client.post('/_ah/queue/webmention', data={
|
||||
'source': 'https://orig/post',
|
||||
'target': 'https://fed.brid.gy/',
|
||||
})
|
||||
self.assertEqual(200, got.status_code)
|
||||
|
||||
mock_get.assert_has_calls((
|
||||
self.req('https://orig/post'),
|
||||
))
|
||||
inboxes = ('https://inbox', 'https://public/inbox', 'https://shared/inbox')
|
||||
self.assert_deliveries(mock_post, inboxes, self.create_as2)
|
||||
|
||||
self.assert_object(f'https://orig/post',
|
||||
domains=['orig'],
|
||||
source_protocol='activitypub',
|
||||
status='complete',
|
||||
mf2=self.create_mf2,
|
||||
as1=self.create_as1,
|
||||
ap_delivered=inboxes,
|
||||
type='note',
|
||||
)
|
||||
|
||||
def test_create_post_run_task_resume(self, mock_get, mock_post):
|
||||
mock_get.side_effect = [self.create, self.actor]
|
||||
mock_post.return_value = requests_response('abc xyz')
|
||||
|
||||
Object(id='https://orig/post', domains=['orig'], status='in progress',
|
||||
as1=json_dumps(self.create_as1),
|
||||
ap_delivered=['https://skipped/inbox'],
|
||||
ap_undelivered=['https://shared/inbox'],
|
||||
ap_failed=['https://public/inbox'],
|
||||
).put()
|
||||
|
||||
self.make_followers()
|
||||
# already sent, should be skipped
|
||||
Follower.get_or_create('orig', 'https://mastodon/eee',
|
||||
last_follow=json_dumps({'actor': {
|
||||
'inbox': 'https://skipped/inbox',
|
||||
}}))
|
||||
|
||||
got = self.client.post('/_ah/queue/webmention', data={
|
||||
'source': 'https://orig/post',
|
||||
'target': 'https://fed.brid.gy/',
|
||||
|
@ -782,23 +804,59 @@ class WebmentionTest(testutil.TestCase):
|
|||
self.req('https://orig/post'),
|
||||
))
|
||||
|
||||
inboxes = ('https://inbox', 'https://public/inbox',
|
||||
'https://shared/inbox', 'https://updated/inbox')
|
||||
inboxes = ['https://inbox', 'https://public/inbox', 'https://shared/inbox']
|
||||
self.assert_deliveries(mock_post, inboxes, self.create_as2)
|
||||
# TODO
|
||||
# self.update_as2 if inbox == 'https://updated/inbox' else
|
||||
|
||||
self.assert_object(f'https://orig/post',
|
||||
domains=['orig'],
|
||||
source_protocol='activitypub',
|
||||
status='complete',
|
||||
#(different_create_mf2 if inbox == 'https://updated/inbox' else
|
||||
mf2=self.create_mf2,
|
||||
as1=self.create_as1,
|
||||
ap_delivered=inboxes + ['https://skipped/inbox'],
|
||||
type='note',
|
||||
)
|
||||
|
||||
def test_create_post_run_task_update(self, mock_get, mock_post):
|
||||
different_create_as1 = copy.deepcopy(self.create_as1)
|
||||
different_create_as1['content'] += ' different'
|
||||
|
||||
mock_get.side_effect = [self.create, self.actor]
|
||||
mock_post.return_value = requests_response('abc xyz')
|
||||
|
||||
Object(id='https://orig/post', domains=['orig'], status='in progress',
|
||||
as1=json_dumps(different_create_as1),
|
||||
ap_delivered=['https://delivered/inbox'],
|
||||
ap_undelivered=['https://shared/inbox'],
|
||||
ap_failed=['https://public/inbox'],
|
||||
).put()
|
||||
|
||||
self.make_followers()
|
||||
|
||||
got = self.client.post('/_ah/queue/webmention', data={
|
||||
'source': 'https://orig/post',
|
||||
'target': 'https://fed.brid.gy/',
|
||||
})
|
||||
self.assertEqual(200, got.status_code)
|
||||
|
||||
mock_get.assert_has_calls((
|
||||
self.req('https://orig/post'),
|
||||
))
|
||||
self.assertEqual(4, len(mock_post.call_args_list), mock_post.call_args_list)
|
||||
|
||||
inboxes = ('https://inbox', 'https://public/inbox', 'https://shared/inbox',
|
||||
'https://delivered/inbox')
|
||||
self.assert_deliveries(mock_post, inboxes, self.update_as2)
|
||||
|
||||
self.assert_object(f'https://orig/post',
|
||||
domains=['orig'],
|
||||
source_protocol='activitypub',
|
||||
status='complete',
|
||||
mf2=self.create_mf2,
|
||||
as1=self.create_as1,
|
||||
ap_delivered=inboxes,
|
||||
type='note',
|
||||
)
|
||||
#(different_create_as1 if inbox == 'https://updated/inbox' else
|
||||
|
||||
def test_create_with_image(self, mock_get, mock_post):
|
||||
create_html = self.create_html.replace(
|
||||
|
|
|
@ -134,36 +134,44 @@ class Webmention(View):
|
|||
last_success = None
|
||||
log_data = True
|
||||
|
||||
type = as1.object_type(self.source_as1)
|
||||
obj = Object.get_by_id(self.source_url)
|
||||
changed = False
|
||||
|
||||
if obj:
|
||||
logging.info(f'Resuming existing Object {obj}')
|
||||
logging.info(f'Resuming existing {obj}')
|
||||
obj.ap_failed = []
|
||||
seen = obj.ap_delivered + obj.ap_undelivered + obj.ap_failed
|
||||
new_inboxes = [i for i in inboxes_to_targets.keys() if i not in seen]
|
||||
if new_inboxes:
|
||||
logging.info(f'Adding new inboxes: {new_inboxes}')
|
||||
obj.ap_undelivered += new_inboxes
|
||||
if type in ('note', 'article', 'comment'):
|
||||
changed = as1.activity_changed(json_loads(obj.as1), self.source_as1)
|
||||
if changed:
|
||||
obj.ap_undelivered += obj.ap_delivered
|
||||
obj.ap_delivered = []
|
||||
logger.info(f'Content has changed from last time at {obj.updated}! Redelivering to all inboxes: {obj.ap_undelivered}')
|
||||
|
||||
else:
|
||||
obj = Object(id=self.source_url, domains=[self.source_domain],
|
||||
source_protocol='activitypub',
|
||||
mf2=json_dumps(self.source_mf2),
|
||||
as1=json_dumps(self.source_as1),
|
||||
obj = Object(id=self.source_url,
|
||||
ap_undelivered=list(inboxes_to_targets.keys()),
|
||||
ap_delivered=[],
|
||||
ap_failed=[],
|
||||
type=as1.object_type(self.source_as1),
|
||||
object_ids=as1.get_ids(self.source_as1, 'object'))
|
||||
|
||||
|
||||
if (obj.status == 'complete' and
|
||||
not as1.activity_changed(json_loads(obj.as1), self.source_as1)):
|
||||
logger.info(f'Skipping; new content is same as content published before at {obj.updated}')
|
||||
return 'OK'
|
||||
ap_failed=[])
|
||||
logging.info(f'Storing new {obj}')
|
||||
|
||||
obj.domains = [self.source_domain]
|
||||
obj.source_protocol = 'activitypub'
|
||||
obj.mf2 = json_dumps(self.source_mf2)
|
||||
obj.as1 = json_dumps(self.source_as1)
|
||||
obj.type = type
|
||||
obj.object_ids = as1.get_ids(self.source_as1, 'object')
|
||||
obj.put()
|
||||
|
||||
# TODO: collect by inbox, add 'to' fields, de-dupe inboxes and recipients
|
||||
#
|
||||
# make copy of ap_undelivered because we modify it below
|
||||
logger.info(f'Delivering to inboxes: {sorted(obj.ap_undelivered)}')
|
||||
for inbox in list(obj.ap_undelivered):
|
||||
if inbox in inboxes_to_targets:
|
||||
target_as2 = inboxes_to_targets[inbox]
|
||||
|
@ -176,7 +184,7 @@ class Webmention(View):
|
|||
as2.from_as1(self.source_as1), target=target_as2, user=self.user)
|
||||
if not self.source_as2.get('actor'):
|
||||
self.source_as2['actor'] = common.host_url(self.source_domain)
|
||||
if obj.status == 'complete' and self.source_as2.get('type') == 'Create':
|
||||
if changed:
|
||||
self.source_as2['type'] = 'Update'
|
||||
|
||||
if self.source_as2.get('type') == 'Update':
|
||||
|
@ -270,7 +278,7 @@ class Webmention(View):
|
|||
inboxes.add(actor.get('endpoints', {}).get('sharedInbox') or
|
||||
actor.get('publicInbox') or
|
||||
actor.get('inbox'))
|
||||
logger.info(f"Delivering to followers' inboxes: {sorted(inboxes)}")
|
||||
logger.info('Delivering to followers')
|
||||
return {inbox: None for inbox in inboxes}
|
||||
|
||||
targets = common.remove_blocklisted(targets)
|
||||
|
|
Ładowanie…
Reference in New Issue