Exemple #1
0
    def stops(self, route):
        params = {'command': 'routeConfig', 'a': route.agency.get_id(),
                  'r': route.get_id()}

        resp = self.session.get(self.url, params=params)

        data = parse(resp.content)['body']['route']
        stops = {}
        for stop in data['stop']:
            tag = stop['@tag']
            code = stop.get('@stopId', None)
            id = Stop.create_id(route.agency.id, tag)
            stop = Stop(agency=route.agency, id=id,
                        name=stop['@title'], code=code, lat=stop['@lat'],
                        lon=stop['@lon'])
            stops[stop.id] = stop
        directions = []
        ds = data['direction']
        if isinstance(ds, OrderedDict):
            # there's only one direction, xmltodict doesn't return an array
            ds = [ds]
        for direction in ds:
            if direction['@useForUI'] != 'true':
                continue
            stop_ids = [Stop.create_id(route.agency.id, stop['@tag'])
                        for stop in direction['stop']]
            id = Direction.create_id(route.id, direction['@tag'])
            direction = Direction(route=route, id=id, name=direction['@title'])
            direction.stop_ids = stop_ids
            directions.append(direction)

        return (directions, stops)
Exemple #2
0
    def _route_info(self, route, number):
        url = '{0}{1}'.format(Bart.url, 'route.aspx')
        params = dict(Bart.params)
        params['cmd'] = 'routeinfo'
        params['route'] = number

        resp = self.session.get(url, params=params)

        data = parse(resp.content)['root']['routes']['route']
        # list of stations this route passes
        abbrs = data['config']['station']
        # will block if we don't already have an answer
        all_stops = self._all_stops()
        stop_ids = []
        stops = {}
        # dest
        dest = abbrs[-1]
        for abbr in abbrs:
            # copy over the relevant stations
            stop = all_stops[abbr]
            stop = Stop(agency=route.agency,
                        id=Stop.create_id(route.agency.id,
                                          '{0}-{1}'.format(abbr, dest)),
                        name=stop.name,
                        lat=stop.lat,
                        lon=stop.lon,
                        type=stop.type)
            stop_ids.append(stop.id)
            stops[stop.id] = stop
        direction = Direction(route=route,
                              id=Direction.create_id(route.id, number),
                              name=data['name'].split(' - ')[1])
        direction.stop_ids = stop_ids

        return (direction, stops)
Exemple #3
0
    def stops(self, route):
        params = {"command": "routeConfig", "a": route.agency.get_id(), "r": route.get_id()}

        resp = self.session.get(self.url, params=params)

        data = parse(resp.content)["body"]["route"]
        stops = {}
        for stop in data["stop"]:
            tag = stop["@tag"]
            code = stop.get("@stopId", None)
            id = Stop.create_id(route.agency.id, tag)
            stop = Stop(agency=route.agency, id=id, name=stop["@title"], code=code, lat=stop["@lat"], lon=stop["@lon"])
            stops[stop.id] = stop
        directions = []
        ds = data["direction"]
        if isinstance(ds, OrderedDict):
            # there's only one direction, xmltodict doesn't return an array
            ds = [ds]
        for direction in ds:
            if direction["@useForUI"] != "true":
                continue
            stop_ids = [Stop.create_id(route.agency.id, stop["@tag"]) for stop in direction["stop"]]
            id = Direction.create_id(route.id, direction["@tag"])
            direction = Direction(route=route, id=id, name=direction["@title"])
            direction.stop_ids = stop_ids
            directions.append(direction)

        return (directions, stops)
Exemple #4
0
    def stops(self, route):
        'returns a tuple, with a list of directions, and a map of stops'
        url = '{0}/stops-for-route/{1}.json' \
            .format(self.url, self._decode_id(route.get_id()))
        params = dict(self.params)
        params['version'] = 2

        resp = self.session.get(url, params=params)

        # TODO: stops can be shared by agencies, but the first one to see it
        # will get it here :(
        data = resp.json()['data']
        stops = {}
        for stop in data['references']['stops']:
            id = self._encode_id(Stop.create_id(route.agency.id, stop['id']))
            stop = Stop(agency=route.agency,
                        id=id,
                        name=stop['name'], lat=stop['lat'],
                        lon=stop['lon'], code=stop['code'],
                        type=stop_types[int(stop['locationType'])])
            stops[stop.id] = stop
        directions = []
        for stop_groupings in data['entry']['stopGroupings']:
            for stop_group in stop_groupings['stopGroups']:
                id = self._encode_id(Direction.create_id(route.id,
                                                         stop_group['id']))
                direction = Direction(route=route, id=id,
                                      name=stop_group['name']['name'])
                direction.stop_ids = \
                    [self._encode_id(Stop.create_id(route.agency.id, sid))
                     for sid in stop_group['stopIds']]
                directions.append(direction)

        return (directions, stops)
