Exemple #1
0
def DisplayJourneySimple(journey, slots, appdef):
    if 'legs' not in journey or len(journey['legs']) == 0:
        display_text = "ERROR_IN_CONNECION"
        myask_log.error("DisplayJourneySimple: cannot present connection: " +
                        str(journey))
    else:
        display_text = u'{:5s} ab {:15s} --> {:15s} an {:5s} {:d} Umstiege '.format(
            journey['start_datetime'].strftime('%H:%M'),
            unicode(journey['start_loc']), unicode(journey['end_loc']),
            journey['end_datetime'].strftime('%H:%M'),
            len(journey['legs']) - 1)
        display_text += "("
        firstleg = True
        for leg in journey['legs']:
            if firstleg: firstleg = False
            else: display_text += ", "
            if leg['type'] == "bus":
                if 'line' in leg:
                    display_text += "Bus " + leg['line']
                else:
                    display_text += "Bus ??"
            elif leg['type'] == "walk":
                display_text += "laufen"
        display_text += ")\n"
    return display_text
Exemple #2
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
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_inbound_connection.INBOUND_LINES:
        inwardlist = aseag_inbound_connection.INBOUND_LINES[key]
    else:
        myask_log.error("Station '" + str(station_ID) +
                        "' not found in inbound list. returning all stations")
        return True

    if direction == "DIR_INWARD":
        # positive list:
        if destination in aseag_data.CENTRAL_DESTINATIONS:
            # if bus goes to one of those, it is by definition inbound. no need to look further
            return True
        elif str(
                line
        ) in inwardlist:  # we have a list of destinations of that line, which pass through the center
            if destination in inwardlist[str(line)]: return True
            else: return False
        else:
            #line unknown
            return False

    elif direction == "DIR_OUTWARD":
        # exclude all known inbound lines
        if destination in aseag_data.CENTRAL_DESTINATIONS:
            # if bus goes to one of those, it is by definition inbound. no need to look further
            return False
        elif str(
                line
        ) in inwardlist:  # we have a list of destinations of that line, which pass through the center
            if destination in inwardlist[str(line)]: return False
            else: return True
        else:
            #line unknown
            return True
    else:
        myask_log.error(u"Invalid direction '" + str(direction) +
                        u"' found ignoring filter")
        return True
def get_user_profile(session):
    #get the user id from the request
    if session['user']['userId'] == "":
        myask_log.error(
            "Missing field 'session.user.userId'. Assuming default user")
        user_profile = bus_userprofile.userProfile(
            "")  # create default_profile
    else:
        user_profile = bus_userprofile.userProfile(session['user']['userId'])

    return user_profile
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
Exemple #6
0
def SpeakConnection(journey, slots, appdef):
    speech_output = ""
    if 'legs' not in journey or len(journey['legs']) == 0:
        speech_output += u"Diese Verbindung kann ich noch nicht vorlesen.<break/>"
        myask_log.error("DisplayJourneySimple: cannot present connection: " +
                        str(journey))
    elif len(journey['legs']) == 1:  #direct connection
        leg = journey['legs'][0]
        if leg['type'] == "bus":
            if 'line' in leg:
                speech_output += u"Mit der Linie " + leg['line']
            else:
                speech_output += u"Mit dem Bus"
        speech_output += u" <break/> "
        speech_output += u" Abfahrt " + journey['start_loc']
        speech_output += u" um " + journey['start_datetime'].strftime(
            '%H:%M') + " . "
        speech_output += u" Ankunft " + journey['end_loc']
        speech_output += u" um " + journey['end_datetime'].strftime(
            '%H:%M') + " . "
    else:  # multi-leg trip
        speech_output += u"Mit "
        firstleg = True
        for leg in journey['legs']:
            if firstleg: firstleg = False
            else: speech_output += u" und "
            if leg['type'] == u"bus":
                if 'line' in leg:
                    speech_output += u"Bus " + leg['line']
                else:
                    speech_output += u"Bus"
            elif leg['type'] == "walk":
                speech_output += u"Fussweg"
        speech_output += u" <break/>"
        speech_output += u" Abfahrt " + journey['start_loc']
        speech_output += u" um " + journey['start_datetime'].strftime(
            '%H:%M') + " . "
        speech_output += u" Ankunft " + journey['end_loc']
        speech_output += u" um " + journey['end_datetime'].strftime(
            '%H:%M') + " . "
    speech_output += u"<break/>"
    return speech_output
def get_stopdata(stop_point_id, lines, getraw=False):
    #--------------------------------------------------------------------------
    # returns the next buses of given lines from a bus stop
    #
    parameter = {'ReturnList': returnlist, 'StopID': stop_point_id}
    if lines:
        parameter['LineID'] = ",".join(lines)
    request = requests.get(baseurl.format(url_i), params=parameter)
    if request.status_code != 200:
        myask_log.error("ASEAG API returned error code" +
                        str(request.status_code))
        return []
    if request.headers['content-type'] != 'application/json;charset=UTF-8':
        myask_log.error("ASEAG API returned invalid result")
        return []
    if getraw:
        return request.text
    else:
        data = deduplication(parsejson(request.text, request.encoding))
        return data
