Commit 383cb2ca authored by Arnaud Delcasse's avatar Arnaud Delcasse

initial commit

parents
Pipeline #2279 failed with stages
This diff is collapsed.
RDEX Golang library
===================
Golang implementation of the RDEX carpooling data format.
## RDEX standard
This library implements :
- [RDEX version 1.2.1](https://www.feduco.org/wp-content/uploads/2016/01/apiRDEXv1.2.1.pdf)
## How to use
### Server
You can easily generate a server implementation of the RDEX API, by implementing the function to retrieve the carpooling data.
### Client
## Contributions
We are open to contributions : feel free to submit pull requests !
## Licence
Copyright 2021 Scity.coop
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
\ No newline at end of file
package rdex
import (
"crypto/hmac"
"crypto/sha256"
)
type RDEXOperator struct {
OperatorName string
PrivateKey string
PublicKey string
}
func (o *RDEXOperator) RDEXOperator(url string) string {
mac := hmac.New(sha256.New, []byte(o.PrivateKey))
mac.Write([]byte(url))
return string(mac.Sum(nil))
}
package rdex
type RDEXError struct {
Name string
MessageDebug string
MessageUser string
Field string
}
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"gitlab.scity.coop/go-libs/rdex-golang"
)
type ExampleHandler struct{}
func (h ExampleHandler) Journeys(rdex.RDEXParameters) []rdex.RDEXJourney {
journeys := []rdex.RDEXJourney{}
fmt.Println("journeys")
jsonJourneys := `
[ {
"uuid": "10945310",
"operator": "operator",
"origin": "www.operator.com",
"url": "http://www.operator.com/65321324",
"driver": {
"uuid": "1011327",
"alias": "jean",
"image": null,
"gender": "male",
"seats": 3,
"state": 1
},
"passenger": {
"uuid": "1011327",
"alias": "jean",
"image": null,
"gender": "male",
"persons": 0,
"state": 0
},
"from": {
"address": "",
"city": "Lans-en-Vercors",
"postalcode": "",
"country": "France",
"latitude": 45.127976,
"longitude": 5.58827
},
"to": {
"address": "",
"city": "Saint-Nizier-du-Moucherotte",
"postalcode": "",
"country": "France",
"latitude": 45.169686,
"longitude": 5.629263
},
"distance": 8998,
"duration": 725,
"cost": {
"fixed": "",
"variable": 0.08
},
"details": "",
"frequency": "punctual",
"type": "one-way",
"days": {
"monday": 1,
"tuesday": 0,
"wednesday": 0,
"thursday": 0,
"friday": 0,
"saturday": 0,
"sunday": 0
},
"outward": {
"mindate": "2015-12-14",
"maxdate": "2015-12-14",
"monday": {
"mintime": "06:30:00",
"maxtime": "07:30:00"
}
}
}]
`
if err := json.Unmarshal([]byte(jsonJourneys), &journeys); err != nil {
fmt.Println(err)
}
return journeys
}
func main() {
server, _ := rdex.NewServer("localhost:8080", ExampleHandler{})
http.Handle("/", server)
log.Fatal(http.ListenAndServe(server.BaseUrl, nil))
}
module gitlab.scity.coop/go-libs/rdex-golang
go 1.14
package rdex
import "time"
// RDEXJourney is the carpooling journey base type of the RDEX protocol
type RDEXJourney struct {
UUID string `json:"uuid"`
Operator string `json:"operatir"`
Origin string `json:"origin"`
URL string `json:"url,omitempty"`
Driver RDEXPerson `json:"driver,omitempty"`
Passenger RDEXPerson `json:"passenger,omitempty"`
From RDEXGeography `json:"from"`
To RDEXGeography `json:"to"`
Distance int64 `json:"distance"`
Duration time.Duration `json:"duration"`
Route string `json:"route,omitempty"`
NumberOfWaypoints int `json:"number_of_waypoints,omitempty"`
Waypoints []RDEXGeography `json:"waypoints,omitempty"`
Cost RDEXCost `json:"cost"`
Details string `json:"details,omitempty"`
Vehicle RDEXVehicle `json:"vehicle,omitempty"`
Frequency string `json:"frequency"` // punctual or regular
Type string `json:"type"` // one-way or round-trip
Realtime bool `json:"real_time,omitempty"`
Stopped bool `json:"stopped,omitempty"`
Days RDEXDays `json:"days"`
Outward RDEXSchedule `json:"outward"`
Return RDEXSchedule `json:"return,omitempty"`
}
// RDEXPerson defines a driver or a passenger
type RDEXPerson struct {
UUID string `json:"uuid,omitempty"`
Alias string `json:"alias,omitempty"`
Image string `json:"image,omitempty"`
Seats int `json:"seats,omitempty"`
State bool `json:"state,omitempty"`
}
// RDEXGeography is a geographical point used in From, To or Waypoints
type RDEXGeography struct {
Address string `json:"address"`
City string `json:"city"`
Postalcode string `json:"postalcode,omitempty"`
Country string `json:"country"`
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
StepDistance int64 `json:"step_distance"`
StepDuration time.Duration `json:"step_duration"`
Type string `json:"type"` // pick-up or drop-point
Mandatory bool `json:"mandatory"`
}
// RDEXCost is the cost of the journey, either fixed or variable
type RDEXCost struct {
Fixed float64 `json:"fixed,omitempty"`
Variable float64 `json:"variable,omitempty"`
}
// RDEXVehicle is the vehicle description
type RDEXVehicle struct {
VehicleImage string `json:"vehicle_image,omitempty"`
Model string `json:"model,omitempty"`
Color string `json:"color,omitempty"`
}
// RDEXDays defines which days of the week the journey happens
type RDEXDays struct {
Monday bool `json:"monday"`
Tuesday bool `json:"tuesday"`
Wednesday bool `json:"wednesday"`
Thursday bool `json:"thursday"`
Friday bool `json:"friday"`
Saturday bool `json:"saturday"`
Sunday bool `json:"sunday"`
}
// RDEXSchedule is used to define outward and return datetimes
type RDEXSchedule struct {
MinDate string `json:"mindate"`
MaxDate string `json:"maxdat"`
Monday RDEXTimeLimits `json:"monday,omitempty"`
Tuesday RDEXTimeLimits `json:"tuesday,omitempty"`
Wednesday RDEXTimeLimits `json:"wednesday,omitempty"`
Thursday RDEXTimeLimits `json:"thursday,omitempty"`
Friday RDEXTimeLimits `json:"friday,omitempty"`
Saturday RDEXTimeLimits `json:"saturday,omitempty"`
Sunday RDEXTimeLimits `json:"sunday,omitempty"`
}
// RDEXTimeLimits defines the minimum time and maximum time for the journey in a day
type RDEXTimeLimits struct {
MinTime string `json:"mintime"`
MaxTime string `json:"maxtime"`
}
package rdex
// RDEXRequest describes a base request as sent and received using RDEX protocol
type RDEXRequest struct {
Timestamp int64
Apikey string
P RDEXParameters // TODO handle both journeys and connections
Signature string
}
// RDEXParameters defines the RDEX parameters used to search a journey
type RDEXParameters struct {
Driver bool
Passenger bool
From RDEXGeography
To RDEXGeography
Frequency string // regular or punctal
Outward RDEXSchedule
}
package rdex
import (
"encoding/json"
"fmt"
"net/http"
)
type RDEXServerHandler interface {
Journeys(RDEXParameters) []RDEXJourney
}
// RDEXServer is a handler to create a RDEX API server
type RDEXServer struct {
BaseUrl string
AuthorizedOperators []RDEXOperator
Handler RDEXServerHandler
}
// NewServer creates a RDEX server handler
func NewServer(baseUrl string, handler RDEXServerHandler) (*RDEXServer, error) {
server := &RDEXServer{
BaseUrl: baseUrl,
Handler: handler,
}
return server, nil
}
func (s RDEXServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
//TODO implement signature
fmt.Println("Serve HTTP")
journeys := s.Handler.Journeys(RDEXParameters{})
resp, err := json.Marshal(journeys)
if err != nil {
fmt.Println(err)
}
respondJSON(w, []byte(resp), 200)
}
// AddAuthorizedOperator adds credentials (public key / private key) for an operator accessing the API
func (s *RDEXServer) AddAuthorizedOperator(o RDEXOperator) {
s.AuthorizedOperators = append(s.AuthorizedOperators, o)
}
func respondJSON(w http.ResponseWriter, body []byte, code int) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.Header().Set("X-Content-Type-Options", "nosniff")
w.WriteHeader(code)
_, _ = w.Write(body)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment