initial commit
This commit is contained in:
5
interoperability/ocss/README.md
Normal file
5
interoperability/ocss/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Golang interoperability library for the OCSS standard
|
||||
|
||||
This library is part of the COOPGO Technical Platform and provides client and server functionalities to implement OCSS compliant REST API.
|
||||
|
||||
OCSS (Open Carpooling Service Standard) is a carpooling interoperability standard defined by the french carpooling ecosystem, including COOPGO, Mobicoop, Klaxit, Blablacar, ...
|
||||
34
interoperability/ocss/bookings.go
Normal file
34
interoperability/ocss/bookings.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package ocss
|
||||
|
||||
import "time"
|
||||
|
||||
type BookingStatus int64
|
||||
|
||||
const (
|
||||
BookingWaitingConfirmation BookingStatus = iota
|
||||
BookingConfirmed
|
||||
BookingCancelled
|
||||
BookingCompletedPendingValidation
|
||||
BookingValidated
|
||||
)
|
||||
|
||||
type Booking struct {
|
||||
ID string `json:"id"` // TODO check uuidv4
|
||||
Driver User `json:"driver"`
|
||||
Passenger User `json:"passenger"`
|
||||
PassengerPickupDate time.Time `json:"passengerPickupDate"`
|
||||
PassengerPickupLat float64 `json:"passengerPickupLat"`
|
||||
PassengerPickupLng float64 `json:"passengerPickupLng"`
|
||||
PassengerDropLat float64 `json:"passengerDropLat"`
|
||||
PassengerDropLng float64 `json:"passengerDropLng"`
|
||||
PassengerPickupAddress *string `json:"passengerPickupAddress,omitempty"`
|
||||
PassengerDropAddress *string `json:"passengerDropAddress,omitempty"`
|
||||
Status BookingStatus `json:"status"`
|
||||
Distance *int64 `json:"distance,omitempty"`
|
||||
Duration *time.Duration `json:"duration,omitempty"`
|
||||
WebUrl *string `json:"webUrl,omitempty"`
|
||||
Price Price `json:"price"`
|
||||
Car *Car `json:"car"`
|
||||
DriverJourneyID string `json:"driverJourneyId"`
|
||||
PassengerJourneyID string `json:"passengerJourneyId"`
|
||||
}
|
||||
50
interoperability/ocss/carpool-bookings.go
Normal file
50
interoperability/ocss/carpool-bookings.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package ocss
|
||||
|
||||
import "time"
|
||||
|
||||
type CarpoolBookingStatus int64
|
||||
|
||||
const (
|
||||
CarpoolBookingWaitingConfirmation CarpoolBookingStatus = iota
|
||||
CarpoolBookingConfirmed
|
||||
CarpoolBookingCancelled
|
||||
CarpoolBookingCompletedPendingValidation
|
||||
CarpoolBookingValidated
|
||||
)
|
||||
|
||||
type CarpoolBookingEventData struct {
|
||||
CarpoolBooking
|
||||
DriverCarpoolBooking
|
||||
PassengerCarpoolBooking
|
||||
}
|
||||
|
||||
type CarpoolBookingEvent struct {
|
||||
ID string `json:"id"` // TODO validate UUID
|
||||
IDToken string `json:"idToken"`
|
||||
Data CarpoolBookingEventData `json:"data"`
|
||||
}
|
||||
|
||||
type CarpoolBooking struct {
|
||||
ID string `json:"id"`
|
||||
PassengerPickupDate time.Time `json:"passengerPickupDate"`
|
||||
PassengerPickupLat float64 `json:"passengerPickupLat"`
|
||||
PassengerPickupLng float64 `json:"passengerPickupLng"`
|
||||
PassengerDropLat float64 `json:"passengerDropLat"`
|
||||
PassengerDropLng float64 `json:"passengerDropLng"`
|
||||
PassengerPickupAddress *string `json:"passengerPickupAddress,omitempty"`
|
||||
PassengerDropAddress *string `json:"passengerDropAddress,omitempty"`
|
||||
Status CarpoolBookingStatus `json:"status"`
|
||||
Distance *int64 `json:"distance,omitempty"`
|
||||
Duration *time.Duration `json:"duration,omitempty"`
|
||||
WebUrl string `json:"webUrl"`
|
||||
}
|
||||
|
||||
type PassengerCarpoolBooking struct {
|
||||
Passenger User `json:"passenger"`
|
||||
}
|
||||
|
||||
type DriverCarpoolBooking struct {
|
||||
Driver User `json:"driver"`
|
||||
Price Price `json:"price"`
|
||||
Car *Car `json:"car,omitempty"`
|
||||
}
|
||||
6
interoperability/ocss/cars.go
Normal file
6
interoperability/ocss/cars.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package ocss
|
||||
|
||||
type Car struct {
|
||||
Model *string `json:"model,omitempty"`
|
||||
Brand *string `json:"brand,omitempty"`
|
||||
}
|
||||
9
interoperability/ocss/client.go
Normal file
9
interoperability/ocss/client.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package ocss
|
||||
|
||||
import "errors"
|
||||
|
||||
type Client struct{}
|
||||
|
||||
func (c Client) GetDriverJourneys() ([]DriverJourney, error) {
|
||||
return nil, errors.New("not implemented")
|
||||
}
|
||||
8
interoperability/ocss/go.mod
Normal file
8
interoperability/ocss/go.mod
Normal file
@@ -0,0 +1,8 @@
|
||||
module git.coopgo.io/coopgo-platform/carpool-service/interoperability/ocss
|
||||
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/gorilla/schema v1.2.0
|
||||
golang.org/x/crypto v0.7.0
|
||||
)
|
||||
4
interoperability/ocss/go.sum
Normal file
4
interoperability/ocss/go.sum
Normal file
@@ -0,0 +1,4 @@
|
||||
github.com/gorilla/schema v1.2.0 h1:YufUaxZYCKGFuAq3c96BOhjgd5nmXiOY9NGzF247Tsc=
|
||||
github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
|
||||
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
57
interoperability/ocss/journeys.go
Normal file
57
interoperability/ocss/journeys.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package ocss
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type JourneyScheduleType int64
|
||||
|
||||
const (
|
||||
Planned JourneyScheduleType = iota
|
||||
Dynamic
|
||||
Line
|
||||
)
|
||||
|
||||
func (t JourneyScheduleType) MarshalJSON() ([]byte, error) {
|
||||
types := map[JourneyScheduleType]string{
|
||||
Planned: "\"PLANNED\"",
|
||||
Dynamic: "\"DYNAMIC\"",
|
||||
Line: "\"Line\"",
|
||||
}
|
||||
|
||||
return []byte(types[t]), nil
|
||||
}
|
||||
|
||||
type JSONTime time.Time
|
||||
|
||||
func (t JSONTime) MarshalJSON() ([]byte, error) {
|
||||
//do your serializing here
|
||||
stamp := fmt.Sprintf("%v", time.Time(t).Unix())
|
||||
return []byte(stamp), nil
|
||||
}
|
||||
|
||||
type JourneySchedule struct {
|
||||
ID *string `json:"id,omitempty"`
|
||||
PassengerPickupDate JSONTime `json:"passengerPickupDate"`
|
||||
PassengerDepartureDate *JSONTime `json:"passengerDepartureDate,omitempty"`
|
||||
DriverDepartureDate *JSONTime `json:"driverDepartureDate,omitempty"`
|
||||
WebUrl *string `json:"webUrl,omitempty"`
|
||||
Type JourneyScheduleType `json:"type"`
|
||||
}
|
||||
|
||||
type DriverJourney struct {
|
||||
DriverTrip
|
||||
JourneySchedule
|
||||
|
||||
AvailableSteats *int `json:"requestedSeats,omitempty"`
|
||||
Price *Price `json:"price,omitempty"`
|
||||
}
|
||||
|
||||
type PassengerJourney struct {
|
||||
PassengerTrip
|
||||
JourneySchedule
|
||||
|
||||
//TODO how to handle requested driverDepartureDate
|
||||
RequestedSteats *int64 `json:"requestedSeats,omitempty"`
|
||||
}
|
||||
9
interoperability/ocss/preferences.go
Normal file
9
interoperability/ocss/preferences.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package ocss
|
||||
|
||||
type Preferences struct {
|
||||
Smoking *bool `json:"smoking,omitempty"`
|
||||
Animals *bool `json:"animals,omitempty"`
|
||||
Music *bool `json:"music,omitempty"`
|
||||
IsTalker *bool `json:"isTalker,omitempty"`
|
||||
LuggageSize *int64 `json:"luggageSize,omitempty"`
|
||||
}
|
||||
15
interoperability/ocss/prices.go
Normal file
15
interoperability/ocss/prices.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package ocss
|
||||
|
||||
type PriceType int64
|
||||
|
||||
const (
|
||||
Free PriceType = iota
|
||||
Paying
|
||||
Unknown
|
||||
)
|
||||
|
||||
type Price struct {
|
||||
Type *PriceType `json:"type,omitempty"`
|
||||
Amount *float64 `json:"amount,omitempty"`
|
||||
Currency *string `json:"currency,omitempty"`
|
||||
}
|
||||
19
interoperability/ocss/schedules.go
Normal file
19
interoperability/ocss/schedules.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package ocss
|
||||
|
||||
type Day int64
|
||||
|
||||
const (
|
||||
Monday Day = iota
|
||||
Tuesday
|
||||
Wednesday
|
||||
Thursday
|
||||
Friday
|
||||
Saturday
|
||||
Sunday
|
||||
)
|
||||
|
||||
type Schedule struct {
|
||||
PassengerPickupDay *Day `json:"passengerPickupDay,omitempty"`
|
||||
|
||||
JourneySchedules *[]JourneySchedule `json:"journeySchedules,omitempty"`
|
||||
}
|
||||
362
interoperability/ocss/server.go
Normal file
362
interoperability/ocss/server.go
Normal file
@@ -0,0 +1,362 @@
|
||||
package ocss
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/schema"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
const OperatorContextKey = "operator"
|
||||
|
||||
type Handler interface {
|
||||
// IV
|
||||
GetDriverJourneys(ctx context.Context, departureLat float64, departureLng float64, arrivalLat float64, arrivalLng float64, departureDate time.Time, timeDelta *time.Duration, departureRadius *float64, arrivalRadius *float64, count *int64) ([]DriverJourney, error)
|
||||
GetPassengerJourneys(ctx context.Context, departureLat float64, departureLng float64, arrivalLat float64, arrivalLng float64, departureDate time.Time, timeDelta *time.Duration, departureRadius *float64, arrivalRadius *float64, count *int64) ([]PassengerJourney, error)
|
||||
GetDriverRegularTrips(ctx context.Context, departureLat float64, departureLng float64, arrivalLat float64, arrivalLng float64, departureTimeOfDay string, departureWeekDays *[]string, timeDelta *time.Duration, departureRadius *float64, arrivalRadius *float64, minDepartureDate *time.Time, maxDepartureDate *time.Time, count *int64) ([]DriverTrip, error)
|
||||
GetPassengerRegularTrips(ctx context.Context, departureLat float64, departureLng float64, arrivalLat float64, arrivalLng float64, departureTimeOfDay string, departureWeekDays *[]string, timeDelta *time.Duration, departureRadius *float64, arrivalRadius *float64, minDepartureDate *time.Time, maxDepartureDate *time.Time, count *int64) ([]PassengerTrip, error)
|
||||
|
||||
//Booking by API
|
||||
PostBookings(ctx context.Context, booking Booking) (*Booking, error)
|
||||
PatchBooking(ctx context.Context, bookingId string, status BookingStatus, message *string) error
|
||||
GetBooking(ctx context.Context, bookingId string) (*Booking, error)
|
||||
|
||||
// Webhooks
|
||||
PostBookingEvents(ctx context.Context, event CarpoolBookingEvent) error
|
||||
|
||||
// Status
|
||||
Status() error
|
||||
}
|
||||
|
||||
type AuthorizedOperator struct {
|
||||
Operator string
|
||||
ApiKey string // encoded using bcrypt
|
||||
}
|
||||
|
||||
type GetDriverJourneysRequest struct {
|
||||
DepartureLat float64 `schema:"departureLat,required"`
|
||||
DepartureLng float64 `schema:"departureLng,required"`
|
||||
ArrivalLat float64 `schema:"arrivalLat,required"`
|
||||
ArrivalLng float64 `schema:"arrivalLng,required"`
|
||||
DepartureDate int64 `schema:"departureDate,required"`
|
||||
TimeDelta *int64 `schema:"timeDelta"`
|
||||
DepartureRadius *float64 `schema:"departureRadius"`
|
||||
ArrivalRadius *float64 `schema:"arrivalRadius"`
|
||||
Count *int64 `schema:"count"`
|
||||
}
|
||||
|
||||
type GetPassengerJourneysRequest struct {
|
||||
DepartureLat float64 `schema:"departureLat,required"`
|
||||
DepartureLng float64 `schema:"departureLng,required"`
|
||||
ArrivalLat float64 `schema:"arrivalLat,required"`
|
||||
ArrivalLng float64 `schema:"arrivalLng,required"`
|
||||
DepartureDate int64 `schema:"departureDate,required"`
|
||||
TimeDelta *int64 `schema:"timeDelta"`
|
||||
DepartureRadius *float64 `schema:"departureRadius"`
|
||||
ArrivalRadius *float64 `schema:"arrivalRadius"`
|
||||
Count *int64 `schema:"count"`
|
||||
}
|
||||
|
||||
type GetDriverRegularTripsRequest struct {
|
||||
DepartureLat float64 `schema:"departureLat,required"`
|
||||
DepartureLng float64 `schema:"departureLng,required"`
|
||||
ArrivalLat float64 `schema:"arrivalLat,required"`
|
||||
ArrivalLng float64 `schema:"arrivalLng,required"`
|
||||
DepartureTimeOfDay string `schema:"departureTimeOfDay,required"`
|
||||
DepartureWeekDays *[]string `schema:"departureWeekdays"`
|
||||
TimeDelta *int64 `schema:"timeDelta"`
|
||||
DepartureRadius *float64 `schema:"departureRadius"`
|
||||
ArrivalRadius *float64 `schema:"arrivalRadius"`
|
||||
MinDepartureDate *int64 `schema:"minDepartureDate"`
|
||||
MaxDepartureDate *int64 `schema:"maxDepartureDate"`
|
||||
Count *int64 `schema:"count"`
|
||||
}
|
||||
|
||||
type GetPassengerRegularTripsRequest struct {
|
||||
DepartureLat float64 `schema:"departureLat,required"`
|
||||
DepartureLng float64 `schema:"departureLng,required"`
|
||||
ArrivalLat float64 `schema:"arrivalLat,required"`
|
||||
ArrivalLng float64 `schema:"arrivalLng,required"`
|
||||
DepartureTimeOfDay string `schema:"departureTimeOfDay,required"`
|
||||
DepartureWeekDays *[]string `schema:"departureWeekdays"`
|
||||
TimeDelta *int64 `schema:"timeDelta"`
|
||||
DepartureRadius *float64 `schema:"departureRadius"`
|
||||
ArrivalRadius *float64 `schema:"arrivalRadius"`
|
||||
MinDepartureDate *int64 `schema:"minDepartureDate"`
|
||||
MaxDepartureDate *int64 `schema:"maxDepartureDate"`
|
||||
Count *int64 `schema:"count"`
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
Handler Handler
|
||||
AuthorizedOperators []AuthorizedOperator
|
||||
}
|
||||
|
||||
func NewServer(handler Handler) *Server {
|
||||
return &Server{
|
||||
Handler: handler,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) FindApiKey(key string) (operator string, err error) {
|
||||
for _, o := range s.AuthorizedOperators {
|
||||
if e := bcrypt.CompareHashAndPassword([]byte(o.ApiKey), []byte(key)); e == nil {
|
||||
return o.Operator, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", errors.New("operator not found")
|
||||
}
|
||||
|
||||
func (s *Server) AddOperator(operator string, apiKey string) error {
|
||||
encryptedKey, err := bcrypt.GenerateFromPassword([]byte(apiKey), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.AuthorizedOperators = append(s.AuthorizedOperators, AuthorizedOperator{
|
||||
Operator: operator,
|
||||
ApiKey: string(encryptedKey),
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
apiKey := r.Header.Get("X-Api-Key")
|
||||
operator, err := s.FindApiKey(apiKey)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.WithValue(r.Context(), OperatorContextKey, operator)
|
||||
|
||||
p := strings.Split(r.URL.Path, "/")[1:]
|
||||
n := len(p)
|
||||
switch {
|
||||
case r.Method == "GET" && n == 1 && p[0] == "driver_journeys":
|
||||
s.getDriverJourneys(w, r.WithContext(ctx))
|
||||
return
|
||||
case r.Method == "GET" && n == 1 && p[0] == "passenger_journeys":
|
||||
s.getPassengerJourneys(w, r.WithContext(ctx))
|
||||
return
|
||||
case r.Method == "GET" && n == 1 && p[0] == "driver_regular_trips":
|
||||
s.getDriverRegularTrips(w, r.WithContext(ctx))
|
||||
return
|
||||
case r.Method == "GET" && n == 1 && p[0] == "passenger_regular_trips":
|
||||
s.getPassengerRegularTrips(w, r.WithContext(ctx))
|
||||
return
|
||||
default:
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) getDriverJourneys(w http.ResponseWriter, r *http.Request) {
|
||||
var request GetDriverJourneysRequest
|
||||
|
||||
var decoder = schema.NewDecoder()
|
||||
|
||||
if err := decoder.Decode(&request, r.URL.Query()); err != nil {
|
||||
fmt.Println(err)
|
||||
badRequest(w, fmt.Errorf("could not parse the request : %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
departureDate := time.Unix(request.DepartureDate, 0)
|
||||
var timeDelta *time.Duration
|
||||
timeDelta = nil
|
||||
if request.TimeDelta != nil {
|
||||
duration := time.Duration(*request.TimeDelta)
|
||||
timeDelta = &duration
|
||||
}
|
||||
|
||||
driverJourneys, err := s.Handler.GetDriverJourneys(
|
||||
r.Context(),
|
||||
request.DepartureLat,
|
||||
request.DepartureLng,
|
||||
request.ArrivalLat,
|
||||
request.ArrivalLng,
|
||||
departureDate,
|
||||
timeDelta,
|
||||
request.DepartureRadius,
|
||||
request.ArrivalRadius,
|
||||
request.Count)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
jsonError(w, err, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
jsonResponse(w, driverJourneys, http.StatusOK)
|
||||
}
|
||||
|
||||
func (s *Server) getPassengerJourneys(w http.ResponseWriter, r *http.Request) {
|
||||
var request GetPassengerJourneysRequest
|
||||
|
||||
var decoder = schema.NewDecoder()
|
||||
|
||||
if err := decoder.Decode(&request, r.URL.Query()); err != nil {
|
||||
fmt.Println(err)
|
||||
badRequest(w, fmt.Errorf("could not parse the request : %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
departureDate := time.Unix(request.DepartureDate, 0)
|
||||
var timeDelta *time.Duration
|
||||
timeDelta = nil
|
||||
if request.TimeDelta != nil {
|
||||
duration := time.Duration(*request.TimeDelta)
|
||||
timeDelta = &duration
|
||||
}
|
||||
|
||||
passengerJourneys, err := s.Handler.GetPassengerJourneys(
|
||||
r.Context(),
|
||||
request.DepartureLat,
|
||||
request.DepartureLng,
|
||||
request.ArrivalLat,
|
||||
request.ArrivalLng,
|
||||
departureDate,
|
||||
timeDelta,
|
||||
request.DepartureRadius,
|
||||
request.ArrivalRadius,
|
||||
request.Count)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
jsonError(w, err, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
jsonResponse(w, passengerJourneys, http.StatusOK)
|
||||
}
|
||||
|
||||
func (s *Server) getDriverRegularTrips(w http.ResponseWriter, r *http.Request) {
|
||||
var request GetDriverRegularTripsRequest
|
||||
|
||||
var decoder = schema.NewDecoder()
|
||||
|
||||
if err := decoder.Decode(&request, r.URL.Query()); err != nil {
|
||||
fmt.Println(err)
|
||||
badRequest(w, fmt.Errorf("could not parse the request : %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
var minDepartureDate *time.Time
|
||||
if request.MinDepartureDate != nil {
|
||||
d := time.Unix(*request.MinDepartureDate, 0)
|
||||
minDepartureDate = &d
|
||||
}
|
||||
|
||||
var maxDepartureDate *time.Time
|
||||
if request.MinDepartureDate != nil {
|
||||
d := time.Unix(*request.MinDepartureDate, 0)
|
||||
maxDepartureDate = &d
|
||||
}
|
||||
|
||||
var timeDelta *time.Duration
|
||||
timeDelta = nil
|
||||
if request.TimeDelta != nil {
|
||||
duration := time.Duration(*request.TimeDelta)
|
||||
timeDelta = &duration
|
||||
}
|
||||
|
||||
driverJourneys, err := s.Handler.GetDriverRegularTrips(
|
||||
r.Context(),
|
||||
request.DepartureLat,
|
||||
request.DepartureLng,
|
||||
request.ArrivalLat,
|
||||
request.ArrivalLng,
|
||||
request.DepartureTimeOfDay,
|
||||
request.DepartureWeekDays,
|
||||
timeDelta,
|
||||
request.DepartureRadius,
|
||||
request.ArrivalRadius,
|
||||
minDepartureDate,
|
||||
maxDepartureDate,
|
||||
request.Count)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
jsonError(w, err, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
jsonResponse(w, driverJourneys, http.StatusOK)
|
||||
}
|
||||
|
||||
func (s *Server) getPassengerRegularTrips(w http.ResponseWriter, r *http.Request) {
|
||||
var request GetPassengerRegularTripsRequest
|
||||
|
||||
var decoder = schema.NewDecoder()
|
||||
|
||||
if err := decoder.Decode(&request, r.URL.Query()); err != nil {
|
||||
fmt.Println(err)
|
||||
badRequest(w, fmt.Errorf("could not parse the request : %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
var minDepartureDate *time.Time
|
||||
if request.MinDepartureDate != nil {
|
||||
d := time.Unix(*request.MinDepartureDate, 0)
|
||||
minDepartureDate = &d
|
||||
}
|
||||
|
||||
var maxDepartureDate *time.Time
|
||||
if request.MinDepartureDate != nil {
|
||||
d := time.Unix(*request.MinDepartureDate, 0)
|
||||
maxDepartureDate = &d
|
||||
}
|
||||
|
||||
var timeDelta *time.Duration
|
||||
timeDelta = nil
|
||||
if request.TimeDelta != nil {
|
||||
duration := time.Duration(*request.TimeDelta)
|
||||
timeDelta = &duration
|
||||
}
|
||||
|
||||
passengerTrips, err := s.Handler.GetPassengerRegularTrips(
|
||||
r.Context(),
|
||||
request.DepartureLat,
|
||||
request.DepartureLng,
|
||||
request.ArrivalLat,
|
||||
request.ArrivalLng,
|
||||
request.DepartureTimeOfDay,
|
||||
request.DepartureWeekDays,
|
||||
timeDelta,
|
||||
request.DepartureRadius,
|
||||
request.ArrivalRadius,
|
||||
minDepartureDate,
|
||||
maxDepartureDate,
|
||||
request.Count)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
jsonError(w, err, http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
jsonResponse(w, passengerTrips, http.StatusOK)
|
||||
}
|
||||
|
||||
func jsonResponse(w http.ResponseWriter, response any, statuscode int) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(statuscode)
|
||||
err := json.NewEncoder(w).Encode(response)
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
func jsonError(w http.ResponseWriter, err error, statuscode int) {
|
||||
jsonResponse(w, map[string]any{"error": err.Error()}, statuscode)
|
||||
}
|
||||
|
||||
func badRequest(w http.ResponseWriter, err error) {
|
||||
jsonError(w, err, http.StatusBadRequest)
|
||||
}
|
||||
43
interoperability/ocss/trips.go
Normal file
43
interoperability/ocss/trips.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package ocss
|
||||
|
||||
import "time"
|
||||
|
||||
type Trip struct {
|
||||
Operator string `json:"operator"`
|
||||
PassengerPickupLat float64 `json:"passengerPickupLat"`
|
||||
PassengerPickupLng float64 `json:"passengerPickupLng"`
|
||||
PassengerDropLat float64 `json:"passengerDropLat"`
|
||||
PassengerDropLng float64 `json:"passengerDropLng"`
|
||||
Duration time.Duration `json:"duration"`
|
||||
PassengerPickupAddress *string `json:"passengerPickupAddress,omitempty"`
|
||||
PassengerDropAddress *string `json:"passengerDropAddress,omitempty"`
|
||||
Distance *int64 `json:"distance,omitempty"`
|
||||
DriverDepartureLat *float64 `json:"driverDepartureLat,omitempty"`
|
||||
DriverDepartureLng *float64 `json:"driverDepartureLng,omitempty"`
|
||||
DriverArrivalLat *float64 `json:"driverArrivalLat,omitempty"`
|
||||
DriverArrivalLng *float64 `json:"driverArrivalLng,omitempty"`
|
||||
DriverDepartureAddress *string `json:"driverDepartureAddress,omitempty"`
|
||||
DriverArrivalAddress *string `json:"driverArrivalAddress,omitempty"`
|
||||
JourneyPolyline *string `json:"journeyPolyline,omitempty"`
|
||||
//WebUrl *string `json:"webUrl,omitempty"`
|
||||
Preferences *Preferences `json:"preferences,omitempty"`
|
||||
}
|
||||
|
||||
type DriverTrip struct {
|
||||
Driver User `json:"driver"`
|
||||
DepartureToPickupWalkingDistance *int64 `json:"departureToPickupWalkingDistance,omitempty"`
|
||||
DepartureToPickupWalkingDuration *time.Duration `json:"departureToPickupWalkingDuration,omitempty"`
|
||||
DepartureToPickupWalkingPolyline *string `json:"departureToPickupWalkingPolyline,omitempty"`
|
||||
DropoffToArrivalWalkingDistance *int64 `json:"dropoffToArrivalWalkingDistance,omitempty"`
|
||||
DropoffToArrivalWalkingDuration *time.Duration `json:"dropoffToArrivalWalkingDuration,omitempty"`
|
||||
DropoffToArrivalWalkingPolyline *string `json:"dropoffToArrivalWalkingPolyline,omitempty"`
|
||||
Car *Car `json:"car,omitempty"`
|
||||
|
||||
Trip
|
||||
}
|
||||
|
||||
type PassengerTrip struct {
|
||||
Passenger User `json:"passenger"`
|
||||
|
||||
Trip
|
||||
}
|
||||
21
interoperability/ocss/users.go
Normal file
21
interoperability/ocss/users.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package ocss
|
||||
|
||||
type Gender int64
|
||||
|
||||
const (
|
||||
Female Gender = iota
|
||||
Male
|
||||
Other
|
||||
)
|
||||
|
||||
type User struct {
|
||||
ID string `json:"id"`
|
||||
Operator string `json:"operator"`
|
||||
Alias string `json:"alias"`
|
||||
FirstName *string `json:"firstName,omitempty"`
|
||||
LastName *string `json:"lastName,omitempty"`
|
||||
Grade *int64 `json:"grade,omitempty"`
|
||||
Picture *string `json:"picture,omitempty"`
|
||||
Gender *Gender `json:"gender,omitempty"`
|
||||
VerifiedIdentity *bool `json:"verifiedIdentity,omitempty"`
|
||||
}
|
||||
5
interoperability/rdex/README.md
Normal file
5
interoperability/rdex/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Golang interoperability library for the RDEX standard
|
||||
|
||||
See [RDEX](http://rdex.org) for RDEX specification.
|
||||
|
||||
This standard is now deprecated on the COOPGO Technical Platform.
|
||||
Reference in New Issue
Block a user