def get_routedata(origin_ID, destination_ID):
    #---------------------------------------------------------------------------
    # core function for retrieving a connection from the ASEAG server
    # 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)
    # RETURNS:
    # raw JSON data structure with the connection results
    #---------------------------------------------------------------------------
    parameter = {
        'startStopId': origin_ID,
        'endStopId': destination_ID,
        'departureTime': unix_epoch_from_now(),
        'maxNumResults': 4
    }
    request = requests.get(baseurl.format(url_j), params=parameter)
    if request.status_code != 200:
        myask_log.error(u"ASEAG API call returned unexpected status code '" +
                        str(request.status_code) + u"' \nRequest: " +
                        str(request))
        return None
    if 'content-type' not in request.headers:
        myask_log.error(u"ASEAG API call misses header '" +
                        str(request.headers) + u"' \nRequest: " + str(request))
        return None
    if request.headers['content-type'] != 'application/json;charset=UTF-8':
        myask_log.error(u"ASEAG API call returned unexpected header '" +
                        str(request.headers['content-type']) +
                        u"' \nRequest: " + str(request))
        return None
    data = request.json()
    return data
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)
Exemple #10
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
def main():
    #        - aseag_api.py [-oid DEP_STOP_ID] [-did DESTINATION_STOP_ID] [-line LINENUMBER] [-dir IN_OUT] [-t TRANSPORT] [-raw]
    #       - if no origin is given, system uses default-stop
    #       - if no destination is given, system shows departures from origin
    #       output: if '-raw' is given, present raw output from ASEAG API, else give simplified output
    print("in main")
    parser = argparse.ArgumentParser()
    parser.add_argument("-v",
                        "--verbosity",
                        type=int,
                        help="define output verbosity")
    org_group = parser.add_mutually_exclusive_group(required=True)
    org_group.add_argument(
        "-oid",
        "--origin_id",
        type=int,
        help="6-digit station ID of origin (departure) station")
    org_group.add_argument("-oname",
                           "--origin_name",
                           type=str,
                           help="name of origin (departure) station")
    dep_group = parser.add_mutually_exclusive_group()
    dep_group.add_argument("-did",
                           "--destination_id",
                           type=int,
                           help="6-digit station ID of destination station")
    dep_group.add_argument("-dname",
                           "--destination_name",
                           type=str,
                           help="name of destination station")

    parser.add_argument("-l", "--busline", type=str, help="Line (NR or string")
    parser.add_argument("-dir",
                        "--direction",
                        type=int,
                        help="direction: 1=inward 2=outward")
    parser.add_argument("-raw",
                        "--raw_mode",
                        action="store_true",
                        help="If set, output raw API results")
    args = parser.parse_args()

    if args.verbosity:
        myask_log.SetDebugLevel(args.verbosity)

    if args.origin_id:
        origin_id = args.origin_id
    elif args.origin_name:
        origin_id_list = get_stoppoint(args.origin_name)
        if len(origin_id_list) != 1:
            myask_log.error("no unique stop found")
            for alt in origin_id_list:
                print alt
            return
        else:
            origin_id = origin_id_list[0][0]
    else:
        myask_log.error("origin destination not specified")
    origin_id = int(origin_id)  # just to be sure

    if origin_id < 100000 or origin_id > 999999:
        myask_log.error("invalid origin id '" + str(origin_id) + "#")

    if args.destination_id:
        destination_id = args.destination_id
    elif args.destination_name:
        destination_id_list = get_stoppoint(args.destination_name)
        if len(destination_id_list) != 1:
            myask_log.error("no unique stop found")
            for alt in destination_id_list:
                print alt
            return
        else:
            destination_id = destination_id_list[0][0]
    else:
        destination_id = 0  # code for not set
    destination_id = int(destination_id)  # just to be sure

    if destination_id != 0 and (destination_id < 100000
                                or destination_id > 999999):
        myask_log.error("invalid destination_id  '" + str(destination_id) +
                        "#")
        return
    if args.busline: busline = args.busline
    else: busline = ""

    if args.direction:
        if args.direction == 1: direction = "DIR_INWARD"
        elif args.direction == 2: direction = "DIR_OUTWARD"
        else:
            myask_log.error("invalid direction  '" + str(args.direction) +
                            " (must be 1 (inbound) or 2 (outbound)")
            return
    else:
        direction = ""
    # now process the commands
    if destination_id == 0:  # (departures only)
        if args.raw_mode:
            if direction != "":
                print "Departure Post-Filter for direction not supported in raw mode"
            if busline == "": buslines = []
            else: buslines = [busline]
            results = get_stopdata(origin_id, buslines, getraw=True)
            print results
        else:
            results = GetDepartures(origin_id,
                                    busline,
                                    direction,
                                    utc_offset=1)
            for result in results:
                print result

    else:  # origin and destination
        if args.raw_mode:
            if busline != "":
                print "Connection Post-Filter for busline not supported in raw mode"
            print "Raw results-----------------"
            output = get_routedata(origin_id, destination_id)
            print json.dumps(output, indent=4, sort_keys=False)
        else:
            match, results = GetConnectionsWithBus(origin_id,
                                                   destination_id,
                                                   busline,
                                                   utc_offset=1)
            print "Match: " + str(match)
            for result in results:
                print result