def getDirectConnection(origin_id, destination_id):
    #---------------------------------------------------------------------------
    # checks for direct connections from tart_id to stop_id and returns
    # a list of entries [line, destination]
    #---------------------------------------------------------------------------
    direct_connections = []
    connections = get_routedata(origin_id, destination_id)
    if connections == None: return []

    if 'resultList' not in connections:
        return direct_connections
    for journey in connections['resultList']:
        if 'elementList' not in journey: continue
        if len(journey['elementList']) != 1:
            myask_log.debug(
                7, "connection found with '" +
                str(len(journey['elementList'])) + "' legs. ignoring")
        else:
            con = {}
            leg = journey['elementList'][0]
            try:
                con['lineName'] = leg['lineName']
                con['tripId'] = leg['tripId']
                con['destinationName'] = leg['destinationName']
                direct_connections.append(con)
            except:
                myask_log.debug(3, "fields missing")
    return direct_connections
Example #2
0
def get_stoppoint(name):
    parameter = {'searchString': name, 'maxResults': 5, 'searchTypes': 'STOPPOINT'}
    request = requests.get(baseurl.format(url_l), params=parameter)
    if request.status_code != 200:
        raise Exception
    if request.headers['content-type'] != 'application/json;charset=UTF-8':
        raise Exception
    data = request.json()
    resultstops = []
    print (u"DEBUG: got request \n"+ str(data) + "\n--------------")
    if data['resultCount'] == 0:
        myask_log.debug(3, u"No result for stop name {}".format(name))
    elif data['resultCount'] > 1:        
        print("More than one result for stop name {}:".format(name))
        print("ID\tName")
        for elem in data['resultList']:
            stopid = elem['stopPointId']
            stopname = unicodify(elem['stopPointName'])        
            resultstops.append([stopid,stopname])
    else: # a single result was shown
        stopid = data['resultList'][0]['stopPointId']
        stopname = unicodify(data['resultList'][0]['stopPointName'])        
        myask_log.debug(3, u"Found a single match for '"+name+"': "+str(stopid) +" : "+stopname)
        resultstops.append([stopid,stopname])
        
    return resultstops
Example #3
0
def process_FindConnectionFromOther(slots, appdef, user_profile):
    #---------------------------------------------------------------------------
    # Lists connections from a specific station to a specific station
    #
    # Intent: 'FindConnection'
    # Slots:
    #  - "Origin"  station to which connections  should be found
    #  - "OriginCity"
    #  - "Destination"  station to which connections  should be found
    #  - "DestinationCity"
    #    "Busline"  : list only buses for a specific line
    #    "Next"      : (future) List only next or next N connections
    #    "Transport" : Filter by Mode of Transport: Bus, Train, Direct
    # Origin is set to the user's default sstation
    #---------------------------------------------------------------------------
    myask_log.debug(3, "Got intent FindConnectionFromOther")

    # convert all times to localtime, independent of the AWS server location

    #-----------------------------------------------------------------------
    # get ID for origin stop
    #-----------------------------------------------------------------------
    if 'Origin' not in slots:
        if user_profile.isKnownUser():
            # user favorite as fall-back
            slots['qorg_id'] = ToInt(user_profile.GetDefaultStopId())
        else:
            return bus_response.out_OriginMissing(slots, appdef, user_profile)
    else:
        slots['qorg_id'] = ToInt(slots['Origin'])

    if slots['qorg_id'] < 10000:
        return bus_response.out_InvalidOrigin(slots['Origin'], slots, appdef,
                                              user_profile)

    #-------------------------------------------------------------------------
    # fill destination ID
    #-------------------------------------------------------------------------
    if 'Destination' in slots:
        destination_id = ToInt(slots["Destination"])
        destination_str = slots["Destination"]
    elif 'qdest_id' in slots:  # check if there is a station from the dialog context to re-use
        destination_id = ToInt(slots['qdest_id'])
        destination_str = ""
    else:  # no information found. Use default location from user profile
        return bus_response.out_DestinationMissing(slots, appdef, user_profile)

    if int(destination_id) < 10000:
        myask_log.warning("Invalid stop id for destination station:" +
                          str(destination_id))
        return bus_response.out_InvalidDestination(destination_str, slots,
                                                   appdef, user_profile)

    # we got a single result
    slots['qdest_id'] = destination_id

    return _FetchConnections(slots, appdef, user_profile)
