diff --git a/api_wrapper.go b/api_wrapper.go index 6a4b02b..dfac304 100644 --- a/api_wrapper.go +++ b/api_wrapper.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "net/http" "net/url" + "strconv" "time" ) @@ -14,20 +15,26 @@ const ( baseURLWidgetDM = "http://www3.vvs.de/vvs/widget/XML_DM_REQUEST" ) +const ( + defaultDepartureLimit = 100 + defaultArrivalLimit = 100 + defaultJourneyLimit = 100 +) + // GetJourney initiates a request to retrieve journey information between two locations at a specified time. // It uses the VVS (Verkehrs- und Tarifverbund Stuttgart) API to calculate routes, taking into account various transport options and preferences. // // Parameters: // - r JourneyRequest: Struct containing the essential information for the journey request. -// - OrigId: The ID or code representing the origin location for the journey. This should be in the format recognized by the VVS API, e.g., "de:08111:2599". -// - DstId: The ID or code representing the destination location for the journey, formatted similarly to OrigId. -// - TimeAt: Pointer to a time.Time object specifying the desired departure or arrival time for the journey. -// - Limit: Pointer to an integer specifying the maximum number of journey options to return. If nil, a default value defined by the API will be used. -// - LangCode: Pointer to a string specifying the language code for the response, e.g., "de" for German. If nil, the API's default language will be used. +// - OrigId: The ID or code representing the origin location for the journey. This should be in the format recognized by the VVS API, e.g., "de:08111:2599". +// - DstId: The ID or code representing the destination location for the journey, formatted similarly to OrigId. +// - TimeAt: Pointer to a time.Time object specifying the desired departure or arrival time for the journey. +// - Limit: Pointer to an integer specifying the maximum number of journey options to return. If nil, a default value defined by the API will be used. +// - LangCode: Pointer to a string specifying the language code for the response, e.g., "de" for German. If nil, the API's default language will be used. // // - reqParams ...ReqParam: An optional slice of ReqParam structs allowing for additional parameters to be specified for the journey request. These can include: -// - Name: The name of the parameter, matching the constant names defined for VVS API parameters, e.g., ParamCalcOneDirection. -// - Value: The value of the parameter, as a string, e.g., "1" for true or specific values like "EPSG:4326" for coordinate formats. +// - Name: The name of the parameter, matching the constant names defined for VVS API parameters, e.g., ParamCalcOneDirection. +// - Value: The value of the parameter, as a string, e.g., "1" for true or specific values like "EPSG:4326" for coordinate formats. // // The function supports various optional parameters that can be used to refine the journey search, including but not limited to: // - ChangeSpeed: Adjusts the assumed speed of changing between transport modes. @@ -39,17 +46,21 @@ const ( // - error: An error object that will be non-nil if there was an issue processing the request or communicating with the VVS API. // // Example usage: -// journeyReq := JourneyRequest{ -// OrigId: "de:08111:2599", -// DstId: "de:08111:6075", -// TimeAt: time.Now(), -// Limit: 10, -// LangCode: "de", -// } +// +// journeyReq := JourneyRequest{ +// OrigId: "de:08111:2599", +// DstId: "de:08111:6075", +// TimeAt: time.Now(), +// Limit: 10, +// LangCode: "de", +// } +// // journeyResp, err := GetJourney(journeyReq, ReqParam{Name: ParamRouteType, Value: "leasttime"}) -// if err != nil { -// // Handle error -// } +// +// if err != nil { +// // Handle error +// } +// // // Process journeyResp func GetJourney(r JourneyRequest, reqParams ...ReqParam) (*JourneyResponse, error) { // Prepare query parameters @@ -59,6 +70,11 @@ func GetJourney(r JourneyRequest, reqParams ...ReqParam) (*JourneyResponse, erro setDefaultJourneyReqParams(params) // Set dynamic values separately + limit := defaultJourneyLimit + if r.Limit != nil { + limit = *r.Limit + } + limitParam := strconv.Itoa(limit) timeAt := time.Now() if r.TimeAt != nil { timeAt = *r.TimeAt @@ -70,6 +86,7 @@ func GetJourney(r JourneyRequest, reqParams ...ReqParam) (*JourneyResponse, erro params.Set(ParamItdTime, timeAt.Format("1504")) params.Set(ParamNameDestination, dst) params.Set(ParamNameOrigin, orig) + params.Set(ParamLimit, limitParam) // override optional params6 overrideReqParams(params, reqParams...) @@ -110,32 +127,56 @@ func GetJourney(r JourneyRequest, reqParams ...ReqParam) (*JourneyResponse, erro // // Parameters: // - r ArrivalRequest: A struct containing the base request parameters such as station ID and request time. +// // - OrigId (string): The origin station identifier. Not used in this context but can be set for consistency. +// // - DstId (string): The destination station identifier. This is typically the station ID for which arrivals are requested. +// // - TimeAt (*time.Time): The specific date and time for which arrival information is requested. If nil, current time is assumed. +// // - Limit (*int): The maximum number of arrival entries to retrieve. If nil, a default limit is applied. +// // - LangCode (*string): The language code for the response (e.g., "de" for German). If nil, a default language is used. // -// - reqParams ...ReqParam: Optional parameters to further customize the request. Each ReqParam consists of a Name and Value. -// Supported optional parameters (refer to constants for parameter names): +// - reqParams ...ReqParam: Optional parameters to further customize the request. Each ReqParam consists of a Name and Value. +// Supported optional parameters (refer to constants for parameter names): +// // - ParamLocationServerActive: Activates the location server for processing the request. +// // - ParamLsShowTrainsExplicit: Specifies whether trains should be shown explicitly in the response. +// // - ParamStateless: Indicates if the request should be processed without maintaining state. +// // - ParamLanguage: Sets the language of the response. +// // - ParamSpEncId: Security parameter, typically "0". +// // - ParamAnySigWhenPerfectNoOtherMatches: Used to refine search results. +// // - ParamLimit: Controls the maximum number of results returned. +// // - ParamDepArr: Indicates whether departure or arrival times are requested ("arrival" for arrivals). +// // - ParamTypeDm: Specifies the type of data management request. +// // - ParamAnyObjFilterDm: Filters objects based on specified criteria. +// // - ParamDeleteAssignedStops: Indicates whether assigned stops should be removed from the response. +// // - ParamNameDm: The name or ID of the station for which arrivals are being requested. +// // - ParamMode: Specifies the mode of transport. +// // - ParamDmLineSelectionAll: Determines if all lines should be selected in the request. +// // - ParamUseRealtime: Specifies whether real-time data should be used. +// // - ParamOutputFormat: Defines the output format of the response. +// // - ParamCoordOutputFormat: Sets the coordinate format for the response. +// // - ParamItdDateTimeDepArr: Specifies the desired time for departure or arrival. +// // - Additional parameters related to date and time of the request: ParamItdDateYear, ParamItdDateMonth, ParamItdDateDay, ParamItdTimeHour, ParamItdTimeMinute. // // Returns: @@ -143,9 +184,11 @@ func GetJourney(r JourneyRequest, reqParams ...ReqParam) (*JourneyResponse, erro // // Example usage: // response, err := GetArrivals(ArrivalRequest{DstId: "stationID", TimeAt: &time.Now()}, ReqParam{Name: ParamLimit, Value: "5"}) -// if err != nil { -// // handle error -// } +// +// if err != nil { +// // handle error +// } +// // // process response func GetArrivals(r ArrivalRequest, reqParams ...ReqParam) (*ArrivalResponse, error) { // Prepare query parameters @@ -153,6 +196,11 @@ func GetArrivals(r ArrivalRequest, reqParams ...ReqParam) (*ArrivalResponse, err setDefaultArrivalReqParams(params) + limit := defaultArrivalLimit + if r.Limit != nil { + limit = *r.Limit + } + limitParam := strconv.Itoa(limit) timeAt := time.Now() if r.TimeAt != nil { timeAt = *r.TimeAt @@ -170,6 +218,7 @@ func GetArrivals(r ArrivalRequest, reqParams ...ReqParam) (*ArrivalResponse, err params.Set(ParamItdTimeHour, hour) params.Set(ParamItdTimeMinute, minute) params.Set(ParamNameDm, stationId) + params.Set(ParamLimit, limitParam) overrideReqParams(params, reqParams...) @@ -209,31 +258,54 @@ func GetArrivals(r ArrivalRequest, reqParams ...ReqParam) (*ArrivalResponse, err // // Parameters: // - r DepartureRequest: A struct containing the base request parameters such as station ID and request time. +// // - OrigId (string): The origin station identifier. In the context of departures, this is the station ID from which departures are requested. +// // - DstId (string): The destination station identifier. Not typically used for departure requests but can be set for API consistency. +// // - TimeAt (*time.Time): The specific date and time for which departure information is requested. If nil, the current time is assumed. +// // - Limit (*int): The maximum number of departure entries to retrieve. If nil, a default limit is applied. +// // - LangCode (*string): The language code for the response (e.g., "de" for German). If nil, a default language is used. // -// - reqParams ...ReqParam: Optional parameters to further customize the request. Each ReqParam consists of a Name and Value. -// Supported optional parameters (refer to constants for parameter names): +// - reqParams ...ReqParam: Optional parameters to further customize the request. Each ReqParam consists of a Name and Value. +// Supported optional parameters (refer to constants for parameter names): +// // - ParamLocationServerActive: Activates the location server for processing the request. +// // - ParamLsShowTrainsExplicit: Specifies whether trains should be shown explicitly in the response. +// // - ParamStateless: Indicates if the request should be processed without maintaining state. +// // - ParamLanguage: Sets the language of the response. +// // - ParamSpEncId: Security parameter, typically "0". +// // - ParamAnySigWhenPerfectNoOtherMatches: Used to refine search results. +// // - ParamLimit: Controls the maximum number of results returned. +// // - ParamDepArr: Indicates whether departure or arrival times are requested ("departure" for departures). +// // - ParamTypeDm: Specifies the type of data management request. +// // - ParamAnyObjFilterDm: Filters objects based on specified criteria. +// // - ParamDeleteAssignedStops: Indicates whether assigned stops should be removed from the response. +// // - ParamNameDm: The name or ID of the station for which departures are being requested. +// // - ParamMode: Specifies the mode of transport. +// // - ParamDmLineSelectionAll: Determines if all lines should be selected in the request. +// // - ParamUseRealtime: Specifies whether real-time data should be used. +// // - ParamOutputFormat: Defines the output format of the response. +// // - ParamCoordOutputFormat: Sets the coordinate format for the response. +// // - Additional parameters related to date and time of the request: ParamItdDateYear, ParamItdDateMonth, ParamItdDateDay, ParamItdTimeHour, ParamItdTimeMinute. // // Returns: @@ -241,9 +313,11 @@ func GetArrivals(r ArrivalRequest, reqParams ...ReqParam) (*ArrivalResponse, err // // Example usage: // response, err := GetDepartures(DepartureRequest{OrigId: "stationID", TimeAt: &time.Now()}, ReqParam{Name: ParamLimit, Value: "10"}) -// if err != nil { -// // handle error -// } +// +// if err != nil { +// // handle error +// } +// // // process response func GetDepartures(r DepartureRequest, reqParams ...ReqParam) (*DepartureResponse, error) { // Assemble the query parameters @@ -251,6 +325,11 @@ func GetDepartures(r DepartureRequest, reqParams ...ReqParam) (*DepartureRespons setDefaultDepartureReqParams(params) + limit := defaultDepartureLimit + if r.Limit != nil { + limit = *r.Limit + } + limitParam := strconv.Itoa(limit) timeAt := time.Now() if r.TimeAt != nil { timeAt = *r.TimeAt @@ -268,6 +347,7 @@ func GetDepartures(r DepartureRequest, reqParams ...ReqParam) (*DepartureRespons params.Set(ParamItdTimeHour, hour) params.Set(ParamItdTimeMinute, minute) params.Set(ParamNameDm, stationId) + params.Set(ParamLimit, limitParam) overrideReqParams(params, reqParams...) diff --git a/api_wrapper_test.go b/api_wrapper_test.go index 9fa8348..364e69f 100644 --- a/api_wrapper_test.go +++ b/api_wrapper_test.go @@ -8,6 +8,7 @@ import ( ) func TestGetJourney(t *testing.T) { + testLimit := 4 testCases := []struct { name string orig string @@ -22,6 +23,13 @@ func TestGetJourney(t *testing.T) { dst: station.HAUPTBAHNHOF_TIEF_STUTTGART, errExpected: false, }, + { + name: "When required params and limit are given then journeys no more than limit are returned", + orig: station.BOPSER_STUTTGART, + dst: station.HAUPTBAHNHOF_TIEF_STUTTGART, + errExpected: false, + limit: &testLimit, + }, } for _, tc := range testCases { @@ -43,6 +51,10 @@ func TestGetJourney(t *testing.T) { t.Fatalf("Error occured: %v\n", err) } + if tc.limit != nil && len(res.Journeys) > *tc.limit { + t.Fatalf("Error occured: %v\n", err) + } + if res == nil { t.Fatalf("Response is nil") } @@ -51,6 +63,7 @@ func TestGetJourney(t *testing.T) { } func TestGetArrivals(t *testing.T) { + testLimit := 4 testCases := []struct { name string stationId string @@ -63,6 +76,12 @@ func TestGetArrivals(t *testing.T) { stationId: station.BOPSER_STUTTGART, errExpected: false, }, + { + name: "When required params and limit are given then arrivals no more than limit are returned", + stationId: station.BOPSER_STUTTGART, + errExpected: false, + limit: &testLimit, + }, } for _, tc := range testCases { @@ -83,6 +102,10 @@ func TestGetArrivals(t *testing.T) { t.Fatalf("Error occured: %v\n", err) } + if tc.limit != nil && len(res.ArrivalList) > *tc.limit { + t.Fatalf("Error occured: %v\n", err) + } + if res == nil { t.Fatalf("Response is nil") } @@ -91,6 +114,7 @@ func TestGetArrivals(t *testing.T) { } func TestGetDepartures(t *testing.T) { + testLimit := 4 testCases := []struct { name string stationId string @@ -103,6 +127,12 @@ func TestGetDepartures(t *testing.T) { stationId: station.BOPSER_STUTTGART, errExpected: false, }, + { + name: "When required params and limit are given then departures no more then limit are returned", + stationId: station.BOPSER_STUTTGART, + errExpected: false, + limit: &testLimit, + }, } for _, tc := range testCases { @@ -123,6 +153,10 @@ func TestGetDepartures(t *testing.T) { t.Fatalf("Error occured: %v\n", err) } + if tc.limit != nil && len(res.DepartureList) > *tc.limit { + t.Fatalf("Error occured: %v\n", err) + } + if res == nil { t.Fatalf("Response is nil") }