mdns-termux/lib/mdns_tools/watch.py

73 lines
2.5 KiB
Python
Raw Normal View History

"""Live service monitor — like `avahi-browse` without -t.
Prints events as they happen:
+ service appeared
= service appeared and was resolved (address:port)
- service disappeared
With no --type it browses the DNS-SD meta-service
(`_services._dns-sd._udp.local.`) to discover types dynamically and attaches a
browser to each the equivalent of `avahi-browse -a`.
"""
import time
from zeroconf import Zeroconf, ServiceBrowser, ServiceListener
class _EventListener(ServiceListener):
def __init__(self, resolve: bool = True) -> None:
self.resolve = resolve
def add_service(self, zc: Zeroconf, type_: str, name: str) -> None: # noqa: N802
line = f"+ {type_:<30} {name}"
if self.resolve:
info = zc.get_service_info(type_, name, timeout=1500)
if info:
addrs = ", ".join(info.parsed_addresses() or []) or "-"
line = f"= {type_:<30} {name} {addrs}:{info.port}"
print(line, flush=True)
def update_service(self, zc: Zeroconf, type_: str, name: str) -> None: # noqa: N802
return
def remove_service(self, zc: Zeroconf, type_: str, name: str) -> None: # noqa: N802
print(f"- {type_:<30} {name}", flush=True)
class _TypeSpawner(ServiceListener):
"""On discovering a new service TYPE, attach a browser for it."""
def __init__(self, zc: Zeroconf, svc_listener: ServiceListener) -> None:
self.zc = zc
self.svc_listener = svc_listener
self.browsers: dict[str, ServiceBrowser] = {}
def add_service(self, zc: Zeroconf, type_: str, name: str) -> None: # noqa: N802
# For the meta-service, `name` is the discovered type (e.g. _http._tcp.local.)
if name not in self.browsers:
self.browsers[name] = ServiceBrowser(zc, name, self.svc_listener)
def update_service(self, *a) -> None: # noqa: N802
return
def remove_service(self, *a) -> None: # noqa: N802
return
def watch(service_type: str | None = None, resolve: bool = True) -> None:
zc = Zeroconf()
svc = _EventListener(resolve=resolve)
try:
if service_type:
ServiceBrowser(zc, service_type, svc)
else:
ServiceBrowser(zc, "_services._dns-sd._udp.local.",
_TypeSpawner(zc, svc))
print("[mdns] watching — Ctrl+C to stop", flush=True)
while True:
time.sleep(1)
except KeyboardInterrupt:
pass
finally:
zc.close()