kopia lustrzana https://github.com/snarfed/bridgy-fed
implement app.bsky.feed.getPostThread
rodzic
cd32cdf6f9
commit
64242f3deb
Plik binarny nie jest wyświetlany.
Po Szerokość: | Wysokość: | Rozmiar: 1.1 MiB |
|
@ -27,8 +27,8 @@ class XrpcActorTest(testutil.TestCase):
|
|||
self.assertEqual({
|
||||
'$type': 'app.bsky.actor.profile',
|
||||
'handle': 'foo.com',
|
||||
'did': 'TODO',
|
||||
'creator': 'TODO (a DID)',
|
||||
'did': 'did:web:foo.com:about-me',
|
||||
'creator': 'did:web:foo.com:about-me',
|
||||
'displayName': 'Mrs. ☕ Foo',
|
||||
'declaration': {
|
||||
'$type': 'app.bsky.system.declRef',
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
"""Unit tests for feed.py."""
|
||||
import copy
|
||||
from unittest.mock import patch
|
||||
|
||||
from granary.tests.test_bluesky import (
|
||||
|
@ -14,9 +15,67 @@ from granary.tests.test_bluesky import (
|
|||
from oauth_dropins.webutil import util
|
||||
from oauth_dropins.webutil.testutil import requests_response
|
||||
import requests
|
||||
from werkzeug.exceptions import BadGateway
|
||||
|
||||
from . import testutil
|
||||
|
||||
AUTHOR_HTML = """
|
||||
<a href="/" class="u-author h-card">
|
||||
<img src="/alice.jpg"> Alice
|
||||
</a>
|
||||
"""
|
||||
|
||||
POST_THREAD_HTML = copy.deepcopy(POST_HTML).replace('</article>', """
|
||||
<div class="u-comment h-cite">
|
||||
<a class="u-author h-card" href="http://bob.org/">Bob</a>
|
||||
<a class="u-url" href="http://bob.org/reply"></a>
|
||||
<p class="p-content">Uh huh</p>
|
||||
</div>
|
||||
|
||||
<div class="h-cite">
|
||||
<a class="u-author h-card" href="http://eve.net/">Eve</a>
|
||||
<p class="p-content">Nuh uh</p>
|
||||
<a class="u-in-reply-to" href="http://orig/post"></a>
|
||||
</div>
|
||||
</article>
|
||||
""")
|
||||
POST_THREAD_BSKY = {
|
||||
'thread': {
|
||||
'$type': 'app.bsky.feed.getPostThread#threadViewPost',
|
||||
'post': POST_BSKY['post'],
|
||||
'replies': [{
|
||||
'$type': 'app.bsky.feed.getPostThread#threadViewPost',
|
||||
'post': {
|
||||
'$type': 'app.bsky.feed.post#view',
|
||||
'uri': 'http://bob.org/reply',
|
||||
'cid': 'TODO',
|
||||
'record': {
|
||||
'$type': 'app.bsky.feed.post',
|
||||
'text': 'Uh huh',
|
||||
'createdAt': '',
|
||||
},
|
||||
'author': {
|
||||
'$type': 'app.bsky.actor.ref#withInfo',
|
||||
'did': 'did:web:bob.org',
|
||||
'displayName': 'Bob',
|
||||
'handle': 'bob.org',
|
||||
'declaration': {
|
||||
'$type': 'app.bsky.system.declRef',
|
||||
'actorType': 'app.bsky.system.actorUser',
|
||||
'cid': 'TODO',
|
||||
},
|
||||
},
|
||||
'replyCount': 0,
|
||||
'repostCount': 0,
|
||||
'upvoteCount': 0,
|
||||
'downvoteCount': 0,
|
||||
'indexedAt': '2022-01-02T03:04:05+00:00',
|
||||
'viewer': {},
|
||||
},
|
||||
}],
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@patch('requests.get')
|
||||
class XrpcFeedTest(testutil.TestCase):
|
||||
|
@ -24,9 +83,7 @@ class XrpcFeedTest(testutil.TestCase):
|
|||
def test_getAuthorFeed(self, mock_get):
|
||||
mock_get.return_value = requests_response(f"""\
|
||||
<body class="h-feed">
|
||||
<a href="/" class="u-author h-card">
|
||||
<img src="/alice.jpg"> Alice
|
||||
</a>
|
||||
{AUTHOR_HTML}
|
||||
{POST_HTML}
|
||||
{REPLY_HTML}
|
||||
{REPOST_HTML}
|
||||
|
@ -45,17 +102,40 @@ class XrpcFeedTest(testutil.TestCase):
|
|||
query_string={'author': 'not a domain'})
|
||||
self.assertEqual(400, resp.status_code)
|
||||
|
||||
# def test_getPostThread(self, mock_get):
|
||||
# mock_get.return_value = requests_response("""
|
||||
# <body>
|
||||
# </body>
|
||||
# """, url='https://foo.com/')
|
||||
def test_getAuthorFeed_fetch_fails(self, mock_get):
|
||||
mock_get.return_value = requests_response(status=500)
|
||||
resp = self.client.get('/xrpc/app.bsky.feed.getAuthorFeed',
|
||||
query_string={'author': 'alice.com'})
|
||||
self.assertEqual(502, resp.status_code)
|
||||
|
||||
# got = self.client.get('/xrpc/app.bsky.actor.getProfile',
|
||||
# query_string={'actor': 'foo.com'},
|
||||
# ).json
|
||||
# self.assertEqual({
|
||||
# }, got)
|
||||
def test_getAuthorFeed_no_feed(self, mock_get):
|
||||
mock_get.return_value = requests_response(AUTHOR_HTML)
|
||||
resp = self.client.get('/xrpc/app.bsky.feed.getAuthorFeed',
|
||||
query_string={'author': 'alice.com'})
|
||||
self.assertEqual(200, resp.status_code)
|
||||
self.assertEqual({'feed': []}, resp.json)
|
||||
|
||||
def test_getPostThread(self, mock_get):
|
||||
mock_get.return_value = requests_response(
|
||||
POST_THREAD_HTML, url='https://alice.com/')
|
||||
|
||||
resp = self.client.get('/xrpc/app.bsky.feed.getPostThread',
|
||||
query_string={'uri': 'http://a/post'})
|
||||
self.assertEqual(200, resp.status_code, resp.get_data(as_text=True))
|
||||
self.assert_equals(POST_THREAD_BSKY, resp.json)
|
||||
|
||||
|
||||
def test_getPostThread_fetch_fails(self, mock_get):
|
||||
mock_get.return_value = requests_response(status=500)
|
||||
resp = self.client.get('/xrpc/app.bsky.feed.getPostThread',
|
||||
query_string={'uri': 'http://a/post'})
|
||||
self.assertEqual(502, resp.status_code)
|
||||
|
||||
def test_getAuthorFeed_no_post(self, mock_get):
|
||||
mock_get.return_value = requests_response(AUTHOR_HTML)
|
||||
resp = self.client.get('/xrpc/app.bsky.feed.getPostThread',
|
||||
query_string={'uri': 'http://a/post'})
|
||||
self.assertEqual(400, resp.status_code, resp.get_data(as_text=True))
|
||||
|
||||
# def test_getRepostedBy(self, mock_get):
|
||||
# mock_get.return_value = requests_response("""
|
||||
|
|
27
xrpc_feed.py
27
xrpc_feed.py
|
@ -39,7 +39,7 @@ def getAuthorFeed(input, author=None, limit=None, before=None):
|
|||
'displayName': author,
|
||||
}
|
||||
|
||||
activities = microformats2.json_to_activities(mf2) #, actor)
|
||||
activities = microformats2.json_to_activities(mf2)
|
||||
# default actor to feed author
|
||||
for a in activities:
|
||||
a.setdefault('actor', actor)
|
||||
|
@ -48,12 +48,33 @@ def getAuthorFeed(input, author=None, limit=None, before=None):
|
|||
return {'feed': [bluesky.from_as1(a) for a in activities]}
|
||||
|
||||
|
||||
# all the rest come from fetching uri, parsing as mf2, and extracting responses
|
||||
@xrpc_server.method('app.bsky.feed.getPostThread')
|
||||
def getPostThread(input):
|
||||
def getPostThread(input, uri=None, depth=None):
|
||||
"""
|
||||
lexicons/app/bsky/feed/getPostThread.json
|
||||
"""
|
||||
mf2 = util.fetch_mf2(uri, gateway=True)
|
||||
logger.info(f'Got mf2: {json.dumps(mf2, indent=2)}')
|
||||
|
||||
entry = mf2util.find_first_entry(mf2, ['h-entry'])
|
||||
logger.info(f'Entry: {json.dumps(entry, indent=2)}')
|
||||
if not entry:
|
||||
raise ValueError(f"No h-entry on {uri}")
|
||||
|
||||
obj = microformats2.json_to_object(entry)
|
||||
logger.info(f'AS1: {json.dumps(obj, indent=2)}')
|
||||
|
||||
return {
|
||||
'thread': {
|
||||
'$type': 'app.bsky.feed.getPostThread#threadViewPost',
|
||||
'post': bluesky.from_as1(obj)['post'],
|
||||
'replies': [{
|
||||
'$type': 'app.bsky.feed.getPostThread#threadViewPost',
|
||||
'post': bluesky.from_as1(reply)['post'],
|
||||
} for reply in obj.get('replies', {}).get('items', [])],
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@xrpc_server.method('app.bsky.feed.getRepostedBy')
|
||||
def getRepostedBy(input, uri=None, cid=None, limit=None, before=None):
|
||||
|
|
Ładowanie…
Reference in New Issue