Move remaining code out of netdisco to eliminate as SSDP dependency (#51588)

This commit is contained in:
J. Nick Koston 2021-06-07 10:12:33 -10:00 committed by GitHub
parent 3db21b407a
commit ccf4b5a265
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 5 deletions

View File

@ -973,6 +973,7 @@ omit =
homeassistant/components/squeezebox/__init__.py
homeassistant/components/squeezebox/browse_media.py
homeassistant/components/squeezebox/media_player.py
homeassistant/components/ssdp/util.py
homeassistant/components/starline/*
homeassistant/components/starlingbank/sensor.py
homeassistant/components/steam_online/sensor.py

View File

@ -6,10 +6,11 @@ import logging
import aiohttp
from defusedxml import ElementTree
from netdisco import util
from homeassistant.core import HomeAssistant, callback
from .util import etree_to_dict
_LOGGER = logging.getLogger(__name__)
@ -64,7 +65,5 @@ class DescriptionManager:
_LOGGER.debug("Error parsing %s: %s", xml_location, err)
return None
parsed: dict[str, str] = (
util.etree_to_dict(tree).get("root", {}).get("device", {})
)
return parsed
root = etree_to_dict(tree).get("root") or {}
return root.get("device") or {}

View File

@ -0,0 +1,42 @@
"""Util functions used by SSDP."""
from __future__ import annotations
from collections import defaultdict
from typing import Any
from defusedxml import ElementTree
# Adapted from http://stackoverflow.com/a/10077069
# to follow the XML to JSON spec
# https://www.xml.com/pub/a/2006/05/31/converting-between-xml-and-json.html
def etree_to_dict(tree: ElementTree) -> dict[str, dict[str, Any] | None]:
"""Convert an ETree object to a dict."""
# strip namespace
tag_name = tree.tag[tree.tag.find("}") + 1 :]
tree_dict: dict[str, dict[str, Any] | None] = {
tag_name: {} if tree.attrib else None
}
children = list(tree)
if children:
child_dict: dict[str, list] = defaultdict(list)
for child in map(etree_to_dict, children):
for k, val in child.items():
child_dict[k].append(val)
tree_dict = {
tag_name: {k: v[0] if len(v) == 1 else v for k, v in child_dict.items()}
}
dict_meta = tree_dict[tag_name]
if tree.attrib:
assert dict_meta is not None
dict_meta.update(("@" + k, v) for k, v in tree.attrib.items())
if tree.text:
text = tree.text.strip()
if children or tree.attrib:
if text:
assert dict_meta is not None
dict_meta["#text"] = text
else:
tree_dict[tag_name] = text
return tree_dict