File: parser.py

package info (click to toggle)
python-osmapi 5.0.0%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 848 kB
  • sloc: python: 4,113; xml: 1,599; makefile: 46; sh: 14
file content (122 lines) | stat: -rw-r--r-- 3,904 bytes parent folder | download
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