first commit
This commit is contained in:
commit
6696cd3152
|
@ -0,0 +1,16 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/spf13/viper"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func ReadConfig() (*viper.Viper, error) {
|
||||
v := viper.New()
|
||||
v.SetConfigName("config")
|
||||
v.AddConfigPath(".")
|
||||
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
||||
v.AutomaticEnv()
|
||||
err := v.ReadInConfig()
|
||||
return v, err
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
name: COOPGO Solidarity Service
|
||||
|
||||
dev_env: true
|
||||
|
||||
storage:
|
||||
db:
|
||||
type: psql
|
||||
psql:
|
||||
host: localhost
|
||||
dbname: coopgo_platform
|
||||
user: postgres
|
||||
password: postgres
|
||||
sslmode: disable
|
||||
port: 5432
|
||||
schema: solidarity_service
|
||||
tables:
|
||||
drivers: drivers
|
||||
passengers: passengers
|
||||
bookings: bookings
|
||||
|
||||
services:
|
||||
grpc:
|
||||
enable: true
|
||||
port: 8089
|
||||
solidarity-api:
|
||||
enable: true
|
||||
address: 0.0.0.0:9999
|
||||
|
||||
routing:
|
||||
type: valhalla
|
||||
valhalla:
|
||||
base_url: https://valhalla.coopgo.io/
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
module solidarity-service
|
||||
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
git.coopgo.io/coopgo-platform/routing-service v0.0.0-20230403183358-4d30329f06be
|
||||
github.com/golang/protobuf v1.5.3
|
||||
github.com/google/uuid v1.3.1
|
||||
github.com/lib/pq v1.10.9
|
||||
github.com/paulmach/orb v0.10.0
|
||||
github.com/rs/zerolog v1.31.0
|
||||
github.com/spf13/viper v1.17.0
|
||||
google.golang.org/grpc v1.58.3
|
||||
google.golang.org/protobuf v1.31.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/gorilla/mux v1.8.0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
|
||||
github.com/sagikazarmark/locafero v0.3.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.10.0 // indirect
|
||||
github.com/spf13/cast v1.5.1 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/twpayne/go-polyline v1.1.1 // indirect
|
||||
go.mongodb.org/mongo-driver v1.11.4 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.9.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
|
||||
golang.org/x/net v0.15.0 // indirect
|
||||
golang.org/x/sys v0.12.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
|
@ -0,0 +1,552 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
|
||||
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
|
||||
cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
git.coopgo.io/coopgo-platform/routing-service v0.0.0-20230403183358-4d30329f06be h1:VIzWX8NftKzQX1clunLaMf79Ut1dygcCc/ZLV/iWOaY=
|
||||
git.coopgo.io/coopgo-platform/routing-service v0.0.0-20230403183358-4d30329f06be/go.mod h1:Nh7o15LlV0OuO9zxvJIs9FlelpeAaLYkXtFdgIkFrgg=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
|
||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
|
||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/paulmach/orb v0.10.0 h1:guVYVqzxHE/CQ1KpfGO077TR0ATHSNjp4s6XGLn3W9s=
|
||||
github.com/paulmach/orb v0.10.0/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU=
|
||||
github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY=
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
|
||||
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A=
|
||||
github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||
github.com/sagikazarmark/locafero v0.3.0 h1:zT7VEGWC2DTflmccN/5T1etyKvxSxpHsjb9cJvm4SvQ=
|
||||
github.com/sagikazarmark/locafero v0.3.0/go.mod h1:w+v7UsPNFwzF1cHuOajOOzoq4U7v/ig1mpRjqV+Bu1U=
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
|
||||
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
|
||||
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
||||
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
|
||||
github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY=
|
||||
github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
|
||||
github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=
|
||||
github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.17.0 h1:I5txKw7MJasPL/BrfkbA0Jyo/oELqVmux4pR/UxOMfI=
|
||||
github.com/spf13/viper v1.17.0/go.mod h1:BmMMMLQXSbcHK6KAOiFLz0l5JHrU89OdIRHvsk0+yVI=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/twpayne/go-polyline v1.1.1 h1:/tSF1BR7rN4HWj4XKqvRUNrCiYVMCvywxTFVofvDV0w=
|
||||
github.com/twpayne/go-polyline v1.1.1/go.mod h1:ybd9IWWivW/rlXPXuuckeKUyF3yrIim+iqA7kSl4NFY=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
|
||||
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.mongodb.org/mongo-driver v1.11.4 h1:4ayjakA013OdpGyL2K3ZqylTac/rMjrJOMZ1EHizXas=
|
||||
go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
||||
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
|
||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
|
||||
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
|
||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
||||
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
|
||||
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 h1:N3bU/SQDCDyD6R528GJ/PwW9KjYcJA3dgyH+MovAkIM=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:KSqppvjFjtoCI+KGd4PELB0qLNxdJHRGqRI09mB6pQA=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
|
||||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ=
|
||||
google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
|
@ -0,0 +1,21 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"git.coopgo.io/coopgo-platform/routing-service"
|
||||
"github.com/spf13/viper"
|
||||
"solidarity-service/storage"
|
||||
)
|
||||
|
||||
type SolidarityServiceHandler struct {
|
||||
Config *viper.Viper
|
||||
Routing routing.RoutingService
|
||||
Storage storage.Storage
|
||||
}
|
||||
|
||||
func NewSolidarityServiceHandler(cfg *viper.Viper, routing routing.RoutingService, storage storage.Storage) (*SolidarityServiceHandler, error) {
|
||||
return &SolidarityServiceHandler{
|
||||
Config: cfg,
|
||||
Routing: routing,
|
||||
Storage: storage,
|
||||
}, nil
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"github.com/paulmach/orb"
|
||||
"github.com/paulmach/orb/geojson"
|
||||
"solidarity-service/servers/utils"
|
||||
)
|
||||
|
||||
func (handler *SolidarityServiceHandler) CalculateDistanceBetweenFeatures(feature1, feature2 *geojson.Feature) int64 {
|
||||
coords1 := feature1.Geometry.(orb.Point)
|
||||
coords2 := feature2.Geometry.(orb.Point)
|
||||
distance := utils.Haversine(coords1[1], coords1[0], coords2[1], coords2[0])
|
||||
return int64(distance)
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"github.com/paulmach/orb"
|
||||
"time"
|
||||
)
|
||||
|
||||
type RoutingService interface {
|
||||
Route(locations []orb.Point) (route *Route, err error)
|
||||
}
|
||||
type Route struct {
|
||||
Summary RouteSummary
|
||||
Legs []RouteLeg
|
||||
}
|
||||
|
||||
type RouteSummary struct {
|
||||
Polyline string
|
||||
}
|
||||
type RouteLeg struct {
|
||||
Distance float64
|
||||
Duration time.Duration
|
||||
Polyline string
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/paulmach/orb/geojson"
|
||||
"solidarity-service/internal"
|
||||
)
|
||||
|
||||
func (s *SolidarityServiceHandler) GetPassenger(ctx context.Context, id string) (passenger internal.Passenger, err error) {
|
||||
passenger, err = s.Storage.GetPassenger(id)
|
||||
if err != nil {
|
||||
return internal.Passenger{}, err
|
||||
}
|
||||
return passenger, nil
|
||||
}
|
||||
|
||||
func (s *SolidarityServiceHandler) GetDriver(ctx context.Context, id string) (driver internal.Driver, err error) {
|
||||
driver, err = s.Storage.GetDriver(id)
|
||||
if err != nil {
|
||||
return internal.Driver{}, err
|
||||
}
|
||||
return driver, nil
|
||||
}
|
||||
|
||||
func (s *SolidarityServiceHandler) SetDriverAvailabilities(ctx context.Context, driver internal.Driver) (err error) {
|
||||
driver.Driver.Operator = "internal-grpc"
|
||||
err = s.Storage.CreateDriver(driver)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SolidarityServiceHandler) SetPassengerTrip(ctx context.Context, passenger internal.Passenger) (err error) {
|
||||
passenger.Passenger.Operator = "internal-grpc"
|
||||
err = s.Storage.CreatePassenger(passenger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SolidarityServiceHandler) CreateBooking(ctx context.Context, bookingRequest internal.BookingRequest) (passenger internal.Passenger, driver internal.Driver, err error) {
|
||||
bookingRequest.Operator = "internal-grpc"
|
||||
err = s.Storage.CreateBooking(bookingRequest)
|
||||
if err != nil {
|
||||
return internal.Passenger{}, internal.Driver{}, err
|
||||
}
|
||||
passenger, err = s.Storage.GetPassenger(bookingRequest.Passenger_id)
|
||||
if err != nil {
|
||||
return internal.Passenger{}, internal.Driver{}, err
|
||||
}
|
||||
driver, err = s.Storage.GetDriver(bookingRequest.Driver_id)
|
||||
if err != nil {
|
||||
return internal.Passenger{}, internal.Driver{}, err
|
||||
}
|
||||
return passenger, driver, nil
|
||||
}
|
||||
|
||||
func (s *SolidarityServiceHandler) UpdateBooking(ctx context.Context, bookingId string, status internal.BookingStatus) (err error) {
|
||||
err = s.Storage.UpdateBookingStatus(bookingId, status)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SolidarityServiceHandler) GetBooking(ctx context.Context, bookingId string) (booking internal.Booking, passenger internal.Passenger, driver internal.Driver, err error) {
|
||||
booking, err = s.Storage.GetBooking(bookingId)
|
||||
if err != nil {
|
||||
return internal.Booking{}, internal.Passenger{}, internal.Driver{}, err
|
||||
}
|
||||
passenger, err = s.Storage.GetPassenger(booking.Passenger.ID)
|
||||
if err != nil {
|
||||
return internal.Booking{}, internal.Passenger{}, internal.Driver{}, err
|
||||
}
|
||||
driver, err = s.Storage.GetDriver(booking.Driver.ID)
|
||||
if err != nil {
|
||||
return internal.Booking{}, internal.Passenger{}, internal.Driver{}, err
|
||||
}
|
||||
return booking, passenger, driver, nil
|
||||
}
|
||||
|
||||
func (s *SolidarityServiceHandler) GetBookingsByStatus(ctx context.Context, status string, filterType string, id string) (bookings []internal.Booking, err error) {
|
||||
bookings, err = s.Storage.FilterUserBookingsByStatus(filterType, internal.BookingStatus(status), id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return bookings, nil
|
||||
}
|
||||
|
||||
func (s *SolidarityServiceHandler) GetDriverJourneys(ctx context.Context, departure_route *geojson.Feature, departure_date int64) (drivers []internal.Driver, err error) {
|
||||
drivers, err = s.Storage.DriverJourneys(departure_route, departure_date)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return drivers, nil
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/paulmach/orb/geojson"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (handler *SolidarityServiceHandler) CalculateDurationBetweenFeatures(feature1, feature2 *geojson.Feature) (int64, error) {
|
||||
coords1 := feature1.Point()
|
||||
coords2 := feature2.Point()
|
||||
routing_base_url := handler.Config.GetString("routing.valhalla.base_url")
|
||||
url := fmt.Sprintf("%sroute?json=%s", routing_base_url, createJSONROUTERequest(coords1.X(), coords1.Y(), coords2.X(), coords2.Y()))
|
||||
response, err := http.Get(url)
|
||||
if err != nil {
|
||||
return 0, errors.New("routing service error")
|
||||
}
|
||||
var result map[string]interface{}
|
||||
decoder := json.NewDecoder(response.Body)
|
||||
if err := decoder.Decode(&result); err != nil {
|
||||
return 0, errors.New("routing response decoding error")
|
||||
}
|
||||
trip, ok := result["trip"].(map[string]interface{})
|
||||
if !ok {
|
||||
return 0, errors.New("routing response decoding error")
|
||||
}
|
||||
summary, ok := trip["summary"].(map[string]interface{})
|
||||
if !ok {
|
||||
return 0, errors.New("routing response decoding error")
|
||||
}
|
||||
duration, ok := summary["time"].(float64)
|
||||
if !ok {
|
||||
return 0, errors.New("routing response decoding error")
|
||||
}
|
||||
|
||||
return int64(duration), nil
|
||||
}
|
||||
|
||||
func createJSONROUTERequest(lat1, lon1, lat2, lon2 float64) string {
|
||||
request := map[string]interface{}{
|
||||
"locations": []map[string]float64{
|
||||
{"lat": lat1, "lon": lon1},
|
||||
{"lat": lat2, "lon": lon2},
|
||||
},
|
||||
"costing": "auto",
|
||||
}
|
||||
|
||||
jsonRequest, _ := json.Marshal(request)
|
||||
return string(jsonRequest)
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"github.com/paulmach/orb/geojson"
|
||||
)
|
||||
|
||||
const (
|
||||
Punctual AvailabilitiesType = "PUNCTUAL"
|
||||
Regular AvailabilitiesType = "REGULAR"
|
||||
BookingStatusINITIATED BookingStatus = "INITIATED"
|
||||
BookingStatusWAITINGPASSENGERCONFIRMATION BookingStatus = "WAITING_PASSENGER_CONFIRMATION"
|
||||
BookingStatusWAITINGDRIVERCONFIRMATION BookingStatus = "WAITING_DRIVER_CONFIRMATION"
|
||||
BookingStatusCONFIRMED BookingStatus = "CONFIRMED"
|
||||
BookingStatusCANCELLED BookingStatus = "CANCELLED"
|
||||
BookingStatusCOMPLETEDPENDINGVALIDATION BookingStatus = "COMPLETED_PENDING_VALIDATION"
|
||||
BookingStatusVALIDATED BookingStatus = "VALIDATED"
|
||||
)
|
||||
|
||||
type Passenger struct {
|
||||
Passenger_departure_address *geojson.Feature
|
||||
Passenger_destination_address *geojson.Feature
|
||||
Passenger_pickup_date int64
|
||||
Passenger User
|
||||
Preferences Preferences
|
||||
}
|
||||
|
||||
type Driver struct {
|
||||
Driver_departure_address *geojson.Feature
|
||||
Radius int32
|
||||
Driver User
|
||||
Preferences Preferences
|
||||
AvailabilitiesType AvailabilitiesType
|
||||
RegularAvailabilities []RegularAvailabilities `json:"availabilities,omitempty"`
|
||||
PunctualAvailabilities []PunctualAvailabilities `json:"availabilities,omitempty"`
|
||||
Car Car `json:"car,omitempty"`
|
||||
}
|
||||
|
||||
type Car struct {
|
||||
Model string `json:"model,omitempty"`
|
||||
Brand string `json:"brand,omitempty"`
|
||||
}
|
||||
|
||||
type AvailabilitiesType string
|
||||
type BookingStatus string
|
||||
|
||||
type User struct {
|
||||
ID string `json:"id"`
|
||||
Operator string `json:"operator"`
|
||||
Alias string `json:"alias"`
|
||||
FirstName string `json:"first_name,omitempty"`
|
||||
LastName string `json:"last_name,omitempty"`
|
||||
Grade int64 `json:"grade,omitempty"`
|
||||
Picture string `json:"picture,omitempty"`
|
||||
Gender string `json:"gender,omitempty"`
|
||||
VerifiedIdentity bool `json:"verified_identity,omitempty"`
|
||||
}
|
||||
|
||||
type Preferences struct {
|
||||
Smoking bool `json:"smoking,omitempty"`
|
||||
Animals bool `json:"animals,omitempty"`
|
||||
Music bool `json:"music,omitempty"`
|
||||
Is_talker bool `json:"is_talker,omitempty"`
|
||||
Luggage_size int64 `json:"luggage_size,omitempty"`
|
||||
}
|
||||
|
||||
type BookingRequest struct {
|
||||
ID string `json:"id"`
|
||||
Passenger_id string `json:"passenger_id"`
|
||||
Driver_id string `json:"driver_id"`
|
||||
Status BookingStatus `json:"booking_status"`
|
||||
Details map[string]any `json:"booking_details"`
|
||||
Operator string `json:"operator"`
|
||||
}
|
||||
|
||||
type Booking struct {
|
||||
ID string `json:"id"`
|
||||
Passenger User `json:"passenger"`
|
||||
Driver User `json:"driver"`
|
||||
PassengerPickupAddress *geojson.Feature
|
||||
PassengerDropAddress *geojson.Feature
|
||||
Status BookingStatus `json:"booking_status"`
|
||||
Details map[string]any `json:"booking_details"`
|
||||
}
|
||||
|
||||
type RegularAvailabilities struct {
|
||||
DayOfWeek string `json:"dayOfWeek"`
|
||||
StartTime string `json:"startTime"`
|
||||
EndTime string `json:"endTime"`
|
||||
}
|
||||
|
||||
type PunctualAvailabilities struct {
|
||||
Date int64 `json:"date"`
|
||||
StartTime string `json:"startTime"`
|
||||
EndTime string `json:"endTime"`
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,23 @@
|
|||
# OpenAPI Generator Ignore
|
||||
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
|
||||
|
||||
# Use this file to prevent files from being overwritten by the generator.
|
||||
# The patterns follow closely to .gitignore or .dockerignore.
|
||||
|
||||
# As an example, the C# client generator defines ApiClient.cs.
|
||||
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
|
||||
#ApiClient.cs
|
||||
|
||||
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
|
||||
#foo/*/qux
|
||||
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
|
||||
|
||||
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
|
||||
#foo/**/qux
|
||||
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
|
||||
|
||||
# You can also negate patterns with an exclamation (!).
|
||||
# For example, you can ignore all files in a docs folder with the file extension .md:
|
||||
#docs/*.md
|
||||
# Then explicitly reverse the ignore rule for a single file:
|
||||
#!docs/README.md
|
|
@ -0,0 +1,40 @@
|
|||
.openapi-generator-ignore
|
||||
Dockerfile
|
||||
README.md
|
||||
api/openapi.yaml
|
||||
go.mod
|
||||
go/api.go
|
||||
go/api_bookings_filter.go
|
||||
go/api_bookings_filter_service.go
|
||||
go/api_driver_availability_and_schedule.go
|
||||
go/api_driver_availability_and_schedule_service.go
|
||||
go/api_interact.go
|
||||
go/api_interact_service.go
|
||||
go/api_passenger_trip_request.go
|
||||
go/api_passenger_trip_request_service.go
|
||||
go/api_search.go
|
||||
go/api_search_service.go
|
||||
go/error.go
|
||||
go/helpers.go
|
||||
go/impl.go
|
||||
go/logger.go
|
||||
go/model__passenger_post_400_response.go
|
||||
go/model_booking.go
|
||||
go/model_booking_request.go
|
||||
go/model_booking_status.go
|
||||
go/model_car.go
|
||||
go/model_driver_journey.go
|
||||
go/model_driver_punctual_availabilities_request.go
|
||||
go/model_driver_regular_availabilities_request.go
|
||||
go/model_driver_trip.go
|
||||
go/model_get_bookings_404_response.go
|
||||
go/model_journey_schedule.go
|
||||
go/model_passenger_trip_request.go
|
||||
go/model_post_connections_request.go
|
||||
go/model_preferences.go
|
||||
go/model_price.go
|
||||
go/model_punctual_availability_slot.go
|
||||
go/model_regular_availability_slot.go
|
||||
go/model_user.go
|
||||
go/routers.go
|
||||
main.go
|
|
@ -0,0 +1 @@
|
|||
7.0.1
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// BookingsFilterAPIRouter defines the required methods for binding the api requests to a responses for the BookingsFilterAPI
|
||||
// The BookingsFilterAPIRouter implementation should parse necessary information from the http request,
|
||||
// pass the data to a BookingsFilterAPIServicer to perform the required actions, then write the service results to the http response.
|
||||
type BookingsFilterAPIRouter interface {
|
||||
FilterBookingsByStatus(http.ResponseWriter, *http.Request)
|
||||
}
|
||||
|
||||
// DriverAvailabilityAndScheduleAPIRouter defines the required methods for binding the api requests to a responses for the DriverAvailabilityAndScheduleAPI
|
||||
// The DriverAvailabilityAndScheduleAPIRouter implementation should parse necessary information from the http request,
|
||||
// pass the data to a DriverAvailabilityAndScheduleAPIServicer to perform the required actions, then write the service results to the http response.
|
||||
type DriverAvailabilityAndScheduleAPIRouter interface {
|
||||
DriverPunctualAvailabilitiesPost(http.ResponseWriter, *http.Request)
|
||||
DriverRegularAvailabilitiesPost(http.ResponseWriter, *http.Request)
|
||||
}
|
||||
|
||||
// InteractAPIRouter defines the required methods for binding the api requests to a responses for the InteractAPI
|
||||
// The InteractAPIRouter implementation should parse necessary information from the http request,
|
||||
// pass the data to a InteractAPIServicer to perform the required actions, then write the service results to the http response.
|
||||
type InteractAPIRouter interface {
|
||||
GetBookings(http.ResponseWriter, *http.Request)
|
||||
PatchBookings(http.ResponseWriter, *http.Request)
|
||||
PostBookings(http.ResponseWriter, *http.Request)
|
||||
PostConnections(http.ResponseWriter, *http.Request)
|
||||
}
|
||||
|
||||
// PassengerTripRequestAPIRouter defines the required methods for binding the api requests to a responses for the PassengerTripRequestAPI
|
||||
// The PassengerTripRequestAPIRouter implementation should parse necessary information from the http request,
|
||||
// pass the data to a PassengerTripRequestAPIServicer to perform the required actions, then write the service results to the http response.
|
||||
type PassengerTripRequestAPIRouter interface {
|
||||
PassengerPost(http.ResponseWriter, *http.Request)
|
||||
}
|
||||
|
||||
// SearchAPIRouter defines the required methods for binding the api requests to a responses for the SearchAPI
|
||||
// The SearchAPIRouter implementation should parse necessary information from the http request,
|
||||
// pass the data to a SearchAPIServicer to perform the required actions, then write the service results to the http response.
|
||||
type SearchAPIRouter interface {
|
||||
GetDriverJourneys(http.ResponseWriter, *http.Request)
|
||||
}
|
||||
|
||||
// BookingsFilterAPIServicer defines the api actions for the BookingsFilterAPI service
|
||||
// This interface intended to stay up to date with the openapi yaml used to generate it,
|
||||
// while the service implementation can be ignored with the .openapi-generator-ignore file
|
||||
// and updated with the logic required for the API.
|
||||
type BookingsFilterAPIServicer interface {
|
||||
FilterBookingsByStatus(context.Context, string, string, string, string) (ImplResponse, error)
|
||||
}
|
||||
|
||||
// DriverAvailabilityAndScheduleAPIServicer defines the api actions for the DriverAvailabilityAndScheduleAPI service
|
||||
// This interface intended to stay up to date with the openapi yaml used to generate it,
|
||||
// while the service implementation can be ignored with the .openapi-generator-ignore file
|
||||
// and updated with the logic required for the API.
|
||||
type DriverAvailabilityAndScheduleAPIServicer interface {
|
||||
DriverPunctualAvailabilitiesPost(context.Context, DriverPunctualAvailabilitiesRequest) (ImplResponse, error)
|
||||
DriverRegularAvailabilitiesPost(context.Context, DriverRegularAvailabilitiesRequest) (ImplResponse, error)
|
||||
}
|
||||
|
||||
// InteractAPIServicer defines the api actions for the InteractAPI service
|
||||
// This interface intended to stay up to date with the openapi yaml used to generate it,
|
||||
// while the service implementation can be ignored with the .openapi-generator-ignore file
|
||||
// and updated with the logic required for the API.
|
||||
type InteractAPIServicer interface {
|
||||
GetBookings(context.Context, string, string) (ImplResponse, error)
|
||||
PatchBookings(context.Context, string, string, BookingStatus, string) (ImplResponse, error)
|
||||
PostBookings(context.Context, BookingRequest) (ImplResponse, error)
|
||||
PostConnections(context.Context, PostConnectionsRequest) (ImplResponse, error)
|
||||
}
|
||||
|
||||
// PassengerTripRequestAPIServicer defines the api actions for the PassengerTripRequestAPI service
|
||||
// This interface intended to stay up to date with the openapi yaml used to generate it,
|
||||
// while the service implementation can be ignored with the .openapi-generator-ignore file
|
||||
// and updated with the logic required for the API.
|
||||
type PassengerTripRequestAPIServicer interface {
|
||||
PassengerPost(context.Context, PassengerTripRequest) (ImplResponse, error)
|
||||
}
|
||||
|
||||
// SearchAPIServicer defines the api actions for the SearchAPI service
|
||||
// This interface intended to stay up to date with the openapi yaml used to generate it,
|
||||
// while the service implementation can be ignored with the .openapi-generator-ignore file
|
||||
// and updated with the logic required for the API.
|
||||
type SearchAPIServicer interface {
|
||||
GetDriverJourneys(context.Context, float32, float32, int32, string) (ImplResponse, error)
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// BookingsFilterAPIController binds http requests to an api service and writes the service results to the http response
|
||||
type BookingsFilterAPIController struct {
|
||||
service BookingsFilterAPIServicer
|
||||
errorHandler ErrorHandler
|
||||
}
|
||||
|
||||
// BookingsFilterAPIOption for how the controller is set up.
|
||||
type BookingsFilterAPIOption func(*BookingsFilterAPIController)
|
||||
|
||||
// WithBookingsFilterAPIErrorHandler inject ErrorHandler into controller
|
||||
func WithBookingsFilterAPIErrorHandler(h ErrorHandler) BookingsFilterAPIOption {
|
||||
return func(c *BookingsFilterAPIController) {
|
||||
c.errorHandler = h
|
||||
}
|
||||
}
|
||||
|
||||
// NewBookingsFilterAPIController creates a default api controller
|
||||
func NewBookingsFilterAPIController(s BookingsFilterAPIServicer, opts ...BookingsFilterAPIOption) Router {
|
||||
controller := &BookingsFilterAPIController{
|
||||
service: s,
|
||||
errorHandler: DefaultErrorHandler,
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(controller)
|
||||
}
|
||||
|
||||
return controller
|
||||
}
|
||||
|
||||
// Routes returns all the api routes for the BookingsFilterAPIController
|
||||
func (c *BookingsFilterAPIController) Routes() Routes {
|
||||
return Routes{
|
||||
"FilterBookingsByStatus": Route{
|
||||
strings.ToUpper("Get"),
|
||||
"/bookings",
|
||||
c.FilterBookingsByStatus,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// FilterBookingsByStatus - Filter and retrieve bookings by status, type, and ID.
|
||||
func (c *BookingsFilterAPIController) FilterBookingsByStatus(w http.ResponseWriter, r *http.Request) {
|
||||
authenticated := CheckOperatorAuthorization(r, AuthorizedOperators)
|
||||
if !authenticated {
|
||||
response := ImplResponse{
|
||||
Code: 401,
|
||||
Body: "Unauthorized request. Check your operator / API Key.",
|
||||
}
|
||||
EncodeJSONResponse(response.Body, &response.Code, w)
|
||||
return
|
||||
}
|
||||
query := r.URL.Query()
|
||||
operatorParam := query.Get("operator")
|
||||
statusParam := query.Get("status")
|
||||
filterTypeParam := query.Get("filterType")
|
||||
idParam := query.Get("Id")
|
||||
result, err := c.service.FilterBookingsByStatus(r.Context(), operatorParam, statusParam, filterTypeParam, idParam)
|
||||
// If an error occurred, encode the error with the status code
|
||||
if err != nil {
|
||||
c.errorHandler(w, r, err, &result)
|
||||
return
|
||||
}
|
||||
// If no error, encode the body and the result code
|
||||
EncodeJSONResponse(result.Body, &result.Code, w)
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/spf13/viper"
|
||||
"net/http"
|
||||
"solidarity-service/handler"
|
||||
"solidarity-service/internal"
|
||||
"solidarity-service/storage"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// BookingsFilterAPIService is a service that implements the logic for the BookingsFilterAPIServicer
|
||||
// This service should implement the business logic for every endpoint for the BookingsFilterAPI API.
|
||||
// Include any external packages or services that will be required by this service.
|
||||
type BookingsFilterAPIService struct {
|
||||
config *viper.Viper
|
||||
handler *handler.SolidarityServiceHandler
|
||||
storage storage.Storage
|
||||
}
|
||||
|
||||
// NewBookingsFilterAPIService creates a default api service
|
||||
func NewBookingsFilterAPIService(config *viper.Viper, handler *handler.SolidarityServiceHandler, storage storage.Storage) BookingsFilterAPIServicer {
|
||||
return &BookingsFilterAPIService{
|
||||
config: config,
|
||||
handler: handler,
|
||||
storage: storage,
|
||||
}
|
||||
}
|
||||
|
||||
// FilterBookingsByStatus - Filter and retrieve bookings by status, type, and ID.
|
||||
func (s *BookingsFilterAPIService) FilterBookingsByStatus(ctx context.Context, operator string, status string, filterType string, id string) (ImplResponse, error) {
|
||||
bookings, err := s.storage.FilterUserBookingsByStatus(filterType, internal.BookingStatus(status), id)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
if strings.Contains(err.Error(), " no rows in result set") {
|
||||
return Response(http.StatusBadRequest, "ID not found in the database"), nil
|
||||
} else {
|
||||
return Response(http.StatusInternalServerError, nil), nil
|
||||
}
|
||||
}
|
||||
responses := []Booking{}
|
||||
for _, v := range bookings {
|
||||
passenger, err := s.storage.GetPassenger(v.Passenger.ID)
|
||||
if err != nil {
|
||||
return Response(http.StatusInternalServerError, nil), nil
|
||||
}
|
||||
driver, err := s.storage.GetDriver(v.Driver.ID)
|
||||
if err != nil {
|
||||
return Response(http.StatusInternalServerError, nil), nil
|
||||
}
|
||||
duration, err := s.handler.CalculateDurationBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address)
|
||||
if err != nil {
|
||||
duration = 0
|
||||
}
|
||||
responses = append(responses, Booking{
|
||||
Id: v.ID,
|
||||
Status: BookingStatus(v.Status),
|
||||
Driver: User{
|
||||
Id: v.Driver.ID,
|
||||
Operator: driver.Driver.Operator,
|
||||
Alias: driver.Driver.Alias,
|
||||
FirstName: driver.Driver.FirstName,
|
||||
LastName: driver.Driver.LastName,
|
||||
Grade: int32(driver.Driver.Grade),
|
||||
Picture: driver.Driver.Picture,
|
||||
Gender: driver.Driver.Gender,
|
||||
VerifiedIdentity: driver.Driver.VerifiedIdentity,
|
||||
},
|
||||
Passenger: User{
|
||||
Id: v.Passenger.ID,
|
||||
Operator: passenger.Passenger.Operator,
|
||||
Alias: passenger.Passenger.Alias,
|
||||
FirstName: passenger.Passenger.FirstName,
|
||||
LastName: passenger.Passenger.LastName,
|
||||
Grade: int32(passenger.Passenger.Grade),
|
||||
Picture: passenger.Passenger.Picture,
|
||||
Gender: passenger.Passenger.Gender,
|
||||
VerifiedIdentity: passenger.Passenger.VerifiedIdentity,
|
||||
},
|
||||
PassengerPickupDate: int32(passenger.Passenger_pickup_date),
|
||||
PassengerPickupLat: passenger.Passenger_departure_address.Point().X(),
|
||||
PassengerPickupLng: passenger.Passenger_departure_address.Point().Y(),
|
||||
PassengerPickupAddress: passenger.Passenger_departure_address.Properties.MustString("name"),
|
||||
PassengerDropLat: passenger.Passenger_destination_address.Point().X(),
|
||||
PassengerDropLng: passenger.Passenger_destination_address.Point().Y(),
|
||||
PassengerDropAddress: passenger.Passenger_destination_address.Properties.MustString("name"),
|
||||
Duration: int32(duration),
|
||||
Distance: int32(s.handler.CalculateDistanceBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address)),
|
||||
Car: Car{
|
||||
Model: driver.Car.Model,
|
||||
Brand: driver.Car.Brand,
|
||||
},
|
||||
Price: Price{
|
||||
Type: "FREE",
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return Response(200, responses), nil
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// DriverAvailabilityAndScheduleAPIController binds http requests to an api service and writes the service results to the http response
|
||||
type DriverAvailabilityAndScheduleAPIController struct {
|
||||
service DriverAvailabilityAndScheduleAPIServicer
|
||||
errorHandler ErrorHandler
|
||||
}
|
||||
|
||||
// DriverAvailabilityAndScheduleAPIOption for how the controller is set up.
|
||||
type DriverAvailabilityAndScheduleAPIOption func(*DriverAvailabilityAndScheduleAPIController)
|
||||
|
||||
// WithDriverAvailabilityAndScheduleAPIErrorHandler inject ErrorHandler into controller
|
||||
func WithDriverAvailabilityAndScheduleAPIErrorHandler(h ErrorHandler) DriverAvailabilityAndScheduleAPIOption {
|
||||
return func(c *DriverAvailabilityAndScheduleAPIController) {
|
||||
c.errorHandler = h
|
||||
}
|
||||
}
|
||||
|
||||
// NewDriverAvailabilityAndScheduleAPIController creates a default api controller
|
||||
func NewDriverAvailabilityAndScheduleAPIController(s DriverAvailabilityAndScheduleAPIServicer, opts ...DriverAvailabilityAndScheduleAPIOption) Router {
|
||||
controller := &DriverAvailabilityAndScheduleAPIController{
|
||||
service: s,
|
||||
errorHandler: DefaultErrorHandler,
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(controller)
|
||||
}
|
||||
|
||||
return controller
|
||||
}
|
||||
|
||||
// Routes returns all the api routes for the DriverAvailabilityAndScheduleAPIController
|
||||
func (c *DriverAvailabilityAndScheduleAPIController) Routes() Routes {
|
||||
return Routes{
|
||||
"DriverPunctualAvailabilitiesPost": Route{
|
||||
strings.ToUpper("Post"),
|
||||
"/driver_punctual_availabilities",
|
||||
c.DriverPunctualAvailabilitiesPost,
|
||||
},
|
||||
"DriverRegularAvailabilitiesPost": Route{
|
||||
strings.ToUpper("Post"),
|
||||
"/driver_regular_availabilities",
|
||||
c.DriverRegularAvailabilitiesPost,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// DriverPunctualAvailabilitiesPost - Set Punctual Driver Availabilities
|
||||
func (c *DriverAvailabilityAndScheduleAPIController) DriverPunctualAvailabilitiesPost(w http.ResponseWriter, r *http.Request) {
|
||||
authenticated := CheckOperatorAuthorization(r, AuthorizedOperators)
|
||||
if !authenticated {
|
||||
response := ImplResponse{
|
||||
Code: 401,
|
||||
Body: "Unauthorized request. Check your operator / API Key.",
|
||||
}
|
||||
EncodeJSONResponse(response.Body, &response.Code, w)
|
||||
return
|
||||
}
|
||||
driverPunctualAvailabilitiesRequestParam := DriverPunctualAvailabilitiesRequest{}
|
||||
d := json.NewDecoder(r.Body)
|
||||
d.DisallowUnknownFields()
|
||||
if err := d.Decode(&driverPunctualAvailabilitiesRequestParam); err != nil {
|
||||
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
|
||||
return
|
||||
}
|
||||
if err := AssertDriverPunctualAvailabilitiesRequestRequired(driverPunctualAvailabilitiesRequestParam); err != nil {
|
||||
c.errorHandler(w, r, err, nil)
|
||||
return
|
||||
}
|
||||
if err := AssertDriverPunctualAvailabilitiesRequestConstraints(driverPunctualAvailabilitiesRequestParam); err != nil {
|
||||
c.errorHandler(w, r, err, nil)
|
||||
return
|
||||
}
|
||||
result, err := c.service.DriverPunctualAvailabilitiesPost(r.Context(), driverPunctualAvailabilitiesRequestParam)
|
||||
// If an error occurred, encode the error with the status code
|
||||
if err != nil {
|
||||
c.errorHandler(w, r, err, &result)
|
||||
return
|
||||
}
|
||||
// If no error, encode the body and the result code
|
||||
EncodeJSONResponse(result.Body, &result.Code, w)
|
||||
}
|
||||
|
||||
// DriverRegularAvailabilitiesPost - Set Regular Driver Availabilities
|
||||
func (c *DriverAvailabilityAndScheduleAPIController) DriverRegularAvailabilitiesPost(w http.ResponseWriter, r *http.Request) {
|
||||
authenticated := CheckOperatorAuthorization(r, AuthorizedOperators)
|
||||
if !authenticated {
|
||||
response := ImplResponse{
|
||||
Code: 401,
|
||||
Body: "Unauthorized request. Check your operator / API Key.",
|
||||
}
|
||||
EncodeJSONResponse(response.Body, &response.Code, w)
|
||||
return
|
||||
}
|
||||
driverRegularAvailabilitiesRequestParam := DriverRegularAvailabilitiesRequest{}
|
||||
d := json.NewDecoder(r.Body)
|
||||
d.DisallowUnknownFields()
|
||||
if err := d.Decode(&driverRegularAvailabilitiesRequestParam); err != nil {
|
||||
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
|
||||
return
|
||||
}
|
||||
if err := AssertDriverRegularAvailabilitiesRequestRequired(driverRegularAvailabilitiesRequestParam); err != nil {
|
||||
c.errorHandler(w, r, err, nil)
|
||||
return
|
||||
}
|
||||
if err := AssertDriverRegularAvailabilitiesRequestConstraints(driverRegularAvailabilitiesRequestParam); err != nil {
|
||||
c.errorHandler(w, r, err, nil)
|
||||
return
|
||||
}
|
||||
result, err := c.service.DriverRegularAvailabilitiesPost(r.Context(), driverRegularAvailabilitiesRequestParam)
|
||||
// If an error occurred, encode the error with the status code
|
||||
if err != nil {
|
||||
c.errorHandler(w, r, err, &result)
|
||||
return
|
||||
}
|
||||
// If no error, encode the body and the result code
|
||||
EncodeJSONResponse(result.Body, &result.Code, w)
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/paulmach/orb"
|
||||
"github.com/paulmach/orb/geojson"
|
||||
"github.com/spf13/viper"
|
||||
"net/http"
|
||||
"solidarity-service/handler"
|
||||
"solidarity-service/internal"
|
||||
"solidarity-service/storage"
|
||||
)
|
||||
|
||||
// DriverAvailabilityAndScheduleAPIService is a service that implements the logic for the DriverAvailabilityAndScheduleAPIServicer
|
||||
// This service should implement the business logic for every endpoint for the DriverAvailabilityAndScheduleAPI API.
|
||||
// Include any external packages or services that will be required by this service.
|
||||
type DriverAvailabilityAndScheduleAPIService struct {
|
||||
config *viper.Viper
|
||||
handler *handler.SolidarityServiceHandler
|
||||
storage storage.Storage
|
||||
}
|
||||
|
||||
// NewDriverAvailabilityAndScheduleAPIService creates a default api service
|
||||
func NewDriverAvailabilityAndScheduleAPIService(config *viper.Viper, handler *handler.SolidarityServiceHandler, storage storage.Storage) DriverAvailabilityAndScheduleAPIServicer {
|
||||
return &DriverAvailabilityAndScheduleAPIService{
|
||||
config: config,
|
||||
handler: handler,
|
||||
storage: storage,
|
||||
}
|
||||
}
|
||||
|
||||
// DriverPunctualAvailabilitiesPost - Set Punctual Driver Availabilities
|
||||
func (s *DriverAvailabilityAndScheduleAPIService) DriverPunctualAvailabilitiesPost(ctx context.Context, driverPunctualAvailabilitiesRequest DriverPunctualAvailabilitiesRequest) (ImplResponse, error) {
|
||||
driver := internal.Driver{}
|
||||
driver.Driver.ID = driverPunctualAvailabilitiesRequest.User.Id
|
||||
driver.Driver.Operator = driverPunctualAvailabilitiesRequest.User.Operator
|
||||
driver.Driver.Alias = driverPunctualAvailabilitiesRequest.User.Alias
|
||||
driver.Driver.Grade = int64(driverPunctualAvailabilitiesRequest.User.Grade)
|
||||
driver.Driver.Picture = driverPunctualAvailabilitiesRequest.User.Picture
|
||||
driver.Driver.LastName = driverPunctualAvailabilitiesRequest.User.LastName
|
||||
driver.Driver.FirstName = driverPunctualAvailabilitiesRequest.User.FirstName
|
||||
driver.Driver.VerifiedIdentity = driverPunctualAvailabilitiesRequest.User.VerifiedIdentity
|
||||
driver.Driver.Gender = driverPunctualAvailabilitiesRequest.User.Gender
|
||||
driver.Preferences.Music = driverPunctualAvailabilitiesRequest.Preferences.Music
|
||||
driver.Preferences.Is_talker = driverPunctualAvailabilitiesRequest.Preferences.IsTalker
|
||||
driver.Preferences.Luggage_size = int64(driverPunctualAvailabilitiesRequest.Preferences.LuggageSize)
|
||||
driver.Preferences.Smoking = driverPunctualAvailabilitiesRequest.Preferences.Smoking
|
||||
driver.Preferences.Animals = driverPunctualAvailabilitiesRequest.Preferences.Animals
|
||||
|
||||
driver.Driver_departure_address = &geojson.Feature{
|
||||
Type: "Feature",
|
||||
Geometry: orb.Geometry(orb.Point{driverPunctualAvailabilitiesRequest.Latitude, driverPunctualAvailabilitiesRequest.Longitude}),
|
||||
Properties: geojson.Properties{
|
||||
"name": driverPunctualAvailabilitiesRequest.Address,
|
||||
},
|
||||
}
|
||||
driver.Radius = driverPunctualAvailabilitiesRequest.Radius
|
||||
driver.AvailabilitiesType = internal.Punctual
|
||||
for _, v := range driverPunctualAvailabilitiesRequest.Availabilities {
|
||||
driver.PunctualAvailabilities = append(driver.PunctualAvailabilities, internal.PunctualAvailabilities{
|
||||
Date: int64(v.Date),
|
||||
StartTime: v.StartTime,
|
||||
EndTime: v.EndTime,
|
||||
})
|
||||
}
|
||||
driver.Car.Brand = driverPunctualAvailabilitiesRequest.Car.Brand
|
||||
driver.Car.Model = driverPunctualAvailabilitiesRequest.Car.Model
|
||||
err := s.storage.CreateDriver(driver)
|
||||
if err != nil {
|
||||
return Response(http.StatusInternalServerError, nil), errors.New("DriverPunctualAvailabilitiesPost internal server error")
|
||||
} else {
|
||||
return Response(201, "Punctual driver availabilities set successfully"), nil
|
||||
}
|
||||
}
|
||||
|
||||
// DriverRegularAvailabilitiesPost - Set Regular Driver Availabilities
|
||||
func (s *DriverAvailabilityAndScheduleAPIService) DriverRegularAvailabilitiesPost(ctx context.Context, driverRegularAvailabilitiesRequest DriverRegularAvailabilitiesRequest) (ImplResponse, error) {
|
||||
driver := internal.Driver{}
|
||||
driver.Driver.ID = driverRegularAvailabilitiesRequest.User.Id
|
||||
driver.Driver.Operator = driverRegularAvailabilitiesRequest.User.Operator
|
||||
driver.Driver.Alias = driverRegularAvailabilitiesRequest.User.Alias
|
||||
driver.Driver.Grade = int64(driverRegularAvailabilitiesRequest.User.Grade)
|
||||
driver.Driver.Picture = driverRegularAvailabilitiesRequest.User.Picture
|
||||
driver.Driver.LastName = driverRegularAvailabilitiesRequest.User.LastName
|
||||
driver.Driver.FirstName = driverRegularAvailabilitiesRequest.User.FirstName
|
||||
driver.Driver.VerifiedIdentity = driverRegularAvailabilitiesRequest.User.VerifiedIdentity
|
||||
driver.Driver.Gender = driverRegularAvailabilitiesRequest.User.Gender
|
||||
driver.Driver_departure_address = &geojson.Feature{
|
||||
Type: "Feature",
|
||||
Geometry: orb.Geometry(orb.Point{driverRegularAvailabilitiesRequest.Latitude, driverRegularAvailabilitiesRequest.Longitude}),
|
||||
Properties: geojson.Properties{
|
||||
"name": driverRegularAvailabilitiesRequest.Address,
|
||||
},
|
||||
}
|
||||
driver.Preferences.Music = driverRegularAvailabilitiesRequest.Preferences.Music
|
||||
driver.Preferences.Is_talker = driverRegularAvailabilitiesRequest.Preferences.IsTalker
|
||||
driver.Preferences.Luggage_size = int64(driverRegularAvailabilitiesRequest.Preferences.LuggageSize)
|
||||
driver.Preferences.Smoking = driverRegularAvailabilitiesRequest.Preferences.Smoking
|
||||
driver.Preferences.Animals = driverRegularAvailabilitiesRequest.Preferences.Animals
|
||||
driver.Radius = driverRegularAvailabilitiesRequest.Radius
|
||||
driver.AvailabilitiesType = internal.Regular
|
||||
for _, v := range driverRegularAvailabilitiesRequest.Availabilities {
|
||||
driver.RegularAvailabilities = append(driver.RegularAvailabilities, internal.RegularAvailabilities{
|
||||
DayOfWeek: v.DayOfWeek,
|
||||
StartTime: v.StartTime,
|
||||
EndTime: v.EndTime,
|
||||
})
|
||||
}
|
||||
driver.Car.Brand = driverRegularAvailabilitiesRequest.Car.Brand
|
||||
driver.Car.Model = driverRegularAvailabilitiesRequest.Car.Model
|
||||
err := s.storage.CreateDriver(driver)
|
||||
if err != nil {
|
||||
return Response(http.StatusInternalServerError, nil), errors.New("DriverPunctualAvailabilitiesPost internal server error")
|
||||
} else {
|
||||
return Response(201, "Regular driver availabilities set successfully"), nil
|
||||
}
|
||||
}
|
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/gorilla/mux"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// InteractAPIController binds http requests to an api service and writes the service results to the http response
|
||||
type InteractAPIController struct {
|
||||
service InteractAPIServicer
|
||||
errorHandler ErrorHandler
|
||||
}
|
||||
|
||||
// InteractAPIOption for how the controller is set up.
|
||||
type InteractAPIOption func(*InteractAPIController)
|
||||
|
||||
// WithInteractAPIErrorHandler inject ErrorHandler into controller
|
||||
func WithInteractAPIErrorHandler(h ErrorHandler) InteractAPIOption {
|
||||
return func(c *InteractAPIController) {
|
||||
c.errorHandler = h
|
||||
}
|
||||
}
|
||||
|
||||
// NewInteractAPIController creates a default api controller
|
||||
func NewInteractAPIController(s InteractAPIServicer, opts ...InteractAPIOption) Router {
|
||||
controller := &InteractAPIController{
|
||||
service: s,
|
||||
errorHandler: DefaultErrorHandler,
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(controller)
|
||||
}
|
||||
|
||||
return controller
|
||||
}
|
||||
|
||||
// Routes returns all the api routes for the InteractAPIController
|
||||
func (c *InteractAPIController) Routes() Routes {
|
||||
return Routes{
|
||||
"GetBookings": Route{
|
||||
strings.ToUpper("Get"),
|
||||
"/bookings/{bookingId}",
|
||||
c.GetBookings,
|
||||
},
|
||||
"PatchBookings": Route{
|
||||
strings.ToUpper("Patch"),
|
||||
"/bookings/{bookingId}",
|
||||
c.PatchBookings,
|
||||
},
|
||||
"PostBookings": Route{
|
||||
strings.ToUpper("Post"),
|
||||
"/bookings",
|
||||
c.PostBookings,
|
||||
},
|
||||
"PostConnections": Route{
|
||||
strings.ToUpper("Post"),
|
||||
"/messages",
|
||||
c.PostConnections,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// GetBookings - Retrieves an existing Booking request.
|
||||
func (c *InteractAPIController) GetBookings(w http.ResponseWriter, r *http.Request) {
|
||||
authenticated := CheckOperatorAuthorization(r, AuthorizedOperators)
|
||||
if !authenticated {
|
||||
response := ImplResponse{
|
||||
Code: 401,
|
||||
Body: "Unauthorized request. Check your operator / API Key.",
|
||||
}
|
||||
EncodeJSONResponse(response.Body, &response.Code, w)
|
||||
return
|
||||
}
|
||||
params := mux.Vars(r)
|
||||
query := r.URL.Query()
|
||||
operatorParam := query.Get("operator")
|
||||
bookingIdParam := params["bookingId"]
|
||||
result, err := c.service.GetBookings(r.Context(), operatorParam, bookingIdParam)
|
||||
// If an error occurred, encode the error with the status code
|
||||
if err != nil {
|
||||
c.errorHandler(w, r, err, &result)
|
||||
return
|
||||
}
|
||||
// If no error, encode the body and the result code
|
||||
EncodeJSONResponse(result.Body, &result.Code, w)
|
||||
}
|
||||
|
||||
// PatchBookings - Updates status of an existing Booking request.
|
||||
func (c *InteractAPIController) PatchBookings(w http.ResponseWriter, r *http.Request) {
|
||||
authenticated := CheckOperatorAuthorization(r, AuthorizedOperators)
|
||||
if !authenticated {
|
||||
response := ImplResponse{
|
||||
Code: 401,
|
||||
Body: "Unauthorized request. Check your operator / API Key.",
|
||||
}
|
||||
EncodeJSONResponse(response.Body, &response.Code, w)
|
||||
return
|
||||
}
|
||||
params := mux.Vars(r)
|
||||
query := r.URL.Query()
|
||||
operatorParam := query.Get("operator")
|
||||
bookingIdParam := params["bookingId"]
|
||||
statusParam := query.Get("status")
|
||||
messageParam := query.Get("message")
|
||||
result, err := c.service.PatchBookings(r.Context(), operatorParam, bookingIdParam, BookingStatus(statusParam), messageParam)
|
||||
// If an error occurred, encode the error with the status code
|
||||
if err != nil {
|
||||
c.errorHandler(w, r, err, &result)
|
||||
return
|
||||
}
|
||||
// If no error, encode the body and the result code
|
||||
EncodeJSONResponse(result.Body, &result.Code, w)
|
||||
}
|
||||
|
||||
// PostBookings - Create a punctual outward Booking request.
|
||||
func (c *InteractAPIController) PostBookings(w http.ResponseWriter, r *http.Request) {
|
||||
authenticated := CheckOperatorAuthorization(r, AuthorizedOperators)
|
||||
if !authenticated {
|
||||
response := ImplResponse{
|
||||
Code: 401,
|
||||
Body: "Unauthorized request. Check your operator / API Key.",
|
||||
}
|
||||
EncodeJSONResponse(response.Body, &response.Code, w)
|
||||
return
|
||||
}
|
||||
bookingRequestParam := BookingRequest{}
|
||||
d := json.NewDecoder(r.Body)
|
||||
d.DisallowUnknownFields()
|
||||
if err := d.Decode(&bookingRequestParam); err != nil && !errors.Is(err, io.EOF) {
|
||||
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
|
||||
return
|
||||
}
|
||||
if err := AssertBookingRequestRequired(bookingRequestParam); err != nil {
|
||||
c.errorHandler(w, r, err, nil)
|
||||
return
|
||||
}
|
||||
if err := AssertBookingRequestConstraints(bookingRequestParam); err != nil {
|
||||
c.errorHandler(w, r, err, nil)
|
||||
return
|
||||
}
|
||||
result, err := c.service.PostBookings(r.Context(), bookingRequestParam)
|
||||
// If an error occurred, encode the error with the status code
|
||||
if err != nil {
|
||||
c.errorHandler(w, r, err, &result)
|
||||
return
|
||||
}
|
||||
// If no error, encode the body and the result code
|
||||
EncodeJSONResponse(result.Body, &result.Code, w)
|
||||
}
|
||||
|
||||
// PostConnections - Send a message to the owner of a retrieved journey.
|
||||
func (c *InteractAPIController) PostConnections(w http.ResponseWriter, r *http.Request) {
|
||||
postConnectionsRequestParam := PostConnectionsRequest{}
|
||||
d := json.NewDecoder(r.Body)
|
||||
d.DisallowUnknownFields()
|
||||
if err := d.Decode(&postConnectionsRequestParam); err != nil && !errors.Is(err, io.EOF) {
|
||||
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
|
||||
return
|
||||
}
|
||||
if err := AssertPostConnectionsRequestRequired(postConnectionsRequestParam); err != nil {
|
||||
c.errorHandler(w, r, err, nil)
|
||||
return
|
||||
}
|
||||
if err := AssertPostConnectionsRequestConstraints(postConnectionsRequestParam); err != nil {
|
||||
c.errorHandler(w, r, err, nil)
|
||||
return
|
||||
}
|
||||
result, err := c.service.PostConnections(r.Context(), postConnectionsRequestParam)
|
||||
// If an error occurred, encode the error with the status code
|
||||
if err != nil {
|
||||
c.errorHandler(w, r, err, &result)
|
||||
return
|
||||
}
|
||||
// If no error, encode the body and the result code
|
||||
EncodeJSONResponse(result.Body, &result.Code, w)
|
||||
}
|
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/spf13/viper"
|
||||
"net/http"
|
||||
"solidarity-service/handler"
|
||||
"solidarity-service/internal"
|
||||
"solidarity-service/storage"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// InteractAPIService is a service that implements the logic for the InteractAPIServicer
|
||||
// This service should implement the business logic for every endpoint for the InteractAPI API.
|
||||
// Include any external packages or services that will be required by this service.
|
||||
type InteractAPIService struct {
|
||||
config *viper.Viper
|
||||
handler *handler.SolidarityServiceHandler
|
||||
storage storage.Storage
|
||||
}
|
||||
|
||||
// NewInteractAPIService creates a default api service
|
||||
func NewInteractAPIService(config *viper.Viper, handler *handler.SolidarityServiceHandler, storage storage.Storage) InteractAPIServicer {
|
||||
return &InteractAPIService{
|
||||
config: config,
|
||||
handler: handler,
|
||||
storage: storage,
|
||||
}
|
||||
}
|
||||
|
||||
// GetBookings - Retrieves an existing Booking request.
|
||||
func (s *InteractAPIService) GetBookings(ctx context.Context, operator string, bookingId string) (ImplResponse, error) {
|
||||
booking, err := s.storage.GetBooking(bookingId)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), " no rows in result set") {
|
||||
return Response(http.StatusBadRequest, "ID not found in the database"), nil
|
||||
} else {
|
||||
return Response(http.StatusInternalServerError, nil), errors.New("DriverPunctualAvailabilitiesPost internal server error")
|
||||
}
|
||||
}
|
||||
passenger, err := s.storage.GetPassenger(booking.Passenger.ID)
|
||||
if err != nil {
|
||||
return Response(http.StatusInternalServerError, nil), nil
|
||||
}
|
||||
driver, err := s.storage.GetDriver(booking.Driver.ID)
|
||||
if err != nil {
|
||||
return Response(http.StatusInternalServerError, nil), nil
|
||||
}
|
||||
duration, err := s.handler.CalculateDurationBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address)
|
||||
if err != nil {
|
||||
duration = 0
|
||||
}
|
||||
response := Booking{
|
||||
Id: booking.ID,
|
||||
Driver: User{
|
||||
Id: driver.Driver.ID,
|
||||
Operator: driver.Driver.Operator,
|
||||
Alias: driver.Driver.Alias,
|
||||
FirstName: driver.Driver.FirstName,
|
||||
LastName: driver.Driver.LastName,
|
||||
Grade: int32(driver.Driver.Grade),
|
||||
Picture: driver.Driver.Picture,
|
||||
Gender: driver.Driver.Gender,
|
||||
VerifiedIdentity: driver.Driver.VerifiedIdentity,
|
||||
},
|
||||
Passenger: User{
|
||||
Id: passenger.Passenger.ID,
|
||||
Operator: passenger.Passenger.Operator,
|
||||
Alias: passenger.Passenger.Alias,
|
||||
FirstName: passenger.Passenger.FirstName,
|
||||
LastName: passenger.Passenger.LastName,
|
||||
Grade: int32(passenger.Passenger.Grade),
|
||||
Picture: passenger.Passenger.Picture,
|
||||
Gender: passenger.Passenger.Gender,
|
||||
VerifiedIdentity: passenger.Passenger.VerifiedIdentity,
|
||||
},
|
||||
PassengerPickupDate: int32(passenger.Passenger_pickup_date),
|
||||
PassengerPickupLat: passenger.Passenger_departure_address.Point().X(),
|
||||
PassengerPickupLng: passenger.Passenger_departure_address.Point().Y(),
|
||||
PassengerPickupAddress: passenger.Passenger_departure_address.Properties.MustString("name"),
|
||||
PassengerDropLat: passenger.Passenger_destination_address.Point().X(),
|
||||
PassengerDropLng: passenger.Passenger_destination_address.Point().Y(),
|
||||
PassengerDropAddress: passenger.Passenger_destination_address.Properties.MustString("name"),
|
||||
Status: BookingStatus(booking.Status),
|
||||
Duration: int32(duration),
|
||||
Distance: int32(s.handler.CalculateDistanceBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address)),
|
||||
Car: Car{
|
||||
Model: driver.Car.Model,
|
||||
Brand: driver.Car.Brand,
|
||||
},
|
||||
Price: Price{
|
||||
Type: "FREE",
|
||||
},
|
||||
}
|
||||
fmt.Println(response)
|
||||
return Response(200, response), nil
|
||||
|
||||
}
|
||||
|
||||
// PatchBookings - Updates status of an existing Booking request.
|
||||
func (s *InteractAPIService) PatchBookings(ctx context.Context, operator string, bookingId string, status BookingStatus, message string) (ImplResponse, error) {
|
||||
err := s.storage.UpdateBookingStatus(bookingId, internal.BookingStatus(status))
|
||||
fmt.Println(err)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), " no rows in result set") {
|
||||
return Response(http.StatusBadRequest, "ID not found in the database"), nil
|
||||
}
|
||||
return Response(http.StatusInternalServerError, nil), nil
|
||||
}
|
||||
return Response(200, "Successful operation"), nil
|
||||
}
|
||||
|
||||
// PostBookings - Create a punctual outward Booking request.
|
||||
func (s *InteractAPIService) PostBookings(ctx context.Context, bookingRequest BookingRequest) (ImplResponse, error) {
|
||||
booking := internal.BookingRequest{}
|
||||
booking.ID = bookingRequest.Id
|
||||
booking.Status = internal.BookingStatus(bookingRequest.Status)
|
||||
booking.Driver_id = bookingRequest.DriverId
|
||||
booking.Passenger_id = bookingRequest.PassengerId
|
||||
booking.Operator = bookingRequest.Operator
|
||||
err := s.storage.CreateBooking(booking)
|
||||
if err != nil {
|
||||
return Response(http.StatusInternalServerError, nil), errors.New("PostBookings internal server error")
|
||||
}
|
||||
passenger, err := s.storage.GetPassenger(booking.Passenger_id)
|
||||
if err != nil {
|
||||
return Response(http.StatusInternalServerError, nil), errors.New("PostBookings internal server error")
|
||||
}
|
||||
driver, err := s.storage.GetDriver(booking.Driver_id)
|
||||
if err != nil {
|
||||
return Response(http.StatusInternalServerError, nil), errors.New("PostBookings internal server error")
|
||||
}
|
||||
duration, err := s.handler.CalculateDurationBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address)
|
||||
if err != nil {
|
||||
duration = 0
|
||||
}
|
||||
response := Booking{
|
||||
Id: bookingRequest.Id,
|
||||
Driver: User{
|
||||
Id: driver.Driver.ID,
|
||||
Operator: driver.Driver.Operator,
|
||||
Alias: driver.Driver.Alias,
|
||||
FirstName: driver.Driver.FirstName,
|
||||
LastName: driver.Driver.LastName,
|
||||
Grade: int32(driver.Driver.Grade),
|
||||
Picture: driver.Driver.Picture,
|
||||
Gender: driver.Driver.Gender,
|
||||
VerifiedIdentity: driver.Driver.VerifiedIdentity,
|
||||
},
|
||||
Passenger: User{
|
||||
Id: passenger.Passenger.ID,
|
||||
Operator: passenger.Passenger.Operator,
|
||||
Alias: passenger.Passenger.Alias,
|
||||
FirstName: passenger.Passenger.FirstName,
|
||||
LastName: passenger.Passenger.LastName,
|
||||
Grade: int32(passenger.Passenger.Grade),
|
||||
Picture: passenger.Passenger.Picture,
|
||||
Gender: passenger.Passenger.Gender,
|
||||
VerifiedIdentity: passenger.Passenger.VerifiedIdentity,
|
||||
},
|
||||
PassengerPickupDate: int32(passenger.Passenger_pickup_date),
|
||||
PassengerPickupLat: passenger.Passenger_departure_address.Point().X(),
|
||||
PassengerPickupLng: passenger.Passenger_departure_address.Point().Y(),
|
||||
PassengerPickupAddress: passenger.Passenger_departure_address.Properties.MustString("name"),
|
||||
PassengerDropLat: passenger.Passenger_destination_address.Point().X(),
|
||||
PassengerDropLng: passenger.Passenger_destination_address.Point().Y(),
|
||||
PassengerDropAddress: passenger.Passenger_destination_address.Properties.MustString("name"),
|
||||
Status: bookingRequest.Status,
|
||||
Duration: int32(duration),
|
||||
Distance: int32(s.handler.CalculateDistanceBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address)),
|
||||
Car: Car{
|
||||
Model: driver.Car.Model,
|
||||
Brand: driver.Car.Brand,
|
||||
},
|
||||
Price: Price{
|
||||
Type: "FREE",
|
||||
},
|
||||
}
|
||||
return Response(201, response), nil
|
||||
}
|
||||
|
||||
// PostConnections - Send a message to the owner of a retrieved journey.
|
||||
func (s *InteractAPIService) PostConnections(ctx context.Context, postConnectionsRequest PostConnectionsRequest) (ImplResponse, error) {
|
||||
return Response(http.StatusNotImplemented, nil), errors.New("PostConnections method not implemented")
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// PassengerTripRequestAPIController binds http requests to an api service and writes the service results to the http response
|
||||
type PassengerTripRequestAPIController struct {
|
||||
service PassengerTripRequestAPIServicer
|
||||
errorHandler ErrorHandler
|
||||
}
|
||||
|
||||
// PassengerTripRequestAPIOption for how the controller is set up.
|
||||
type PassengerTripRequestAPIOption func(*PassengerTripRequestAPIController)
|
||||
|
||||
// WithPassengerTripRequestAPIErrorHandler inject ErrorHandler into controller
|
||||
func WithPassengerTripRequestAPIErrorHandler(h ErrorHandler) PassengerTripRequestAPIOption {
|
||||
return func(c *PassengerTripRequestAPIController) {
|
||||
c.errorHandler = h
|
||||
}
|
||||
}
|
||||
|
||||
// NewPassengerTripRequestAPIController creates a default api controller
|
||||
func NewPassengerTripRequestAPIController(s PassengerTripRequestAPIServicer, opts ...PassengerTripRequestAPIOption) Router {
|
||||
controller := &PassengerTripRequestAPIController{
|
||||
service: s,
|
||||
errorHandler: DefaultErrorHandler,
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(controller)
|
||||
}
|
||||
|
||||
return controller
|
||||
}
|
||||
|
||||
// Routes returns all the api routes for the PassengerTripRequestAPIController
|
||||
func (c *PassengerTripRequestAPIController) Routes() Routes {
|
||||
return Routes{
|
||||
"PassengerPost": Route{
|
||||
strings.ToUpper("Post"),
|
||||
"/passenger",
|
||||
c.PassengerPost,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// PassengerPost - Create a Passenger Trip Request
|
||||
func (c *PassengerTripRequestAPIController) PassengerPost(w http.ResponseWriter, r *http.Request) {
|
||||
authenticated := CheckOperatorAuthorization(r, AuthorizedOperators)
|
||||
if !authenticated {
|
||||
response := ImplResponse{
|
||||
Code: 401,
|
||||
Body: "Unauthorized request. Check your operator / API Key.",
|
||||
}
|
||||
EncodeJSONResponse(response.Body, &response.Code, w)
|
||||
return
|
||||
}
|
||||
passengerTripRequestParam := PassengerTripRequest{}
|
||||
d := json.NewDecoder(r.Body)
|
||||
d.DisallowUnknownFields()
|
||||
if err := d.Decode(&passengerTripRequestParam); err != nil {
|
||||
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
|
||||
return
|
||||
}
|
||||
if err := AssertPassengerTripRequestRequired(passengerTripRequestParam); err != nil {
|
||||
c.errorHandler(w, r, err, nil)
|
||||
return
|
||||
}
|
||||
if err := AssertPassengerTripRequestConstraints(passengerTripRequestParam); err != nil {
|
||||
c.errorHandler(w, r, err, nil)
|
||||
return
|
||||
}
|
||||
result, err := c.service.PassengerPost(r.Context(), passengerTripRequestParam)
|
||||
// If an error occurred, encode the error with the status code
|
||||
if err != nil {
|
||||
c.errorHandler(w, r, err, &result)
|
||||
return
|
||||
}
|
||||
// If no error, encode the body and the result code
|
||||
EncodeJSONResponse(result.Body, &result.Code, w)
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/paulmach/orb"
|
||||
"github.com/paulmach/orb/geojson"
|
||||
"github.com/spf13/viper"
|
||||
"net/http"
|
||||
"solidarity-service/handler"
|
||||
"solidarity-service/internal"
|
||||
"solidarity-service/storage"
|
||||
)
|
||||
|
||||
// PassengerTripRequestAPIService is a service that implements the logic for the PassengerTripRequestAPIServicer
|
||||
// This service should implement the business logic for every endpoint for the PassengerTripRequestAPI API.
|
||||
// Include any external packages or services that will be required by this service.
|
||||
type PassengerTripRequestAPIService struct {
|
||||
config *viper.Viper
|
||||
handler *handler.SolidarityServiceHandler
|
||||
storage storage.Storage
|
||||
}
|
||||
|
||||
// NewPassengerTripRequestAPIService creates a default api service
|
||||
func NewPassengerTripRequestAPIService(config *viper.Viper, handler *handler.SolidarityServiceHandler, storage storage.Storage) PassengerTripRequestAPIServicer {
|
||||
return &PassengerTripRequestAPIService{
|
||||
config: config,
|
||||
handler: handler,
|
||||
storage: storage,
|
||||
}
|
||||
}
|
||||
|
||||
// PassengerPost - Create a Passenger Trip Request
|
||||
func (s *PassengerTripRequestAPIService) PassengerPost(ctx context.Context, passengerTripRequest PassengerTripRequest) (ImplResponse, error) {
|
||||
passenger := internal.Passenger{}
|
||||
passenger.Passenger_departure_address = &geojson.Feature{
|
||||
Type: "Feature",
|
||||
Geometry: orb.Geometry(orb.Point{passengerTripRequest.DepartureLatitude, passengerTripRequest.DepartureLongitude}),
|
||||
Properties: geojson.Properties{
|
||||
"name": passengerTripRequest.DepartureAddress,
|
||||
},
|
||||
}
|
||||
passenger.Passenger_destination_address = &geojson.Feature{
|
||||
Type: "Feature",
|
||||
Geometry: orb.Geometry(orb.Point{passengerTripRequest.DestinationLatitude, passengerTripRequest.DestinationLongitude}),
|
||||
Properties: geojson.Properties{
|
||||
"name": passengerTripRequest.DestinationAddress,
|
||||
},
|
||||
}
|
||||
passenger.Passenger_pickup_date = int64(passengerTripRequest.DepartureDate)
|
||||
passenger.Passenger.ID = passengerTripRequest.User.Id
|
||||
passenger.Passenger.Operator = passengerTripRequest.User.Operator
|
||||
passenger.Passenger.Alias = passengerTripRequest.User.Alias
|
||||
passenger.Passenger.FirstName = passengerTripRequest.User.FirstName
|
||||
passenger.Passenger.LastName = passengerTripRequest.User.LastName
|
||||
passenger.Passenger.Picture = passengerTripRequest.User.Picture
|
||||
passenger.Passenger.Grade = int64(passengerTripRequest.User.Grade)
|
||||
passenger.Passenger.Gender = passengerTripRequest.User.Gender
|
||||
passenger.Passenger.VerifiedIdentity = passengerTripRequest.User.VerifiedIdentity
|
||||
passenger.Preferences.Animals = passengerTripRequest.Preferences.Animals
|
||||
passenger.Preferences.Luggage_size = int64(passengerTripRequest.Preferences.LuggageSize)
|
||||
passenger.Preferences.Smoking = passengerTripRequest.Preferences.Smoking
|
||||
passenger.Preferences.Is_talker = passengerTripRequest.Preferences.IsTalker
|
||||
passenger.Preferences.Music = passengerTripRequest.Preferences.Music
|
||||
err := s.storage.CreatePassenger(passenger)
|
||||
if err != nil {
|
||||
return Response(http.StatusInternalServerError, nil), errors.New("DriverPunctualAvailabilitiesPost internal server error")
|
||||
} else {
|
||||
return Response(201, "Trip request created"), nil
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SearchAPIController binds http requests to an api service and writes the service results to the http response
|
||||
type SearchAPIController struct {
|
||||
service SearchAPIServicer
|
||||
errorHandler ErrorHandler
|
||||
}
|
||||
|
||||
// SearchAPIOption for how the controller is set up.
|
||||
type SearchAPIOption func(*SearchAPIController)
|
||||
|
||||
// WithSearchAPIErrorHandler inject ErrorHandler into controller
|
||||
func WithSearchAPIErrorHandler(h ErrorHandler) SearchAPIOption {
|
||||
return func(c *SearchAPIController) {
|
||||
c.errorHandler = h
|
||||
}
|
||||
}
|
||||
|
||||
// NewSearchAPIController creates a default api controller
|
||||
func NewSearchAPIController(s SearchAPIServicer, opts ...SearchAPIOption) Router {
|
||||
controller := &SearchAPIController{
|
||||
service: s,
|
||||
errorHandler: DefaultErrorHandler,
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(controller)
|
||||
}
|
||||
|
||||
return controller
|
||||
}
|
||||
|
||||
// Routes returns all the api routes for the SearchAPIController
|
||||
func (c *SearchAPIController) Routes() Routes {
|
||||
return Routes{
|
||||
"GetDriverJourneys": Route{
|
||||
strings.ToUpper("Get"),
|
||||
"/driver_journeys",
|
||||
c.GetDriverJourneys,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// GetDriverJourneys - Search for matching punctual planned outward driver journeys.
|
||||
func (c *SearchAPIController) GetDriverJourneys(w http.ResponseWriter, r *http.Request) {
|
||||
authenticated := CheckOperatorAuthorization(r, AuthorizedOperators)
|
||||
if !authenticated {
|
||||
response := ImplResponse{
|
||||
Code: 401,
|
||||
Body: "Unauthorized request. Check your operator / API Key.",
|
||||
}
|
||||
EncodeJSONResponse(response.Body, &response.Code, w)
|
||||
return
|
||||
}
|
||||
query := r.URL.Query()
|
||||
departureLatParam, err := parseNumericParameter[float32](
|
||||
query.Get("departureLat"),
|
||||
WithRequire[float32](parseFloat32),
|
||||
)
|
||||
if err != nil {
|
||||
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
|
||||
return
|
||||
}
|
||||
departureLngParam, err := parseNumericParameter[float32](
|
||||
query.Get("departureLng"),
|
||||
WithRequire[float32](parseFloat32),
|
||||
)
|
||||
if err != nil {
|
||||
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
|
||||
return
|
||||
}
|
||||
departureDateParam, err := parseNumericParameter[int32](
|
||||
query.Get("departureDate"),
|
||||
WithRequire[int32](parseInt32),
|
||||
)
|
||||
if err != nil {
|
||||
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
|
||||
return
|
||||
}
|
||||
operatorParam := query.Get("operator")
|
||||
result, err := c.service.GetDriverJourneys(r.Context(), departureLatParam, departureLngParam, departureDateParam, operatorParam)
|
||||
// If an error occurred, encode the error with the status code
|
||||
if err != nil {
|
||||
c.errorHandler(w, r, err, &result)
|
||||
return
|
||||
}
|
||||
// If no error, encode the body and the result code
|
||||
EncodeJSONResponse(result.Body, &result.Code, w)
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/paulmach/orb"
|
||||
"github.com/paulmach/orb/geojson"
|
||||
"github.com/spf13/viper"
|
||||
"net/http"
|
||||
"solidarity-service/handler"
|
||||
"solidarity-service/internal"
|
||||
"solidarity-service/storage"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SearchAPIService is a service that implements the logic for the SearchAPIServicer
|
||||
// This service should implement the business logic for every endpoint for the SearchAPI API.
|
||||
// Include any external packages or services that will be required by this service.
|
||||
type SearchAPIService struct {
|
||||
config *viper.Viper
|
||||
handler *handler.SolidarityServiceHandler
|
||||
storage storage.Storage
|
||||
}
|
||||
|
||||
// NewSearchAPIService creates a default api service
|
||||
func NewSearchAPIService(config *viper.Viper, handler *handler.SolidarityServiceHandler, storage storage.Storage) SearchAPIServicer {
|
||||
return &SearchAPIService{
|
||||
config: config,
|
||||
handler: handler,
|
||||
storage: storage,
|
||||
}
|
||||
}
|
||||
|
||||
// GetDriverJourneys - Search for matching punctual planned outward driver journeys.
|
||||
func (s *SearchAPIService) GetDriverJourneys(ctx context.Context, departureLat float32, departureLng float32, departureDate int32, operator string) (ImplResponse, error) {
|
||||
drivers, err := s.storage.DriverJourneys(&geojson.Feature{
|
||||
Type: "Feature",
|
||||
Geometry: orb.Geometry(orb.Point{float64(departureLat), float64(departureLng)}),
|
||||
}, int64(departureDate))
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), " no rows in result set") {
|
||||
return Response(http.StatusBadRequest, "ID not found in the database"), nil
|
||||
} else {
|
||||
return Response(http.StatusInternalServerError, nil), nil
|
||||
}
|
||||
}
|
||||
response := []DriverJourney{}
|
||||
for _, v := range drivers {
|
||||
temp := DriverJourney{}
|
||||
if v.AvailabilitiesType == internal.Regular && v.RegularAvailabilities != nil {
|
||||
for _, v := range v.RegularAvailabilities {
|
||||
temp.RegularAvailabilitySlot = append(temp.RegularAvailabilitySlot, RegularAvailabilitySlot{
|
||||
DayOfWeek: v.DayOfWeek,
|
||||
StartTime: v.StartTime,
|
||||
EndTime: v.EndTime,
|
||||
})
|
||||
}
|
||||
} else if v.AvailabilitiesType == internal.Punctual && v.PunctualAvailabilities != nil {
|
||||
for _, v := range v.PunctualAvailabilities {
|
||||
temp.PunctualAvailabilitySlot = append(temp.PunctualAvailabilitySlot, PunctualAvailabilitySlot{
|
||||
Date: int32(v.Date),
|
||||
StartTime: v.StartTime,
|
||||
EndTime: v.EndTime,
|
||||
})
|
||||
}
|
||||
}
|
||||
tamp := DriverJourney{
|
||||
User: User{
|
||||
Id: v.Driver.ID,
|
||||
Operator: v.Driver.Operator,
|
||||
Alias: v.Driver.Alias,
|
||||
FirstName: v.Driver.FirstName,
|
||||
LastName: v.Driver.LastName,
|
||||
Grade: int32(v.Driver.Grade),
|
||||
Picture: v.Driver.Picture,
|
||||
Gender: v.Driver.Gender,
|
||||
VerifiedIdentity: v.Driver.VerifiedIdentity,
|
||||
},
|
||||
Car: Car{
|
||||
Model: v.Car.Model,
|
||||
Brand: v.Car.Brand,
|
||||
},
|
||||
DriverDepartureDate: int64(departureDate),
|
||||
Price: Price{
|
||||
Type: "FREE",
|
||||
},
|
||||
DriverDepartureAddress: v.Driver_departure_address.Properties.MustString("name"),
|
||||
}
|
||||
temp.DriverDepartureAddress = tamp.DriverDepartureAddress
|
||||
temp.Car = tamp.Car
|
||||
temp.User = tamp.User
|
||||
temp.DriverDepartureDate = tamp.DriverDepartureDate
|
||||
temp.Price = tamp.Price
|
||||
response = append(response, temp)
|
||||
}
|
||||
return Response(200, response), nil
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrTypeAssertionError is thrown when type an interface does not match the asserted type
|
||||
ErrTypeAssertionError = errors.New("unable to assert type")
|
||||
)
|
||||
|
||||
// ParsingError indicates that an error has occurred when parsing request parameters
|
||||
type ParsingError struct {
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e *ParsingError) Unwrap() error {
|
||||
return e.Err
|
||||
}
|
||||
|
||||
func (e *ParsingError) Error() string {
|
||||
return e.Err.Error()
|
||||
}
|
||||
|
||||
// RequiredError indicates that an error has occurred when parsing request parameters
|
||||
type RequiredError struct {
|
||||
Field string
|
||||
}
|
||||
|
||||
func (e *RequiredError) Error() string {
|
||||
return fmt.Sprintf("required field '%s' is zero value.", e.Field)
|
||||
}
|
||||
|
||||
// ErrorHandler defines the required method for handling error. You may implement it and inject this into a controller if
|
||||
// you would like errors to be handled differently from the DefaultErrorHandler
|
||||
type ErrorHandler func(w http.ResponseWriter, r *http.Request, err error, result *ImplResponse)
|
||||
|
||||
// DefaultErrorHandler defines the default logic on how to handle errors from the controller. Any errors from parsing
|
||||
// request params will return a StatusBadRequest. Otherwise, the error code originating from the servicer will be used.
|
||||
func DefaultErrorHandler(w http.ResponseWriter, r *http.Request, err error, result *ImplResponse) {
|
||||
if _, ok := err.(*ParsingError); ok {
|
||||
// Handle parsing errors
|
||||
EncodeJSONResponse(err.Error(), func(i int) *int { return &i }(http.StatusBadRequest), w)
|
||||
} else if _, ok := err.(*RequiredError); ok {
|
||||
// Handle missing required errors
|
||||
EncodeJSONResponse(err.Error(), func(i int) *int { return &i }(http.StatusUnprocessableEntity), w)
|
||||
} else {
|
||||
// Handle all other errors
|
||||
EncodeJSONResponse(err.Error(), &result.Code, w)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// Response return a ImplResponse struct filled
|
||||
func Response(code int, body interface{}) ImplResponse {
|
||||
return ImplResponse {
|
||||
Code: code,
|
||||
Body: body,
|
||||
}
|
||||
}
|
||||
|
||||
// IsZeroValue checks if the val is the zero-ed value.
|
||||
func IsZeroValue(val interface{}) bool {
|
||||
return val == nil || reflect.DeepEqual(val, reflect.Zero(reflect.TypeOf(val)).Interface())
|
||||
}
|
||||
|
||||
// AssertRecurseInterfaceRequired recursively checks each struct in a slice against the callback.
|
||||
// This method traverse nested slices in a preorder fashion.
|
||||
func AssertRecurseInterfaceRequired[T any](obj interface{}, callback func(T) error) error {
|
||||
return AssertRecurseValueRequired(reflect.ValueOf(obj), callback)
|
||||
}
|
||||
|
||||
// AssertRecurseValueRequired checks each struct in the nested slice against the callback.
|
||||
// This method traverse nested slices in a preorder fashion. ErrTypeAssertionError is thrown if
|
||||
// the underlying struct does not match type T.
|
||||
func AssertRecurseValueRequired[T any](value reflect.Value, callback func(T) error) error {
|
||||
switch value.Kind() {
|
||||
// If it is a struct we check using callback
|
||||
case reflect.Struct:
|
||||
obj, ok := value.Interface().(T)
|
||||
if !ok {
|
||||
return ErrTypeAssertionError
|
||||
}
|
||||
|
||||
if err := callback(obj); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If it is a slice we continue recursion
|
||||
case reflect.Slice:
|
||||
for i := 0; i < value.Len(); i += 1 {
|
||||
if err := AssertRecurseValueRequired(value.Index(i), callback); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
// ImplResponse defines an implementation response with error code and the associated body
|
||||
type ImplResponse struct {
|
||||
Code int
|
||||
Body interface{}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
func Logger(inner http.Handler, name string) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
start := time.Now()
|
||||
|
||||
inner.ServeHTTP(w, r)
|
||||
|
||||
log.Printf(
|
||||
"%s %s %s %s",
|
||||
r.Method,
|
||||
r.RequestURI,
|
||||
name,
|
||||
time.Since(start),
|
||||
)
|
||||
})
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
|
||||
|
||||
|
||||
type PassengerPost400Response struct {
|
||||
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// AssertPassengerPost400ResponseRequired checks if the required fields are not zero-ed
|
||||
func AssertPassengerPost400ResponseRequired(obj PassengerPost400Response) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// AssertPassengerPost400ResponseConstraints checks if the values respects the defined constraints
|
||||
func AssertPassengerPost400ResponseConstraints(obj PassengerPost400Response) error {
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
type Booking struct {
|
||||
|
||||
// Booking id is common between both operators, and must be created as a [UUID](https://datatracker.ietf.org/doc/html/rfc4122) by whoever initiates the booking. Usage of a [4 UUID](https://datatracker.ietf.org/doc/html/rfc4122#section-4.4) generation algorithm is advised.
|
||||
Id string `json:"id"`
|
||||
|
||||
Driver User `json:"driver"`
|
||||
|
||||
Passenger User `json:"passenger"`
|
||||
|
||||
// Passenger pickup datetime as a UNIX UTC timestamp in seconds.
|
||||
PassengerPickupDate int32 `json:"passengerPickupDate"`
|
||||
|
||||
// Latitude of the passenger pick-up point.
|
||||
PassengerPickupLat float64 `json:"passengerPickupLat"`
|
||||
|
||||
// Longitude of the passenger pick-up point.
|
||||
PassengerPickupLng float64 `json:"passengerPickupLng"`
|
||||
|
||||
// Latitude of the passenger drop-off point.
|
||||
PassengerDropLat float64 `json:"passengerDropLat"`
|
||||
|
||||
// Longitude of the passenger drop-off point.
|
||||
PassengerDropLng float64 `json:"passengerDropLng"`
|
||||
|
||||
// String representing the pickup-up address.
|
||||
PassengerPickupAddress string `json:"passengerPickupAddress,omitempty"`
|
||||
|
||||
// String representing the drop-off address.
|
||||
PassengerDropAddress string `json:"passengerDropAddress,omitempty"`
|
||||
|
||||
Status BookingStatus `json:"status"`
|
||||
|
||||
// Carpooling duration in seconds.
|
||||
Duration int32 `json:"duration,omitempty"`
|
||||
|
||||
// Carpooling distance in meters.
|
||||
Distance int32 `json:"distance,omitempty"`
|
||||
|
||||
Price Price `json:"price"`
|
||||
|
||||
Car Car `json:"car,omitempty"`
|
||||
}
|
||||
|
||||
// AssertBookingRequired checks if the required fields are not zero-ed
|
||||
func AssertBookingRequired(obj Booking) error {
|
||||
elements := map[string]interface{}{
|
||||
"id": obj.Id,
|
||||
"driver": obj.Driver,
|
||||
"passenger": obj.Passenger,
|
||||
"passengerPickupDate": obj.PassengerPickupDate,
|
||||
"passengerPickupLat": obj.PassengerPickupLat,
|
||||
"passengerPickupLng": obj.PassengerPickupLng,
|
||||
"passengerDropLat": obj.PassengerDropLat,
|
||||
"passengerDropLng": obj.PassengerDropLng,
|
||||
"status": obj.Status,
|
||||
"price": obj.Price,
|
||||
}
|
||||
for name, el := range elements {
|
||||
if isZero := IsZeroValue(el); isZero {
|
||||
return &RequiredError{Field: name}
|
||||
}
|
||||
}
|
||||
|
||||
if err := AssertUserRequired(obj.Driver); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := AssertUserRequired(obj.Passenger); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := AssertPriceRequired(obj.Price); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := AssertCarRequired(obj.Car); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AssertBookingConstraints checks if the values respects the defined constraints
|
||||
func AssertBookingConstraints(obj Booking) error {
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
|
||||
|
||||
|
||||
type BookingRequest struct {
|
||||
|
||||
// Booking id is common between both operators, and must be created as a [UUID](https://datatracker.ietf.org/doc/html/rfc4122) by whoever initiates the booking. Usage of a [4 UUID](https://datatracker.ietf.org/doc/html/rfc4122#section-4.4) generation algorithm is advised.
|
||||
Id string `json:"id"`
|
||||
|
||||
PassengerId string `json:"passengerId"`
|
||||
|
||||
DriverId string `json:"driverId"`
|
||||
|
||||
Status BookingStatus `json:"status"`
|
||||
|
||||
Operator string `json:"operator"`
|
||||
}
|
||||
|
||||
// AssertBookingRequestRequired checks if the required fields are not zero-ed
|
||||
func AssertBookingRequestRequired(obj BookingRequest) error {
|
||||
elements := map[string]interface{}{
|
||||
"id": obj.Id,
|
||||
"passengerId": obj.PassengerId,
|
||||
"driverId": obj.DriverId,
|
||||
"status": obj.Status,
|
||||
"operator": obj.Operator,
|
||||
}
|
||||
for name, el := range elements {
|
||||
if isZero := IsZeroValue(el); isZero {
|
||||
return &RequiredError{Field: name}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AssertBookingRequestConstraints checks if the values respects the defined constraints
|
||||
func AssertBookingRequestConstraints(obj BookingRequest) error {
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
|
||||
|
||||
// BookingStatus : Status of the booking.
|
||||
type BookingStatus string
|
||||
|
||||
// List of BookingStatus
|
||||
const (
|
||||
WAITING_DRIVER_CONFIRMATION BookingStatus = "WAITING_DRIVER_CONFIRMATION"
|
||||
WAITING_PASSENGER_CONFIRMATION BookingStatus = "WAITING_PASSENGER_CONFIRMATION"
|
||||
CONFIRMED BookingStatus = "CONFIRMED"
|
||||
CANCELLED BookingStatus = "CANCELLED"
|
||||
COMPLETED_PENDING_VALIDATION BookingStatus = "COMPLETED_PENDING_VALIDATION"
|
||||
VALIDATED BookingStatus = "VALIDATED"
|
||||
)
|
||||
|
||||
// AssertBookingStatusRequired checks if the required fields are not zero-ed
|
||||
func AssertBookingStatusRequired(obj BookingStatus) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// AssertBookingStatusConstraints checks if the values respects the defined constraints
|
||||
func AssertBookingStatusConstraints(obj BookingStatus) error {
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
|
||||
|
||||
|
||||
type Car struct {
|
||||
|
||||
// Model of the car.
|
||||
Model string `json:"model,omitempty"`
|
||||
|
||||
// Brand of the car.
|
||||
Brand string `json:"brand,omitempty"`
|
||||
}
|
||||
|
||||
// AssertCarRequired checks if the required fields are not zero-ed
|
||||
func AssertCarRequired(obj Car) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// AssertCarConstraints checks if the values respects the defined constraints
|
||||
func AssertCarConstraints(obj Car) error {
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
type DriverJourney struct {
|
||||
User User `json:"user"`
|
||||
|
||||
Car Car `json:"car,omitempty"`
|
||||
RegularAvailabilitySlot []RegularAvailabilitySlot `json:"regular_availabilities,omitempty"`
|
||||
PunctualAvailabilitySlot []PunctualAvailabilitySlot `json:"punctual_availabilities,omitempty"`
|
||||
// Driver departure datetime as a UNIX UTC timestamp in seconds.
|
||||
DriverDepartureDate int64 `json:"driver_departure_Date"`
|
||||
DriverDepartureAddress string `json:"driver_departure_Address,omitempty"`
|
||||
Price Price `json:"price,omitempty"`
|
||||
}
|
||||
|
||||
// AssertDriverJourneyRequired checks if the required fields are not zero-ed
|
||||
func AssertDriverJourneyRequired(obj DriverJourney) error {
|
||||
elements := map[string]interface{}{
|
||||
"user": obj.User,
|
||||
"driverDepartureDate": obj.DriverDepartureDate,
|
||||
}
|
||||
for name, el := range elements {
|
||||
if isZero := IsZeroValue(el); isZero {
|
||||
return &RequiredError{Field: name}
|
||||
}
|
||||
}
|
||||
|
||||
if err := AssertUserRequired(obj.User); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := AssertCarRequired(obj.Car); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := AssertPriceRequired(obj.Price); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AssertDriverJourneyConstraints checks if the values respects the defined constraints
|
||||
func AssertDriverJourneyConstraints(obj DriverJourney) error {
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
|
||||
|
||||
|
||||
type DriverPunctualAvailabilitiesRequest struct {
|
||||
|
||||
// The address or location description.
|
||||
Address string `json:"address"`
|
||||
|
||||
// The latitude coordinate of the location.
|
||||
Latitude float64 `json:"latitude"`
|
||||
|
||||
// The longitude coordinate of the location.
|
||||
Longitude float64 `json:"longitude"`
|
||||
|
||||
// The radius around the location.
|
||||
Radius int32 `json:"radius"`
|
||||
|
||||
Availabilities []PunctualAvailabilitySlot `json:"availabilities"`
|
||||
|
||||
User User `json:"user"`
|
||||
|
||||
Preferences Preferences `json:"preferences,omitempty"`
|
||||
|
||||
Car Car `json:"car,omitempty"`
|
||||
}
|
||||
|
||||
// AssertDriverPunctualAvailabilitiesRequestRequired checks if the required fields are not zero-ed
|
||||
func AssertDriverPunctualAvailabilitiesRequestRequired(obj DriverPunctualAvailabilitiesRequest) error {
|
||||
elements := map[string]interface{}{
|
||||
"address": obj.Address,
|
||||
"latitude": obj.Latitude,
|
||||
"longitude": obj.Longitude,
|
||||
"radius": obj.Radius,
|
||||
"availabilities": obj.Availabilities,
|
||||
"user": obj.User,
|
||||
}
|
||||
for name, el := range elements {
|
||||
if isZero := IsZeroValue(el); isZero {
|
||||
return &RequiredError{Field: name}
|
||||
}
|
||||
}
|
||||
|
||||
for _, el := range obj.Availabilities {
|
||||
if err := AssertPunctualAvailabilitySlotRequired(el); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := AssertUserRequired(obj.User); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := AssertPreferencesRequired(obj.Preferences); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := AssertCarRequired(obj.Car); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AssertDriverPunctualAvailabilitiesRequestConstraints checks if the values respects the defined constraints
|
||||
func AssertDriverPunctualAvailabilitiesRequestConstraints(obj DriverPunctualAvailabilitiesRequest) error {
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
|
||||
|
||||
|
||||
type DriverRegularAvailabilitiesRequest struct {
|
||||
|
||||
// The address or location description.
|
||||
Address string `json:"address"`
|
||||
|
||||
// The latitude coordinate of the location.
|
||||
Latitude float64 `json:"latitude"`
|
||||
|
||||
// The longitude coordinate of the location.
|
||||
Longitude float64 `json:"longitude"`
|
||||
|
||||
// The radius around the location.
|
||||
Radius int32 `json:"radius"`
|
||||
|
||||
Availabilities []RegularAvailabilitySlot `json:"availabilities"`
|
||||
|
||||
User User `json:"user"`
|
||||
|
||||
Preferences Preferences `json:"preferences,omitempty"`
|
||||
|
||||
Car Car `json:"car,omitempty"`
|
||||
}
|
||||
|
||||
// AssertDriverRegularAvailabilitiesRequestRequired checks if the required fields are not zero-ed
|
||||
func AssertDriverRegularAvailabilitiesRequestRequired(obj DriverRegularAvailabilitiesRequest) error {
|
||||
elements := map[string]interface{}{
|
||||
"address": obj.Address,
|
||||
"latitude": obj.Latitude,
|
||||
"longitude": obj.Longitude,
|
||||
"radius": obj.Radius,
|
||||
"availabilities": obj.Availabilities,
|
||||
"user": obj.User,
|
||||
}
|
||||
for name, el := range elements {
|
||||
if isZero := IsZeroValue(el); isZero {
|
||||
return &RequiredError{Field: name}
|
||||
}
|
||||
}
|
||||
|
||||
for _, el := range obj.Availabilities {
|
||||
if err := AssertRegularAvailabilitySlotRequired(el); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := AssertUserRequired(obj.User); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := AssertPreferencesRequired(obj.Preferences); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := AssertCarRequired(obj.Car); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AssertDriverRegularAvailabilitiesRequestConstraints checks if the values respects the defined constraints
|
||||
func AssertDriverRegularAvailabilitiesRequestConstraints(obj DriverRegularAvailabilitiesRequest) error {
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
|
||||
|
||||
|
||||
type DriverTrip struct {
|
||||
|
||||
User User `json:"user"`
|
||||
|
||||
Car Car `json:"car,omitempty"`
|
||||
}
|
||||
|
||||
// AssertDriverTripRequired checks if the required fields are not zero-ed
|
||||
func AssertDriverTripRequired(obj DriverTrip) error {
|
||||
elements := map[string]interface{}{
|
||||
"user": obj.User,
|
||||
}
|
||||
for name, el := range elements {
|
||||
if isZero := IsZeroValue(el); isZero {
|
||||
return &RequiredError{Field: name}
|
||||
}
|
||||
}
|
||||
|
||||
if err := AssertUserRequired(obj.User); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := AssertCarRequired(obj.Car); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AssertDriverTripConstraints checks if the values respects the defined constraints
|
||||
func AssertDriverTripConstraints(obj DriverTrip) error {
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
|
||||
|
||||
|
||||
type GetBookings404Response struct {
|
||||
|
||||
// Explain why the request couldn't be processed.
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// AssertGetBookings404ResponseRequired checks if the required fields are not zero-ed
|
||||
func AssertGetBookings404ResponseRequired(obj GetBookings404Response) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// AssertGetBookings404ResponseConstraints checks if the values respects the defined constraints
|
||||
func AssertGetBookings404ResponseConstraints(obj GetBookings404Response) error {
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
|
||||
|
||||
|
||||
type JourneySchedule struct {
|
||||
|
||||
// Passenger pickup datetime as a UNIX UTC timestamp in seconds.
|
||||
PassengerPickupDate float32 `json:"passengerPickupDate"`
|
||||
|
||||
// Driver departure datetime as a UNIX UTC timestamp in seconds.
|
||||
DriverDepartureDate float32 `json:"driverDepartureDate,omitempty"`
|
||||
|
||||
// Type of journey. A dynamic journey is happening in real time.
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
// AssertJourneyScheduleRequired checks if the required fields are not zero-ed
|
||||
func AssertJourneyScheduleRequired(obj JourneySchedule) error {
|
||||
elements := map[string]interface{}{
|
||||
"passengerPickupDate": obj.PassengerPickupDate,
|
||||
"type": obj.Type,
|
||||
}
|
||||
for name, el := range elements {
|
||||
if isZero := IsZeroValue(el); isZero {
|
||||
return &RequiredError{Field: name}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AssertJourneyScheduleConstraints checks if the values respects the defined constraints
|
||||
func AssertJourneyScheduleConstraints(obj JourneySchedule) error {
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
|
||||
|
||||
|
||||
type PassengerTripRequest struct {
|
||||
|
||||
User User `json:"user"`
|
||||
|
||||
DestinationAddress string `json:"destination_address"`
|
||||
|
||||
DestinationLatitude float64 `json:"destination_latitude"`
|
||||
|
||||
DestinationLongitude float64 `json:"destination_longitude"`
|
||||
|
||||
DepartureAddress string `json:"departure_address"`
|
||||
|
||||
DepartureLatitude float64 `json:"departure_latitude"`
|
||||
|
||||
DepartureLongitude float64 `json:"departure_longitude"`
|
||||
|
||||
// Departure datetime using a UNIX UTC timestamp in seconds.
|
||||
DepartureDate int32 `json:"departure_date"`
|
||||
|
||||
Preferences Preferences `json:"preferences,omitempty"`
|
||||
}
|
||||
|
||||
// AssertPassengerTripRequestRequired checks if the required fields are not zero-ed
|
||||
func AssertPassengerTripRequestRequired(obj PassengerTripRequest) error {
|
||||
elements := map[string]interface{}{
|
||||
"user": obj.User,
|
||||
"destination_address": obj.DestinationAddress,
|
||||
"destination_latitude": obj.DestinationLatitude,
|
||||
"destination_longitude": obj.DestinationLongitude,
|
||||
"departure_address": obj.DepartureAddress,
|
||||
"departure_latitude": obj.DepartureLatitude,
|
||||
"departure_longitude": obj.DepartureLongitude,
|
||||
"departure_date": obj.DepartureDate,
|
||||
}
|
||||
for name, el := range elements {
|
||||
if isZero := IsZeroValue(el); isZero {
|
||||
return &RequiredError{Field: name}
|
||||
}
|
||||
}
|
||||
|
||||
if err := AssertUserRequired(obj.User); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := AssertPreferencesRequired(obj.Preferences); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AssertPassengerTripRequestConstraints checks if the values respects the defined constraints
|
||||
func AssertPassengerTripRequestConstraints(obj PassengerTripRequest) error {
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
|
||||
|
||||
|
||||
type PostConnectionsRequest struct {
|
||||
|
||||
From User `json:"from"`
|
||||
|
||||
To User `json:"to"`
|
||||
|
||||
// Free text content of a message. The message can contain all the details (phone number, email, etc.) allowing the recipient to call back the sender in order to carpool with him/her.
|
||||
Message string `json:"message"`
|
||||
|
||||
// Defines if the recipient of this message is either the driver or the passenger.
|
||||
RecipientCarpoolerType string `json:"recipientCarpoolerType"`
|
||||
|
||||
// ID of the Driver's journey to which the message is related (if any). Unique given the `Driver`'s `operator` property.
|
||||
DriverJourneyId string `json:"driverJourneyId,omitempty"`
|
||||
|
||||
// ID of the Passenger's journey to which the message is related (if any). Unique given the `Passenger`'s `operator` property.
|
||||
PassengerJourneyId string `json:"passengerJourneyId,omitempty"`
|
||||
|
||||
// Booking id is common between both operators, and must be created as a [UUID](https://datatracker.ietf.org/doc/html/rfc4122) by whoever initiates the booking. Usage of a [4 UUID](https://datatracker.ietf.org/doc/html/rfc4122#section-4.4) generation algorithm is advised.
|
||||
BookingId string `json:"bookingId,omitempty"`
|
||||
}
|
||||
|
||||
// AssertPostConnectionsRequestRequired checks if the required fields are not zero-ed
|
||||
func AssertPostConnectionsRequestRequired(obj PostConnectionsRequest) error {
|
||||
elements := map[string]interface{}{
|
||||
"from": obj.From,
|
||||
"to": obj.To,
|
||||
"message": obj.Message,
|
||||
"recipientCarpoolerType": obj.RecipientCarpoolerType,
|
||||
}
|
||||
for name, el := range elements {
|
||||
if isZero := IsZeroValue(el); isZero {
|
||||
return &RequiredError{Field: name}
|
||||
}
|
||||
}
|
||||
|
||||
if err := AssertUserRequired(obj.From); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := AssertUserRequired(obj.To); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AssertPostConnectionsRequestConstraints checks if the values respects the defined constraints
|
||||
func AssertPostConnectionsRequestConstraints(obj PostConnectionsRequest) error {
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
|
||||
|
||||
type Preferences struct {
|
||||
|
||||
// If driver journey, specifies if the driver allows smoking in the car.
|
||||
Smoking bool `json:"smoking,omitempty"`
|
||||
|
||||
// If driver journey, specifies if the driver allows animals in the car.
|
||||
Animals bool `json:"animals,omitempty"`
|
||||
|
||||
// If driver journey, specifies if the driver enjoys music in the car.
|
||||
Music bool `json:"music,omitempty"`
|
||||
|
||||
// If driver journey, specifies if the driver enjoys talking with passengers.
|
||||
IsTalker bool `json:"isTalker,omitempty"`
|
||||
|
||||
// If driver journey, specifies the size of allowed luggages. From very small (1) to very big (5).
|
||||
LuggageSize int32 `json:"luggageSize,omitempty"`
|
||||
}
|
||||
|
||||
// AssertPreferencesRequired checks if the required fields are not zero-ed
|
||||
func AssertPreferencesRequired(obj Preferences) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// AssertPreferencesConstraints checks if the values respects the defined constraints
|
||||
func AssertPreferencesConstraints(obj Preferences) error {
|
||||
if obj.LuggageSize < 1 {
|
||||
return &ParsingError{Err: errors.New(errMsgMinValueConstraint)}
|
||||
}
|
||||
if obj.LuggageSize > 5 {
|
||||
return &ParsingError{Err: errors.New(errMsgMaxValueConstraint)}
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
|
||||
|
||||
|
||||
type Price struct {
|
||||
|
||||
// Either « FREE », « PAYING » or « UNKNOWN ». « UNKNOWN » is given when it should be « PAYING » but we cannot set the price yet.
|
||||
Type string `json:"type,omitempty"`
|
||||
|
||||
// Carpooling passenger cost estimate. In the case of integrated booking by API, amount expected by the carpooling operator.
|
||||
Amount float32 `json:"amount,omitempty"`
|
||||
|
||||
// ISO 4217 code representing the currency of the price.
|
||||
Currency string `json:"currency,omitempty"`
|
||||
}
|
||||
|
||||
// AssertPriceRequired checks if the required fields are not zero-ed
|
||||
func AssertPriceRequired(obj Price) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// AssertPriceConstraints checks if the values respects the defined constraints
|
||||
func AssertPriceConstraints(obj Price) error {
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
|
||||
|
||||
|
||||
type PunctualAvailabilitySlot struct {
|
||||
|
||||
// UNIX UTC timestamp in seconds.
|
||||
Date int32 `json:"date"`
|
||||
|
||||
// Start time for punctual scheduling (RFC3339 partial-time).
|
||||
StartTime string `json:"startTime"`
|
||||
|
||||
// End time for punctual scheduling (RFC3339 partial-time).
|
||||
EndTime string `json:"endTime"`
|
||||
}
|
||||
|
||||
// AssertPunctualAvailabilitySlotRequired checks if the required fields are not zero-ed
|
||||
func AssertPunctualAvailabilitySlotRequired(obj PunctualAvailabilitySlot) error {
|
||||
elements := map[string]interface{}{
|
||||
"date": obj.Date,
|
||||
"startTime": obj.StartTime,
|
||||
"endTime": obj.EndTime,
|
||||
}
|
||||
for name, el := range elements {
|
||||
if isZero := IsZeroValue(el); isZero {
|
||||
return &RequiredError{Field: name}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AssertPunctualAvailabilitySlotConstraints checks if the values respects the defined constraints
|
||||
func AssertPunctualAvailabilitySlotConstraints(obj PunctualAvailabilitySlot) error {
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
|
||||
|
||||
|
||||
type RegularAvailabilitySlot struct {
|
||||
|
||||
// Day of the week for regular scheduling.
|
||||
DayOfWeek string `json:"dayOfWeek"`
|
||||
|
||||
// Start time for regular scheduling (RFC3339 partial-time).
|
||||
StartTime string `json:"startTime"`
|
||||
|
||||
// End time for regular scheduling (RFC3339 partial-time).
|
||||
EndTime string `json:"endTime"`
|
||||
}
|
||||
|
||||
// AssertRegularAvailabilitySlotRequired checks if the required fields are not zero-ed
|
||||
func AssertRegularAvailabilitySlotRequired(obj RegularAvailabilitySlot) error {
|
||||
elements := map[string]interface{}{
|
||||
"dayOfWeek": obj.DayOfWeek,
|
||||
"startTime": obj.StartTime,
|
||||
"endTime": obj.EndTime,
|
||||
}
|
||||
for name, el := range elements {
|
||||
if isZero := IsZeroValue(el); isZero {
|
||||
return &RequiredError{Field: name}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AssertRegularAvailabilitySlotConstraints checks if the values respects the defined constraints
|
||||
func AssertRegularAvailabilitySlotConstraints(obj RegularAvailabilitySlot) error {
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
|
||||
|
||||
type User struct {
|
||||
|
||||
// User's identifier. It MUST be unique for a given `operator`.
|
||||
Id string `json:"id"`
|
||||
|
||||
// The operator identifier. MUST be a Fully Qualified Domain Name (example carpool.mycity.com) owned by the operator or a Partially Qualified Domain Name (example operator.org) owned and exclusively operated by the operator. Operators SHOULD always send the same value.
|
||||
Operator string `json:"operator"`
|
||||
|
||||
// User's alias.
|
||||
Alias string `json:"alias"`
|
||||
|
||||
// User's first name.
|
||||
FirstName string `json:"firstName,omitempty"`
|
||||
|
||||
// User's last name.
|
||||
LastName string `json:"lastName,omitempty"`
|
||||
|
||||
// User's grade from 1 to 5.
|
||||
Grade int32 `json:"grade,omitempty"`
|
||||
|
||||
// User's profile picture absolute URL.
|
||||
Picture string `json:"picture,omitempty"`
|
||||
|
||||
// User's gender. 'O' stands for 'Other'.
|
||||
Gender string `json:"gender,omitempty"`
|
||||
|
||||
// true if the identity of this user has been verified by the operator or a third party; and the firstName, lastName, birthdate have been confirmed as identitical to an official identity proof document. Can be left empty if the information is not available.
|
||||
VerifiedIdentity bool `json:"verifiedIdentity,omitempty"`
|
||||
}
|
||||
|
||||
// AssertUserRequired checks if the required fields are not zero-ed
|
||||
func AssertUserRequired(obj User) error {
|
||||
elements := map[string]interface{}{
|
||||
"id": obj.Id,
|
||||
"operator": obj.Operator,
|
||||
"alias": obj.Alias,
|
||||
}
|
||||
for name, el := range elements {
|
||||
if isZero := IsZeroValue(el); isZero {
|
||||
return &RequiredError{Field: name}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AssertUserConstraints checks if the values respects the defined constraints
|
||||
func AssertUserConstraints(obj User) error {
|
||||
if obj.Grade < 1 {
|
||||
return &ParsingError{Err: errors.New(errMsgMinValueConstraint)}
|
||||
}
|
||||
if obj.Grade > 5 {
|
||||
return &ParsingError{Err: errors.New(errMsgMaxValueConstraint)}
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package openapi
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func CheckOperatorAuthorization(r *http.Request, authorizedOperators map[string]string) bool {
|
||||
authorizationHeader := r.Header.Get("Authorization")
|
||||
if authorizationHeader == "" {
|
||||
return false
|
||||
}
|
||||
parts := strings.Split(authorizationHeader, " ")
|
||||
if len(parts) != 2 {
|
||||
return false
|
||||
}
|
||||
if parts[0] != "Bearer" {
|
||||
return false
|
||||
}
|
||||
apiKey := parts[1]
|
||||
operatorName, authorized := authorizedOperators[apiKey]
|
||||
var operator string
|
||||
var found bool
|
||||
|
||||
if r.Body != nil {
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
if err == nil {
|
||||
var payload map[string]interface{}
|
||||
if json.Unmarshal(body, &payload) == nil {
|
||||
// Check for "operator" in the top-level body
|
||||
if op, ok := payload["operator"].(string); ok {
|
||||
operator = op
|
||||
found = true
|
||||
} else {
|
||||
// Check for "user" struct in the body
|
||||
if user, ok := payload["user"].(map[string]interface{}); ok {
|
||||
if op, ok := user["operator"].(string); ok {
|
||||
operator = op
|
||||
found = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
r.Body = ioutil.NopCloser(bytes.NewReader(body))
|
||||
}
|
||||
|
||||
// If operator is not found in the request body, check the request parameters.
|
||||
if !found {
|
||||
operatorFromParams := r.URL.Query().Get("operator")
|
||||
if operatorFromParams != "" {
|
||||
operator = operatorFromParams
|
||||
found = true
|
||||
}
|
||||
}
|
||||
|
||||
if found && operator == operatorName && authorized {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var AuthorizedOperators = map[string]string{
|
||||
"$2y$10$TJuDZDu.mqy5dDKGMSfxSO5f6pz/36XVrAyQ1CXJd63ccjRlX7lmK": "test.com",
|
||||
}
|
|
@ -0,0 +1,297 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package openapi
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/gorilla/mux"
|
||||
"io/ioutil"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// A Route defines the parameters for an api endpoint
|
||||
type Route struct {
|
||||
Method string
|
||||
Pattern string
|
||||
HandlerFunc http.HandlerFunc
|
||||
}
|
||||
|
||||
// Routes is a map of defined api endpoints
|
||||
type Routes map[string]Route
|
||||
|
||||
// Router defines the required methods for retrieving api routes
|
||||
type Router interface {
|
||||
Routes() Routes
|
||||
}
|
||||
|
||||
const errMsgRequiredMissing = "required parameter is missing"
|
||||
const errMsgMinValueConstraint = "provided parameter is not respecting minimum value constraint"
|
||||
const errMsgMaxValueConstraint = "provided parameter is not respecting maximum value constraint"
|
||||
|
||||
// NewRouter creates a new router for any number of api routers
|
||||
func NewRouter(routers ...Router) *mux.Router {
|
||||
router := mux.NewRouter().StrictSlash(true)
|
||||
for _, api := range routers {
|
||||
for name, route := range api.Routes() {
|
||||
var handler http.Handler
|
||||
handler = route.HandlerFunc
|
||||
handler = Logger(handler, name)
|
||||
|
||||
router.
|
||||
Methods(route.Method).
|
||||
Path(route.Pattern).
|
||||
Name(name).
|
||||
Handler(handler)
|
||||
}
|
||||
}
|
||||
|
||||
return router
|
||||
}
|
||||
|
||||
// EncodeJSONResponse uses the json encoder to write an interface to the http response with an optional status code
|
||||
func EncodeJSONResponse(i interface{}, status *int, w http.ResponseWriter) error {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
if status != nil {
|
||||
w.WriteHeader(*status)
|
||||
} else {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
if i != nil {
|
||||
return json.NewEncoder(w).Encode(i)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReadFormFileToTempFile reads file data from a request form and writes it to a temporary file
|
||||
func ReadFormFileToTempFile(r *http.Request, key string) (*os.File, error) {
|
||||
_, fileHeader, err := r.FormFile(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return readFileHeaderToTempFile(fileHeader)
|
||||
}
|
||||
|
||||
// ReadFormFilesToTempFiles reads files array data from a request form and writes it to a temporary files
|
||||
func ReadFormFilesToTempFiles(r *http.Request, key string) ([]*os.File, error) {
|
||||
if err := r.ParseMultipartForm(32 << 20); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
files := make([]*os.File, 0, len(r.MultipartForm.File[key]))
|
||||
|
||||
for _, fileHeader := range r.MultipartForm.File[key] {
|
||||
file, err := readFileHeaderToTempFile(fileHeader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
files = append(files, file)
|
||||
}
|
||||
|
||||
return files, nil
|
||||
}
|
||||
|
||||
// readFileHeaderToTempFile reads multipart.FileHeader and writes it to a temporary file
|
||||
func readFileHeaderToTempFile(fileHeader *multipart.FileHeader) (*os.File, error) {
|
||||
formFile, err := fileHeader.Open()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer formFile.Close()
|
||||
|
||||
fileBytes, err := ioutil.ReadAll(formFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
file, err := ioutil.TempFile("", fileHeader.Filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
|
||||
file.Write(fileBytes)
|
||||
|
||||
return file, nil
|
||||
}
|
||||
|
||||
type Number interface {
|
||||
~int32 | ~int64 | ~float32 | ~float64
|
||||
}
|
||||
|
||||
type ParseString[T Number | string | bool] func(v string) (T, error)
|
||||
|
||||
// parseFloat64 parses a string parameter to an float64.
|
||||
func parseFloat64(param string) (float64, error) {
|
||||
if param == "" {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
return strconv.ParseFloat(param, 64)
|
||||
}
|
||||
|
||||
// parseFloat32 parses a string parameter to an float32.
|
||||
func parseFloat32(param string) (float32, error) {
|
||||
if param == "" {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
v, err := strconv.ParseFloat(param, 32)
|
||||
return float32(v), err
|
||||
}
|
||||
|
||||
// parseInt64 parses a string parameter to an int64.
|
||||
func parseInt64(param string) (int64, error) {
|
||||
if param == "" {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
return strconv.ParseInt(param, 10, 64)
|
||||
}
|
||||
|
||||
// parseInt32 parses a string parameter to an int32.
|
||||
func parseInt32(param string) (int32, error) {
|
||||
if param == "" {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
val, err := strconv.ParseInt(param, 10, 32)
|
||||
return int32(val), err
|
||||
}
|
||||
|
||||
// parseBool parses a string parameter to an bool.
|
||||
func parseBool(param string) (bool, error) {
|
||||
if param == "" {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return strconv.ParseBool(param)
|
||||
}
|
||||
|
||||
type Operation[T Number | string | bool] func(actual string) (T, bool, error)
|
||||
|
||||
func WithRequire[T Number | string | bool](parse ParseString[T]) Operation[T] {
|
||||
var empty T
|
||||
return func(actual string) (T, bool, error) {
|
||||
if actual == "" {
|
||||
return empty, false, errors.New(errMsgRequiredMissing)
|
||||
}
|
||||
|
||||
v, err := parse(actual)
|
||||
return v, false, err
|
||||
}
|
||||
}
|
||||
|
||||
func WithDefaultOrParse[T Number | string | bool](def T, parse ParseString[T]) Operation[T] {
|
||||
return func(actual string) (T, bool, error) {
|
||||
if actual == "" {
|
||||
return def, true, nil
|
||||
}
|
||||
|
||||
v, err := parse(actual)
|
||||
return v, false, err
|
||||
}
|
||||
}
|
||||
|
||||
func WithParse[T Number | string | bool](parse ParseString[T]) Operation[T] {
|
||||
return func(actual string) (T, bool, error) {
|
||||
v, err := parse(actual)
|
||||
return v, false, err
|
||||
}
|
||||
}
|
||||
|
||||
type Constraint[T Number | string | bool] func(actual T) error
|
||||
|
||||
func WithMinimum[T Number](expected T) Constraint[T] {
|
||||
return func(actual T) error {
|
||||
if actual < expected {
|
||||
return errors.New(errMsgMinValueConstraint)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func WithMaximum[T Number](expected T) Constraint[T] {
|
||||
return func(actual T) error {
|
||||
if actual > expected {
|
||||
return errors.New(errMsgMaxValueConstraint)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// parseNumericParameter parses a numeric parameter to its respective type.
|
||||
func parseNumericParameter[T Number](param string, fn Operation[T], checks ...Constraint[T]) (T, error) {
|
||||
v, ok, err := fn(param)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if !ok {
|
||||
for _, check := range checks {
|
||||
if err := check(v); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// parseBoolParameter parses a string parameter to a bool
|
||||
func parseBoolParameter(param string, fn Operation[bool]) (bool, error) {
|
||||
v, _, err := fn(param)
|
||||
return v, err
|
||||
}
|
||||
|
||||
// parseNumericArrayParameter parses a string parameter containing array of values to its respective type.
|
||||
func parseNumericArrayParameter[T Number](param, delim string, required bool, fn Operation[T], checks ...Constraint[T]) ([]T, error) {
|
||||
if param == "" {
|
||||
if required {
|
||||
return nil, errors.New(errMsgRequiredMissing)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
str := strings.Split(param, delim)
|
||||
values := make([]T, len(str))
|
||||
|
||||
for i, s := range str {
|
||||
v, ok, err := fn(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !ok {
|
||||
for _, check := range checks {
|
||||
if err := check(v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
values[i] = v
|
||||
}
|
||||
|
||||
return values, nil
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Solidarity Mobility API
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* API version: 1.0.0
|
||||
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
|
||||
*/
|
||||
|
||||
package Solidarity_api
|
||||
|
||||
import (
|
||||
"github.com/spf13/viper"
|
||||
"log"
|
||||
"net/http"
|
||||
"solidarity-service/handler"
|
||||
"solidarity-service/interoperability/solidarity-api/server/openapi"
|
||||
"solidarity-service/storage"
|
||||
)
|
||||
|
||||
func Run(cfg *viper.Viper, handler *handler.SolidarityServiceHandler, storage storage.Storage) {
|
||||
BookingsFilterAPIService := openapi.NewBookingsFilterAPIService(cfg, handler, storage)
|
||||
BookingsFilterAPIController := openapi.NewBookingsFilterAPIController(BookingsFilterAPIService)
|
||||
|
||||
DriverAvailabilityAndScheduleAPIService := openapi.NewDriverAvailabilityAndScheduleAPIService(cfg, handler, storage)
|
||||
DriverAvailabilityAndScheduleAPIController := openapi.NewDriverAvailabilityAndScheduleAPIController(DriverAvailabilityAndScheduleAPIService)
|
||||
|
||||
InteractAPIService := openapi.NewInteractAPIService(cfg, handler, storage)
|
||||
InteractAPIController := openapi.NewInteractAPIController(InteractAPIService)
|
||||
|
||||
PassengerTripRequestAPIService := openapi.NewPassengerTripRequestAPIService(cfg, handler, storage)
|
||||
PassengerTripRequestAPIController := openapi.NewPassengerTripRequestAPIController(PassengerTripRequestAPIService)
|
||||
|
||||
SearchAPIService := openapi.NewSearchAPIService(cfg, handler, storage)
|
||||
SearchAPIController := openapi.NewSearchAPIController(SearchAPIService)
|
||||
|
||||
router := openapi.NewRouter(BookingsFilterAPIController, DriverAvailabilityAndScheduleAPIController, InteractAPIController, PassengerTripRequestAPIController, SearchAPIController)
|
||||
|
||||
log.Fatal(http.ListenAndServe(":9999", router))
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
routing "git.coopgo.io/coopgo-platform/routing-service"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
SolidarityServiceHandler "solidarity-service/handler"
|
||||
api "solidarity-service/interoperability/solidarity-api/server"
|
||||
grpcserver "solidarity-service/servers/grpc/server"
|
||||
"solidarity-service/storage"
|
||||
)
|
||||
|
||||
func main() {
|
||||
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
|
||||
|
||||
cfg, err := ReadConfig()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var (
|
||||
service_name = cfg.GetString("name")
|
||||
grpc_enable = cfg.GetBool("services.grpc.enable")
|
||||
solidarity_api_enable = cfg.GetBool("services.solidarity-api.enable")
|
||||
routing_service_type = cfg.GetString("routing.type")
|
||||
valhalla_base_url = cfg.GetString("routing.valhalla.base_url")
|
||||
)
|
||||
|
||||
log.Info().Msg("Running " + service_name)
|
||||
storageService, err := storage.NewStorage(cfg)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("Could not initiate the storage service")
|
||||
return
|
||||
}
|
||||
routing, err := routing.NewRoutingService(routing_service_type, valhalla_base_url)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("Could not initiate the routing service")
|
||||
return
|
||||
}
|
||||
handler, err := SolidarityServiceHandler.NewSolidarityServiceHandler(cfg, routing, storageService)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("Could not initiate the solidarity service handler")
|
||||
return
|
||||
}
|
||||
|
||||
failed := make(chan error)
|
||||
if grpc_enable {
|
||||
log.Info().Msg("Running gRPC server")
|
||||
go grpcserver.Run(failed, cfg, handler)
|
||||
}
|
||||
|
||||
if solidarity_api_enable {
|
||||
log.Info().Msg("Running OCSS REST API")
|
||||
go api.Run(cfg, handler, storageService)
|
||||
}
|
||||
|
||||
err = <-failed
|
||||
|
||||
log.Fatal().Err(err).Msg("Terminating")
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,133 @@
|
|||
syntax = "proto3";
|
||||
option go_package = "git.coopgo.io/coopgo-platform/solidarity-service/servers/grpc/proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
|
||||
|
||||
|
||||
message Feature {
|
||||
double lat = 1;
|
||||
double long = 2;
|
||||
string address = 3;
|
||||
}
|
||||
|
||||
message DriverJourney {
|
||||
User user = 1;
|
||||
optional Car car = 2;
|
||||
google.protobuf.Timestamp driver_departure_Date = 3;
|
||||
optional Price price = 4;
|
||||
string driver_departure_Address = 5;
|
||||
oneof availabilities {
|
||||
RepeatedPunctualAvailabilitySlot repeated_punctual_availabilities = 6;
|
||||
RepeatedRegularAvailabilitySlot repeated_regular_availabilities = 7;
|
||||
}
|
||||
}
|
||||
message RepeatedPunctualAvailabilitySlot {
|
||||
repeated PunctualAvailabilitySlot punctual_availabilities = 1;
|
||||
}
|
||||
|
||||
message RepeatedRegularAvailabilitySlot {
|
||||
repeated RegularAvailabilitySlot regular_availabilities = 1;
|
||||
}
|
||||
|
||||
message DriverRequest{
|
||||
Feature driver_address = 1;
|
||||
int32 driver_radius = 2;
|
||||
User driver = 3;
|
||||
optional Preferences preferences = 4;
|
||||
optional Car car = 5;
|
||||
}
|
||||
|
||||
message PunctualAvailabilitySlot {
|
||||
google.protobuf.Timestamp date = 1;
|
||||
string startTime = 2;
|
||||
string endTime = 3;
|
||||
}
|
||||
message RegularAvailabilitySlot {
|
||||
DayOfWeek dayOfWeek = 1;
|
||||
string startTime = 2;
|
||||
string endTime = 3;
|
||||
}
|
||||
|
||||
enum DayOfWeek {
|
||||
MON = 0;
|
||||
TUE = 1;
|
||||
WED = 3;
|
||||
THU = 4;
|
||||
FRI = 5;
|
||||
SAT = 6;
|
||||
SUN = 7;
|
||||
}
|
||||
|
||||
message BookingRequest {
|
||||
string id = 1;
|
||||
string passengerId = 2;
|
||||
string driverId = 3;
|
||||
BookingStatus status = 4;
|
||||
}
|
||||
|
||||
message Booking {
|
||||
string id = 1;
|
||||
User driver = 2;
|
||||
User passenger = 3;
|
||||
google.protobuf.Timestamp passengerPickupDate =4;
|
||||
Feature passenger_departure_route = 5;
|
||||
Feature passenger_destination_route = 6;
|
||||
BookingStatus status = 7;
|
||||
optional int64 duration = 8;
|
||||
optional int64 distance = 9;
|
||||
Price price = 10;
|
||||
optional Car car = 11;
|
||||
}
|
||||
|
||||
|
||||
message Car {
|
||||
optional string model = 1;
|
||||
optional string brand = 2;
|
||||
}
|
||||
|
||||
message Preferences {
|
||||
optional bool smoking = 1;
|
||||
optional bool animals = 2;
|
||||
optional bool music = 3;
|
||||
optional bool is_talker = 4;
|
||||
optional int64 luggage_size = 5;
|
||||
}
|
||||
|
||||
|
||||
enum PriceType {
|
||||
FREE = 0;
|
||||
PAYING = 1;
|
||||
UNKNOWN = 2;
|
||||
}
|
||||
|
||||
message Price {
|
||||
optional PriceType type = 1;
|
||||
optional double amount = 2;
|
||||
optional string currency = 3;
|
||||
}
|
||||
|
||||
message User {
|
||||
string id = 1;
|
||||
string alias = 2;
|
||||
optional string first_name = 3;
|
||||
optional string last_name = 4;
|
||||
optional int64 grade = 5;
|
||||
optional string picture = 6;
|
||||
optional string gender = 7;
|
||||
optional bool verified_identity = 8;
|
||||
}
|
||||
|
||||
enum BookingStatus {
|
||||
INITIATED = 0;
|
||||
WAITING_DRIVER_CONFIRMATION = 1;
|
||||
WAITING_PASSENGER_CONFIRMATION = 2;
|
||||
CONFIRMED = 3;
|
||||
CANCELLED = 4;
|
||||
COMPLETED_PENDING_VALIDATION = 5;
|
||||
VALIDATED = 6;
|
||||
}
|
||||
|
||||
enum UserType{
|
||||
driver = 0;
|
||||
passenger = 1;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,91 @@
|
|||
syntax = "proto3";
|
||||
option go_package = "git.coopgo.io/coopgo-platform/solidarity-service/servers/grpc/proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "solidarity-api-types.proto";
|
||||
|
||||
service SolidarityService {
|
||||
rpc SetDriverRegularAvailabilities(DriverRegularAvailabilities) returns (DriverAvailabilitiesResponse) {}
|
||||
rpc SetDriverPunctualAvailabilities(DriverPunctualAvailabilities) returns (DriverAvailabilitiesResponse) {}
|
||||
rpc CreateBooking(CreateBookingRequest) returns (CreateBookingResponse) {}
|
||||
rpc UpdateBooking(UpdateBookingRequest) returns (UpdateBookingResponse) {}
|
||||
rpc GetBooking(GetBookingRequest) returns (GetBookingResponse) {}
|
||||
rpc GetBookingsByStatus(GetBookingsByStatusRequest) returns (GetBookingsByStatusResponse) {}
|
||||
rpc DriverJourneys(DriverJourneysRequest) returns (DriverJourneysResponse) {}
|
||||
rpc SetPassengerTrip(PassengerTripRequest) returns (PassengerTripResponse) {}
|
||||
}
|
||||
|
||||
|
||||
message PassengerTripRequest{
|
||||
Feature passenger_departure_address = 1;
|
||||
Feature passenger_destination_address = 2;
|
||||
google.protobuf.Timestamp passenger_pickup_date = 3;
|
||||
User passenger = 4;
|
||||
optional Preferences preferences = 5;
|
||||
}
|
||||
|
||||
message DriverRegularAvailabilities{
|
||||
|
||||
DriverRequest driver_request = 1;
|
||||
repeated RegularAvailabilitySlot driver_availabilities = 2;
|
||||
}
|
||||
|
||||
message DriverPunctualAvailabilities{
|
||||
DriverRequest driver_request = 1;
|
||||
repeated PunctualAvailabilitySlot driver_availabilities = 2;
|
||||
}
|
||||
|
||||
message PassengerTripResponse {
|
||||
bool success = 1;
|
||||
optional string message = 2;
|
||||
}
|
||||
|
||||
message DriverAvailabilitiesResponse {
|
||||
bool success = 1;
|
||||
optional string message = 2;
|
||||
}
|
||||
|
||||
message CreateBookingRequest {
|
||||
BookingRequest booking = 1;
|
||||
}
|
||||
message CreateBookingResponse {
|
||||
Booking booking = 1;
|
||||
}
|
||||
|
||||
message UpdateBookingRequest {
|
||||
string booking_id = 1;
|
||||
BookingStatus status = 2;
|
||||
optional string message = 3;
|
||||
}
|
||||
|
||||
message UpdateBookingResponse {
|
||||
bool success = 1;
|
||||
optional string message = 2;
|
||||
}
|
||||
|
||||
message GetBookingRequest {
|
||||
string booking_id = 1;
|
||||
}
|
||||
|
||||
|
||||
message GetBookingResponse {
|
||||
Booking booking = 1;
|
||||
}
|
||||
|
||||
message GetBookingsByStatusRequest{
|
||||
BookingStatus status = 1;
|
||||
UserType type = 2;
|
||||
string user_id = 3;
|
||||
}
|
||||
|
||||
message DriverJourneysRequest {
|
||||
Feature departure = 1;
|
||||
google.protobuf.Timestamp departure_date = 2;
|
||||
}
|
||||
|
||||
message DriverJourneysResponse {
|
||||
repeated DriverJourney driver_journeys = 1;
|
||||
}
|
||||
|
||||
message GetBookingsByStatusResponse{
|
||||
repeated Booking booking = 1;
|
||||
}
|
|
@ -0,0 +1,368 @@
|
|||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.3.0
|
||||
// - protoc v3.12.4
|
||||
// source: solidarity-api.proto
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.32.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion7
|
||||
|
||||
const (
|
||||
SolidarityService_SetDriverRegularAvailabilities_FullMethodName = "/SolidarityService/SetDriverRegularAvailabilities"
|
||||
SolidarityService_SetDriverPunctualAvailabilities_FullMethodName = "/SolidarityService/SetDriverPunctualAvailabilities"
|
||||
SolidarityService_CreateBooking_FullMethodName = "/SolidarityService/CreateBooking"
|
||||
SolidarityService_UpdateBooking_FullMethodName = "/SolidarityService/UpdateBooking"
|
||||
SolidarityService_GetBooking_FullMethodName = "/SolidarityService/GetBooking"
|
||||
SolidarityService_GetBookingsByStatus_FullMethodName = "/SolidarityService/GetBookingsByStatus"
|
||||
SolidarityService_DriverJourneys_FullMethodName = "/SolidarityService/DriverJourneys"
|
||||
SolidarityService_SetPassengerTrip_FullMethodName = "/SolidarityService/SetPassengerTrip"
|
||||
)
|
||||
|
||||
// SolidarityServiceClient is the client API for SolidarityService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type SolidarityServiceClient interface {
|
||||
SetDriverRegularAvailabilities(ctx context.Context, in *DriverRegularAvailabilities, opts ...grpc.CallOption) (*DriverAvailabilitiesResponse, error)
|
||||
SetDriverPunctualAvailabilities(ctx context.Context, in *DriverPunctualAvailabilities, opts ...grpc.CallOption) (*DriverAvailabilitiesResponse, error)
|
||||
CreateBooking(ctx context.Context, in *CreateBookingRequest, opts ...grpc.CallOption) (*CreateBookingResponse, error)
|
||||
UpdateBooking(ctx context.Context, in *UpdateBookingRequest, opts ...grpc.CallOption) (*UpdateBookingResponse, error)
|
||||
GetBooking(ctx context.Context, in *GetBookingRequest, opts ...grpc.CallOption) (*GetBookingResponse, error)
|
||||
GetBookingsByStatus(ctx context.Context, in *GetBookingsByStatusRequest, opts ...grpc.CallOption) (*GetBookingsByStatusResponse, error)
|
||||
DriverJourneys(ctx context.Context, in *DriverJourneysRequest, opts ...grpc.CallOption) (*DriverJourneysResponse, error)
|
||||
SetPassengerTrip(ctx context.Context, in *PassengerTripRequest, opts ...grpc.CallOption) (*PassengerTripResponse, error)
|
||||
}
|
||||
|
||||
type solidarityServiceClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewSolidarityServiceClient(cc grpc.ClientConnInterface) SolidarityServiceClient {
|
||||
return &solidarityServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *solidarityServiceClient) SetDriverRegularAvailabilities(ctx context.Context, in *DriverRegularAvailabilities, opts ...grpc.CallOption) (*DriverAvailabilitiesResponse, error) {
|
||||
out := new(DriverAvailabilitiesResponse)
|
||||
err := c.cc.Invoke(ctx, SolidarityService_SetDriverRegularAvailabilities_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *solidarityServiceClient) SetDriverPunctualAvailabilities(ctx context.Context, in *DriverPunctualAvailabilities, opts ...grpc.CallOption) (*DriverAvailabilitiesResponse, error) {
|
||||
out := new(DriverAvailabilitiesResponse)
|
||||
err := c.cc.Invoke(ctx, SolidarityService_SetDriverPunctualAvailabilities_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *solidarityServiceClient) CreateBooking(ctx context.Context, in *CreateBookingRequest, opts ...grpc.CallOption) (*CreateBookingResponse, error) {
|
||||
out := new(CreateBookingResponse)
|
||||
err := c.cc.Invoke(ctx, SolidarityService_CreateBooking_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *solidarityServiceClient) UpdateBooking(ctx context.Context, in *UpdateBookingRequest, opts ...grpc.CallOption) (*UpdateBookingResponse, error) {
|
||||
out := new(UpdateBookingResponse)
|
||||
err := c.cc.Invoke(ctx, SolidarityService_UpdateBooking_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *solidarityServiceClient) GetBooking(ctx context.Context, in *GetBookingRequest, opts ...grpc.CallOption) (*GetBookingResponse, error) {
|
||||
out := new(GetBookingResponse)
|
||||
err := c.cc.Invoke(ctx, SolidarityService_GetBooking_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *solidarityServiceClient) GetBookingsByStatus(ctx context.Context, in *GetBookingsByStatusRequest, opts ...grpc.CallOption) (*GetBookingsByStatusResponse, error) {
|
||||
out := new(GetBookingsByStatusResponse)
|
||||
err := c.cc.Invoke(ctx, SolidarityService_GetBookingsByStatus_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *solidarityServiceClient) DriverJourneys(ctx context.Context, in *DriverJourneysRequest, opts ...grpc.CallOption) (*DriverJourneysResponse, error) {
|
||||
out := new(DriverJourneysResponse)
|
||||
err := c.cc.Invoke(ctx, SolidarityService_DriverJourneys_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *solidarityServiceClient) SetPassengerTrip(ctx context.Context, in *PassengerTripRequest, opts ...grpc.CallOption) (*PassengerTripResponse, error) {
|
||||
out := new(PassengerTripResponse)
|
||||
err := c.cc.Invoke(ctx, SolidarityService_SetPassengerTrip_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// SolidarityServiceServer is the server API for SolidarityService service.
|
||||
// All implementations must embed UnimplementedSolidarityServiceServer
|
||||
// for forward compatibility
|
||||
type SolidarityServiceServer interface {
|
||||
SetDriverRegularAvailabilities(context.Context, *DriverRegularAvailabilities) (*DriverAvailabilitiesResponse, error)
|
||||
SetDriverPunctualAvailabilities(context.Context, *DriverPunctualAvailabilities) (*DriverAvailabilitiesResponse, error)
|
||||
CreateBooking(context.Context, *CreateBookingRequest) (*CreateBookingResponse, error)
|
||||
UpdateBooking(context.Context, *UpdateBookingRequest) (*UpdateBookingResponse, error)
|
||||
GetBooking(context.Context, *GetBookingRequest) (*GetBookingResponse, error)
|
||||
GetBookingsByStatus(context.Context, *GetBookingsByStatusRequest) (*GetBookingsByStatusResponse, error)
|
||||
DriverJourneys(context.Context, *DriverJourneysRequest) (*DriverJourneysResponse, error)
|
||||
SetPassengerTrip(context.Context, *PassengerTripRequest) (*PassengerTripResponse, error)
|
||||
mustEmbedUnimplementedSolidarityServiceServer()
|
||||
}
|
||||
|
||||
// UnimplementedSolidarityServiceServer must be embedded to have forward compatible implementations.
|
||||
type UnimplementedSolidarityServiceServer struct {
|
||||
}
|
||||
|
||||
func (UnimplementedSolidarityServiceServer) SetDriverRegularAvailabilities(context.Context, *DriverRegularAvailabilities) (*DriverAvailabilitiesResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method SetDriverRegularAvailabilities not implemented")
|
||||
}
|
||||
func (UnimplementedSolidarityServiceServer) SetDriverPunctualAvailabilities(context.Context, *DriverPunctualAvailabilities) (*DriverAvailabilitiesResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method SetDriverPunctualAvailabilities not implemented")
|
||||
}
|
||||
func (UnimplementedSolidarityServiceServer) CreateBooking(context.Context, *CreateBookingRequest) (*CreateBookingResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CreateBooking not implemented")
|
||||
}
|
||||
func (UnimplementedSolidarityServiceServer) UpdateBooking(context.Context, *UpdateBookingRequest) (*UpdateBookingResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method UpdateBooking not implemented")
|
||||
}
|
||||
func (UnimplementedSolidarityServiceServer) GetBooking(context.Context, *GetBookingRequest) (*GetBookingResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetBooking not implemented")
|
||||
}
|
||||
func (UnimplementedSolidarityServiceServer) GetBookingsByStatus(context.Context, *GetBookingsByStatusRequest) (*GetBookingsByStatusResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetBookingsByStatus not implemented")
|
||||
}
|
||||
func (UnimplementedSolidarityServiceServer) DriverJourneys(context.Context, *DriverJourneysRequest) (*DriverJourneysResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method DriverJourneys not implemented")
|
||||
}
|
||||
func (UnimplementedSolidarityServiceServer) SetPassengerTrip(context.Context, *PassengerTripRequest) (*PassengerTripResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method SetPassengerTrip not implemented")
|
||||
}
|
||||
func (UnimplementedSolidarityServiceServer) mustEmbedUnimplementedSolidarityServiceServer() {}
|
||||
|
||||
// UnsafeSolidarityServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to SolidarityServiceServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeSolidarityServiceServer interface {
|
||||
mustEmbedUnimplementedSolidarityServiceServer()
|
||||
}
|
||||
|
||||
func RegisterSolidarityServiceServer(s grpc.ServiceRegistrar, srv SolidarityServiceServer) {
|
||||
s.RegisterService(&SolidarityService_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _SolidarityService_SetDriverRegularAvailabilities_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(DriverRegularAvailabilities)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SolidarityServiceServer).SetDriverRegularAvailabilities(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SolidarityService_SetDriverRegularAvailabilities_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SolidarityServiceServer).SetDriverRegularAvailabilities(ctx, req.(*DriverRegularAvailabilities))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SolidarityService_SetDriverPunctualAvailabilities_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(DriverPunctualAvailabilities)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SolidarityServiceServer).SetDriverPunctualAvailabilities(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SolidarityService_SetDriverPunctualAvailabilities_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SolidarityServiceServer).SetDriverPunctualAvailabilities(ctx, req.(*DriverPunctualAvailabilities))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SolidarityService_CreateBooking_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(CreateBookingRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SolidarityServiceServer).CreateBooking(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SolidarityService_CreateBooking_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SolidarityServiceServer).CreateBooking(ctx, req.(*CreateBookingRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SolidarityService_UpdateBooking_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(UpdateBookingRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SolidarityServiceServer).UpdateBooking(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SolidarityService_UpdateBooking_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SolidarityServiceServer).UpdateBooking(ctx, req.(*UpdateBookingRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SolidarityService_GetBooking_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetBookingRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SolidarityServiceServer).GetBooking(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SolidarityService_GetBooking_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SolidarityServiceServer).GetBooking(ctx, req.(*GetBookingRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SolidarityService_GetBookingsByStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetBookingsByStatusRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SolidarityServiceServer).GetBookingsByStatus(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SolidarityService_GetBookingsByStatus_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SolidarityServiceServer).GetBookingsByStatus(ctx, req.(*GetBookingsByStatusRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SolidarityService_DriverJourneys_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(DriverJourneysRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SolidarityServiceServer).DriverJourneys(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SolidarityService_DriverJourneys_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SolidarityServiceServer).DriverJourneys(ctx, req.(*DriverJourneysRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _SolidarityService_SetPassengerTrip_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(PassengerTripRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(SolidarityServiceServer).SetPassengerTrip(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: SolidarityService_SetPassengerTrip_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(SolidarityServiceServer).SetPassengerTrip(ctx, req.(*PassengerTripRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// SolidarityService_ServiceDesc is the grpc.ServiceDesc for SolidarityService service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var SolidarityService_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "SolidarityService",
|
||||
HandlerType: (*SolidarityServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "SetDriverRegularAvailabilities",
|
||||
Handler: _SolidarityService_SetDriverRegularAvailabilities_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "SetDriverPunctualAvailabilities",
|
||||
Handler: _SolidarityService_SetDriverPunctualAvailabilities_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "CreateBooking",
|
||||
Handler: _SolidarityService_CreateBooking_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "UpdateBooking",
|
||||
Handler: _SolidarityService_UpdateBooking_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetBooking",
|
||||
Handler: _SolidarityService_GetBooking_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetBookingsByStatus",
|
||||
Handler: _SolidarityService_GetBookingsByStatus_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "DriverJourneys",
|
||||
Handler: _SolidarityService_DriverJourneys_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "SetPassengerTrip",
|
||||
Handler: _SolidarityService_SetPassengerTrip_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "solidarity-api.proto",
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package grpcserver
|
||||
|
||||
import (
|
||||
"solidarity-service/internal"
|
||||
"solidarity-service/servers/grpc/proto"
|
||||
)
|
||||
|
||||
func ConvertInternalToProtoBookingStatus(internalStatus internal.BookingStatus) proto.BookingStatus {
|
||||
switch internalStatus {
|
||||
case internal.BookingStatusINITIATED:
|
||||
return proto.BookingStatus_INITIATED
|
||||
case internal.BookingStatusWAITINGPASSENGERCONFIRMATION:
|
||||
return proto.BookingStatus_WAITING_PASSENGER_CONFIRMATION
|
||||
case internal.BookingStatusWAITINGDRIVERCONFIRMATION:
|
||||
return proto.BookingStatus_WAITING_DRIVER_CONFIRMATION
|
||||
case internal.BookingStatusCONFIRMED:
|
||||
return proto.BookingStatus_CONFIRMED
|
||||
case internal.BookingStatusCANCELLED:
|
||||
return proto.BookingStatus_CANCELLED
|
||||
case internal.BookingStatusCOMPLETEDPENDINGVALIDATION:
|
||||
return proto.BookingStatus_COMPLETED_PENDING_VALIDATION
|
||||
case internal.BookingStatusVALIDATED:
|
||||
return proto.BookingStatus_VALIDATED
|
||||
default:
|
||||
return proto.BookingStatus_CONFIRMED
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package grpcserver
|
||||
|
||||
import (
|
||||
"solidarity-service/servers/grpc/proto"
|
||||
)
|
||||
|
||||
func ConvertToProtoDayOfTheWeek(day string) proto.DayOfWeek {
|
||||
switch day {
|
||||
case "MON":
|
||||
return proto.DayOfWeek_MON
|
||||
case "TUE":
|
||||
return proto.DayOfWeek_TUE
|
||||
case "WED":
|
||||
return proto.DayOfWeek_WED
|
||||
case "THU":
|
||||
return proto.DayOfWeek_THU
|
||||
case "FRI":
|
||||
return proto.DayOfWeek_FRI
|
||||
case "SAT":
|
||||
return proto.DayOfWeek_FRI
|
||||
case "SUN":
|
||||
return proto.DayOfWeek_SAT
|
||||
default:
|
||||
return proto.DayOfWeek_MON
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package grpcserver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/viper"
|
||||
"google.golang.org/grpc"
|
||||
"net"
|
||||
"solidarity-service/handler"
|
||||
"solidarity-service/servers/grpc/proto"
|
||||
)
|
||||
|
||||
type SolidarityServiceServerImpl struct {
|
||||
Handler *handler.SolidarityServiceHandler
|
||||
proto.UnimplementedSolidarityServiceServer
|
||||
}
|
||||
|
||||
func NewSolidarityServiceServer(handler *handler.SolidarityServiceHandler) *SolidarityServiceServerImpl {
|
||||
return &SolidarityServiceServerImpl{
|
||||
Handler: handler,
|
||||
}
|
||||
}
|
||||
|
||||
func Run(done chan error, cfg *viper.Viper, handler *handler.SolidarityServiceHandler) {
|
||||
var (
|
||||
address = ":" + cfg.GetString("services.grpc.port")
|
||||
)
|
||||
|
||||
server := grpc.NewServer()
|
||||
proto.RegisterSolidarityServiceServer(server, NewSolidarityServiceServer(handler))
|
||||
l, err := net.Listen("tcp", address)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err)
|
||||
return
|
||||
}
|
||||
if err := server.Serve(l); err != nil {
|
||||
fmt.Println("gRPC service ended")
|
||||
done <- err
|
||||
}
|
||||
}
|
|
@ -0,0 +1,543 @@
|
|||
package grpcserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/golang/protobuf/ptypes/timestamp"
|
||||
"github.com/paulmach/orb"
|
||||
"github.com/paulmach/orb/geojson"
|
||||
"solidarity-service/internal"
|
||||
"solidarity-service/servers/grpc/proto"
|
||||
)
|
||||
|
||||
func (s *SolidarityServiceServerImpl) SetDriverRegularAvailabilities(ctx context.Context, req *proto.DriverRegularAvailabilities) (resp *proto.DriverAvailabilitiesResponse, err error) {
|
||||
if req.DriverRequest.Driver.Id == "" || req.DriverRequest.Driver.Alias == "" || req.DriverAvailabilities == nil || req.DriverRequest.DriverAddress == nil || req.DriverRequest.DriverRadius == 0 {
|
||||
return &proto.DriverAvailabilitiesResponse{
|
||||
Success: false,
|
||||
}, errors.New("missing required fields")
|
||||
}
|
||||
driver := internal.Driver{
|
||||
Driver_departure_address: &geojson.Feature{
|
||||
Type: "Feature",
|
||||
Geometry: orb.Geometry(orb.Point{req.DriverRequest.DriverAddress.Lat, req.DriverRequest.DriverAddress.Long}),
|
||||
Properties: geojson.Properties{
|
||||
"name": req.DriverRequest.DriverAddress.Address,
|
||||
},
|
||||
},
|
||||
Radius: req.DriverRequest.DriverRadius,
|
||||
Driver: internal.User{
|
||||
ID: req.DriverRequest.Driver.Id,
|
||||
Alias: req.DriverRequest.Driver.Alias,
|
||||
},
|
||||
AvailabilitiesType: internal.Regular,
|
||||
}
|
||||
|
||||
if req.DriverRequest.Driver.FirstName != nil {
|
||||
driver.Driver.FirstName = *req.DriverRequest.Driver.FirstName
|
||||
}
|
||||
if req.DriverRequest.Driver.LastName != nil {
|
||||
driver.Driver.LastName = *req.DriverRequest.Driver.LastName
|
||||
}
|
||||
if req.DriverRequest.Driver.Grade != nil {
|
||||
driver.Driver.Grade = *req.DriverRequest.Driver.Grade
|
||||
}
|
||||
if req.DriverRequest.Driver.Picture != nil {
|
||||
driver.Driver.Picture = *req.DriverRequest.Driver.Picture
|
||||
}
|
||||
if req.DriverRequest.Driver.Gender != nil {
|
||||
driver.Driver.Gender = *req.DriverRequest.Driver.Gender
|
||||
}
|
||||
if req.DriverRequest.Driver.VerifiedIdentity != nil {
|
||||
driver.Driver.VerifiedIdentity = *req.DriverRequest.Driver.VerifiedIdentity
|
||||
}
|
||||
|
||||
if req.DriverRequest.Car != nil {
|
||||
driver.Car = internal.Car{
|
||||
Model: *req.DriverRequest.Car.Model,
|
||||
Brand: *req.DriverRequest.Car.Brand,
|
||||
}
|
||||
}
|
||||
if req.DriverRequest.Preferences != nil {
|
||||
driver.Preferences = internal.Preferences{
|
||||
Smoking: *req.DriverRequest.Preferences.Smoking,
|
||||
Animals: *req.DriverRequest.Preferences.Animals,
|
||||
Music: *req.DriverRequest.Preferences.Music,
|
||||
Is_talker: *req.DriverRequest.Preferences.IsTalker,
|
||||
Luggage_size: *req.DriverRequest.Preferences.LuggageSize,
|
||||
}
|
||||
}
|
||||
for _, v := range req.DriverAvailabilities {
|
||||
driver.RegularAvailabilities = append(driver.RegularAvailabilities, internal.RegularAvailabilities{
|
||||
DayOfWeek: v.DayOfWeek.String(),
|
||||
StartTime: v.StartTime,
|
||||
EndTime: v.EndTime,
|
||||
})
|
||||
}
|
||||
|
||||
err = s.Handler.SetDriverAvailabilities(context.Background(), driver)
|
||||
if err != nil {
|
||||
return &proto.DriverAvailabilitiesResponse{
|
||||
Success: false,
|
||||
}, err
|
||||
}
|
||||
return &proto.DriverAvailabilitiesResponse{
|
||||
Success: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *SolidarityServiceServerImpl) SetDriverPunctualAvailabilities(ctx context.Context, req *proto.DriverPunctualAvailabilities) (resp *proto.DriverAvailabilitiesResponse, err error) {
|
||||
if req.DriverRequest.Driver.Id == "" || req.DriverRequest.Driver.Alias == "" || req.DriverAvailabilities == nil || req.DriverRequest.DriverAddress == nil || req.DriverRequest.DriverRadius == 0 {
|
||||
return &proto.DriverAvailabilitiesResponse{
|
||||
Success: false,
|
||||
}, errors.New("missing required fields")
|
||||
}
|
||||
driver := internal.Driver{
|
||||
Driver_departure_address: &geojson.Feature{
|
||||
Type: "Feature",
|
||||
Geometry: orb.Geometry(orb.Point{req.DriverRequest.DriverAddress.Lat, req.DriverRequest.DriverAddress.Long}),
|
||||
Properties: geojson.Properties{
|
||||
"name": req.DriverRequest.DriverAddress.Address,
|
||||
},
|
||||
},
|
||||
Radius: req.DriverRequest.DriverRadius,
|
||||
Driver: internal.User{
|
||||
ID: req.DriverRequest.Driver.Id,
|
||||
Alias: req.DriverRequest.Driver.Alias,
|
||||
},
|
||||
AvailabilitiesType: internal.Punctual,
|
||||
}
|
||||
|
||||
if req.DriverRequest.Driver.FirstName != nil {
|
||||
driver.Driver.FirstName = *req.DriverRequest.Driver.FirstName
|
||||
}
|
||||
if req.DriverRequest.Driver.LastName != nil {
|
||||
driver.Driver.LastName = *req.DriverRequest.Driver.LastName
|
||||
}
|
||||
if req.DriverRequest.Driver.Grade != nil {
|
||||
driver.Driver.Grade = *req.DriverRequest.Driver.Grade
|
||||
}
|
||||
if req.DriverRequest.Driver.Picture != nil {
|
||||
driver.Driver.Picture = *req.DriverRequest.Driver.Picture
|
||||
}
|
||||
if req.DriverRequest.Driver.Gender != nil {
|
||||
driver.Driver.Gender = *req.DriverRequest.Driver.Gender
|
||||
}
|
||||
if req.DriverRequest.Driver.VerifiedIdentity != nil {
|
||||
driver.Driver.VerifiedIdentity = *req.DriverRequest.Driver.VerifiedIdentity
|
||||
}
|
||||
|
||||
if req.DriverRequest.Car != nil {
|
||||
driver.Car = internal.Car{
|
||||
Model: *req.DriverRequest.Car.Model,
|
||||
Brand: *req.DriverRequest.Car.Brand,
|
||||
}
|
||||
}
|
||||
if req.DriverRequest.Preferences != nil {
|
||||
driver.Preferences = internal.Preferences{
|
||||
Smoking: *req.DriverRequest.Preferences.Smoking,
|
||||
Animals: *req.DriverRequest.Preferences.Animals,
|
||||
Music: *req.DriverRequest.Preferences.Music,
|
||||
Is_talker: *req.DriverRequest.Preferences.IsTalker,
|
||||
Luggage_size: *req.DriverRequest.Preferences.LuggageSize,
|
||||
}
|
||||
}
|
||||
for _, v := range req.DriverAvailabilities {
|
||||
driver.PunctualAvailabilities = append(driver.PunctualAvailabilities, internal.PunctualAvailabilities{
|
||||
Date: v.Date.Seconds,
|
||||
StartTime: v.StartTime,
|
||||
EndTime: v.EndTime,
|
||||
})
|
||||
}
|
||||
|
||||
err = s.Handler.SetDriverAvailabilities(context.Background(), driver)
|
||||
if err != nil {
|
||||
return &proto.DriverAvailabilitiesResponse{
|
||||
Success: false,
|
||||
}, err
|
||||
}
|
||||
return &proto.DriverAvailabilitiesResponse{
|
||||
Success: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *SolidarityServiceServerImpl) CreateBooking(ctx context.Context, req *proto.CreateBookingRequest) (resp *proto.CreateBookingResponse, err error) {
|
||||
if req.Booking.DriverId == "" || req.Booking.PassengerId == "" || req.Booking.Id == "" || req.Booking.Status.String() == "" {
|
||||
return nil, errors.New("missing required fields")
|
||||
}
|
||||
bookingRequest := internal.BookingRequest{
|
||||
ID: req.Booking.Id,
|
||||
Passenger_id: req.Booking.PassengerId,
|
||||
Driver_id: req.Booking.DriverId,
|
||||
Status: internal.BookingStatus(req.Booking.Status),
|
||||
}
|
||||
passenger, driver, err := s.Handler.CreateBooking(context.Background(), bookingRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
duration, err := s.Handler.CalculateDurationBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address)
|
||||
if err != nil {
|
||||
duration = 0
|
||||
}
|
||||
distance := s.Handler.CalculateDistanceBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address)
|
||||
priceType := proto.PriceType_FREE
|
||||
resp.Booking = &proto.Booking{
|
||||
Id: bookingRequest.ID,
|
||||
Driver: &proto.User{
|
||||
Id: driver.Driver.ID,
|
||||
Alias: driver.Driver.Alias,
|
||||
FirstName: &driver.Driver.FirstName,
|
||||
LastName: &driver.Driver.LastName,
|
||||
Grade: &driver.Driver.Grade,
|
||||
Picture: &driver.Driver.Picture,
|
||||
Gender: &driver.Driver.Gender,
|
||||
VerifiedIdentity: &driver.Driver.VerifiedIdentity,
|
||||
},
|
||||
Passenger: &proto.User{
|
||||
Id: passenger.Passenger.ID,
|
||||
Alias: passenger.Passenger.Alias,
|
||||
FirstName: &passenger.Passenger.FirstName,
|
||||
LastName: &passenger.Passenger.LastName,
|
||||
Grade: &passenger.Passenger.Grade,
|
||||
Picture: &passenger.Passenger.Picture,
|
||||
Gender: &passenger.Passenger.Gender,
|
||||
VerifiedIdentity: &passenger.Passenger.VerifiedIdentity,
|
||||
},
|
||||
PassengerPickupDate: ×tamp.Timestamp{
|
||||
Seconds: passenger.Passenger_pickup_date,
|
||||
},
|
||||
PassengerDepartureRoute: &proto.Feature{
|
||||
Lat: passenger.Passenger_departure_address.Point().Lat(),
|
||||
Long: passenger.Passenger_departure_address.Point().Lon(),
|
||||
Address: passenger.Passenger_departure_address.Properties.MustString("name"),
|
||||
},
|
||||
PassengerDestinationRoute: &proto.Feature{
|
||||
Lat: passenger.Passenger_destination_address.Point().Lat(),
|
||||
Long: passenger.Passenger_destination_address.Point().Lon(),
|
||||
Address: passenger.Passenger_destination_address.Properties.MustString("name"),
|
||||
},
|
||||
Status: ConvertInternalToProtoBookingStatus(bookingRequest.Status),
|
||||
Duration: &duration,
|
||||
Distance: &distance,
|
||||
Price: &proto.Price{
|
||||
Type: &priceType,
|
||||
},
|
||||
Car: &proto.Car{
|
||||
Model: &driver.Car.Model,
|
||||
Brand: &driver.Car.Brand,
|
||||
},
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (s *SolidarityServiceServerImpl) UpdateBooking(ctx context.Context, req *proto.UpdateBookingRequest) (resp *proto.UpdateBookingResponse, err error) {
|
||||
if req.BookingId == "" || req.Status.String() == "" {
|
||||
return &proto.UpdateBookingResponse{
|
||||
Success: false,
|
||||
}, errors.New("missing required fields")
|
||||
}
|
||||
bookingStatus := internal.BookingStatus(req.Status.String())
|
||||
err = s.Handler.UpdateBooking(context.Background(), req.BookingId, bookingStatus)
|
||||
if err != nil {
|
||||
return &proto.UpdateBookingResponse{
|
||||
Success: false,
|
||||
}, err
|
||||
}
|
||||
return &proto.UpdateBookingResponse{
|
||||
Success: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *SolidarityServiceServerImpl) GetBooking(ctx context.Context, req *proto.GetBookingRequest) (resp *proto.GetBookingResponse, err error) {
|
||||
if req.BookingId == "" {
|
||||
return nil, errors.New("empty booking ID")
|
||||
}
|
||||
booking, passenger, driver, err := s.Handler.GetBooking(context.Background(), req.BookingId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
duration, err := s.Handler.CalculateDurationBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address)
|
||||
if err != nil {
|
||||
duration = 0
|
||||
}
|
||||
distance := s.Handler.CalculateDistanceBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address)
|
||||
priceType := proto.PriceType_FREE
|
||||
resp.Booking = &proto.Booking{
|
||||
Id: booking.ID,
|
||||
Driver: &proto.User{
|
||||
Id: driver.Driver.ID,
|
||||
Alias: driver.Driver.Alias,
|
||||
FirstName: &driver.Driver.FirstName,
|
||||
LastName: &driver.Driver.LastName,
|
||||
Grade: &driver.Driver.Grade,
|
||||
Picture: &driver.Driver.Picture,
|
||||
Gender: &driver.Driver.Gender,
|
||||
VerifiedIdentity: &driver.Driver.VerifiedIdentity,
|
||||
},
|
||||
Passenger: &proto.User{
|
||||
Id: passenger.Passenger.ID,
|
||||
Alias: passenger.Passenger.Alias,
|
||||
FirstName: &passenger.Passenger.FirstName,
|
||||
LastName: &passenger.Passenger.LastName,
|
||||
Grade: &passenger.Passenger.Grade,
|
||||
Picture: &passenger.Passenger.Picture,
|
||||
Gender: &passenger.Passenger.Gender,
|
||||
VerifiedIdentity: &passenger.Passenger.VerifiedIdentity,
|
||||
},
|
||||
PassengerPickupDate: ×tamp.Timestamp{
|
||||
Seconds: passenger.Passenger_pickup_date,
|
||||
},
|
||||
PassengerDepartureRoute: &proto.Feature{
|
||||
Lat: passenger.Passenger_departure_address.Point().Lat(),
|
||||
Long: passenger.Passenger_departure_address.Point().Lon(),
|
||||
Address: passenger.Passenger_departure_address.Properties.MustString("name"),
|
||||
},
|
||||
PassengerDestinationRoute: &proto.Feature{
|
||||
Lat: passenger.Passenger_destination_address.Point().Lat(),
|
||||
Long: passenger.Passenger_destination_address.Point().Lon(),
|
||||
Address: passenger.Passenger_destination_address.Properties.MustString("name"),
|
||||
},
|
||||
Status: ConvertInternalToProtoBookingStatus(booking.Status),
|
||||
Duration: &duration,
|
||||
Distance: &distance,
|
||||
Price: &proto.Price{
|
||||
Type: &priceType,
|
||||
},
|
||||
Car: &proto.Car{
|
||||
Model: &driver.Car.Model,
|
||||
Brand: &driver.Car.Brand,
|
||||
},
|
||||
}
|
||||
return resp, nil
|
||||
|
||||
}
|
||||
|
||||
func (s *SolidarityServiceServerImpl) GetBookingsByStatus(ctx context.Context, req *proto.GetBookingsByStatusRequest) (resp *proto.GetBookingsByStatusResponse, err error) {
|
||||
if req.Type.String() == "" || req.Status.String() == "" || req.UserId == "" {
|
||||
return nil, errors.New("missing required fields")
|
||||
}
|
||||
bookings, err := s.Handler.GetBookingsByStatus(context.Background(), req.Status.String(), req.Type.String(), req.UserId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
responses := []*proto.Booking{}
|
||||
for _, v := range bookings {
|
||||
passenger, err := s.Handler.GetPassenger(context.Background(), v.Passenger.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
driver, err := s.Handler.GetDriver(context.Background(), v.Driver.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
duration, err := s.Handler.CalculateDurationBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address)
|
||||
if err != nil {
|
||||
duration = 0
|
||||
}
|
||||
priceType := proto.PriceType_FREE
|
||||
distance := s.Handler.CalculateDistanceBetweenFeatures(passenger.Passenger_departure_address, passenger.Passenger_destination_address)
|
||||
responses = append(responses, &proto.Booking{
|
||||
Id: v.ID,
|
||||
Status: ConvertInternalToProtoBookingStatus(v.Status),
|
||||
Driver: &proto.User{
|
||||
Id: v.Driver.ID,
|
||||
Alias: driver.Driver.Alias,
|
||||
FirstName: &driver.Driver.FirstName,
|
||||
LastName: &driver.Driver.LastName,
|
||||
Grade: &driver.Driver.Grade,
|
||||
Picture: &driver.Driver.Picture,
|
||||
Gender: &driver.Driver.Gender,
|
||||
VerifiedIdentity: &driver.Driver.VerifiedIdentity,
|
||||
},
|
||||
Passenger: &proto.User{
|
||||
Id: v.Passenger.ID,
|
||||
Alias: passenger.Passenger.Alias,
|
||||
FirstName: &passenger.Passenger.FirstName,
|
||||
LastName: &passenger.Passenger.LastName,
|
||||
Grade: &passenger.Passenger.Grade,
|
||||
Picture: &passenger.Passenger.Picture,
|
||||
Gender: &passenger.Passenger.Gender,
|
||||
VerifiedIdentity: &passenger.Passenger.VerifiedIdentity,
|
||||
},
|
||||
PassengerPickupDate: ×tamp.Timestamp{
|
||||
Seconds: passenger.Passenger_pickup_date,
|
||||
},
|
||||
PassengerDepartureRoute: &proto.Feature{
|
||||
Lat: passenger.Passenger_departure_address.Point().Lat(),
|
||||
Long: passenger.Passenger_departure_address.Point().Lon(),
|
||||
Address: passenger.Passenger_departure_address.Properties.MustString("name"),
|
||||
},
|
||||
PassengerDestinationRoute: &proto.Feature{
|
||||
Lat: passenger.Passenger_destination_address.Point().Lat(),
|
||||
Long: passenger.Passenger_destination_address.Point().Lon(),
|
||||
Address: passenger.Passenger_destination_address.Properties.MustString("name"),
|
||||
},
|
||||
Duration: &duration,
|
||||
Distance: &distance,
|
||||
Car: &proto.Car{
|
||||
Model: &driver.Car.Model,
|
||||
Brand: &driver.Car.Brand,
|
||||
},
|
||||
Price: &proto.Price{
|
||||
Type: &priceType,
|
||||
},
|
||||
})
|
||||
}
|
||||
resp.Booking = responses
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (s *SolidarityServiceServerImpl) DriverJourneys(ctx context.Context, req *proto.DriverJourneysRequest) (resp *proto.DriverJourneysResponse, err error) {
|
||||
|
||||
if req.DepartureDate.Seconds == 0 || req.Departure == nil {
|
||||
return nil, errors.New("missing required fields")
|
||||
}
|
||||
drivers, err := s.Handler.GetDriverJourneys(context.Background(), &geojson.Feature{
|
||||
Type: "Feature",
|
||||
Geometry: orb.Geometry(orb.Point{req.Departure.Lat, req.Departure.Long}),
|
||||
Properties: geojson.Properties{
|
||||
"name": req.Departure.Address,
|
||||
}},
|
||||
req.DepartureDate.Seconds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response := []*proto.DriverJourney{}
|
||||
for _, v := range drivers {
|
||||
temp := &proto.DriverJourney{}
|
||||
if v.AvailabilitiesType == internal.Regular && v.RegularAvailabilities != nil {
|
||||
regularAvailabilities := make([]*proto.RegularAvailabilitySlot, 0) // Initialize an empty slice
|
||||
for _, v := range v.RegularAvailabilities {
|
||||
day := ConvertToProtoDayOfTheWeek(v.DayOfWeek)
|
||||
regularAvailabilities = append(regularAvailabilities, &proto.RegularAvailabilitySlot{
|
||||
DayOfWeek: day,
|
||||
StartTime: v.StartTime,
|
||||
EndTime: v.EndTime,
|
||||
})
|
||||
}
|
||||
convertedAvailability := &proto.RepeatedRegularAvailabilitySlot{
|
||||
RegularAvailabilities: regularAvailabilities,
|
||||
}
|
||||
temp.Availabilities = &proto.DriverJourney_RepeatedRegularAvailabilities{
|
||||
RepeatedRegularAvailabilities: convertedAvailability,
|
||||
}
|
||||
|
||||
} else if v.AvailabilitiesType == internal.Punctual && v.PunctualAvailabilities != nil {
|
||||
punctualAvailabilities := make([]*proto.PunctualAvailabilitySlot, 0) // Initialize an empty slice
|
||||
for _, v := range v.PunctualAvailabilities {
|
||||
punctualAvailabilities = append(punctualAvailabilities, &proto.PunctualAvailabilitySlot{
|
||||
Date: ×tamp.Timestamp{
|
||||
Seconds: v.Date,
|
||||
},
|
||||
StartTime: v.StartTime,
|
||||
EndTime: v.EndTime,
|
||||
})
|
||||
}
|
||||
convertedAvailability := &proto.RepeatedPunctualAvailabilitySlot{
|
||||
PunctualAvailabilities: punctualAvailabilities,
|
||||
}
|
||||
|
||||
temp.Availabilities = &proto.DriverJourney_RepeatedPunctualAvailabilities{
|
||||
RepeatedPunctualAvailabilities: convertedAvailability,
|
||||
}
|
||||
}
|
||||
priceType := proto.PriceType_FREE
|
||||
tamp := &proto.DriverJourney{
|
||||
User: &proto.User{
|
||||
Id: v.Driver.ID,
|
||||
Alias: v.Driver.Alias,
|
||||
FirstName: &v.Driver.FirstName,
|
||||
LastName: &v.Driver.LastName,
|
||||
Grade: &v.Driver.Grade,
|
||||
Picture: &v.Driver.Picture,
|
||||
Gender: &v.Driver.Gender,
|
||||
VerifiedIdentity: &v.Driver.VerifiedIdentity,
|
||||
},
|
||||
Car: &proto.Car{
|
||||
Model: &v.Car.Model,
|
||||
Brand: &v.Car.Brand,
|
||||
},
|
||||
DriverDeparture_Date: ×tamp.Timestamp{
|
||||
Seconds: req.DepartureDate.Seconds,
|
||||
},
|
||||
Price: &proto.Price{
|
||||
Type: &priceType,
|
||||
},
|
||||
DriverDeparture_Address: v.Driver_departure_address.Properties.MustString("name"),
|
||||
}
|
||||
temp.DriverDeparture_Address = tamp.DriverDeparture_Address
|
||||
temp.Car = tamp.Car
|
||||
temp.User = tamp.User
|
||||
temp.DriverDeparture_Date = tamp.DriverDeparture_Date
|
||||
temp.Price = tamp.Price
|
||||
response = append(response, temp)
|
||||
}
|
||||
resp.DriverJourneys = response
|
||||
return resp, nil
|
||||
}
|
||||
func (s *SolidarityServiceServerImpl) SetPassengerTrip(ctx context.Context, req *proto.PassengerTripRequest) (resp *proto.PassengerTripResponse, err error) {
|
||||
if req.Passenger.Id == "" || req.Passenger.Alias == "" || req.PassengerPickupDate.Seconds == 0 || req.PassengerDestinationAddress == nil || req.PassengerDestinationAddress == nil {
|
||||
return &proto.PassengerTripResponse{
|
||||
Success: false,
|
||||
}, errors.New("missing required fields")
|
||||
}
|
||||
passenger := internal.Passenger{
|
||||
Passenger_departure_address: &geojson.Feature{
|
||||
Type: "Feature",
|
||||
Geometry: orb.Geometry(orb.Point{req.PassengerDepartureAddress.Lat, req.PassengerDepartureAddress.Long}),
|
||||
Properties: geojson.Properties{
|
||||
"name": req.PassengerDepartureAddress.Address,
|
||||
},
|
||||
},
|
||||
Passenger_destination_address: &geojson.Feature{
|
||||
Type: "Feature",
|
||||
Geometry: orb.Geometry(orb.Point{req.PassengerDestinationAddress.Lat, req.PassengerDestinationAddress.Long}),
|
||||
Properties: geojson.Properties{
|
||||
"name": req.PassengerDestinationAddress.Address,
|
||||
},
|
||||
},
|
||||
Passenger_pickup_date: req.PassengerPickupDate.Seconds,
|
||||
Passenger: internal.User{
|
||||
ID: req.Passenger.Id,
|
||||
Alias: req.Passenger.Alias,
|
||||
},
|
||||
}
|
||||
|
||||
if req.Passenger.FirstName != nil {
|
||||
passenger.Passenger.FirstName = *req.Passenger.FirstName
|
||||
}
|
||||
if req.Passenger.LastName != nil {
|
||||
passenger.Passenger.LastName = *req.Passenger.LastName
|
||||
}
|
||||
if req.Passenger.Grade != nil {
|
||||
passenger.Passenger.Grade = *req.Passenger.Grade
|
||||
}
|
||||
if req.Passenger.Picture != nil {
|
||||
passenger.Passenger.Picture = *req.Passenger.Picture
|
||||
}
|
||||
if req.Passenger.Gender != nil {
|
||||
passenger.Passenger.Gender = *req.Passenger.Gender
|
||||
}
|
||||
if req.Passenger.VerifiedIdentity != nil {
|
||||
passenger.Passenger.VerifiedIdentity = *req.Passenger.VerifiedIdentity
|
||||
}
|
||||
if req.Preferences != nil {
|
||||
passenger.Preferences = internal.Preferences{
|
||||
Smoking: *req.Preferences.Smoking,
|
||||
Animals: *req.Preferences.Animals,
|
||||
Music: *req.Preferences.Music,
|
||||
Is_talker: *req.Preferences.IsTalker,
|
||||
Luggage_size: *req.Preferences.LuggageSize,
|
||||
}
|
||||
}
|
||||
|
||||
err = s.Handler.SetPassengerTrip(context.Background(), passenger)
|
||||
if err != nil {
|
||||
return &proto.PassengerTripResponse{
|
||||
Success: false,
|
||||
}, nil
|
||||
}
|
||||
return &proto.PassengerTripResponse{
|
||||
Success: true,
|
||||
}, nil
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package utils
|
||||
|
||||
import "math"
|
||||
|
||||
func Haversine(lat1, lon1, lat2, lon2 float64) float64 {
|
||||
// Radius of the Earth in kilometers
|
||||
R := 6371.0
|
||||
|
||||
lat1 = lat1 * math.Pi / 180
|
||||
lon1 = lon1 * math.Pi / 180
|
||||
lat2 = lat2 * math.Pi / 180
|
||||
lon2 = lon2 * math.Pi / 180
|
||||
|
||||
dlat := lat2 - lat1
|
||||
dlon := lon2 - lon1
|
||||
|
||||
a := math.Sin(dlat/2)*math.Sin(dlat/2) + math.Cos(lat1)*math.Cos(lat2)*math.Sin(dlon/2)*math.Sin(dlon/2)
|
||||
c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))
|
||||
|
||||
distance := R * c
|
||||
return distance
|
||||
}
|
|
@ -0,0 +1,558 @@
|
|||
package storage
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/google/uuid"
|
||||
_ "github.com/lib/pq"
|
||||
"github.com/paulmach/orb"
|
||||
"github.com/paulmach/orb/geojson"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/viper"
|
||||
"solidarity-service/internal"
|
||||
"solidarity-service/servers/utils"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type PostgresqlStorage struct {
|
||||
DbConnection *sql.DB
|
||||
Schema string
|
||||
Tables map[string]string
|
||||
}
|
||||
|
||||
func NewPostgresqlStorage(cfg *viper.Viper) (PostgresqlStorage, error) {
|
||||
var (
|
||||
host = cfg.GetString("storage.db.psql.host")
|
||||
port = cfg.GetString("storage.db.psql.port")
|
||||
user = cfg.GetString("storage.db.psql.user")
|
||||
password = cfg.GetString("storage.db.psql.password")
|
||||
dbname = cfg.GetString("storage.db.psql.dbname")
|
||||
sslmode = cfg.GetString("storage.db.psql.sslmode")
|
||||
pg_schema = cfg.GetString("storage.db.psql.schema")
|
||||
pgtables_drivers = cfg.GetString("storage.db.psql.tables.drivers")
|
||||
pgtables_passengers = cfg.GetString("storage.db.psql.tables.passengers")
|
||||
pgtables_bookings = cfg.GetString("storage.db.psql.tables.bookings")
|
||||
)
|
||||
portInt, _ := strconv.Atoi(port)
|
||||
psqlconn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=%s", host, portInt, user, password, dbname, sslmode)
|
||||
db, err := sql.Open("postgres", psqlconn)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("opening connection to postgresql failed")
|
||||
return PostgresqlStorage{}, fmt.Errorf("connection to postgresql failed")
|
||||
}
|
||||
err = db.Ping()
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("ping to postgresql failed")
|
||||
return PostgresqlStorage{}, fmt.Errorf("connection to postgresql database failed")
|
||||
}
|
||||
return PostgresqlStorage{
|
||||
DbConnection: db,
|
||||
Schema: pg_schema,
|
||||
Tables: map[string]string{
|
||||
"drivers": fmt.Sprintf("%s.%s", pg_schema, pgtables_drivers),
|
||||
"bookings": fmt.Sprintf("%s.%s", pg_schema, pgtables_bookings),
|
||||
"passengers": fmt.Sprintf("%s.%s", pg_schema, pgtables_passengers),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s PostgresqlStorage) CreatePassenger(passenger internal.Passenger) (err error) {
|
||||
_, err = uuid.Parse(passenger.Passenger.ID)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Postgresql Storage CreatePassenger invalid ID")
|
||||
return err
|
||||
}
|
||||
if passenger.Passenger_pickup_date == 0 {
|
||||
errMsg := "Postgresql Storage CreatePassenger empty UNIX pickup Date timestamp"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
if passenger.Passenger.Alias == "" || passenger.Passenger.Operator == "" {
|
||||
errMsg := "Postgresql Storage CreatePassenger empty alias or operator FQDN."
|
||||
log.Error().Msg(errMsg)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
preferencesJSON, err := json.Marshal(passenger.Preferences)
|
||||
if err != nil {
|
||||
errMsg := "Postgresql Storage CreatePassenger Error encoding Preferences to JSON"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
departureJSON, err := json.Marshal(passenger.Passenger_departure_address)
|
||||
if err != nil {
|
||||
errMsg := "Postgresql Storage CreatePassenger Error encoding departure Feature to JSON"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
|
||||
destinationJSON, err := json.Marshal(passenger.Passenger_destination_address)
|
||||
if err != nil {
|
||||
errMsg := "Postgresql Storage CreatePassenger Error converting destination Feature to JSON"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
_, err = s.DbConnection.Exec(fmt.Sprintf("INSERT INTO %s (passenger_id, passenger_departure_route, passenger_destination_route, alias, last_name, first_name, grade, picture, verified_identity, operator, preferences, passenger_pickup_date) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12)", s.Tables["passengers"]),
|
||||
passenger.Passenger.ID,
|
||||
departureJSON,
|
||||
destinationJSON,
|
||||
passenger.Passenger.Alias,
|
||||
passenger.Passenger.LastName,
|
||||
passenger.Passenger.FirstName,
|
||||
passenger.Passenger.Grade,
|
||||
passenger.Passenger.Picture,
|
||||
passenger.Passenger.VerifiedIdentity,
|
||||
passenger.Passenger.Operator,
|
||||
preferencesJSON,
|
||||
passenger.Passenger_pickup_date)
|
||||
if err != nil {
|
||||
errMsg := "Postgresql Storage CreatePassenger Error inserting data into the database"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s PostgresqlStorage) GetPassenger(passengerID string) (passenger internal.Passenger, err error) {
|
||||
var preferencesJSON []byte
|
||||
var departure_address []byte
|
||||
var destination_address []byte
|
||||
err = s.DbConnection.QueryRow(fmt.Sprintf("SELECT passenger_departure_route, passenger_destination_route, alias, last_name, first_name, grade, picture, verified_identity, operator, preferences, passenger_pickup_date , passenger_id FROM %s WHERE passenger_id = $1", s.Tables["passengers"]), passengerID).
|
||||
Scan(
|
||||
&departure_address,
|
||||
&destination_address,
|
||||
&passenger.Passenger.Alias,
|
||||
&passenger.Passenger.LastName,
|
||||
&passenger.Passenger.FirstName,
|
||||
&passenger.Passenger.Grade,
|
||||
&passenger.Passenger.Picture,
|
||||
&passenger.Passenger.VerifiedIdentity,
|
||||
&passenger.Passenger.Operator,
|
||||
&preferencesJSON,
|
||||
&passenger.Passenger_pickup_date,
|
||||
&passenger.Passenger.ID,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
errMsg := "Postgresql Storage GetPassenger Error querying data from the database"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return passenger, errors.New(errMsg)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(preferencesJSON, &passenger.Preferences)
|
||||
if err != nil {
|
||||
errMsg := "Postgresql Storage GetPassenger Error decoding Preferences from JSON"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return passenger, errors.New(errMsg)
|
||||
}
|
||||
passenger.Passenger_destination_address, err = geojson.UnmarshalFeature(destination_address)
|
||||
if err != nil {
|
||||
errMsg := "Postgresql Storage GetPassenger Error decoding Passenger destination route into GeoJSON"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return passenger, errors.New(errMsg)
|
||||
}
|
||||
passenger.Passenger_departure_address, err = geojson.UnmarshalFeature(departure_address)
|
||||
if err != nil {
|
||||
errMsg := "Postgresql Storage GetPassenger Error decoding Passenger departure route into GeoJSON"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return passenger, errors.New(errMsg)
|
||||
}
|
||||
return passenger, nil
|
||||
}
|
||||
|
||||
func (s PostgresqlStorage) CreateDriver(driver internal.Driver) (err error) {
|
||||
var availabilities []byte
|
||||
_, err = uuid.Parse(driver.Driver.ID)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Postgresql Storage CreateDriver invalid ID")
|
||||
return err
|
||||
}
|
||||
departureJSON, err := json.Marshal(driver.Driver_departure_address)
|
||||
if err != nil {
|
||||
errMsg := "Postgresql Storage CreateDriver Error encoding departure Feature to JSON"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
preferencesJSON, err := json.Marshal(driver.Preferences)
|
||||
if err != nil {
|
||||
errMsg := "Postgresql Storage CreateDriver Error encoding Preferences to JSON"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
carJSON, err := json.Marshal(driver.Car)
|
||||
if err != nil {
|
||||
errMsg := "Postgresql Storage CreateDriver Error encoding Car to JSON"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
if driver.Driver.Alias == "" || driver.Driver.Operator == "" {
|
||||
errMsg := "Postgresql Storage CreateDriver empty alias or operator FQDN."
|
||||
log.Error().Msg(errMsg)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
if driver.AvailabilitiesType != internal.Punctual && driver.AvailabilitiesType != internal.Regular {
|
||||
errMsg := "Postgresql Storage CreateDriver invalid Availabilities Type"
|
||||
log.Error().Msg(errMsg)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
if driver.Radius == 0 {
|
||||
errMsg := "Postgresql Storage CreateDriver Radius has to be defined"
|
||||
log.Error().Msg(errMsg)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
switch driver.AvailabilitiesType {
|
||||
case internal.Punctual:
|
||||
availabilities, err = json.Marshal(driver.PunctualAvailabilities)
|
||||
if err != nil {
|
||||
errMsg := "Postgresql Storage CreateDriver error converting Punctual availabilities"
|
||||
log.Error().Msg(errMsg)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
case internal.Regular:
|
||||
availabilities, err = json.Marshal(driver.RegularAvailabilities)
|
||||
if err != nil {
|
||||
errMsg := "Postgresql Storage CreateDriver error converting Regular availabilities"
|
||||
log.Error().Msg(errMsg)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
}
|
||||
_, err = s.DbConnection.Exec(fmt.Sprintf("INSERT INTO %s (driver_id,driver_departure_route,driver_radius,last_name,first_name,grade,alias,picture,verified_identity,preferences,availabilities_type,availabilities,operator , car) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14)", s.Tables["drivers"]),
|
||||
driver.Driver.ID,
|
||||
departureJSON,
|
||||
driver.Radius,
|
||||
driver.Driver.LastName,
|
||||
driver.Driver.FirstName,
|
||||
driver.Driver.Grade,
|
||||
driver.Driver.Alias,
|
||||
driver.Driver.Picture,
|
||||
driver.Driver.VerifiedIdentity,
|
||||
preferencesJSON,
|
||||
driver.AvailabilitiesType,
|
||||
string(availabilities),
|
||||
driver.Driver.Operator,
|
||||
carJSON,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
errMsg := "Postgresql Storage CreateDriver Error inserting data into the database"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s PostgresqlStorage) GetDriver(driverID string) (driver internal.Driver, err error) {
|
||||
var preferencesJSON []byte
|
||||
var departureAddress []byte
|
||||
var availabilitiesJSON []byte
|
||||
var carJSON []byte
|
||||
err = s.DbConnection.QueryRow(fmt.Sprintf("SELECT driver_departure_route, driver_radius, last_name, first_name, grade, alias, picture, verified_identity, preferences, availabilities_type, availabilities, operator , driver_id , car FROM %s WHERE driver_id = $1", s.Tables["drivers"]), driverID).
|
||||
Scan(
|
||||
&departureAddress,
|
||||
&driver.Radius,
|
||||
&driver.Driver.LastName,
|
||||
&driver.Driver.FirstName,
|
||||
&driver.Driver.Grade,
|
||||
&driver.Driver.Alias,
|
||||
&driver.Driver.Picture,
|
||||
&driver.Driver.VerifiedIdentity,
|
||||
&preferencesJSON,
|
||||
&driver.AvailabilitiesType,
|
||||
&availabilitiesJSON,
|
||||
&driver.Driver.Operator,
|
||||
&driver.Driver.ID,
|
||||
&carJSON,
|
||||
)
|
||||
if err != nil {
|
||||
errMsg := "Postgresql Storage GetDriver Error querying data from the database"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return driver, errors.New(errMsg)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(preferencesJSON, &driver.Preferences)
|
||||
if err != nil {
|
||||
errMsg := "Postgresql Storage GetDriver Error decoding Preferences from JSON"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return driver, errors.New(errMsg)
|
||||
}
|
||||
err = json.Unmarshal(carJSON, &driver.Car)
|
||||
if err != nil {
|
||||
errMsg := "Postgresql Storage GetDriver Error decoding Car from JSON"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return driver, errors.New(errMsg)
|
||||
}
|
||||
driver.Driver_departure_address, err = geojson.UnmarshalFeature(departureAddress)
|
||||
if err != nil {
|
||||
errMsg := "Postgresql Storage GetDriver Error decoding Driver departure route into GeoJSON"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return driver, errors.New(errMsg)
|
||||
}
|
||||
|
||||
switch driver.AvailabilitiesType {
|
||||
case internal.Regular:
|
||||
err = json.Unmarshal(availabilitiesJSON, &driver.RegularAvailabilities)
|
||||
if err != nil {
|
||||
errMsg := "Postgresql Storage GetDriver Error decoding Regular Availabilities from JSON"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return driver, errors.New(errMsg)
|
||||
}
|
||||
case internal.Punctual:
|
||||
err = json.Unmarshal(availabilitiesJSON, &driver.PunctualAvailabilities)
|
||||
if err != nil {
|
||||
errMsg := "Postgresql Storage GetDriver Error decoding Punctual Availabilities from JSON"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return driver, errors.New(errMsg)
|
||||
}
|
||||
default:
|
||||
errMsg := "Postgresql Storage GetDriver Invalid Availabilities Type"
|
||||
log.Error().Msg(errMsg)
|
||||
return driver, errors.New(errMsg)
|
||||
}
|
||||
|
||||
return driver, nil
|
||||
}
|
||||
|
||||
func (s PostgresqlStorage) CreateBooking(booking internal.BookingRequest) (err error) {
|
||||
_, err = uuid.Parse(booking.Driver_id)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Postgresql Storage CreateBooking invalid Driver ID")
|
||||
return err
|
||||
}
|
||||
_, err = uuid.Parse(booking.Passenger_id)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Postgresql Storage CreateBooking invalid Passenger ID")
|
||||
return err
|
||||
}
|
||||
_, err = uuid.Parse(booking.ID)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Postgresql Storage CreateBooking invalid Booking ID")
|
||||
return err
|
||||
}
|
||||
if booking.Operator == "" {
|
||||
log.Error().Err(err).Msg("Postgresql Storage CreateBooking empty operator")
|
||||
return err
|
||||
}
|
||||
_, err = s.DbConnection.Exec(fmt.Sprintf("INSERT INTO %s (booking_id , passenger_id , driver_id , operator, booking_status) VALUES ($1,$2,$3,$4,$5)", s.Tables["bookings"]),
|
||||
booking.ID,
|
||||
booking.Passenger_id,
|
||||
booking.Driver_id,
|
||||
booking.Operator,
|
||||
booking.Status,
|
||||
)
|
||||
if err != nil {
|
||||
errMsg := "Postgresql Storage CreateBooking Error inserting data into the database"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s PostgresqlStorage) GetBooking(id string) (booking internal.Booking, err error) {
|
||||
err = s.DbConnection.QueryRow(fmt.Sprintf("SELECT booking_id , passenger_id , driver_id , booking_status FROM %s WHERE booking_id = $1", s.Tables["bookings"]), id).
|
||||
Scan(
|
||||
&booking.ID,
|
||||
&booking.Passenger.ID,
|
||||
&booking.Driver.ID,
|
||||
&booking.Status,
|
||||
)
|
||||
fmt.Println(err)
|
||||
if err != nil {
|
||||
errMsg := "Postgresql Storage GetBooking Error getting booking"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return booking, errors.New(errMsg + err.Error())
|
||||
}
|
||||
passenger, err := s.GetPassenger(booking.Passenger.ID)
|
||||
if err != nil {
|
||||
errMsg := "Postgresql Storage GetBooking Error getting passenger"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return booking, errors.New(errMsg + err.Error())
|
||||
}
|
||||
booking.Passenger = passenger.Passenger
|
||||
booking.PassengerPickupAddress = passenger.Passenger_departure_address
|
||||
booking.PassengerDropAddress = passenger.Passenger_destination_address
|
||||
driver, err := s.GetDriver(booking.Driver.ID)
|
||||
if err != nil {
|
||||
errMsg := "Postgresql Storage GetBooking Error getting driver"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return booking, errors.New(errMsg + err.Error())
|
||||
}
|
||||
booking.Driver = driver.Driver
|
||||
return booking, nil
|
||||
}
|
||||
|
||||
func (s PostgresqlStorage) UpdateBookingStatus(id string, status internal.BookingStatus) (err error) {
|
||||
_, err = uuid.Parse(id)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Postgresql Storage UpdateBookingStatus invalid Booking ID")
|
||||
return err
|
||||
}
|
||||
_, err = s.GetBooking(id)
|
||||
if err != nil {
|
||||
return errors.New(err.Error())
|
||||
}
|
||||
query := fmt.Sprintf("UPDATE %s SET booking_status = $1 WHERE booking_id = $2", s.Tables["bookings"])
|
||||
_, err = s.DbConnection.Exec(query, status, id)
|
||||
if err != nil {
|
||||
errMsg := "Postgresql Storage UpdateBookingStatus Error updating booking status"
|
||||
log.Error().Err(err).Msg(errMsg)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s PostgresqlStorage) FilterUserBookingsByStatus(user_type string, status internal.BookingStatus, user_id string) (bookings []internal.Booking, err error) {
|
||||
_, err = uuid.Parse(user_id)
|
||||
if err != nil {
|
||||
return nil, errors.New("invalid uuid")
|
||||
}
|
||||
|
||||
if user_type != "driver" && user_type != "passenger" {
|
||||
return nil, errors.New("invalid user type")
|
||||
}
|
||||
switch user_type {
|
||||
case "driver":
|
||||
rows, err := s.DbConnection.Query(fmt.Sprintf("SELECT booking_id, passenger_id, driver_id, booking_status FROM %s WHERE driver_id = $1 AND booking_status = $2", s.Tables["bookings"]),
|
||||
user_id, status)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var booking internal.Booking
|
||||
if err := rows.Scan(&booking.ID, &booking.Passenger.ID, &booking.Driver.ID, &booking.Status); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bookings = append(bookings, booking)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "passenger":
|
||||
rows, err := s.DbConnection.Query(fmt.Sprintf("SELECT booking_id, passenger_id, driver_id, booking_status FROM %s WHERE passenger_id = $1 AND booking_status = $2", s.Tables["bookings"]),
|
||||
user_id, status)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var booking internal.Booking
|
||||
if err := rows.Scan(&booking.ID, &booking.Passenger.ID, &booking.Driver.ID, &booking.Status); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bookings = append(bookings, booking)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
}
|
||||
return bookings, nil
|
||||
}
|
||||
|
||||
func (s PostgresqlStorage) GetAllDrivers(date int64) (drivers []internal.Driver, err error) {
|
||||
rows, err := s.DbConnection.Query(fmt.Sprintf("SELECT driver_id, driver_departure_route, driver_radius, last_name, first_name, grade, alias, picture, verified_identity, preferences, availabilities_type, availabilities, operator, car FROM %s", s.Tables["drivers"]))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
var driver internal.Driver
|
||||
var departureRoute []byte
|
||||
var preferencesJSON []byte
|
||||
var availabilitiesJSON []byte
|
||||
var carJSON []byte
|
||||
|
||||
if err := rows.Scan(
|
||||
&driver.Driver.ID,
|
||||
&departureRoute,
|
||||
&driver.Radius,
|
||||
&driver.Driver.LastName,
|
||||
&driver.Driver.FirstName,
|
||||
&driver.Driver.Grade,
|
||||
&driver.Driver.Alias,
|
||||
&driver.Driver.Picture,
|
||||
&driver.Driver.VerifiedIdentity,
|
||||
&preferencesJSON,
|
||||
&driver.AvailabilitiesType,
|
||||
&availabilitiesJSON,
|
||||
&driver.Driver.Operator,
|
||||
&carJSON,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(departureRoute, &driver.Driver_departure_address); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := json.Unmarshal(preferencesJSON, &driver.Preferences); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := json.Unmarshal(carJSON, &driver.Car); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Filter drivers based on date matching punctual or regular availabilities.
|
||||
if driver.AvailabilitiesType == internal.Punctual {
|
||||
if err := json.Unmarshal(availabilitiesJSON, &driver.PunctualAvailabilities); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Convert the date to the day of the week and make it lowercase.
|
||||
dayOfWeek := strings.ToLower(time.Unix(date, 0).UTC().Format("Mon"))
|
||||
|
||||
for _, avail := range driver.PunctualAvailabilities {
|
||||
// Extract the day part of the punctual driver's date and compare.
|
||||
availDate := time.Unix(avail.Date, 0)
|
||||
if strings.ToLower(availDate.Format("Mon")) == dayOfWeek {
|
||||
drivers = append(drivers, driver)
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if driver.AvailabilitiesType == internal.Regular {
|
||||
if err := json.Unmarshal(availabilitiesJSON, &driver.RegularAvailabilities); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Convert the date to the day of the week and make it lowercase.
|
||||
dayOfWeek := strings.ToLower(time.Unix(date, 0).UTC().Format("Mon"))
|
||||
for _, avail := range driver.RegularAvailabilities {
|
||||
if strings.ToLower(avail.DayOfWeek) == dayOfWeek {
|
||||
drivers = append(drivers, driver)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return drivers, nil
|
||||
}
|
||||
|
||||
func (s PostgresqlStorage) DriverJourneys(departure_route *geojson.Feature, departure_date int64) (drivers []internal.Driver, err error) {
|
||||
allDrivers, err := s.GetAllDrivers(departure_date)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, driver := range allDrivers {
|
||||
// Check if the departure route is the same as the driver's departure route.
|
||||
if departure_route.Point().Y() == driver.Driver_departure_address.Point().Y() && departure_route.Point().X() == driver.Driver_departure_address.Point().X() {
|
||||
drivers = append(drivers, driver)
|
||||
} else {
|
||||
// Calculate the distance between the departure point and the driver's departure route.
|
||||
coords1 := departure_route.Geometry.(orb.Point)
|
||||
coords2 := driver.Driver_departure_address.Geometry.(orb.Point)
|
||||
distance := utils.Haversine(coords1[1], coords1[0], coords2[1], coords2[0])
|
||||
if int64(distance) <= int64(driver.Radius) {
|
||||
drivers = append(drivers, driver)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return drivers, nil
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
|
||||
table "passengers" {
|
||||
schema = schema.solidarity_service
|
||||
column "passenger_id" {
|
||||
null = false
|
||||
type = uuid
|
||||
}
|
||||
column "passenger_departure_route" {
|
||||
null = false
|
||||
type = jsonb
|
||||
}
|
||||
column "passenger_destination_route" {
|
||||
null = false
|
||||
type = jsonb
|
||||
}
|
||||
column "alias" {
|
||||
null = false
|
||||
type = varchar(15)
|
||||
}
|
||||
column "last_name" {
|
||||
null = true
|
||||
type = text
|
||||
}
|
||||
column "first_name" {
|
||||
null = true
|
||||
type = text
|
||||
}
|
||||
column "grade" {
|
||||
null = true
|
||||
type = int
|
||||
}
|
||||
column "picture" {
|
||||
null = true
|
||||
type = varchar(200)
|
||||
}
|
||||
column "verified_identity"{
|
||||
null = true
|
||||
type = bool
|
||||
}
|
||||
column "operator" {
|
||||
null = false
|
||||
type = varchar(35)
|
||||
}
|
||||
column "preferences" {
|
||||
null = true
|
||||
type = jsonb
|
||||
}
|
||||
column "passenger_pickup_date" {
|
||||
null = false
|
||||
type = int
|
||||
}
|
||||
primary_key {
|
||||
columns = [column.passenger_id]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
table "drivers" {
|
||||
schema = schema.solidarity_service
|
||||
column "driver_id" {
|
||||
null = false
|
||||
type = uuid
|
||||
}
|
||||
column "driver_departure_route" {
|
||||
null = false
|
||||
type = jsonb
|
||||
}
|
||||
column "driver_radius" {
|
||||
null = false
|
||||
type = integer
|
||||
}
|
||||
column "last_name" {
|
||||
null = true
|
||||
type = text
|
||||
}
|
||||
column "first_name" {
|
||||
null = true
|
||||
type = text
|
||||
}
|
||||
column "grade" {
|
||||
null = true
|
||||
type = int
|
||||
}
|
||||
column "alias" {
|
||||
null = false
|
||||
type = varchar(15)
|
||||
}
|
||||
column "picture" {
|
||||
null = true
|
||||
type = text
|
||||
}
|
||||
column "verified_identity"{
|
||||
null = true
|
||||
type = bool
|
||||
}
|
||||
column "preferences" {
|
||||
null = true
|
||||
type = jsonb
|
||||
}
|
||||
column "availabilities_type" {
|
||||
null = false
|
||||
type = enum.availabilities_type
|
||||
}
|
||||
column "availabilities" {
|
||||
null = false
|
||||
type = jsonb
|
||||
}
|
||||
column "car" {
|
||||
null = true
|
||||
type = jsonb
|
||||
}
|
||||
column "operator" {
|
||||
null = false
|
||||
type = varchar(35)
|
||||
}
|
||||
primary_key {
|
||||
columns = [column.driver_id]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
table "bookings" {
|
||||
schema = schema.solidarity_service
|
||||
column "booking_id" {
|
||||
null = false
|
||||
type = uuid
|
||||
}
|
||||
column "driver_id" {
|
||||
null = false
|
||||
type = uuid
|
||||
}
|
||||
column "operator" {
|
||||
null = false
|
||||
type = varchar(35)
|
||||
}
|
||||
column "passenger_id" {
|
||||
null = false
|
||||
type = uuid
|
||||
}
|
||||
column "booking_status" {
|
||||
null = false
|
||||
type = enum.booking_status
|
||||
}
|
||||
primary_key {
|
||||
columns = [column.booking_id]
|
||||
}
|
||||
foreign_key "bookings_driver_id_fkey" {
|
||||
columns = [column.driver_id]
|
||||
ref_columns = [table.drivers.column.driver_id]
|
||||
}
|
||||
foreign_key "group_members_passenger_id_fkey" {
|
||||
columns = [column.passenger_id]
|
||||
ref_columns = [table.passengers.column.passenger_id]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum "booking_status" {
|
||||
schema = schema.solidarity_service
|
||||
values = ["INITIATED", "WAITING_PASSENGER_CONFIRMATION", "WAITING_DRIVER_CONFIRMATION", "CONFIRMED", "CANCELLED", "COMPLETED_PENDING_VALIDATION", "VALIDATED"]
|
||||
}
|
||||
enum "availabilities_type" {
|
||||
schema = schema.solidarity_service
|
||||
values = ["PUNCTUAL","REGULAR"]
|
||||
}
|
||||
|
||||
schema "solidarity_service" {
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package storage
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/paulmach/orb/geojson"
|
||||
"github.com/spf13/viper"
|
||||
"solidarity-service/internal"
|
||||
)
|
||||
|
||||
type Storage interface {
|
||||
CreatePassenger(passenger internal.Passenger) (err error)
|
||||
GetPassenger(passengerID string) (passenger internal.Passenger, err error)
|
||||
CreateDriver(driver internal.Driver) (err error)
|
||||
GetDriver(driverID string) (driver internal.Driver, err error)
|
||||
GetBooking(id string) (booking internal.Booking, err error)
|
||||
CreateBooking(booking internal.BookingRequest) (err error)
|
||||
UpdateBookingStatus(id string, status internal.BookingStatus) (err error)
|
||||
FilterUserBookingsByStatus(user_type string, status internal.BookingStatus, user_id string) (bookings []internal.Booking, err error)
|
||||
DriverJourneys(departure_route *geojson.Feature, departure_date int64) (drivers []internal.Driver, err error)
|
||||
GetAllDrivers(date int64) (drivers []internal.Driver, err error)
|
||||
}
|
||||
|
||||
func NewStorage(cfg *viper.Viper) (Storage, error) {
|
||||
var (
|
||||
storage_type = cfg.GetString("storage.db.type")
|
||||
)
|
||||
switch storage_type {
|
||||
case "psql":
|
||||
s, err := NewPostgresqlStorage(cfg)
|
||||
return s, err
|
||||
default:
|
||||
return nil, fmt.Errorf("storage type %v is not supported", storage_type)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue