update transitous connection
This commit is contained in:
parent
8680f56006
commit
63fc3e7c83
|
@ -0,0 +1,105 @@
|
|||
package transitous
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// Client represents a Transitous API client
|
||||
type Client struct {
|
||||
baseURL string
|
||||
httpClient *http.Client
|
||||
}
|
||||
|
||||
// NewClient creates a new Transitous client
|
||||
func NewClient(baseURL string) *Client {
|
||||
return &Client{
|
||||
baseURL: baseURL,
|
||||
httpClient: &http.Client{
|
||||
Timeout: 30 * time.Second,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// PlanParams represents the parameters for route planning
|
||||
type PlanParams struct {
|
||||
FromPlace string
|
||||
ToPlace string
|
||||
Time *time.Time
|
||||
}
|
||||
|
||||
// PlanResponse represents the response from the Transitous API
|
||||
type PlanResponse struct {
|
||||
Itineraries []Itinerary `json:"itineraries"`
|
||||
}
|
||||
|
||||
// PlanWithResponse plans a route and returns the response
|
||||
func (c *Client) PlanWithResponse(ctx context.Context, params *PlanParams) (*TransitousResponse, error) {
|
||||
// Build URL with query parameters
|
||||
u, err := url.Parse(fmt.Sprintf("%s/api/v4/plan", c.baseURL))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse base URL: %w", err)
|
||||
}
|
||||
|
||||
query := u.Query()
|
||||
query.Set("fromPlace", params.FromPlace)
|
||||
query.Set("toPlace", params.ToPlace)
|
||||
|
||||
if params.Time != nil {
|
||||
// Use ISO 8601 format with timezone like in the example
|
||||
query.Set("time", params.Time.Format(time.RFC3339))
|
||||
}
|
||||
|
||||
// Additional parameters matching the example
|
||||
query.Set("withFares", "true")
|
||||
query.Set("fastestDirectFactor", "1.5")
|
||||
query.Set("joinInterlinedLegs", "false")
|
||||
query.Set("maxMatchingDistance", "250")
|
||||
query.Set("arriveBy", "true")
|
||||
|
||||
u.RawQuery = query.Encode()
|
||||
|
||||
// Create HTTP request
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create request: %w", err)
|
||||
}
|
||||
|
||||
req.Header.Set("Accept", "application/json")
|
||||
req.Header.Set("User-Agent", "COOPGO-Platform/1.0")
|
||||
|
||||
log.Debug().
|
||||
Str("url", u.String()).
|
||||
Msg("Making Transitous API request")
|
||||
|
||||
// Execute request
|
||||
resp, err := c.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("request failed: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("API request failed with status %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
// Parse response
|
||||
var transitousResponse TransitousResponse
|
||||
if err := json.NewDecoder(resp.Body).Decode(&transitousResponse); err != nil {
|
||||
return nil, fmt.Errorf("failed to decode response: %w", err)
|
||||
}
|
||||
|
||||
log.Debug().
|
||||
Str("from", params.FromPlace).
|
||||
Str("to", params.ToPlace).
|
||||
Int("itineraries", len(transitousResponse.Itineraries)).
|
||||
Msg("Transitous API response received")
|
||||
|
||||
return &transitousResponse, nil
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
package transitous
|
||||
|
||||
import "time"
|
||||
|
||||
// TransitousResponse represents the top-level response from Transitous API
|
||||
type TransitousResponse struct {
|
||||
RequestParameters map[string]interface{} `json:"requestParameters"`
|
||||
DebugOutput map[string]interface{} `json:"debugOutput"`
|
||||
From Place `json:"from"`
|
||||
To Place `json:"to"`
|
||||
Direct []interface{} `json:"direct"`
|
||||
Itineraries []Itinerary `json:"itineraries"`
|
||||
PreviousPageCursor string `json:"previousPageCursor,omitempty"`
|
||||
NextPageCursor string `json:"nextPageCursor,omitempty"`
|
||||
}
|
||||
|
||||
// Itinerary represents a complete journey from origin to destination
|
||||
type Itinerary struct {
|
||||
StartTime time.Time `json:"startTime"`
|
||||
EndTime time.Time `json:"endTime"`
|
||||
Duration int `json:"duration"` // Duration in seconds
|
||||
Legs []Leg `json:"legs"`
|
||||
}
|
||||
|
||||
// Leg represents a single segment of a journey
|
||||
type Leg struct {
|
||||
Mode string `json:"mode"` // WALK, BUS, TRAIN, etc.
|
||||
StartTime time.Time `json:"startTime"`
|
||||
EndTime time.Time `json:"endTime"`
|
||||
Duration int `json:"duration"` // Duration in seconds
|
||||
Distance float64 `json:"distance"` // Distance in meters
|
||||
From Place `json:"from"`
|
||||
To Place `json:"to"`
|
||||
Route *Route `json:"route,omitempty"`
|
||||
AgencyName string `json:"agencyName,omitempty"`
|
||||
Headsign string `json:"headsign,omitempty"`
|
||||
RouteShortName string `json:"routeShortName,omitempty"`
|
||||
RouteColor string `json:"routeColor,omitempty"`
|
||||
RouteTextColor string `json:"routeTextColor,omitempty"`
|
||||
}
|
||||
|
||||
// Place represents a location (stop, station, or coordinate)
|
||||
type Place struct {
|
||||
Name string `json:"name"`
|
||||
Lat float64 `json:"lat"`
|
||||
Lon float64 `json:"lon"`
|
||||
StopId string `json:"stopId,omitempty"`
|
||||
StopCode string `json:"stopCode,omitempty"`
|
||||
}
|
||||
|
||||
// Route represents a transit route
|
||||
type Route struct {
|
||||
AgencyName string `json:"agencyName"`
|
||||
ShortName string `json:"shortName"`
|
||||
LongName string `json:"longName"`
|
||||
Type int `json:"type"`
|
||||
Color string `json:"color"`
|
||||
TextColor string `json:"textColor"`
|
||||
Url string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
// Agency represents a transit agency
|
||||
type Agency struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Url string `json:"url"`
|
||||
Timezone string `json:"timezone"`
|
||||
Lang string `json:"lang,omitempty"`
|
||||
Phone string `json:"phone,omitempty"`
|
||||
}
|
||||
|
||||
// Stop represents a transit stop or station
|
||||
type Stop struct {
|
||||
Id string `json:"id"`
|
||||
Code string `json:"code,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Lat float64 `json:"lat"`
|
||||
Lon float64 `json:"lon"`
|
||||
ZoneId string `json:"zoneId,omitempty"`
|
||||
Url string `json:"url,omitempty"`
|
||||
LocationType int `json:"locationType,omitempty"`
|
||||
ParentStation string `json:"parentStation,omitempty"`
|
||||
Timezone string `json:"timezone,omitempty"`
|
||||
WheelchairBoarding int `json:"wheelchairBoarding,omitempty"`
|
||||
}
|
Loading…
Reference in New Issue