microblog.pub/little_boxes/utils.py

61 lines
2 KiB
Python
Raw Normal View History

2018-06-06 22:00:35 +00:00
"""Contains some ActivityPub related utils."""
from typing import Optional
2018-06-10 11:51:43 +00:00
from typing import Callable
2018-06-06 22:00:35 +00:00
from typing import Dict
from typing import List
from typing import Any
from .errors import RecursionLimitExceededError
from .errors import UnexpectedActivityTypeError
def parse_collection(
payload: Optional[Dict[str, Any]] = None,
url: Optional[str] = None,
level: int = 0,
2018-06-10 11:51:43 +00:00
fetcher: Optional[Callable[[str], Dict[str, Any]]] = None,
2018-06-06 22:00:35 +00:00
) -> List[Any]:
"""Resolve/fetch a `Collection`/`OrderedCollection`."""
2018-06-10 11:51:43 +00:00
if not fetcher:
raise Exception('must provide a fetcher')
2018-06-06 22:00:35 +00:00
if level > 3:
raise RecursionLimitExceededError('recursion limit exceeded')
# Go through all the pages
out: List[Any] = []
if url:
2018-06-10 11:51:43 +00:00
payload = fetcher(url)
2018-06-06 22:00:35 +00:00
if not payload:
raise ValueError('must at least prove a payload or an URL')
if payload['type'] in ['Collection', 'OrderedCollection']:
if 'orderedItems' in payload:
return payload['orderedItems']
if 'items' in payload:
return payload['items']
if 'first' in payload:
if 'orderedItems' in payload['first']:
out.extend(payload['first']['orderedItems'])
if 'items' in payload['first']:
out.extend(payload['first']['items'])
n = payload['first'].get('next')
if n:
2018-06-10 11:51:43 +00:00
out.extend(parse_collection(url=n, level=level+1, fetcher=fetcher))
2018-06-06 22:00:35 +00:00
return out
while payload:
if payload['type'] in ['CollectionPage', 'OrderedCollectionPage']:
if 'orderedItems' in payload:
out.extend(payload['orderedItems'])
if 'items' in payload:
out.extend(payload['items'])
n = payload.get('next')
if n is None:
break
2018-06-10 11:51:43 +00:00
payload = fetcher(n)
2018-06-06 22:00:35 +00:00
else:
raise UnexpectedActivityTypeError('unexpected activity type {}'.format(payload['type']))
return out