little-boxes/little_boxes/collection.py

71 wiersze
2.3 KiB
Python
Czysty Zwykły widok Historia

2018-06-16 12:19:47 +00:00
"""Collection releated utils."""
2018-06-15 22:27:49 +00:00
from typing import Any
2018-06-11 20:50:02 +00:00
from typing import Callable
from typing import Dict
from typing import List
2018-06-15 22:27:49 +00:00
from typing import Optional
2018-06-11 20:50:02 +00:00
from .errors import RecursionLimitExceededError
from .errors import UnexpectedActivityTypeError
2018-06-16 12:19:47 +00:00
def parse_collection( # noqa: C901
2018-06-11 20:50:02 +00:00
payload: Optional[Dict[str, Any]] = None,
url: Optional[str] = None,
level: int = 0,
fetcher: Optional[Callable[[str], Dict[str, Any]]] = None,
) -> List[Any]:
"""Resolve/fetch a `Collection`/`OrderedCollection`."""
if not fetcher:
2018-06-12 17:57:40 +00:00
raise Exception("must provide a fetcher")
2018-06-11 20:50:02 +00:00
if level > 3:
2018-06-12 17:57:40 +00:00
raise RecursionLimitExceededError("recursion limit exceeded")
2018-06-11 20:50:02 +00:00
# Go through all the pages
out: List[Any] = []
if url:
payload = fetcher(url)
if not payload:
2018-06-12 17:57:40 +00:00
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:
2018-06-16 12:19:47 +00:00
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)
)
2018-06-11 20:50:02 +00:00
return out
while payload:
2018-06-12 17:57:40 +00:00
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")
2018-06-11 20:50:02 +00:00
if n is None:
break
payload = fetcher(n)
else:
2018-06-12 17:57:40 +00:00
raise UnexpectedActivityTypeError(
"unexpected activity type {}".format(payload["type"])
)
2018-06-11 20:50:02 +00:00
return out