osmapi.parser

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

Parse osm data.

Returns list of dict:

#!python
{
    type: node|way|relation,
    data: {}
}
def parse_osc(data: bytes) -> list[dict[str, typing.Any]]:
42def parse_osc(data: bytes) -> list[dict[str, Any]]:
43    """
44    Parse osc data.
45
46    Returns list of dict:
47
48        #!python
49        {
50            type: node|way|relation,
51            action: create|delete|modify,
52            data: {}
53        }
54    """
55    try:
56        data_parsed = xml.dom.minidom.parseString(data)
57        data_parsed = data_parsed.getElementsByTagName("osmChange")[0]  # type: ignore[assignment]  # noqa: E501
58    except (xml.parsers.expat.ExpatError, IndexError) as e:
59        raise errors.XmlResponseInvalidError(
60            f"The XML response from the OSM API is invalid: {e!r}"
61        ) from e
62
63    result: list[dict[str, Any]] = []
64    for action in data_parsed.childNodes:
65        if action.nodeName == "#text":
66            continue
67        for elem in action.childNodes:
68            if elem.nodeName == "node":
69                result.append(
70                    {
71                        "action": action.nodeName,
72                        "type": elem.nodeName,
73                        "data": dom.dom_parse_node(elem),  # type: ignore[arg-type]
74                    }
75                )
76            elif elem.nodeName == "way":
77                result.append(
78                    {
79                        "action": action.nodeName,
80                        "type": elem.nodeName,
81                        "data": dom.dom_parse_way(elem),  # type: ignore[arg-type]
82                    }
83                )
84            elif elem.nodeName == "relation":
85                result.append(
86                    {
87                        "action": action.nodeName,
88                        "type": elem.nodeName,
89                        "data": dom.dom_parse_relation(elem),  # type: ignore[arg-type]
90                    }
91                )
92    return result

Parse osc data.

Returns list of dict:

#!python
{
    type: node|way|relation,
    action: create|delete|modify,
    data: {}
}
def parse_notes(data: bytes) -> list[dict[str, typing.Any]]:
 95def parse_notes(data: bytes) -> list[dict[str, Any]]:
 96    """
 97    Parse notes data.
 98
 99    Returns a list of dict:
100
101        #!python
102        [
103            {
104                'id': integer,
105                'action': opened|commented|closed,
106                'status': open|closed
107                'date_created': creation date
108                'date_closed': closing data|None
109                'uid': User ID|None
110                'user': User name|None
111                'comments': {}
112            },
113            { ... }
114        ]
115    """
116    noteElements = cast(
117        list[Element], dom.OsmResponseToDom(data, tag="note", allow_empty=True)
118    )
119    result: list[dict[str, Any]] = []
120    for noteElement in noteElements:
121        note = dom.dom_parse_note(noteElement)
122        result.append(note)
123    return result

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': {}
    },
    { ... }
]