Exemple #5
0
    def _all_stops(self):
        if self._cached_all_stops:
            return self._cached_all_stops

        url = '{0}{1}'.format(Bart.url, 'stn.aspx')
        params = dict(Bart.params)
        params['cmd'] = 'stns'

        resp = self.session.get(url, params=params)

        data = parse(resp.content)
        stops = {}
        for station in data['root']['stations']['station']:
            # don't care about having "real" ids here
            stop = Stop(agency=self.agency,
                        id=station['abbr'],
                        name=station['name'],
                        lat=station['gtfs_latitude'],
                        lon=station['gtfs_longitude'],
                        type=stop_types[1])
            stops[stop.id] = stop

        self._cached_all_stops = stops

        return stops
Exemple #6
0
    def retrieve(self, request, region, agency, pk):
        try:
            stop = Stop.objects.select_related('agency') \
                .get(pk=Stop.create_id(Agency.create_id(region, agency), pk))
        except Stop.DoesNotExist:
            raise Http404('No Route matches the given query.')
        agency = stop.agency
        arrivals = get_provider(stop.agency).arrivals(stop)
        # odd if we have a mixture of units, but we currently don't so...
        # sort the arrivals
        arrivals.sort(key=attrgetter('away'))
        # never return more than 15 arrivals, limit before the prefetch to
        # avoid extra work
        arrivals = arrivals[:15]
        prefetch_related_objects(arrivals, ['direction__route__directions'])

        routes = {}
        for arrival in arrivals:
            if arrival.direction:
                route = arrival.direction.route
                routes[route.id] = route

        self.object = StopAdapter(stop, arrivals=arrivals,
                                  routes=routes.values())
        serializer = self.get_serializer(self.object)
        return Response(serializer.data)
Exemple #7
0
    def _route_info(self, route, number):
        url = '{0}{1}'.format(Bart.url, 'route.aspx')
        params = dict(Bart.params)
        params['cmd'] = 'routeinfo'
        params['route'] = number

        resp = self.session.get(url, params=params)

        data = parse(resp.content)['root']['routes']['route']
        # list of stations this route passes
        abbrs = data['config']['station']
        # will block if we don't already have an answer
        all_stops = self._all_stops()
        stop_ids = []
        stops = {}
        # dest
        dest = abbrs[-1]
        for abbr in abbrs:
            # copy over the relevant stations
            stop = all_stops[abbr]
            stop = Stop(agency=route.agency,
                        id=Stop.create_id(route.agency.id,
                                          '{0}-{1}'.format(abbr, dest)),
                        name=stop.name, lat=stop.lat, lon=stop.lon,
                        type=stop.type)
            stop_ids.append(stop.id)
            stops[stop.id] = stop
        direction = Direction(route=route,
                              id=Direction.create_id(route.id, number),
                              name=data['name'].split(' - ')[1])
        direction.stop_ids = stop_ids

        return (direction, stops)
Exemple #8
0
    def stops(self, route):
        directions = defaultdict(list)
        trip_names = defaultdict(list)
        rid = route.get_id()

        directory = join('data', route.agency.id)

        trip_stops = self._trip_stops(directory)
        direction_stops = defaultdict(list)
        trips = filter(lambda c: rid == c['route_id'], self._trips(directory))
        for i, t in enumerate(trips):
            tid = t['direction_id']
            direction_stops[tid].append(trip_stops[t['trip_id']])
            trip_names[tid].append(t['trip_headsign'])

        all_stops = self._stops(directory)
        directions = []
        stops = {}
        for d, ts in direction_stops.items():
            did = Direction.create_id(route.id, str(d))
            # TODO: pick the most common name?
            direction = Direction(route=route, id=did, name=trip_names[d][0])

            # pick the largest set of stops, hopefully that'll cover everything
            stop_ids = []
            for sid in max(ts, key=len):
                stop = all_stops[sid]
                sid = Stop.create_id(route.agency.id, sid)
                stop_type = stop.get('location_type', None)
                if stop_type:
                    stop_type = stop_types[int(stop_type)]
                stop = Stop(agency=route.agency,
                            id=sid,
                            name=stop['stop_name'],
                            lat=stop['stop_lat'],
                            lon=stop['stop_lon'],
                            type=stop_type,
                            code=stop.get('code', None))

                stop_ids.append(stop.id)
                stops[stop.id] = stop

            direction.stop_ids = stop_ids
            directions.append(direction)

        return (directions, stops)
