2022-08-31 12:34:25 +03:00
|
|
|
from asyncio import exceptions
|
2022-08-24 08:09:41 +03:00
|
|
|
from json import loads
|
|
|
|
from typing import AsyncGenerator
|
|
|
|
from urllib.parse import urlencode
|
|
|
|
|
2022-08-24 08:28:18 +03:00
|
|
|
from mastoposter.types import Status
|
2022-08-24 08:09:41 +03:00
|
|
|
|
|
|
|
|
2022-08-26 18:37:36 +03:00
|
|
|
async def websocket_source(
|
|
|
|
url: str, reconnect: bool = False, **params
|
|
|
|
) -> AsyncGenerator[Status, None]:
|
2022-08-24 08:09:41 +03:00
|
|
|
from websockets.client import connect
|
2022-08-26 18:37:36 +03:00
|
|
|
from websockets.exceptions import WebSocketException
|
2022-08-24 08:09:41 +03:00
|
|
|
|
|
|
|
url = f"{url}?" + urlencode({"stream": "list", **params})
|
2022-08-26 18:37:36 +03:00
|
|
|
while True:
|
|
|
|
try:
|
|
|
|
async with connect(url) as ws:
|
2022-08-27 14:27:42 +03:00
|
|
|
while (msg := await ws.recv()) is not None:
|
2022-08-26 18:37:36 +03:00
|
|
|
event = loads(msg)
|
|
|
|
if "error" in event:
|
|
|
|
raise Exception(event["error"])
|
|
|
|
if event["event"] == "update":
|
|
|
|
yield Status.from_dict(loads(event["payload"]))
|
2022-08-31 12:34:25 +03:00
|
|
|
except (WebSocketException, TimeoutError, exceptions.TimeoutError):
|
2022-08-26 18:37:36 +03:00
|
|
|
if not reconnect:
|
|
|
|
raise
|