def process_FindConnectionFromFavorite(slots, appdef, user_profile):
    #---------------------------------------------------------------------------
    # Lists connections to a specific station from the user's default station
    #
    # Intent: 'FindConnectionFromFavorite'
    # Slots:
    #  - "Destination"  station to which connections  should be found
    #  - "DestinationCity"
    #    "Busline"  : list only buses for a specific line
    #    "Next"      : (future) List only next or next N connections
    #    "Transport" : Filter by Mode of Transport: Bus, Train, Direct
    # Origin is set to the user's default sstation
    #---------------------------------------------------------------------------
    myask_log.debug(3, "Got intent FindConnectionFromFavorite")

    #-----------------------------------------------------------------------
    # fill origin  ID from user profile
    #-----------------------------------------------------------------------
    if user_profile.isKnownUser():
        slots['qorg_id'] = ToInt(user_profile.GetDefaultStopId())
    else:
        return bus_response.out_PromptUserProfileNeeded(slots)

    #-------------------------------------------------------------------------
    # fill destination ID
    #-------------------------------------------------------------------------
    if 'Destination' in slots:
        destination_id = ToInt(slots["Destination"])
        destination_str = slots["Destination"]
    elif 'qdest_id' in slots:  # check if there is a station from the dialog context to re-use
        destination_id = ToInt(slots['qdest_id'])
        destination_str = ""
    else:  # no information found. Use default location from user profile
        return bus_response.out_DestinationMissing(slots, appdef, user_profile)

    myask_log.debug(5, "Got destination ID " + str(destination_id))
    if int(destination_id) < 10000:
        myask_log.warning("Invalid stop id for destination station:" +
                          str(destination_id))
        if 'Destination.literal' in slots:
            return bus_response.out_InvalidDestination(
                slots["Destination.literal"], slots, appdef, user_profile)
        else:
            return bus_response.out_InvalidDestination(destination_str, slots,
                                                       appdef, user_profile)

    # we got a single result
    slots['qdest_id'] = destination_id

    return _FetchConnections(slots, appdef, user_profile)
def process_GetDeparturesFromOther(slots, appdef, user_profile):
    #--------------------------------------------------------------------------
    # Shows live departures from a specific station 'origin'
    #
    # Intent: 'Departures'
    # Slots:
    #    "Origin"    : station from which the departures are requested
    #    "Direction" : lists only inbound / outbound buses
    #    "Busline"  : list only buses for a specific line
    #    "Next"      : (future) List only next or next N connections
    #    "Transport" : FIlter by Mode of Transport: Bus, Train, Direct
    #--------------------------------------------------------------------------
    myask_log.debug(3, "Got intent 'GetDeparturesFromOther'")

    # convert all times to localtime, independent of the AWS server location
    if 'utc_offset' in slots: utc_offset = slots['utc_offset']
    else: utc_offset = 0

    if 'Busline' in slots and slots['Busline'] != "?":
        linefilter = slots['Busline']
    else:
        linefilter = ''

    if "Direction" in slots: direction = slots["Direction"]
    else: direction = ""

    #-----------------------------------------------------------------------
    # get ID for origin stop
    #-----------------------------------------------------------------------
    if 'Origin' not in slots:
        myask_log.debug(5,
                        "Slot 'Origin' missing in GetDeparturesFromOther...")
        if user_profile.HasDefaultStop():
            # user favorite as fall-back
            slots['qorg_id'] = ToInt(user_profile.GetDefaultStopId())
            myask_log.debug(5, "...Using user profile default instead")
        else:
            myask_log.debug(5, "...and no default stop found in user profile")
            return bus_response.out_OriginMissing(slots, appdef, user_profile)

    else:
        slots['qorg_id'] = ToInt(slots['Origin'])

    if slots['qorg_id'] < 10000:
        if 'Origin.literal' in slots['Origin.literal']:
            return bus_response.out_InvalidOrigin(slots['Origin.literal'],
                                                  slots, appdef, user_profile)
        else:
            return bus_response.out_InvalidOrigin('', slots, appdef,
                                                  user_profile)
    else:
        results = aseag_api.GetDepartures(slots['qorg_id'], linefilter,
                                          direction, utc_offset)
        return bus_response.out_Departures(results, slots, appdef,
                                           user_profile)

    # if we are here, something went wrong
    return bus_response.out_ImplementationError("GetDeparturesFromOther",
                                                slots, appdef, user_profile)
