-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
TRAN-7600: Add translator for MNMT (#60)
* TRAN-7600: add translator for mnmt * TRAN-7600: update registry * TRAN-7600: cast stop_id * TRAN-7600: set arrival times * TRAN-7600: stop name * TRAN-7600: remove seconds from time parser * TRAN-7600: flip condition * TRAN-7600: timezone * TRAN-7600: create trip_update with timezone * TRAN-7600: use actual field * TRAN-7600: add arrival time * TRAN-7600: append terminal to route short name * TRAN-7600: add tests * TRAN-7600: newline
- Loading branch information
Showing
5 changed files
with
230 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import json | ||
|
||
import pendulum | ||
|
||
from gtfs_realtime_translators.factories import TripUpdate, FeedMessage | ||
|
||
|
||
class MnmtGtfsRealtimeTranslator: | ||
TIMEZONE = 'America/Chicago' | ||
|
||
def __call__(self, data): | ||
json_data = json.loads(data) | ||
|
||
stops_list = json_data.get('stops') | ||
departures_list = json_data.get('departures') | ||
|
||
entities = [] | ||
if stops_list and departures_list: | ||
entities = self.__make_trip_updates(stops_list, departures_list) | ||
|
||
return FeedMessage.create(entities=entities) | ||
|
||
@classmethod | ||
def __make_trip_updates(cls, stops_list, departures_list): | ||
trip_updates = [] | ||
stop_name = stops_list[0].get("description") | ||
|
||
for index, departure in enumerate(departures_list): | ||
entity_id = str(index + 1) | ||
|
||
trip_id = departure.get('trip_id') | ||
|
||
stop_id = departure.get('stop_id') | ||
if stop_id: | ||
stop_id = str(stop_id) | ||
|
||
headsign = departure.get('description') | ||
route_id = departure.get('route_id') | ||
direction_id = departure.get('direction_id') | ||
|
||
departure_time, scheduled_departure_time = None, None | ||
arrival_time, scheduled_arrival_time = None, None | ||
if cls.__is_realtime_departure(departure): | ||
departure_time = departure.get('departure_time') | ||
arrival_time = departure_time | ||
else: | ||
scheduled_departure_time = departure.get('departure_time') | ||
scheduled_arrival_time = scheduled_departure_time | ||
|
||
route_short_name = cls.__get_route_short_name(departure) | ||
|
||
trip_update = TripUpdate.create(entity_id=entity_id, | ||
departure_time=departure_time, | ||
arrival_time=arrival_time, | ||
scheduled_departure_time=scheduled_departure_time, | ||
scheduled_arrival_time=scheduled_arrival_time, | ||
trip_id=trip_id, | ||
route_id=route_id, | ||
route_short_name=route_short_name, | ||
stop_id=stop_id, | ||
stop_name=stop_name, | ||
headsign=headsign, | ||
direction_id=direction_id, | ||
agency_timezone=cls.TIMEZONE | ||
) | ||
|
||
trip_updates.append(trip_update) | ||
|
||
return trip_updates | ||
|
||
@classmethod | ||
def __is_realtime_departure(cls, departure): | ||
return departure.get('actual') is True | ||
|
||
@classmethod | ||
def __get_route_short_name(cls, departure): | ||
terminal = departure.get('terminal') | ||
route_short_name = departure.get('route_short_name') | ||
if terminal: | ||
return f'{route_short_name}{terminal}' | ||
return route_short_name |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
{ | ||
"stops": [ | ||
{ | ||
"stop_id": 11191, | ||
"latitude": 45.013401, | ||
"longitude": -93.287947, | ||
"description": "Lyndale Ave N & Lowry Ave N" | ||
} | ||
], | ||
"alerts": [ | ||
{ | ||
"stop_closed": false, | ||
"alert_text": "The following stop is closed for Routes 3, 7 and 22 until further notice: Washington Ave S & Park Ave - Stop #19306 (westbound)" | ||
} | ||
], | ||
"departures": [ | ||
{ | ||
"actual": true, | ||
"trip_id": "24557038-DEC23-MVS-BUS-Weekday-03", | ||
"stop_id": 11191, | ||
"departure_text": "14 Min", | ||
"departure_time": 1702923655, | ||
"description": "Brklyn Ctr Tc / N Lyndale / Via Penn Av", | ||
"route_id": "22", | ||
"route_short_name": "22", | ||
"direction_id": 0, | ||
"direction_text": "NB", | ||
"terminal": "A", | ||
"schedule_relationship": "Scheduled" | ||
}, | ||
{ | ||
"actual": false, | ||
"trip_id": "24557032-DEC23-MVS-BUS-Weekday-03", | ||
"stop_id": 11191, | ||
"departure_text": "12:42", | ||
"departure_time": 1702924920, | ||
"description": "Brklyn Ctr Tc / N Lyndale / Via Humboldt", | ||
"route_id": "22", | ||
"route_short_name": "22", | ||
"direction_id": 0, | ||
"direction_text": "NB", | ||
"schedule_relationship": "Scheduled" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import pytest | ||
|
||
from gtfs_realtime_translators.translators import MnmtGtfsRealtimeTranslator | ||
from gtfs_realtime_translators.bindings import intersection_pb2 as intersection_gtfs_realtime | ||
from gtfs_realtime_translators.factories import FeedMessage | ||
|
||
|
||
@pytest.fixture | ||
def mnmt(): | ||
with open('test/fixtures/mnmt.json') as f: | ||
raw = f.read() | ||
return raw | ||
|
||
|
||
def test_mnmt_realtime_departure(mnmt): | ||
translator = MnmtGtfsRealtimeTranslator() | ||
message = translator(mnmt) | ||
|
||
entity = message.entity[0] | ||
trip_update = entity.trip_update | ||
stop_time_update = trip_update.stop_time_update[0] | ||
|
||
assert message.header.gtfs_realtime_version == FeedMessage.VERSION | ||
assert entity.id == '1' | ||
|
||
assert stop_time_update.departure.time == 1702923655 | ||
assert stop_time_update.arrival.time == 1702923655 | ||
|
||
assert not stop_time_update.Extensions[ | ||
intersection_gtfs_realtime.intersection_stop_time_update].\ | ||
scheduled_arrival.time | ||
assert not stop_time_update.Extensions[ | ||
intersection_gtfs_realtime.intersection_stop_time_update].\ | ||
scheduled_departure.time | ||
|
||
|
||
def test_mnmt_scheduled_departure(mnmt): | ||
translator = MnmtGtfsRealtimeTranslator() | ||
message = translator(mnmt) | ||
|
||
entity = message.entity[1] | ||
trip_update = entity.trip_update | ||
stop_time_update = trip_update.stop_time_update[0] | ||
|
||
assert message.header.gtfs_realtime_version == FeedMessage.VERSION | ||
assert entity.id == '2' | ||
|
||
assert not stop_time_update.departure.time | ||
assert not stop_time_update.arrival.time | ||
|
||
assert stop_time_update.Extensions[ | ||
intersection_gtfs_realtime.intersection_stop_time_update].\ | ||
scheduled_arrival.time == 1702924920 | ||
assert stop_time_update.Extensions[ | ||
intersection_gtfs_realtime.intersection_stop_time_update].\ | ||
scheduled_departure.time == 1702924920 | ||
|
||
|
||
def test_mnmt_route_short_name_with_terminal(mnmt): | ||
translator = MnmtGtfsRealtimeTranslator() | ||
message = translator(mnmt) | ||
|
||
entity = message.entity[0] | ||
trip_update = entity.trip_update | ||
|
||
assert message.header.gtfs_realtime_version == FeedMessage.VERSION | ||
assert entity.id == '1' | ||
|
||
assert trip_update.Extensions[ | ||
intersection_gtfs_realtime.intersection_trip_update].\ | ||
route_short_name == '22A' | ||
|
||
|
||
def test_mnmt_route_short_name_without_terminal(mnmt): | ||
translator = MnmtGtfsRealtimeTranslator() | ||
message = translator(mnmt) | ||
|
||
entity = message.entity[1] | ||
trip_update = entity.trip_update | ||
|
||
assert message.header.gtfs_realtime_version == FeedMessage.VERSION | ||
assert entity.id == '2' | ||
|
||
assert trip_update.Extensions[ | ||
intersection_gtfs_realtime.intersection_trip_update].\ | ||
route_short_name == '22' | ||
|
||
|
||
def test_mnmt_headsign(mnmt): | ||
translator = MnmtGtfsRealtimeTranslator() | ||
message = translator(mnmt) | ||
|
||
entity = message.entity[0] | ||
trip_update = entity.trip_update | ||
|
||
assert message.header.gtfs_realtime_version == FeedMessage.VERSION | ||
assert entity.id == '1' | ||
|
||
assert trip_update.Extensions[ | ||
intersection_gtfs_realtime.intersection_trip_update].headsign \ | ||
== 'Brklyn Ctr Tc / N Lyndale / Via Penn Av' |