Exemple #9
0
    def stops(self, route):
        directions = defaultdict(list)
        trip_names = defaultdict(list)
        rid = route.get_id()

        directory = join('data', route.agency.id)

        trip_stops = self._trip_stops(directory)
        direction_stops = defaultdict(list)
        trips = filter(lambda c: rid == c['route_id'], self._trips(directory))
        for i, t in enumerate(trips):
            tid = t['direction_id']
            direction_stops[tid].append(trip_stops[t['trip_id']])
            trip_names[tid].append(t['trip_headsign'])

        all_stops = self._stops(directory)
        directions = []
        stops = {}
        for d, ts in direction_stops.items():
            did = Direction.create_id(route.id, str(d))
            # TODO: pick the most common name?
            direction = Direction(route=route, id=did,
                                  name=trip_names[d][0])

            # pick the largest set of stops, hopefully that'll cover everything
            stop_ids = []
            for sid in max(ts, key=len):
                stop = all_stops[sid]
                sid = Stop.create_id(route.agency.id, sid)
                stop_type = stop.get('location_type', None)
                if stop_type:
                    stop_type = stop_types[int(stop_type)]
                stop = Stop(agency=route.agency, id=sid,
                            name=stop['stop_name'], lat=stop['stop_lat'],
                            lon=stop['stop_lon'], type=stop_type,
                            code=stop.get('code', None))

                stop_ids.append(stop.id)
                stops[stop.id] = stop

            direction.stop_ids = stop_ids
            directions.append(direction)

        return (directions, stops)
Exemple #10
0
    def stops(self, route):
        'returns a tuple, with a list of directions, and a map of stops'
        url = '{0}/stops-for-route/{1}.json' \
            .format(self.url, self._decode_id(route.get_id()))
        params = dict(self.params)
        params['version'] = 2

        resp = self.session.get(url, params=params)

        # TODO: stops can be shared by agencies, but the first one to see it
        # will get it here :(
        data = resp.json()['data']
        stops = {}
        for stop in data['references']['stops']:
            id = self._encode_id(Stop.create_id(route.agency.id, stop['id']))
            stop = Stop(agency=route.agency,
                        id=id,
                        name=stop['name'],
                        lat=stop['lat'],
                        lon=stop['lon'],
                        code=stop['code'],
                        type=stop_types[int(stop['locationType'])])
            stops[stop.id] = stop
        directions = []
        for stop_groupings in data['entry']['stopGroupings']:
            for stop_group in stop_groupings['stopGroups']:
                id = self._encode_id(
                    Direction.create_id(route.id, stop_group['id']))
                direction = Direction(route=route,
                                      id=id,
                                      name=stop_group['name']['name'])
                direction.stop_ids = \
                    [self._encode_id(Stop.create_id(route.agency.id, sid))
                     for sid in stop_group['stopIds']]
                directions.append(direction)

        return (directions, stops)
Exemple #11
0
    def retrieve(self, request, region, agency, route, pk):
        try:
            stop = Stop.objects.select_related('agency', 'agency__region') \
                .get(pk=Stop.create_id(Agency.create_id(region, agency), pk))
        except Stop.DoesNotExist:
            raise Http404('No Route matches the given query.')
        agency = stop.agency

        route = get_object_or_404(Route, pk=Route.create_id(agency.id, route))
        arrivals = get_provider(stop.agency).arrivals(stop, route)

        self.object = StopAdapter(stop, arrivals=arrivals, route=route)

        serializer = self.get_serializer(self.object)
        return Response(serializer.data)
