Compare commits
2 commits
d3f5bdaac6
...
5706443217
Author | SHA1 | Date | |
---|---|---|---|
Midgard | 5706443217 | ||
Midgard | 9f5847088c |
28
tests.py
28
tests.py
|
@ -1,6 +1,5 @@
|
||||||
from trainmap_backup import \
|
from trainmap_backup import \
|
||||||
camel_to_snake, transform_dict, RETAIN_KEY, RETAIN_VALUE, DISCARD, \
|
camel_to_snake, transform_dict, VERBATIM_KEY, VERBATIM_VALUE, DISCARD
|
||||||
JsonRoundingFloat, JsonLonLatCoord, json_encode
|
|
||||||
|
|
||||||
|
|
||||||
def test_camel_to_snake():
|
def test_camel_to_snake():
|
||||||
|
@ -16,9 +15,9 @@ def test_transform_dict():
|
||||||
assert transform_dict(
|
assert transform_dict(
|
||||||
{
|
{
|
||||||
"discard": DISCARD,
|
"discard": DISCARD,
|
||||||
"otherkey": ("newkey", RETAIN_VALUE),
|
"otherkey": ("newkey", VERBATIM_VALUE),
|
||||||
"uppervalue": (RETAIN_KEY, str.upper),
|
"uppervalue": (VERBATIM_KEY, str.upper),
|
||||||
"retainboth": (RETAIN_KEY, RETAIN_VALUE)
|
"retainboth": (VERBATIM_KEY, VERBATIM_VALUE)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"discard": True,
|
"discard": True,
|
||||||
|
@ -33,22 +32,3 @@ def test_transform_dict():
|
||||||
"uppervalue": "VALUE",
|
"uppervalue": "VALUE",
|
||||||
"retainboth": "value",
|
"retainboth": "value",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_JsonRoundingFloat():
|
|
||||||
assert str(JsonRoundingFloat(1.1234567890123456789012345678901234567890, 2)) == "1.12"
|
|
||||||
assert str(JsonRoundingFloat(1.1234567890123456789012345678901234567890, 3)) == "1.123"
|
|
||||||
assert str(JsonRoundingFloat(1.1, 3)) == "1.1"
|
|
||||||
|
|
||||||
|
|
||||||
def test_JsonLonLatCoord():
|
|
||||||
assert str(JsonLonLatCoord(1.1234567890123456789012345678901234567890, 50.1234)) == \
|
|
||||||
"[1.123457, 50.1234]"
|
|
||||||
|
|
||||||
|
|
||||||
def test_json_encode():
|
|
||||||
assert json_encode(JsonLonLatCoord(1, 2)) == "[1, 2]"
|
|
||||||
assert json_encode([
|
|
||||||
JsonLonLatCoord(1, 2),
|
|
||||||
JsonLonLatCoord(3, 4),
|
|
||||||
]) == "[[1, 2], [3, 4]]"
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
from dataclasses import dataclass
|
|
||||||
import re
|
import re
|
||||||
import json
|
import json
|
||||||
import socketio
|
import socketio
|
||||||
|
@ -8,30 +7,8 @@ import socketio
|
||||||
WS_URL = "wss://trainmap.belgiantrain.be/socket.io/"
|
WS_URL = "wss://trainmap.belgiantrain.be/socket.io/"
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
class VERBATIM_KEY: pass
|
||||||
class JsonLonLatCoord:
|
class VERBATIM_VALUE: pass
|
||||||
lon: float
|
|
||||||
lat: float
|
|
||||||
def __repr__(self):
|
|
||||||
return str(self.__to_json__())
|
|
||||||
def __to_json__(self):
|
|
||||||
# return f"[{self.lon:.6f}, {self.lat:.6f}]"
|
|
||||||
return [round(self.lon, 6), round(self.lat, 6)]
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class JsonRoundingFloat:
|
|
||||||
value: float
|
|
||||||
decimals: int
|
|
||||||
def __repr__(self):
|
|
||||||
return str(self.__to_json__())
|
|
||||||
def __to_json__(self):
|
|
||||||
# return f"{{0:.{self.decimals}f}}".format(self.value)
|
|
||||||
return round(self.value, self.decimals)
|
|
||||||
|
|
||||||
|
|
||||||
class RETAIN_KEY: pass
|
|
||||||
class RETAIN_VALUE: pass
|
|
||||||
class DISCARD: pass
|
class DISCARD: pass
|
||||||
def transform_dict(specification: dict, d: dict):
|
def transform_dict(specification: dict, d: dict):
|
||||||
"""
|
"""
|
||||||
|
@ -40,18 +17,18 @@ def transform_dict(specification: dict, d: dict):
|
||||||
- keys that should be discarded: DISCARD
|
- keys that should be discarded: DISCARD
|
||||||
- keys whose key and value should be retained verbatim: not present
|
- keys whose key and value should be retained verbatim: not present
|
||||||
- keys whose key and/or value should be transformed, with None denoting no change: tuple of
|
- keys whose key and/or value should be transformed, with None denoting no change: tuple of
|
||||||
(str, function), or any of those two RETAIN_KEY or RETAIN_VALUE respectively
|
(str, function), or any of those two VERBATIM_KEY or VERBATIM_VALUE respectively
|
||||||
|
|
||||||
{
|
{
|
||||||
"""
|
"""
|
||||||
return {
|
return {
|
||||||
(
|
(
|
||||||
specification[k][0]
|
specification[k][0]
|
||||||
if specification.get(k) not in (None, DISCARD) and specification[k][0] is not RETAIN_KEY
|
if specification.get(k) not in (None, DISCARD) and specification[k][0] is not VERBATIM_KEY
|
||||||
else k
|
else k
|
||||||
): (
|
): (
|
||||||
specification[k][1](v)
|
specification[k][1](v)
|
||||||
if specification.get(k) not in (None, DISCARD) and specification[k][1] is not RETAIN_VALUE
|
if specification.get(k) not in (None, DISCARD) and specification[k][1] is not VERBATIM_VALUE
|
||||||
else v
|
else v
|
||||||
)
|
)
|
||||||
for k, v in d.items()
|
for k, v in d.items()
|
||||||
|
@ -84,17 +61,17 @@ def filtered_data(data):
|
||||||
trip["trip_short_name"]: transform_dict({
|
trip["trip_short_name"]: transform_dict({
|
||||||
"trip_id": DISCARD,
|
"trip_id": DISCARD,
|
||||||
"trip_short_name": DISCARD,
|
"trip_short_name": DISCARD,
|
||||||
"position": (RETAIN_KEY, lambda l: (
|
"position": (VERBATIM_KEY, lambda p: (
|
||||||
JsonLonLatCoord(*l)
|
[round(p[0], 6), round(p[1], 6)]
|
||||||
if isinstance(l, list) else l
|
if isinstance(p, list) else p
|
||||||
)),
|
)),
|
||||||
"current_traveled_distance": (RETAIN_KEY, lambda x: (
|
"current_traveled_distance": (VERBATIM_KEY, lambda x: (
|
||||||
JsonRoundingFloat(x, 1)
|
round(x, 1)
|
||||||
if isinstance(x, float) else x
|
if isinstance(x, float) else x
|
||||||
)),
|
)),
|
||||||
"fromstationdistance": ("from_station_distance", RETAIN_VALUE),
|
"fromstationdistance": ("from_station_distance", VERBATIM_VALUE),
|
||||||
"nextstationdistance": ("next_station_distance", RETAIN_VALUE),
|
"nextstationdistance": ("next_station_distance", VERBATIM_VALUE),
|
||||||
"trip_headsign": (RETAIN_KEY, lambda x: transform_dict({
|
"trip_headsign": (VERBATIM_KEY, lambda x: transform_dict({
|
||||||
"default": DISCARD,
|
"default": DISCARD,
|
||||||
"en": DISCARD,
|
"en": DISCARD,
|
||||||
"de": DISCARD,
|
"de": DISCARD,
|
||||||
|
@ -105,20 +82,8 @@ def filtered_data(data):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class JsonEncoder(json.JSONEncoder):
|
|
||||||
def default(self, o):
|
|
||||||
if hasattr(o, "__to_json__"):
|
|
||||||
return o.__to_json__()
|
|
||||||
else:
|
|
||||||
return super().default(o)
|
|
||||||
|
|
||||||
|
|
||||||
def json_encode(data, *args, **kwargs):
|
|
||||||
return json.dumps(data, *args, cls=JsonEncoder, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def emit(data):
|
def emit(data):
|
||||||
print(json_encode(filtered_data(data), ensure_ascii=False))
|
print(json.dumps(filtered_data(data), ensure_ascii=False))
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
Loading…
Reference in a new issue