Files
adaptive-multi-protocol-bro…/ampbrowser/plan.py
T

128 lines
4.6 KiB
Python

from __future__ import annotations
from dataclasses import dataclass
from .config import AppConfig, default_config
from .platforms import PlatformCapability, capability_for
from .routing import Route, route_url
from .transports import TransportStatus, inspect_transport
@dataclass(frozen=True)
class BrowsePlan:
route: Route
status: TransportStatus | None
platform_capability: PlatformCapability
action: str
requires_consent: bool = False
prompt: str = ""
policy_mode: str = "adopt-or-prompt-manage"
def plan_url(
raw_url: str,
*,
config: AppConfig | None = None,
platform: str | None = None,
) -> BrowsePlan:
config = config or default_config()
route = route_url(raw_url)
status = inspect_transport(route.transport)
policy_mode = config.transport_mode(route.transport)
platform_capability = capability_for(route.transport, platform)
if platform_capability.browse == "unsupported":
return BrowsePlan(
route=route,
status=status,
platform_capability=platform_capability,
action=f"blocked by platform: {route.transport} unsupported on {platform_capability.platform}",
policy_mode=policy_mode,
)
if policy_mode == "disabled":
return BrowsePlan(
route=route,
status=status,
platform_capability=platform_capability,
action=f"blocked by policy: {route.transport} disabled",
policy_mode=policy_mode,
)
if route.transport in {"clearnet", "unknown"}:
return BrowsePlan(
route=route,
status=status,
platform_capability=platform_capability,
action="open with clearnet profile",
policy_mode=policy_mode,
)
if status and status.adoptable:
return BrowsePlan(
route=route,
status=status,
platform_capability=platform_capability,
action="adopt existing transport",
policy_mode=policy_mode,
)
if policy_mode == "adopt":
return BrowsePlan(
route=route,
status=status,
platform_capability=platform_capability,
action=f"blocked by policy: {route.transport} mode is adopt",
policy_mode=policy_mode,
)
if status and status.manage_supported and not platform_capability.can_manage_setup:
return BrowsePlan(
route=route,
status=status,
platform_capability=platform_capability,
action=(
f"blocked by platform: {route.transport} managed setup is "
f"{platform_capability.manage} on {platform_capability.platform}"
),
policy_mode=policy_mode,
)
if status and status.manage_supported:
if platform_capability.manage == "foreground-only":
action = "prompt to start foreground-only transport session"
prompt = (
f"{route.transport} is not running. AMPB can start a foreground-only "
f"{route.transport} session for {route.normalized} on {platform_capability.platform}."
)
else:
action = "prompt to start managed transport"
prompt = (
f"{route.transport} is not running. AMPB can start a managed {route.transport} "
f"transport for {route.normalized}."
)
if not status.installed:
if platform_capability.manage == "foreground-only":
action = "prompt to enable foreground-only transport session"
prompt = (
f"{route.transport} is not available. AMPB can enable a foreground-only "
f"{route.transport} session for {route.normalized} on {platform_capability.platform}."
)
else:
action = "prompt to install and start managed transport"
prompt = (
f"{route.transport} is not installed or running. AMPB can install and start "
f"a managed {route.transport} transport for {route.normalized}."
)
return BrowsePlan(
route=route,
status=status,
platform_capability=platform_capability,
action=action,
requires_consent=True,
prompt=prompt,
policy_mode=policy_mode,
)
return BrowsePlan(
route=route,
status=status,
platform_capability=platform_capability,
action="blocked until adapter is configured",
policy_mode=policy_mode,
)