Exemple #12
0
    def _stop_arrivals(self, stop):
        abbr = stop.get_id().split('-')[0]

        url = '{0}{1}'.format(self.url, 'etd.aspx')
        params = dict(self.params)
        params['cmd'] = 'etd'
        # the station we're interested in
        params['orig'] = abbr
        resp = requests.get(url, params=params)

        arrivals = []
        etds = parse(resp.content)['root']['station']['etd']
        if isinstance(etds, OrderedDict):
            etds = [etds]
        for destination in etds:
            # where this train is stopping
            abbr = destination['abbreviation']
            estimates = destination['estimate']
            if isinstance(estimates, OrderedDict):
                estimates = [estimates]
            for arrival in estimates:
                try:
                    away = int(arrival['minutes']) * 60
                except ValueError:
                    continue
                # the color tells us which route it is and in combination with
                # the direction tells we know the last station on the line
                color = arrival['hexcolor']
                dest, dir_id = \
                    self.color_bearing_lookup[color][arrival['direction']]
                dest_id = Stop.create_id(stop.agency_id,
                                         '{0}-{1}'.format(abbr, dest))
                arrivals.append(
                    Arrival(stop=stop,
                            away=away,
                            direction_id=dir_id,
                            destination_id=dest_id))

        return arrivals
Exemple #13
0
    def _stop_arrivals(self, stop):
        abbr = stop.get_id().split('-')[0]

        url = '{0}{1}'.format(self.url, 'etd.aspx')
        params = dict(self.params)
        params['cmd'] = 'etd'
        # the station we're interested in
        params['orig'] = abbr
        resp = requests.get(url, params=params)

        arrivals = []
        etds = parse(resp.content)['root']['station']['etd']
        if isinstance(etds, OrderedDict):
            etds = [etds]
        for destination in etds:
            # where this train is stopping
            abbr = destination['abbreviation']
            estimates = destination['estimate']
            if isinstance(estimates, OrderedDict):
                estimates = [estimates]
            for arrival in estimates:
                try:
                    away = int(arrival['minutes']) * 60
                except ValueError:
                    continue
                # the color tells us which route it is and in combination with
                # the direction tells we know the last station on the line
                color = arrival['hexcolor']
                dest, dir_id = \
                    self.color_bearing_lookup[color][arrival['direction']]
                dest_id = Stop.create_id(stop.agency_id,
                                         '{0}-{1}'.format(abbr, dest))
                arrivals.append(Arrival(stop=stop, away=away,
                                        direction_id=dir_id,
                                        destination_id=dest_id))

        return arrivals
Exemple #14
0
    def _route_arrivals(self, stop, route):
        orig, dest = stop.get_id().split('-')

        url = '{0}{1}'.format(self.url, 'etd.aspx')
        params = dict(self.params)
        params['cmd'] = 'etd'
        params['orig'] = orig
        resp = requests.get(url, params=params)

        # we're looking for trains heading in which direction
        color, bearing = self.route_dest_to_bearing[route.id][dest]

        arrivals = []
        etds = parse(resp.content)['root']['station']['etd']
        if isinstance(etds, OrderedDict):
            etds = [etds]
        for direction in etds:
            dest_id = \
                Stop.create_id(stop.agency.id,
                               '{0}-{1}'.format(direction['abbreviation'],
                                                dest))
            estimates = direction['estimate']
            if isinstance(estimates, OrderedDict):
                estimates = [estimates]
            for arrival in estimates:
                # TODO: we should be looking for the right route
                if arrival['hexcolor'] == color and \
                   arrival['direction'] == bearing:
                    try:
                        away = int(arrival['minutes']) * 60
                    except ValueError:
                        continue
                    arrivals.append(
                        Arrival(stop=stop, away=away, destination_id=dest_id))

        return arrivals
Exemple #15
0
    def _route_arrivals(self, stop, route):
        orig, dest = stop.get_id().split('-')

        url = '{0}{1}'.format(self.url, 'etd.aspx')
        params = dict(self.params)
        params['cmd'] = 'etd'
        params['orig'] = orig
        resp = requests.get(url, params=params)

        # we're looking for trains heading in which direction
        color, bearing = self.route_dest_to_bearing[route.id][dest]

        arrivals = []
        etds = parse(resp.content)['root']['station']['etd']
        if isinstance(etds, OrderedDict):
            etds = [etds]
        for direction in etds:
            dest_id = \
                Stop.create_id(stop.agency.id,
                               '{0}-{1}'.format(direction['abbreviation'],
                                                dest))
            estimates = direction['estimate']
            if isinstance(estimates, OrderedDict):
                estimates = [estimates]
            for arrival in estimates:
                # TODO: we should be looking for the right route
                if arrival['hexcolor'] == color and \
                   arrival['direction'] == bearing:
                    try:
                        away = int(arrival['minutes']) * 60
                    except ValueError:
                        continue
                    arrivals.append(Arrival(stop=stop, away=away,
                                            destination_id=dest_id))

        return arrivals