Source code for time_split.app._create_explorer_link

from base64 import b16encode as encode_binary_data
from datetime import datetime
from typing import Any, Unpack
from urllib.parse import ParseResult, urlencode, urlparse, urlunparse

from .._backend import DatetimeIndexSplitter
from .._docstrings import docs
from ..types import DatetimeIndexSplitterKwargs, DatetimeIterable






def _create_explorer_link(
    host: str,
    data: DatetimeIterable | str | bytes,
    *,
    show_removed: bool = True,
    skip_default: bool = False,
    **kwargs: Unpack[DatetimeIndexSplitterKwargs],
) -> ParseResult:
    query = _create_query(data, skip_default=skip_default, show_removed=show_removed, kwargs=kwargs)

    pr: ParseResult = urlparse(host)  # scheme netloc path params query fragment
    if pr.query:
        raise ValueError(f"Bad {host=}; query={pr.query!r} is not allowed.")
    return pr._replace(query=urlencode(query))


def _create_query(
    data: DatetimeIterable | str | bytes,
    *,
    skip_default: bool,
    show_removed: bool,
    kwargs: DatetimeIndexSplitterKwargs,
) -> dict[str, Any]:
    query: dict[str, Any] = {}

    if isinstance(data, bytes):
        data = "0x" + encode_binary_data(data).decode()

    if isinstance(data, str):
        query = {"data": data, **kwargs}
    else:
        splitter = DatetimeIndexSplitter(**kwargs)
        start, end = splitter._materialize_schedule(data).available_metadata.limits
        query["data"] = _get_data_param(start, end)

        if skip_default:
            schedule = kwargs["schedule"]
            query["schedule"] = schedule

            default = DatetimeIndexSplitter(schedule).as_dict()
            no_defaults = {
                key: value
                for key, value in kwargs.items()
                if value != default[key]  # type: ignore[literal-required]
            }
            query.update(no_defaults)
        else:
            query.update(kwargs)

    query["show_removed"] = show_removed
    return query


def _get_data_param(start: datetime, end: datetime) -> str:
    return f"{int(start.timestamp())}-{int(end.timestamp())}"