def _FetchConnections(slots, appdef, user_profile):
    #--------------------------------------------------------------------------
    # Finds connections from one bus stop to another
    #
    # Requires the following slots to be set:
    # 'qorg_id' bus stop ID for the origin stop
    # 'qdest_is' bus stop ID for the destination stop
    # Optional slots (used to filter the results=
    #    "Busline"  : list only this buses for a specific line
    #    "Next"      : (future) List only next or next N connections
    #    "Transport" : (future) Filter by Mode of Transport: Bus, Train, Direct
    # RETURNS: Alexa output structure
    #--------------------------------------------------------------------------

    if myask_slots.checkslots(slots, ['lang', 'qorg_id', 'qdest_id'],
                              "_FetchConnections") == False:
        return myask_alexaout.createAlexaErrorOutput(
            myask_slots.error_slots_missing("_FetchConnections"), slots)

    myask_log.debug(
        3, "In Function _FindConnection " + str(slots['qorg_id']) + "-->" +
        str(slots['qdest_id']))

    # prepare slots for call to aseag API

    # convert all times to localtime, independent of the AWS server location
    if 'utc_offset' in slots: utc_offset = slots['utc_offset']
    else: utc_offset = 0

    if 'Busline' in slots and slots['Busline'] != "?":
        linefilter = slots['Busline']
    else:
        linefilter = ''

    if 'Transport' in slots: transport = slots['Transport']
    else: transport = ""

    match, result_connections = aseag_api.GetFilteredConnections(
        slots['qorg_id'], slots['qdest_id'], linefilter, transport, utc_offset)

    myask_log.debug(2, "connection results from "+ str(slots['qorg_id'])+ " to " + str(slots['qdest_id'])+ \
                    "match:" +str(match)+":\n" + str(result_connections))

    return bus_response.out_Connections(result_connections, slots, appdef,
                                        user_profile)
 def __init__(self, userID):
     self._user_id = userID
     if userID == "FAKE":
         #Found profile of "diekellnerfamilie"
         self._profile_data = HARDCODED_PROFILES['TESTUSER']
     else:
         self._profiletable = myask_dynamodb.dynamoDB("aseag_userprofile")
         myask_log.debug(0,
                         "GetTable: " + str(self._profiletable.GetStatus()))
         profile_data = self._profiletable.FetchUserProfile(userID)
         if profile_data == {}:
             myask_log.warning(
                 "Could not locate user profile. Creating new one. User: " +
                 str(userID))
             self._profiletable.CreateNewUserProfile(userID, {})
             self._profile_data = {}
         else:
             self._profile_data = profile_data
Example #8
0
def GetConnectionsWithBus(origin_ID, destination_ID, busline, utc_offset):
    #---------------------------------------------------------------------------
    # Retrieves connection thet contain a specific busline only.
    # The system fetches connections from 'origin_ID' to 'destination_ID' using
    # GetConnections().
    # The results are then filtered to only contain connections where
    # at least one leg uses the specified busline.
    # If no matches are found at all, the system returns the full list (constraint is relaxed)
    # PARAMETERS:
    # - origin_ID:      Bus stop ID for the departure station (integer, 1000000-999999)
    # - destination_ID: Bus stop ID for the departure station (integer, 1000000-999999)
    # - busline:        (int/string) denoting the busline to be filtered for
    # - utc_offset:     Timezone, for which the times should be returned (API uses UTC)
    # RETURNS:  match,connection_list
    # 'match' (booloean): True if the busline constraint was met, False if it was relaxed
    # 'connection_list' list of bus connections. See GetConnections() for details
    #---------------------------------------------------------------------------   
    connection_list =  GetConnections(origin_ID, destination_ID, utc_offset)
    
    if busline == 0: return (True, connection_list)
    
    print(u"checking for buses"+ str(busline))
    matching_connections = []
    # check if the buses are indeed used
    for connection in connection_list:
        # check if this connection uses the specified buy
        if 'legs' in connection:
            usesbus = False
            for leg in connection['legs']:
                if 'line' in leg and int(leg['line']) == busline:
                    myask_log.debug(5, u"match found for bus "+str(busline) +\
                                    u" in connection "+str(connection) )
                    usesbus = True
                    break
            if usesbus: matching_connections.append(connection)
            else: myask_log.debug(5, u"NO match found for bus "+str(busline) +\
                                    u" in connection "+str(connection) )

    if len(matching_connections) == 0:
        return (False, connection_list)
    else:
        return (True, matching_connections)
def process_GetDeparturesFromFavorite(slots, appdef, user_profile):
    #--------------------------------------------------------------------------
    # Shows live departures from the user's default connection
    #
    # Intent: 'DeparturesFromFavorite'
    # Slots:  (used to filter departures)
    #    "Direction" : lists only inbound / outbound buses
    #    "Busline"  : list only buses for a specific line
    #    "Next"      : (future) List only next or next N connections
    #    "Transport" : FIlter by Mode of Transport: Bus, Train, Direct
    #--------------------------------------------------------------------------
    myask_log.debug(3, "Got intent 'GetDeparturesFromFavorite'")

    # convert all times to localtime, independent of the AWS server location
    if 'utc_offset' in slots: utc_offset = slots['utc_offset']
    else: utc_offset = 0

    if 'Busline' in slots and slots['Busline'] != "?":
        linefilter = slots['Busline']
    else:
        linefilter = ''

    if "Direction" in slots: direction = slots["Direction"]
    else: direction = ""

    #-----------------------------------------------------------------------
    # get ID for origin stop from user profile
    #-----------------------------------------------------------------------
    if user_profile.isKnownUser():
        slots['qorg_id'] = ToInt(user_profile.GetDefaultStopId())
    else:
        return bus_response.out_PromptUserProfileNeeded(slots)

    if (slots['qorg_id']) < 10000:
        return bus_response.out_InvalidFavorite(user_profile)

    results = aseag_api.GetDepartures(slots['qorg_id'], linefilter, direction,
                                      utc_offset)
    return bus_response.out_Departures(results, slots, appdef, user_profile)
