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/__init__.py
homeassistant/components/squeezebox/browse_media.py homeassistant/components/squeezebox/browse_media.py
homeassistant/components/squeezebox/media_player.py homeassistant/components/squeezebox/media_player.py
homeassistant/components/ssdp/util.py
homeassistant/components/starline/* homeassistant/components/starline/*
homeassistant/components/starlingbank/sensor.py homeassistant/components/starlingbank/sensor.py
homeassistant/components/steam_online/sensor.py homeassistant/components/steam_online/sensor.py

View File

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

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