bridgy-fed/xrpc_feed.py

121 wiersze
3.6 KiB
Python
Czysty Zwykły widok Historia

"""app.bsky.feed.* XRPC methods."""
2022-12-30 18:10:49 +00:00
import json
2022-12-28 17:27:42 +00:00
import logging
2022-12-30 18:10:49 +00:00
import re
from flask import g
noop, lint fixes from flake8 remaining: $ flake8 --extend-ignore=E501 *.py tests/*.py "pyflakes" failed during execution due to "'FlakesChecker' object has no attribute 'NAMEDEXPR'" Run flake8 with greater verbosity to see more details activitypub.py:15:1: F401 'oauth_dropins.webutil.util.json_loads' imported but unused activitypub.py:36:1: F401 'web' imported but unused activitypub.py:48:1: E302 expected 2 blank lines, found 1 activitypub.py:51:9: F811 redefinition of unused 'web' from line 36 app.py:6:1: F401 'flask_app.app' imported but unused app.py:9:1: F401 'activitypub' imported but unused app.py:9:1: F401 'convert' imported but unused app.py:9:1: F401 'follow' imported but unused app.py:9:1: F401 'pages' imported but unused app.py:9:1: F401 'redirect' imported but unused app.py:9:1: F401 'superfeedr' imported but unused app.py:9:1: F401 'ui' imported but unused app.py:9:1: F401 'webfinger' imported but unused app.py:9:1: F401 'web' imported but unused app.py:9:1: F401 'xrpc_actor' imported but unused app.py:9:1: F401 'xrpc_feed' imported but unused app.py:9:1: F401 'xrpc_graph' imported but unused app.py:9:19: E401 multiple imports on one line models.py:19:1: F401 'oauth_dropins.webutil.util.json_loads' imported but unused models.py:364:31: E114 indentation is not a multiple of four (comment) models.py:364:31: E116 unexpected indentation (comment) protocol.py:17:1: F401 'oauth_dropins.webutil.util.json_loads' imported but unused redirect.py:26:1: F401 'oauth_dropins.webutil.util.json_loads' imported but unused web.py:18:1: F401 'oauth_dropins.webutil.util.json_loads' imported but unused webfinger.py:13:1: F401 'oauth_dropins.webutil.util.json_loads' imported but unused webfinger.py:110:13: E122 continuation line missing indentation or outdented webfinger.py:111:13: E122 continuation line missing indentation or outdented webfinger.py:131:13: E122 continuation line missing indentation or outdented webfinger.py:132:13: E122 continuation line missing indentation or outdented webfinger.py:133:13: E122 continuation line missing indentation or outdented webfinger.py:134:13: E122 continuation line missing indentation or outdented tests/__init__.py:2:1: F401 'oauth_dropins.webutil.tests' imported but unused tests/test_follow.py:11:1: F401 'oauth_dropins.webutil.util.json_dumps' imported but unused tests/test_follow.py:14:1: F401 '.testutil.Fake' imported but unused tests/test_models.py:156:15: E122 continuation line missing indentation or outdented tests/test_models.py:157:15: E122 continuation line missing indentation or outdented tests/test_models.py:158:11: E122 continuation line missing indentation or outdented tests/test_web.py:12:1: F401 'oauth_dropins.webutil.util.json_dumps' imported but unused tests/test_web.py:17:1: F401 '.testutil' imported but unused tests/test_web.py:1513:13: E128 continuation line under-indented for visual indent tests/test_web.py:1514:9: E124 closing bracket does not match visual indentation tests/testutil.py:106:1: E402 module level import not at top of file tests/testutil.py:107:1: E402 module level import not at top of file tests/testutil.py:108:1: E402 module level import not at top of file tests/testutil.py:109:1: E402 module level import not at top of file tests/testutil.py:110:1: E402 module level import not at top of file tests/testutil.py:301:24: E203 whitespace before ':' tests/testutil.py:301:25: E701 multiple statements on one line (colon) tests/testutil.py:301:25: E231 missing whitespace after ':'
2023-06-20 18:22:54 +00:00
from granary import bluesky
2022-12-30 18:10:49 +00:00
from oauth_dropins.webutil import util
2022-12-28 17:27:42 +00:00
from flask_app import xrpc_server
noop, lint fixes from flake8 remaining: $ flake8 --extend-ignore=E501 *.py tests/*.py "pyflakes" failed during execution due to "'FlakesChecker' object has no attribute 'NAMEDEXPR'" Run flake8 with greater verbosity to see more details activitypub.py:15:1: F401 'oauth_dropins.webutil.util.json_loads' imported but unused activitypub.py:36:1: F401 'web' imported but unused activitypub.py:48:1: E302 expected 2 blank lines, found 1 activitypub.py:51:9: F811 redefinition of unused 'web' from line 36 app.py:6:1: F401 'flask_app.app' imported but unused app.py:9:1: F401 'activitypub' imported but unused app.py:9:1: F401 'convert' imported but unused app.py:9:1: F401 'follow' imported but unused app.py:9:1: F401 'pages' imported but unused app.py:9:1: F401 'redirect' imported but unused app.py:9:1: F401 'superfeedr' imported but unused app.py:9:1: F401 'ui' imported but unused app.py:9:1: F401 'webfinger' imported but unused app.py:9:1: F401 'web' imported but unused app.py:9:1: F401 'xrpc_actor' imported but unused app.py:9:1: F401 'xrpc_feed' imported but unused app.py:9:1: F401 'xrpc_graph' imported but unused app.py:9:19: E401 multiple imports on one line models.py:19:1: F401 'oauth_dropins.webutil.util.json_loads' imported but unused models.py:364:31: E114 indentation is not a multiple of four (comment) models.py:364:31: E116 unexpected indentation (comment) protocol.py:17:1: F401 'oauth_dropins.webutil.util.json_loads' imported but unused redirect.py:26:1: F401 'oauth_dropins.webutil.util.json_loads' imported but unused web.py:18:1: F401 'oauth_dropins.webutil.util.json_loads' imported but unused webfinger.py:13:1: F401 'oauth_dropins.webutil.util.json_loads' imported but unused webfinger.py:110:13: E122 continuation line missing indentation or outdented webfinger.py:111:13: E122 continuation line missing indentation or outdented webfinger.py:131:13: E122 continuation line missing indentation or outdented webfinger.py:132:13: E122 continuation line missing indentation or outdented webfinger.py:133:13: E122 continuation line missing indentation or outdented webfinger.py:134:13: E122 continuation line missing indentation or outdented tests/__init__.py:2:1: F401 'oauth_dropins.webutil.tests' imported but unused tests/test_follow.py:11:1: F401 'oauth_dropins.webutil.util.json_dumps' imported but unused tests/test_follow.py:14:1: F401 '.testutil.Fake' imported but unused tests/test_models.py:156:15: E122 continuation line missing indentation or outdented tests/test_models.py:157:15: E122 continuation line missing indentation or outdented tests/test_models.py:158:11: E122 continuation line missing indentation or outdented tests/test_web.py:12:1: F401 'oauth_dropins.webutil.util.json_dumps' imported but unused tests/test_web.py:17:1: F401 '.testutil' imported but unused tests/test_web.py:1513:13: E128 continuation line under-indented for visual indent tests/test_web.py:1514:9: E124 closing bracket does not match visual indentation tests/testutil.py:106:1: E402 module level import not at top of file tests/testutil.py:107:1: E402 module level import not at top of file tests/testutil.py:108:1: E402 module level import not at top of file tests/testutil.py:109:1: E402 module level import not at top of file tests/testutil.py:110:1: E402 module level import not at top of file tests/testutil.py:301:24: E203 whitespace before ':' tests/testutil.py:301:25: E701 multiple statements on one line (colon) tests/testutil.py:301:25: E231 missing whitespace after ':'
2023-06-20 18:22:54 +00:00
from models import Object, PAGE_SIZE
from web import Web
2022-12-25 05:08:12 +00:00
2022-12-28 17:27:42 +00:00
logger = logging.getLogger(__name__)
2022-12-25 05:08:12 +00:00
@xrpc_server.method('app.bsky.feed.getAuthorFeed')
def getAuthorFeed(input, author=None, limit=None, before=None):
2022-12-25 05:08:12 +00:00
"""
lexicons/app/bsky/feed/getAuthorFeed.json, feedViewPost.json
2022-12-25 05:08:12 +00:00
"""
if not author or not re.match(util.DOMAIN_RE, author):
2022-12-30 18:10:49 +00:00
raise ValueError(f'{author} is not a domain')
g.user = Web.get_by_id(author)
if not g.user:
raise ValueError(f'User {author} not found')
elif not g.user.obj.as1:
return ValueError(f'User {author} not fully set up')
# TODO: unify with pages.feed?
limit = min(limit or PAGE_SIZE, PAGE_SIZE)
objects, _, _ = Object.query(Object.domains == author, Object.labels == 'user') \
.order(-Object.created) \
.fetch_page(limit)
activities = [obj.as1 for obj in objects if not obj.deleted]
2022-12-30 18:10:49 +00:00
logger.info(f'AS1 activities: {json.dumps(activities, indent=2)}')
2022-12-30 18:10:49 +00:00
return {'feed': [bluesky.from_as1(a) for a in activities]}
2022-12-25 05:08:12 +00:00
@xrpc_server.method('app.bsky.feed.getPostThread')
2023-01-13 00:36:12 +00:00
def getPostThread(input, uri=None, depth=None):
2022-12-25 05:08:12 +00:00
"""
lexicons/app/bsky/feed/getPostThread.json
"""
if not uri:
raise ValueError('Missing uri')
obj = Object.get_by_id(uri)
if not obj:
raise ValueError(f'{uri} not found')
2023-01-13 00:36:12 +00:00
logger.info(f'AS1: {json.dumps(obj.as1, indent=2)}')
2023-01-13 00:36:12 +00:00
return {
'thread': {
'$type': 'app.bsky.feed.defs#threadViewPost',
'post': bluesky.from_as1(obj.as1)['post'],
2023-01-13 00:36:12 +00:00
'replies': [{
'$type': 'app.bsky.feed.defs#threadViewPost',
2023-01-13 00:36:12 +00:00
'post': bluesky.from_as1(reply)['post'],
} for reply in obj.as1.get('replies', {}).get('items', [])],
2023-01-13 00:36:12 +00:00
},
}
2022-12-25 05:08:12 +00:00
@xrpc_server.method('app.bsky.feed.getRepostedBy')
def getRepostedBy(input, uri=None, cid=None, limit=None, before=None):
"""
TODO: implement before, as query filter. what's input type? str or datetime?
lexicons/app/bsky/feed/getRepostedBy.json
"""
if not uri:
raise ValueError('Missing uri')
limit = min(limit or PAGE_SIZE, PAGE_SIZE)
objects, _, _ = Object.query(Object.object_ids == uri) \
.order(-Object.created) \
.fetch_page(limit)
activities = [obj.as1 for obj in objects if not obj.deleted]
logger.info(f'AS1 activities: {json.dumps(activities, indent=2)}')
return {
'uri': 'http://orig/post',
'repostBy': [{
**bluesky.from_as1(a['actor']),
'$type': 'app.bsky.feed.getRepostedBy#repostedBy',
} for a in activities if a.get('actor')],
}
2023-01-13 02:05:07 +00:00
# TODO: cursor
@xrpc_server.method('app.bsky.feed.getTimeline')
def getTimeline(input, algorithm=None, limit=50, before=None):
"""
lexicons/app/bsky/feed/getTimeline.json
"""
# TODO: how to get authed user?
domain = 'user.com'
# TODO: de-dupe with pages.feed()
logger.info(f'Fetching {limit} objects for {domain}')
objects, _, _ = Object.query(Object.domains == domain, Object.labels == 'feed') \
.order(-Object.created) \
.fetch_page(limit)
return {'feed': [bluesky.from_as1(obj.as1) for obj in objects if not obj.deleted]}
2022-12-25 05:08:12 +00:00
# TODO
@xrpc_server.method('app.bsky.feed.getLikes')
def getLikes(input, uri=None, direction=None, cid=None, limit=None, before=None):
2022-12-25 05:08:12 +00:00
"""
lexicons/app/bsky/feed/getLikes.json
2022-12-25 05:08:12 +00:00
"""
return {
'uri': uri,
'likes': [],
}