Example #1
0
    def add_stop(self, key, props):
        """Add stop to favorite `key`."""
        favorite = self.get(key)
        props = pan.AttrDict(props)
        self.remove_stop(key, props.id)
        favorite.stops.append(pan.AttrDict(id=props.id,
                                           name=props.name,
                                           x=props.x,
                                           y=props.y,
                                           color=props.color))

        self._update_meta(key)
Example #2
0
def find_nearby_stops(x, y):
    """Return a list of stops near given coordinates."""
    # XXX: The API endpoint used by find_stops doesn't require
    # a stopTypes argument, but returns sensibly filtered results.
    # We try to match that, but don't quite succeed.
    params = dict(stopTypes=",".join(STOP_TYPES),
                  radius="500",
                  useStopPointHierarchy="false",
                  categories="none",
                  returnLines="true",
                  lat="{:.6f}".format(y),
                  lon="{:.6f}".format(x))

    url = format_url("/StopPoint", **params)
    result = pan.http.get_json(url)
    result = pan.AttrDict(result)
    return [{
        "color": get_stop_color(stop.modes),
        "description": get_stop_description(stop),
        "id": stop.id,
        "line_summary": get_line_summary(stop),
        "name": stop.commonName,
        "x": float(stop.lon),
        "y": float(stop.lat),
    } for stop in result.stopPoints]
Example #3
0
def find_departures(stops):
    """Return a list of departures from `stops`."""
    stops = ", ".join('"{}"'.format(x) for x in stops)
    body = format_graphql("find_departures", ids=stops)
    url = URL.format(region=REGION)
    result = pan.http.post_json(url, body, headers=HEADERS)
    result = pan.AttrDict(result)

    def departures():
        for stop in result.data.stops:
            for departure in stop.stoptimesWithoutPatterns:
                yield stop, departure

    return pan.util.sorted_departures([{
        "destination":
        parse_headsign(departure.trip.tripHeadsign),
        "line":
        parse_line_name(departure.trip.route),
        "realtime":
        bool(departure.realtime),
        "scheduled_time":
        parse_scheduled_time(departure),
        "stop":
        stop.gtfsId,
        "time":
        parse_time(departure),
        "x":
        float(stop.lon),
        "y":
        float(stop.lat),
    } for stop, departure in departures()])
Example #4
0
def get_line_summary(stop):
    """Return a summary of lines that use `stop`."""
    lines = pan.util.sorted_unique_lines([
        pan.AttrDict({
            "name": parse_line_name(pattern.route),
            "destination": parse_headsign(pattern.headsign),
        }) for pattern in stop.patterns
    ])
    return "\n".join("{} → {}".format(x.name, x.destination)
                     for x in lines[:3])
Example #5
0
 def _split_option(self, option, create=False):
     """Split dotted option to dictionary and option name."""
     root = self
     for section in option.split(".")[:-1]:
         if create and not section in root:
             # Create missing hierarchies.
             root[section] = pan.AttrDict()
         root = root[section]
     name = option.split(".")[-1]
     return root, name
Example #6
0
    def add(self, name):
        """Add `name` as a new favorite and return key."""
        key = str(uuid.uuid4())
        self._favorites.append(pan.AttrDict(key=key,
                                            provider=pan.conf.provider,
                                            name=name,
                                            stops=[],
                                            ignore_lines=[]))

        self._update_meta(key)
        return key
Example #7
0
def list_networks():
    """Return a list of supported city bike networks."""
    url = "https://api.citybik.es/v2/networks?fields=id,location,name"
    networks = pan.http.get_json(url)
    networks = pan.AttrDict(networks)
    return [
        dict(
            city=network.location.city,
            country=network.location.country,
            id=network.id,
            name=network.name,
            x=network.location.longitude,
            y=network.location.latitude,
        ) for network in networks.networks
    ]
Example #8
0
def find_nearby_stops(x, y):
    """Return a list of stops near given coordinates."""
    body = format_graphql("find_nearby_stops", x=x, y=y)
    url = URL.format(region=REGION)
    result = pan.http.post_json(url, body, headers=HEADERS)
    result = pan.AttrDict(result)
    return [{
        "color": get_stop_color(stop),
        "description": stop.desc or _("Stop"),
        "id": stop.gtfsId,
        "line_summary": get_line_summary(stop),
        "name": format_stop_name(stop),
        "x": float(stop.lon),
        "y": float(stop.lat),
    } for stop in [x.node.stop for x in result.data.stopsByRadius.edges]]
Example #9
0
def list_stations(network):
    """Return a list of bike stations and their occupancy."""
    url = "https://api.digitransit.fi/routing/v1/routers/hsl/bike_rental"
    stations = pan.http.get_json(url, headers=HEADERS)
    stations = pan.AttrDict(stations)
    return [
        dict(
            empty_slots=station.spacesAvailable,
            free_bikes=station.bikesAvailable,
            id=station.id,
            name=station.name,
            x=station.x,
            y=station.y,
        ) for station in stations.stations
    ]
Example #10
0
def list_stations(network):
    """Return a list of bike stations and their occupancy."""
    url = "https://api.citybik.es/v2/networks/{}?fields=stations".format(
        network)
    stations = pan.http.get_json(url)
    stations = pan.AttrDict(stations)
    return [
        dict(
            empty_slots=station.empty_slots,
            free_bikes=station.free_bikes,
            id=station.id,
            name=parse_station_name(station),
            x=station.longitude,
            y=station.latitude,
        ) for station in stations.network.stations
    ]
Example #11
0
def find_stops(query, x, y):
    """Return a list of stops matching `query`."""
    query = re.sub('["{}]', "", query)
    body = format_graphql("find_stops", query=query)
    url = URL.format(region=REGION)
    result = pan.http.post_json(url, body, headers=HEADERS)
    result = pan.AttrDict(result)
    return [{
        "color": get_stop_color(stop),
        "description": stop.desc or _("Stop"),
        "id": stop.gtfsId,
        "line_summary": get_line_summary(stop),
        "name": format_stop_name(stop),
        "x": float(stop.lon),
        "y": float(stop.lat),
    } for stop in result.data.stops]
Example #12
0
def find_stops(query, x, y):
    """Return a list of stops matching `query`."""
    # XXX: We cannot seem to get a list of lines without
    # needing to do separate API calls for each stop.
    query = urllib.parse.quote(query)
    path = "/StopPoint/Search/{}".format(query)
    url = format_url(path, maxResults="50", includeHubs="false")
    result = pan.http.get_json(url)
    result = pan.AttrDict(result)
    return [{
        "color": get_stop_color(match.modes),
        "description": get_stop_description(match),
        "id": match.id,
        "line_summary": "",
        "name": match.name,
        "x": float(match.lon),
        "y": float(match.lat),
    } for match in result.matches]
Example #13
0
 def _update(self, values, root=None, defaults=None, path=()):
     """Load values of options after validation."""
     if root is None: root = self
     if defaults is None: defaults = DEFAULTS
     for name, value in values.items():
         if isinstance(value, dict):
             self._update(value, root.setdefault(name, pan.AttrDict()),
                          defaults.setdefault(name, {}), path + (name, ))
             continue
         try:
             if name in defaults:
                 # Be liberal, but careful in what to accept.
                 value = self._coerce(value, defaults[name])
             root[name] = copy.deepcopy(value)
         except Exception as error:
             full_name = ".".join(path + (name, ))
             print("Discarding bad option-value pair {}, {}: {}".format(
                 repr(full_name), repr(value), str(error)),
                   file=sys.stderr)
Example #14
0
def find_lines(stops):
    """Return a list of lines that use `stops`."""
    stops = ", ".join('"{}"'.format(x) for x in stops)
    body = format_graphql("find_lines", ids=stops)
    url = URL.format(region=REGION)
    result = pan.http.post_json(url, body, headers=HEADERS)
    result = pan.AttrDict(result)

    def patterns():
        for stop in result.data.stops:
            for pattern in stop.patterns:
                yield pattern

    return pan.util.sorted_unique_lines([{
        "color":
        COLORS.get(pattern.route.mode, COLORS.BUS),
        "destination":
        parse_headsign(pattern.headsign),
        "id":
        pattern.route.gtfsId,
        "name":
        parse_line_name(pattern.route),
    } for pattern in patterns()])
Example #15
0
https://api.tfl.gov.uk/swagger/ui/
https://tfl.gov.uk/plan-a-journey/
"""

import datetime
import pan
import re
import urllib.parse

COLORS = pan.AttrDict({
             "bus": "#ed192d",
       "cable-car": "#ed192d",
           "coach": "#ed192d",
             "dlr": "#244ba6",
   "national-rail": "#244ba6",
      "overground": "#244ba6",
 "replacement-bus": "#ed192d",
       "river-bus": "#289ee0",
      "river-tour": "#289ee0",
         "tflrail": "#244ba6",
            "tram": "#59c134",
            "tube": "#244ba6",
})

DESTINATION_SUFFIXES = [
    "dlr station",
    "rail station",
    "tram stop",
    "underground station",
]

MODE_COLOR_ORDER = [
Example #16
0
def get_line_summary(stop):
    """Return a list of lines that use `stop`."""
    line = lambda x: pan.AttrDict(name=x.name, destination="")
    lines = pan.util.sorted_unique_lines(map(line, stop.lines))
    return ", ".join(x.name for x in lines[:10])
Example #17
0
http://digitransit.fi/en/developers/services-and-apis/1-routing-api/
http://dev.hsl.fi/graphql/console/
"""

import functools
import os
import pan
import re

from pan.i18n import _

COLORS = pan.AttrDict({
    "AIRPLANE": "#ed145d",
    "BUS": "#007ac9",
    "FERRY": "#00b9e4",
    "RAIL": "#8c4799",
    "SUBWAY": "#ff6319",
    "TRAM": "#00985f",
    "WALK": "#888888",
})

HEADERS = {"Content-Type": "application/graphql"}
URL = "http://api.digitransit.fi/routing/v1/routers/{region}/index/graphql"

# Overriden by region-specific implementations.
REGION = None


def find_departures(stops):
    """Return a list of departures from `stops`."""
    stops = ", ".join('"{}"'.format(x) for x in stops)