from my.core import __NOT_HPI_MODULE__ from typing import Iterator, Optional, Protocol from my.core import datetime_aware class Thread(Protocol): @property def id(self) -> str: ... @property def name(self) -> Optional[str]: ... class Sender(Protocol): @property def id(self) -> str: ... @property def name(self) -> Optional[str]: ... class Message(Protocol): @property def id(self) -> str: ... @property def dt(self) -> datetime_aware: ... @property def text(self) -> Optional[str]: ... @property def thread(self) -> Thread: ... @property def sender(self) -> Sender: ... from itertools import chain from more_itertools import unique_everseen from my.core import warn_if_empty, Res @warn_if_empty def _merge_messages(*sources: Iterator[Res[Message]]) -> Iterator[Res[Message]]: # todo might be nice to dump some stats for debugging, e.g. how many were overlapping? def key(r: Res[Message]): if isinstance(r, Exception): return str(r) else: # use both just in case, would be easier to spot tz issues # similar to twitter, might make sense to generify/document as a pattern return (r.id, r.dt) yield from unique_everseen(chain(*sources), key=key) # TODO some notes about gdpr export (since there is no module yet) # ugh, messages seem to go from new to old in messages_N.json files as N increases :facepalm: # seems like it's storing local timestamp :facepalm: # checked against a message sent on 4 may 2022