Beispiel #1
0
 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