def GetDepartures(StopID, busline, direction, utc_offset):
    #--------------------------------------------------------------------------
    # Returns a list of live bus departures from the specified bus stop
    # PARAMETERS:
    # - 'StopID'  Bus stop ID for the departure station (integer, 1000000-999999)
    # - 'busline' : (integer/string) Filter to show only buses from that line.
    #                If '0', all buses are shown
    # - 'direction: (string) Shows only buses for the specified connection
    #                either 'DIR_INWARD_ or 'DIR_OUTWARD'
    #                if "", all departures are shown
    #
    # - utc_offset:     Timezone, for which the times should be returned (API uses UTC)
    # RETURNS:
    # List of departures from the station with:
    # [
    #    dep_time,    // datetime. Estimated departure time
    #    busnr,       // string    Bus number
    #    destination, // (string) destination of the bus
    # ]
    #--------------------------------------------------------------------------
    myask_log.debug(
        3, u"aseag_api.GetDepartures: Haltestellenabfrage von " + str(StopID) +
        u". Buslinie: '" + str(busline) + u"'. Direction: " + str(direction))
    if busline == '' or busline == '?': buses = []
    else: buses = [str(busline)]

    output = get_stopdata(StopID, buses)
    #    print "DEPARTURES:-------------------------"
    #    print json.dumps(output, indent=4, sort_keys=False)
    #    print "END_CONNECTION-------------------------------------"
    connection_list = []
    for line in output:
        myask_log.debug(5, "LINE: " + str(line))
        if tsfilter(line[0], totime):
            dep_time = unix_epoch_to_utcdatetime(
                line[0]) + datetime.timedelta(hours=utc_offset)
            busnr = line[1]
            destination = unicodify(line[2])
            # check if the connection matches the filters for busline and direction
            if MatchesDirection(StopID, direction, busnr, destination):
                connection = (dep_time, busnr, destination)
                connection_list.append(connection)
            else:
                myask_log.debug(
                    5, u"Ignoring connection line " + str(busnr) + u" to " +
                    destination + u": does not match direction")
    myask_log.debug(4, str(len(connection_list)) + u" connections found")

    return connection_list
def process_ChangeDefaultStation(slots, appdef, user_profile):
    #---------------------------------------------------------------------------
    # Handles a user request to change the default stop
    #
    # The system triggers a confirmation question back to the user
    # if the user answers with "yes" or "no", the function ConfirmChangeDefaultStation is called
    #---------------------------------------------------------------------------
    myask_log.debug(3, "Got intent 'GetFavConnecionDepartures'")

    if "Origin" not in slots:
        return bus_response.out_DefaultStationMissing(slots, appdef,
                                                      user_profile)
    elif ToInt(slots["Origin"]) < 10000:
        return bus_response.out_DefaultStationMissing(slots, appdef,
                                                      user_profile)

    slotlist = ["Origin"]
    session_attributes = myask_slots.store_session_slots(
        "ChangeDefaultStation", slotlist, slots)

    return bus_response.out_ConfirmChangeFavorite(slots["Origin"],
                                                  session_attributes, slots,
                                                  appdef, user_profile)
def on_intent(intent_request, session, appdef, user_profile):
    #--------------------------------------------------------------------------
    # Main intent handler function.
    # Called when Alexa receives a speech intent
    """ Called when the user specifies an intent for this skill """

    myask_log.debug(
        5, "on_intent requestId=" + intent_request['requestId'] +
        ", sessionId=" + session['sessionId'])

    intent = intent_request['intent']
    current_intent = intent_request['intent']['name']
    input_locale = intent_request['locale']

    myask_log.debug(2, "Got user profile: " + str(user_profile.GetProfile()))

    if current_intent in ["AMAZON.YesIntent", "AMAZON.NoIntent"]:
        slots = myask_slots.parse_slots(intent, session, True, input_locale,
                                        appdef)
        if current_intent == "AMAZON.YesIntent": slots["Confirmed"] = True
        elif current_intent == "AMAZON.NoIntent": slots["Confirmed"] = False
        if 'prev_intent' in slots:
            if slots["prev_intent"] == "ChangeDefaultStation":
                return ConfirmChangeDefaultStation(slots, appdef, user_profile)
            else:
                myask_alexaout.createAlexaErrorOutput(
                    "Oops, da ist was schiefgelaufen")
        else:
            myask_alexaout.createAlexaErrorOutput(
                "Sorry, das habe ich nicht verstanden")

    slots = myask_slots.parse_slots(intent, session, False, input_locale,
                                    appdef)
    slots['current_intent'] = current_intent

    #Now process the intent via the appropriate function
    myask_log.debug(3, "Handling current_intent='" + str(current_intent) + "'")
    if current_intent == "GetDeparturesFromFavorite":
        return process_GetDeparturesFromFavorite(slots, appdef, user_profile)
    elif current_intent == "GetDeparturesFromOther":
        return process_GetDeparturesFromOther(slots, appdef, user_profile)
    elif current_intent == "GetFavConnecionDepartures":
        return process_GetFavConnecionDepartures(slots, appdef, user_profile)
    elif current_intent == "FindConnectionFromFavorite":
        return process_FindConnectionFromFavorite(slots, appdef, user_profile)
    elif current_intent == "FindConnectionFromOther":
        return process_FindConnectionFromOther(slots, appdef, user_profile)
    elif current_intent == "ChangeDefaultStation":
        return process_ChangeDefaultStation(slots, appdef, user_profile)
    elif current_intent == "DeleteProfile":
        return process_DeleteProfile(slots, appdef, user_profile)
    elif current_intent == "AMAZON.HelpIntent":
        return bus_response.out_Help(user_profile)
    elif current_intent == "AMAZON.CancelIntent" or current_intent == "AMAZON.StopIntent":
        return bus_response.out_SessionEnd()
    else:
        raise ValueError("Invalid intent")
def FindFavoriteConnetions(start_id, stop_id, start_time, end_time,
                           preferred_bus, utc_offset):
    match, lineconnections = GetConnectionsWithBus(start_id, stop_id,
                                                   preferred_bus, utc_offset)

    if match and start_time != "":  # filter for time window only if there is a bus match
        matching_connections = []
        if re.match("\d\d:\d\d$", start_time):
            tmp = datetime.datetime.strptime(start_time, "%H:%M")
            window_start = tmp.time()
        else:
            myask_log.error(
                u"Invalid start time format in 'FindFavoriteConnetions': " +
                start_time)
            start_time = datetime.datetime.utcnow() + datetime.timedelta(
                hours=utc_offset)

        if (end_time == ""):
            window_end = window_start + datetime.timedelta(hours=1)
        elif re.match("\d\d:\d\d$", end_time):
            tmp = datetime.datetime.strptime(end_time, "%H:%M")
            window_end = tmp.time()
        else:
            myask_log.error(
                u"Invalid end time format in 'FindFavoriteConnetions': " +
                end_time)
            window_end = window_start + datetime.timedelta(hours=1)

        # now loop over all connections and check if they depart in the right time window
        for connection in lineconnections:
            # check if this connection departs in the specified time
            deptime = connection['start_datetime'].time()
            if (deptime >= window_start and deptime <= window_end):
                myask_log.debug(5,
                                u"time match in connection " + str(connection))
                matching_connections.append(connection)
            else:
                myask_log.debug(
                    5, u"NO time match in connection " + str(connection))

        if len(matching_connections) == 0:
            myask_log.debug(
                5,
                u"No matchin connections in timewondow found. Returning all")
            return (False, lineconnections)
        else:
            return (True, matching_connections)

    else:
        return match, lineconnections
def ConfirmChangeDefaultStation(slots, appdef, user_profile):
    #---------------------------------------------------------------------------
    # Handles confirmation of change of default slot
    # slot "Confirmed" contains the user answer
    #---------------------------------------------------------------------------
    if myask_slots.checkslots(slots, ['lang', 'Confirmed'],
                              "ConfirmChangeDefaultStation") == False:
        return myask_alexaout.createAlexaErrorOutput(
            myask_slots.error_slots_missing("ConfirmChangeDefaultStation"),
            slots)

    myask_log.debug(3, "Got command 'ConfirmChangeDefaultStation'")

    if "Origin" in slots:
        new_default_id = slots["Origin"]
    else:
        myask_log.error(
            "ConfirmChangeDefaultStation called without slot 'Origin'. How could this happen?"
        )
        new_default_id = user_profile.GetDefaultStopId()

    if slots["Confirmed"] == True:  # user confirmed
        myask_log.debug(5,
                        "User has confirmed selection of new default station")
        myask_log.debug(2, "New default station is " + str(new_default_id))
        result = user_profile.SetDefaultStopId(new_default_id)
        if result:
            myask_log.debug(1, "New favorite set successfully")
        else:
            myask_log.error("New favorite could not be set")
        return bus_response.out_DefaultChanged(slots, appdef, user_profile)
    else:  # user did not confirm
        return bus_response.out_DefaultChangeCancelled(slots, appdef,
                                                       user_profile)

    # if we are here, something went wrong
    return bus_response.out_ImplementationError(
        "process_GetFavConnecionDepartures", slots, appdef, user_profile)
def process_GetFavConnecionDepartures(slots, appdef, user_profile):
    #--------------------------------------------------------------------------
    # shows departures a favorite connection from the uer's user profile
    #
    # Intent: 'GetFavConnecionDepartures'
    # Slot: 'FavConnection' identifier for a favorite connection from the user profile
    # A favorite connection (slot '') from the user profile provides
    #  - departure station
    #  - destination station
    #  - preferred busline (optional)
    #  - preferred time-window (optional)
    #--------------------------------------------------------------------------
    myask_log.debug(3, "Got intent 'GetFavConnecionDepartures'")

    if 'FavConnection' not in slots:
        return bus_response.out_FavoriteConnectionMissing(
            slots, appdef, user_profile)

    else:
        fav_connection = user_profile.GetFavoriteConnection(
            slots["FavConnection"])
        if len(fav_connection) == 0:
            return bus_response.out_FavoriteConnectionNotInUserProfile(
                slots["FavConnection"], slots, appdef, user_profile)
        else:  # favorite connection found
            if "OrgID" not in fav_connection or "DestID" not in fav_connection:
                myask_log.warning(
                    "No StartID or StopID found in FavoriteConnection '" +
                    slots["FavConnection"] + "' for user ")
                return bus_response.out_InvalidFavoriteConnection(
                    slots, appdef, user_profile)
            else:
                if "PreferredLines" in fav_connection:
                    linefilter = fav_connection["PreferredLine"]
                else:
                    linefilter = ''

                if "DepTimeWindowStart" in fav_connection:
                    start_time = fav_connection["DepTimeWindowStart"]
                else:
                    start_time = ""

                if "DepTimeWindowEnd" in fav_connection:
                    end_time = fav_connection["DepTimeWindowEnd"]
                else:
                    end_time = ""

                if 'utc_offset' in slots: utc_offset = slots['utc_offset']
                else: utc_offset = 0

                (match, result_connections) = aseag_api.FindFavoriteConnetions(
                    fav_connection["OrgID"], fav_connection["DestID"],
                    start_time, end_time, linefilter, utc_offset)
                # put it in the normal fields for smooth output
                slots['qorg_id'] = ToInt(fav_connection["OrgID"])
                slots['qdest_id'] = ToInt(fav_connection["DestID"])
                if linefilter != '': slots['Busline'] = str(linefilter)
                return bus_response.out_FavoriteConnection(
                    match, result_connections, slots, appdef, user_profile)

    # if we are here, something went wrong
    return bus_response.out_ImplementationError(
        "process_GetFavConnecionDepartures", slots, appdef, user_profile)
Example #16
0
def MatchesDirection(station_ID, direction, line, destination):
    #---------------------------------------------------------------------------
    # checks if a given connection matches the list of specified direction 
    #
    # PARAMETERS
    #  'station' station ID for a bus stop
    #  'direction': either 'DIR_INWARD_ or 'DIR_OUTWARD'
    #  'line' : line of the connection under investigation
    #  'destination' destination station of the connection under investigation
    # 
    # RETURNS True if the bus goes in the requested direction
    # If no valid direction is specified or the bus direction cannot be
    # determined, the function returns True
    #---------------------------------------------------------------------------
    if direction == "": return True # if there's no direction, everything matches

    key = str(station_ID)
    if key in aseag_data.HARDCODED_DIRECTIONS:
        inwardlist = aseag_data.HARDCODED_DIRECTIONS[key]["inward"]
        outwardlist = aseag_data.HARDCODED_DIRECTIONS[key]["outward"]
    else:
        inwardlist = aseag_data.HARDCODED_DIRECTIONS["DEFAULT"]["inward"]
        outwardlist = aseag_data.HARDCODED_DIRECTIONS["DEFAULT"]["outward"]
    busline = int(line)
    
    if direction == "DIR_INWARD":
        # positive list: 
        for (itemid, itemdest) in inwardlist:
            if destination == itemdest: # the destination is in the list
                if itemid == 0 or itemid == busline: # the destination matches for all buses or the bus is the right one
                    myask_log.debug(10, u"Match: Found inbound match for station '"+key+u"' Bus "+str(busline)+ ": "+destination)
                    return True    
        # negative list let's check if the item is in the outbound list
        for (itemid, itemdest) in outwardlist:
            if destination == itemdest: # the destination is in the list
                if itemid == 0 or itemid == busline: # the destination matches for all buses or the bus is the right one
                    myask_log.debug(10, u"Mismatch: Found outbound match for station '"+key+u"' Bus "+str(busline)+ ": "+destination)
                    return False    
        myask_log.debug(10, u"Did not find in/out match for '"+key+u"' Bus "+str(busline)+ u": "+destination)
        return True
    elif  direction == "DIR_OUTWARD":
        # positive list: 
        for (itemid, itemdest) in outwardlist:
            if destination == itemdest: # the destination is in the list
                if itemid == 0 or itemid == busline: # the destination matches for all buses or the bus is the right one
                    myask_log.debug(10, u"Match: Found outbound match for station '"+key+u"' Bus "+str(busline)+ u": "+destination)
                    return True    
        # negative list let's check if the item is in the outbound list
        for (itemid, itemdest) in inwardlist:
            if destination == itemdest: # the destination is in the list
                if itemid == 0 or itemid == busline: # the destination matches for all buses or the bus is the right one
                    myask_log.debug(10, u"Mismatch: Found inbound match for station '"+key+u"' Bus "+str(busline)+ u": "+destination)
                    return False    
        myask_log.debug(10, u"Did not find in/out match for '"+key+u"' Bus "+str(busline)+ ": "+destination)
        return True
    else:
        myask_log.error(u"Invalid direction '"+str(direction) +u"' found ignoring filter")
        return True
Example #17
0
def GetConnections(origin_ID, destination_ID, utc_offset):
    #---------------------------------------------------------------------------
    # Retrieves a connection from the ASEAG server (using get_routedata) and
    # returns the connection in a simplified format
    # PARAMETERS:
    # - origin_ID:      Bus stop ID for the departure station (integer, 1000000-999999)
    # - destination_ID: Bus stop ID for the departure station (integer, 1000000-999999)
    # - utc_offset:     Timezone, for which the times should be returned (API uses UTC)
    #
    # RETURNS: datastructure holding multiple connections (joruneys)
    #         Each connection can consist of several parts ('legs')
    #   '[     // list of journeys (matching connections)
    #       'start_datetime' : (datetime) departure time in local time
    #       'end_datetime'   : (datetime) arrival time in local time
    #       'start_loc'      : (string)  name of the overall departure station
    #       'end_loc'        : (string)  name of the overall arrival station
    #       'legs' :  [ // list of legs in this journey
    #           'type' : 'LineChange' | 'bus' | 'walk'
    #            'start_loc': (string)  name of the departure location for this leg
    #            'end_loc' :  (string)  name of the arrival location for this leg
    #            'line'  (string) name of busline (only for type 'bus')
    #            'start_datetime' :  (datetime) start time for this leg (in local time)
    #            'end_datetime'   :  (datetime) end time for this leg (in local time)
    #          ]
    #      ] 
    # If an error occurs, the function returns an empty connection list
    # If an error occurs parsing a specific journey, this journey is returned as empty
    #---------------------------------------------------------------------------
    myask_log.debug(3, u"Fetching connection from  '"+str(origin_ID) + u"' to '"+ str(destination_ID)+u"'...")
    output = get_routedata(origin_ID, destination_ID)
    if output == None: return []

#    print "CONNECTION:-------------------------"
#    print json.dumps(output, indent=4, sort_keys=False)
#    print "END_CONNECTION-------------------------------------"
    result_connections = []
    for journey in output['resultList']:
        res_journey = {}
        try:
            # get jorney_start end end time
            res_journey['start_datetime']   = unix_epoch_to_utcdatetime(journey['startTimeInUnixEpochMillis']) + datetime.timedelta(hours = utc_offset)
            res_journey['end_datetime'] = unix_epoch_to_utcdatetime(journey['endTimeInUnixEpochMillis']) + datetime.timedelta(hours = utc_offset)
            res_journey['start_loc'] = journey['startLocation']['stopPointName']
            res_journey['end_loc'] = journey['endLocation']['stopPointName']
            res_journey['legs'] = []
            #loop over all parts (legs) of this journey
            for connection_leg in journey['elementList']:
                res_connection_leg = {}
                if connection_leg["type"] == "LineChange":
                    res_connection_leg ['type'] = "LineChange"
                elif connection_leg['modalType'] == "bus":
                    res_connection_leg['type'] = "bus"
                    res_connection_leg['start_loc'] = connection_leg['start']['location']['stopPointName']
                    res_connection_leg['end_loc'] =   connection_leg['end']['location']['stopPointName']
                    res_connection_leg['line'] = connection_leg['lineName']
                    tmp_datetime = unix_epoch_to_utcdatetime(
                            connection_leg['start']['aimedArrivalInUnixEpochMillis'] or
                            connection_leg['start']['estimatedArrivalInUnixEpochMillis'] or
                            connection_leg['start']['scheduledArrivalInUnixEpochMillis'])
                    res_connection_leg['start_datetime'] = tmp_datetime + datetime.timedelta(hours = utc_offset)
                    tmp_datetime = unix_epoch_to_utcdatetime(
                            connection_leg['end']['aimedArrivalInUnixEpochMillis']    or 
                            connection_leg['end']['estimatedArrivalInUnixEpochMillis'] or
                            connection_leg['end']['scheduledArrivalInUnixEpochMillis'])                    
                    res_connection_leg['end_datetime'] = tmp_datetime + datetime.timedelta(hours = utc_offset)
                elif connection_leg['modalType'] == "walk":
                    res_connection_leg ['type'] = "walk"
                    tmp_datetime = unix_epoch_to_utcdatetime(
                            connection_leg['start']['aimedArrivalInUnixEpochMillis'] or
                            connection_leg['start']['estimatedArrivalInUnixEpochMillis'] or
                            connection_leg['start']['scheduledArrivalInUnixEpochMillis'])
                    res_connection_leg['start_datetime'] = tmp_datetime + datetime.timedelta(hours = utc_offset)
                    tmp_datetime = unix_epoch_to_utcdatetime(
                            connection_leg['end']['aimedArrivalInUnixEpochMillis'] or 
                            connection_leg['end']['estimatedArrivalInUnixEpochMillis'] or
                            connection_leg['end']['scheduledArrivalInUnixEpochMillis'])
                    res_connection_leg['end_datetime'] = tmp_datetime + datetime.timedelta(hours = utc_offset) 
                    res_connection_leg['start_loc'] = connection_leg['start']['location']['stopPointName']
                    res_connection_leg['end_loc'] =   connection_leg['end']['location']['stopPointName']
                res_journey['legs'].append(res_connection_leg)
        except KeyError as e:
            myask_log.error(u"error: cannot parse journey "+ str(journey))
            print e.message, e.args
