def test_dataparsers(self): """ Unit tests for Data parsers objects """ # Check against our test data and make sure we are correctly parsing & fetching the right objects from the data bus_data = parse_bus_data(self.bot.browser.fetch_json(self.bot.urls.BUS_URL % "53410"), '15') self.assertEqual(bus_data[0], Bus("Regent Street", gmt_to_localtime("1831"))) tube_data = parse_tube_data(self.bot.browser.fetch_xml_tree(self.bot.urls.TUBE_URL % ("D", "ECT")), RailStation("Earl's Court"), "D") self.assertEqual(tube_data["Eastbound"][0], TubeTrain("Edgware Road", "Eastbound", "2139", "D", "075")) dlr_data = parse_dlr_data(self.bot.browser.fetch_xml_tree(self.bot.urls.DLR_URL % "pop"), RailStation("Poplar")) self.assertEqual(dlr_data['P1'][0], Train("Beckton", "2107"))
def get_departure_data(self, origin, line_code, must_stop_at=None, direction=None): """ Take a RailStation origin and a string line_code, and get departure data for that station Optional args RailStation must_stop_at and string direction Return a dictionary; keys are slot names (platform for DLR, direction for Tube), values lists of Train objects """ #pylint: disable=W0108 # Check if the station is open and if so (it will throw an exception if not), summon the data self.check_station_is_open(origin) # Circle line is coded H as it shares with the Hammersmith & City if line_code == 'O': line_code = 'H' # DLR and Tube have different APIs and different structures (Tube data contains compass directions, DLR does not) if line_code == 'DLR': dlr_data = self.browser.fetch_xml_tree(self.urls.DLR_URL % origin.code) departures = parse_dlr_data(dlr_data, origin) null_constructor = lambda platform: NullDeparture("from " + platform) else: tube_data = self.browser.fetch_xml_tree(self.urls.TUBE_URL % (line_code, origin.code)) departures = parse_tube_data(tube_data, origin, line_code) null_constructor = lambda direction: NullDeparture(direction) # Turn parsed destination & via station names into canonical versions for this train so we can do lookups & checks for slot in departures: for train in departures[slot]: if train.destination: train.destination = self.get_station_by_station_name(train.get_destination_no_via(), line_code) if train.via: train.via = self.get_station_by_station_name(train.get_via(), line_code) # Deal with any departures filed under "Unknown", slotting them into Eastbound/Westbound if their direction is not known # (By a stroke of luck, all the stations this applies to - North Acton, Edgware Road, Loughton, White City - are on an east/west line) if "Unknown" in departures: for train in departures["Unknown"]: destination_station = self.get_station_by_station_name(train.get_destination_no_via(), line_code) if not destination_station: continue if destination_station.location_easting < origin.location_easting: departures.add_to_slot("Westbound", train) else: departures.add_to_slot("Eastbound", train) del departures["Unknown"] # For any non-empty list of departures, filter out any that terminate here. Note that existing empty lists remain empty and are not deleted does_not_terminate_here = lambda train: train.get_destination_no_via() != origin.name departures.filter(does_not_terminate_here, delete_existing_empty_slots=False) # If we've specified a station to stop at, filter out any that do not stop at that station or are not in its direction # Note that unlike the above, this will turn all existing empty lists into Nones (and thus deletable) as well if must_stop_at: filter_by_stop_at = lambda train: self.geodata.does_train_stop_at(train, origin, must_stop_at) departures.filter(filter_by_stop_at, delete_existing_empty_slots=True) # Else filter by direction - Tubs is already classified by direction, DLR is not direction-aware so must calculate manually elif direction: if line_code == 'DLR': filter_by_direction = lambda train: self.geodata.is_correct_direction(direction, origin, train.destination, line_code) departures.filter(filter_by_direction, delete_existing_empty_slots=True) else: for slot in list(departures): if slot != direction: del departures[slot] departures.cleanup(null_constructor) return departures