pull/1/head
Thomas Sileo 2018-06-16 14:19:47 +02:00
rodzic 479000d418
commit 4ff4b3a85c
3 zmienionych plików z 127 dodań i 9 usunięć

Wyświetl plik

@ -1,11 +1,28 @@
import abc
import typing
from typing import Any
from typing import Dict
import requests
from .__version__ import __version__
if typing.TYPE_CHECKING:
from little_boxes import activitypub as ap # noqa: type checking
class Backend(abc.ABC):
def user_agent(self) -> str:
return f"Little Boxes {__version__} (+http://github.com/tsileo/little-boxes)"
def fetch_json(self, url: str) -> Dict[str, Any]:
resp = requests.get(
url, headers={"User-Agent": self.user_agent(), "Accept": "application/json"}
)
resp.raise_for_status()
return resp.json()
@abc.abstractmethod
def base_url(self) -> str:
pass

Wyświetl plik

@ -1,4 +1,4 @@
"""Contains some ActivityPub related utils."""
"""Collection releated utils."""
from typing import Any
from typing import Callable
from typing import Dict
@ -9,7 +9,7 @@ from .errors import RecursionLimitExceededError
from .errors import UnexpectedActivityTypeError
def parse_collection(
def parse_collection( # noqa: C901
payload: Optional[Dict[str, Any]] = None,
url: Optional[str] = None,
level: int = 0,
@ -34,13 +34,22 @@ def parse_collection(
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:
out.extend(parse_collection(url=n, level=level + 1, fetcher=fetcher))
if isinstance(payload["first"], str):
out.extend(
parse_collection(
url=payload["first"], level=level + 1, fetcher=fetcher
)
)
else:
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:
out.extend(
parse_collection(url=n, level=level + 1, fetcher=fetcher)
)
return out
while payload:

Wyświetl plik

@ -0,0 +1,92 @@
import logging
import pytest
from little_boxes import activitypub as ap
from little_boxes.collection import parse_collection
from little_boxes.errors import RecursionLimitExceededError
from little_boxes.errors import UnexpectedActivityTypeError
from test_backend import InMemBackend
logging.basicConfig(level=logging.DEBUG)
def test_empty_collection():
back = InMemBackend()
ap.use_backend(back)
back.FETCH_MOCK["https://lol.com"] = {
"type": "Collection",
"items": [],
"id": "https://lol.com",
}
out = parse_collection(url="https://lol.com", fetcher=back.fetch_iri)
assert out == []
def test_recursive_collection_limit():
back = InMemBackend()
ap.use_backend(back)
back.FETCH_MOCK["https://lol.com"] = {
"type": "Collection",
"first": "https://lol.com",
"id": "https://lol.com",
}
with pytest.raises(RecursionLimitExceededError):
parse_collection(url="https://lol.com", fetcher=back.fetch_iri)
def test_unexpected_activity_type():
back = InMemBackend()
ap.use_backend(back)
back.FETCH_MOCK["https://lol.com"] = {"type": "Actor", "id": "https://lol.com"}
with pytest.raises(UnexpectedActivityTypeError):
parse_collection(url="https://lol.com", fetcher=back.fetch_iri)
def test_collection():
back = InMemBackend()
ap.use_backend(back)
back.FETCH_MOCK["https://lol.com"] = {
"type": "Collection",
"first": "https://lol.com/page1",
"id": "https://lol.com",
}
back.FETCH_MOCK["https://lol.com/page1"] = {
"type": "CollectionPage",
"id": "https://lol.com/page1",
"items": [1, 2, 3],
}
out = parse_collection(url="https://lol.com", fetcher=back.fetch_iri)
assert out == [1, 2, 3]
def test_ordered_collection():
back = InMemBackend()
ap.use_backend(back)
back.FETCH_MOCK["https://lol.com"] = {
"type": "OrderedCollection",
"first": {
"type": "OrderedCollectionPage",
"id": "https://lol.com/page1",
"orderedItems": [1, 2, 3],
"next": "https://lol.com/page2",
},
"id": "https://lol.com",
}
back.FETCH_MOCK["https://lol.com/page2"] = {
"type": "OrderedCollectionPage",
"id": "https://lol.com/page2",
"orderedItems": [4, 5, 6],
}
out = parse_collection(url="https://lol.com", fetcher=back.fetch_iri)
assert out == [1, 2, 3, 4, 5, 6]