#            print json.dumps(output, indent=4, sort_keys=False)
            res_journey = []

        result_connections.append(res_journey)
   
    myask_log.debug(3, u"..."+str(len(result_connections))+u" connections found" )    
    return result_connections
Example #18
0
def CollectInbound(outputfile):
    existing_connections = aseag_inbound_connection.INBOUND_LINES
    fout = open(outputfile, 'w+')
    fout.write("# coding: utf-8\n\n")
    fout.write("#List of inbound connections per station.\n")
    fout.write("#Auto-generated on " +
               datetime.now().strftime("%Y-%m-%d %H:%M") + "\n\n")
    fout.write("INBOUND_LINES= {\n")
    newcounter = 0
    existingcounter = 0
    observedcounter = 0
    stationcounter = 0
    nodirect_con = 0
    for station in aseag_data.STATIONLIST:
        stationcounter += 1
        origin_id = int(station[0])
        orig_str = str(origin_id)
        myask_log.debug(9, "--- Station: " + orig_str)
        if orig_str in existing_connections:
            debugstr = "--- Station: " + orig_str
            inbound_line_departures = existing_connections[orig_str]
            # do some statistics
            stationlinecounter = 0
            for lines in inbound_line_departures:
                stationlinecounter += len(lines)
            existingcounter += stationlinecounter
        else:
            debugstr = "+++ Station: " + orig_str
            inbound_line_departures = {}
        dircon = aseag_api.getDirectConnection(origin_id, 100000)
        if len(dircon
               ) == 0:  # no direct connection to bushof, let's try kaiserplatz
            dircon = aseag_api.getDirectConnection(origin_id, 100003)
            if len(dircon) > 0: debugstr += "(KP):"
            else: debugstr += " NONE"
        else: debugstr += "    :"
        #        dircon = []
        for con in dircon:
            observedcounter += 1
            dest = con['destinationName']
            #            if dest == "Aachen Bushof" : continue
            line = con['lineName']
            if line not in inbound_line_departures:
                debugstr += "+"
                myask_log.debug(3, "new: " + str(line) + " --> " + dest)
                newcounter += 1
                stationlinecounter += 1
                inbound_line_departures[line] = [dest]
            else:
                if dest not in inbound_line_departures[line]:
                    debugstr += "+"
                    myask_log.debug(3, "new: " + str(line) + " --> " + dest)
                    newcounter += 1
                    stationlinecounter += 1
                    inbound_line_departures[line].append(dest)
                else:
                    debugstr += "."
                    myask_log.debug(9, "old " + str(line) + " --> " + dest)
        myask_log.debug(3, str(stationcounter) + " : " + debugstr)
        data_str = json.dumps(inbound_line_departures,
                              sort_keys=True,
                              ensure_ascii=False,
                              separators=(',', ':')).encode('utf8')
        #enforce proper unicode tracking to avoid issues when re-reading
        data_str = data_str.replace('["', '[u"')
        data_str = data_str.replace('","', '", u"')
        fout.write(" '" + str(origin_id) + "' : " + data_str + ",\n")
        # do some statistics
        if stationlinecounter == 0: nodirect_con += 1
    fout.write("}")
    fout.close()
    myask_log.debug(1, "-----------------------------------")
    myask_log.debug(
        1, "Stations: " + str(stationcounter) + " (" + str(nodirect_con) +
        " without direction info)")
    myask_log.debug(1, "Existing: Dest.   " + str(existingcounter) + " ")
    myask_log.debug(
        1, "Observed  Dest.   " + str(observedcounter) +
        "  destinations found this time")
    myask_log.debug(
        1, "New  Destinations " + str(newcounter) + "  destinations added")