1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
|
import xml.dom.minidom
import xml.parsers.expat
from typing import Any, cast
from xml.dom.minidom import Element
from . import errors
from . import dom
def parse_osm(data: bytes) -> list[dict[str, Any]]:
"""
Parse osm data.
Returns list of dict:
#!python
{
type: node|way|relation,
data: {}
}
"""
try:
data_parsed = xml.dom.minidom.parseString(data)
data_parsed = data_parsed.getElementsByTagName("osm")[0] # type: ignore[assignment] # noqa: E501
except (xml.parsers.expat.ExpatError, IndexError) as e:
raise errors.XmlResponseInvalidError(
f"The XML response from the OSM API is invalid: {e!r}"
) from e
result: list[dict[str, Any]] = []
for elem in data_parsed.childNodes:
if elem.nodeName == "node":
result.append({"type": elem.nodeName, "data": dom.dom_parse_node(elem)}) # type: ignore[arg-type] # noqa: E501
elif elem.nodeName == "way":
result.append({"type": elem.nodeName, "data": dom.dom_parse_way(elem)}) # type: ignore[arg-type] # noqa: E501
elif elem.nodeName == "relation":
result.append({"type": elem.nodeName, "data": dom.dom_parse_relation(elem)}) # type: ignore[arg-type] # noqa: E501
return result
def parse_osc(data: bytes) -> list[dict[str, Any]]:
"""
Parse osc data.
Returns list of dict:
#!python
{
type: node|way|relation,
action: create|delete|modify,
data: {}
}
"""
try:
data_parsed = xml.dom.minidom.parseString(data)
data_parsed = data_parsed.getElementsByTagName("osmChange")[0] # type: ignore[assignment] # noqa: E501
except (xml.parsers.expat.ExpatError, IndexError) as e:
raise errors.XmlResponseInvalidError(
f"The XML response from the OSM API is invalid: {e!r}"
) from e
result: list[dict[str, Any]] = []
for action in data_parsed.childNodes:
if action.nodeName == "#text":
continue
for elem in action.childNodes:
if elem.nodeName == "node":
result.append(
{
"action": action.nodeName,
"type": elem.nodeName,
"data": dom.dom_parse_node(elem), # type: ignore[arg-type]
}
)
elif elem.nodeName == "way":
result.append(
{
"action": action.nodeName,
"type": elem.nodeName,
"data": dom.dom_parse_way(elem), # type: ignore[arg-type]
}
)
elif elem.nodeName == "relation":
result.append(
{
"action": action.nodeName,
"type": elem.nodeName,
"data": dom.dom_parse_relation(elem), # type: ignore[arg-type]
}
)
return result
def parse_notes(data: bytes) -> list[dict[str, Any]]:
"""
Parse notes data.
Returns a list of dict:
#!python
[
{
'id': integer,
'action': opened|commented|closed,
'status': open|closed
'date_created': creation date
'date_closed': closing data|None
'uid': User ID|None
'user': User name|None
'comments': {}
},
{ ... }
]
"""
noteElements = cast(
list[Element], dom.OsmResponseToDom(data, tag="note", allow_empty=True)
)
result: list[dict[str, Any]] = []
for noteElement in noteElements:
note = dom.dom_parse_note(noteElement)
result.append(note)
return result
|