Skip to content

Commit

Permalink
fix flight schedules conversion handling of legs on the next day
Browse files Browse the repository at this point in the history
previously, flights conversion saved the result file using the same date used to query from the LH API.
When there is a flight with multiple legs, where one log falls into the next day (e.g. 4Y136), the flight was saved to the wrong flights file.

This fix handles this by always taking the UTC departure date after conversion of legs to flights, then upserting the existing file if it exists
  • Loading branch information
its-felix committed Aug 24, 2024
1 parent f54eecc commit 850ea7a
Show file tree
Hide file tree
Showing 24 changed files with 444 additions and 101 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ jobs:
GOOS: 'linux'
GOARCH: 'arm64' # keep this in sync with the arch configured in CDK!
CGO_ENABLED: '0'
run: 'go build -o bootstrap -tags "lambda.norpc"'
run: |
go build -o bootstrap -tags "lambda,lambda.norpc"
- name: 'Store cron artifact'
uses: actions/upload-artifact@v4
with:
Expand Down
2 changes: 1 addition & 1 deletion go/api/auth/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"context"
"errors"
"fmt"
"github.com/explore-flights/monorepo/go/api/adapt"
"github.com/explore-flights/monorepo/go/common/adapt"
"github.com/gofrs/uuid/v5"
"io"
"net/url"
Expand Down
2 changes: 1 addition & 1 deletion go/api/data/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
"fmt"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/explore-flights/monorepo/go/api/adapt"
"github.com/explore-flights/monorepo/go/common"
"github.com/explore-flights/monorepo/go/common/adapt"
"github.com/explore-flights/monorepo/go/common/lufthansa"
"io"
"slices"
Expand Down
2 changes: 1 addition & 1 deletion go/api/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.23
require (
github.com/aws/aws-sdk-go-v2 v1.30.4
github.com/aws/aws-sdk-go-v2/config v1.27.28
github.com/aws/aws-sdk-go-v2/service/s3 v1.59.0
github.com/aws/aws-sdk-go-v2/service/s3 v1.60.1
github.com/aws/aws-sdk-go-v2/service/ssm v1.52.5
github.com/explore-flights/monorepo/go/common v0.0.0
github.com/goccy/go-graphviz v0.1.3
Expand Down
4 changes: 2 additions & 2 deletions go/api/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 h1:tJ5RnkHC
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18/go.mod h1:++NHzT+nAF7ZPrHPsA+ENvsXkOO8wEu+C6RXltAG4/c=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.16 h1:jg16PhLPUiHIj8zYIW6bqzeQSuHVEiWnGA0Brz5Xv2I=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.16/go.mod h1:Uyk1zE1VVdsHSU7096h/rwnXDzOzYQVl+FNPhPw7ShY=
github.com/aws/aws-sdk-go-v2/service/s3 v1.59.0 h1:Cso4Ev/XauMVsbwdhYEoxg8rxZWw43CFqqaPB5w3W2c=
github.com/aws/aws-sdk-go-v2/service/s3 v1.59.0/go.mod h1:BSPI0EfnYUuNHPS0uqIo5VrRwzie+Fp+YhQOUs16sKI=
github.com/aws/aws-sdk-go-v2/service/s3 v1.60.1 h1:mx2ucgtv+MWzJesJY9Ig/8AFHgoE5FwLXwUVgW/FGdI=
github.com/aws/aws-sdk-go-v2/service/s3 v1.60.1/go.mod h1:BSPI0EfnYUuNHPS0uqIo5VrRwzie+Fp+YhQOUs16sKI=
github.com/aws/aws-sdk-go-v2/service/ssm v1.52.5 h1:eY1n+pyBbgqRBRnpVUg0QguAGMWVLQp2n+SfjjOJuQI=
github.com/aws/aws-sdk-go-v2/service/ssm v1.52.5/go.mod h1:Bw2YSeqq/I4VyVs9JSfdT9ArqyAbQkJEwj13AVm0heg=
github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 h1:zCsFCKvbj25i7p1u94imVoO447I/sFv8qq+lGJhRN0c=
Expand Down
2 changes: 1 addition & 1 deletion go/api/local/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ package local
import (
"context"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/explore-flights/monorepo/go/api/adapt"
"github.com/explore-flights/monorepo/go/common/adapt"
"io"
"os"
"path/filepath"
Expand Down
4 changes: 2 additions & 2 deletions go/api/search/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ func buildConnectionsResponse(conns []Connection, flights map[string]FlightRespo
return r
}

func convertCodeShares(inp []common.FlightNumber) []FlightNumberResponse {
func convertCodeShares(inp map[common.FlightNumber]map[int]string) []FlightNumberResponse {
r := make([]FlightNumberResponse, 0, len(inp))
for _, fn := range inp {
for fn := range inp {
r = append(r, FlightNumberResponse{
Airline: string(fn.Airline),
Number: fn.Number,
Expand Down
2 changes: 1 addition & 1 deletion go/api/search/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import (
"encoding/json"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/explore-flights/monorepo/go/api/adapt"
"github.com/explore-flights/monorepo/go/common"
"github.com/explore-flights/monorepo/go/common/adapt"
"github.com/explore-flights/monorepo/go/common/concurrent"
"golang.org/x/sync/errgroup"
"sync"
Expand Down
2 changes: 1 addition & 1 deletion go/api/web/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package web
import (
"context"
"errors"
"github.com/explore-flights/monorepo/go/api/adapt"
"github.com/explore-flights/monorepo/go/api/data"
"github.com/explore-flights/monorepo/go/common"
"github.com/explore-flights/monorepo/go/common/adapt"
"github.com/labstack/echo/v4"
"net/http"
)
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
39 changes: 25 additions & 14 deletions go/common/flight.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ func (f FlightNumber) String() string {
return fmt.Sprintf("%v%d%v", f.Airline, f.Number, f.Suffix)
}

func (f *FlightNumber) UnmarshalText(text []byte) error {
var err error
*f, err = ParseFlightNumber(string(text))
return err
}

func (f FlightNumber) MarshalText() ([]byte, error) {
return []byte(f.String()), nil
}

func (f FlightNumber) Id(dep Departure) FlightId {
return FlightId{
Number: f,
Expand All @@ -55,20 +65,21 @@ type FlightId struct {
}

type Flight struct {
Airline AirlineIdentifier `json:"airline"`
FlightNumber int `json:"flightNumber"`
Suffix string `json:"suffix"`
DepartureTime time.Time `json:"departureTime"`
DepartureAirport string `json:"departureAirport"`
ArrivalTime time.Time `json:"arrivalTime"`
ArrivalAirport string `json:"arrivalAirport"`
ServiceType string `json:"serviceType"`
AircraftOwner AirlineIdentifier `json:"aircraftOwner"`
AircraftType string `json:"aircraftType"`
AircraftConfigurationVersion string `json:"aircraftConfigurationVersion"`
Registration string `json:"registration"`
DataElements map[int]string `json:"dataElements"`
CodeShares []FlightNumber `json:"codeShares"`
QueryDate LocalDate `json:"queryDate"`
Airline AirlineIdentifier `json:"airline"`
FlightNumber int `json:"flightNumber"`
Suffix string `json:"suffix"`
DepartureTime time.Time `json:"departureTime"`
DepartureAirport string `json:"departureAirport"`
ArrivalTime time.Time `json:"arrivalTime"`
ArrivalAirport string `json:"arrivalAirport"`
ServiceType string `json:"serviceType"`
AircraftOwner AirlineIdentifier `json:"aircraftOwner"`
AircraftType string `json:"aircraftType"`
AircraftConfigurationVersion string `json:"aircraftConfigurationVersion"`
Registration string `json:"registration"`
DataElements map[int]string `json:"dataElements"`
CodeShares map[FlightNumber]map[int]string `json:"codeShares"`
}

func (f *Flight) DepartureDate() LocalDate {
Expand Down
59 changes: 59 additions & 0 deletions go/common/flight_schedule.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package common

import (
"maps"
)

type FlightScheduleData struct {
DepartureTime OffsetTime `json:"departureTime"`
DepartureAirport string `json:"departureAirport"`
ArrivalTime OffsetTime `json:"arrivalTime"`
ArrivalAirport string `json:"arrivalAirport"`
ServiceType string `json:"serviceType"`
AircraftOwner AirlineIdentifier `json:"aircraftOwner"`
AircraftType string `json:"aircraftType"`
AircraftConfigurationVersion string `json:"aircraftConfigurationVersion"`
Registration string `json:"registration"`
DataElements map[int]string `json:"dataElements"`
CodeShares []FlightNumber `json:"codeShares"`
}

func (fsd FlightScheduleData) Equal(other FlightScheduleData) bool {
return fsd.DepartureTime == other.DepartureTime &&
fsd.DepartureAirport == other.DepartureAirport &&
fsd.ArrivalTime == other.ArrivalTime &&
fsd.ArrivalAirport == other.ArrivalAirport &&
fsd.ServiceType == other.ServiceType &&
fsd.AircraftOwner == other.AircraftOwner &&
fsd.AircraftType == other.AircraftType &&
fsd.AircraftConfigurationVersion == other.AircraftConfigurationVersion &&
fsd.Registration == other.Registration &&
maps.Equal(fsd.DataElements, other.DataElements) &&
SliceEqualContent(fsd.CodeShares, other.CodeShares)
}

type FlightScheduleVariant struct {
Ranges []LocalDateRange `json:"ranges"`
Data FlightScheduleData `json:"data"`
}

func (fsv *FlightScheduleVariant) Expand(d LocalDate) {

}

type FlightSchedule struct {
Airline AirlineIdentifier `json:"airline"`
FlightNumber int `json:"flightNumber"`
Suffix string `json:"suffix"`
Variants []*FlightScheduleVariant `json:"variants"`
}

func (fs *FlightSchedule) DataVariant(fsd FlightScheduleData) *FlightScheduleVariant {
for _, variant := range fs.Variants {
if variant.Data.Equal(fsd) {
return variant
}
}

return nil
}
15 changes: 14 additions & 1 deletion go/common/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,22 @@ module github.com/explore-flights/monorepo/go/common
go 1.23

require (
github.com/aws/aws-sdk-go-v2 v1.30.4
github.com/aws/aws-sdk-go-v2/service/s3 v1.60.1
github.com/go-jose/go-jose/v4 v4.0.4
github.com/golang-jwt/jwt/v5 v5.2.1
golang.org/x/time v0.6.0
)

require golang.org/x/crypto v0.26.0 // indirect
require (
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.4 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.16 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.18 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.16 // indirect
github.com/aws/smithy-go v1.20.4 // indirect
golang.org/x/crypto v0.26.0 // indirect
)
22 changes: 22 additions & 0 deletions go/common/go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
github.com/aws/aws-sdk-go-v2 v1.30.4 h1:frhcagrVNrzmT95RJImMHgabt99vkXGslubDaDagTk8=
github.com/aws/aws-sdk-go-v2 v1.30.4/go.mod h1:CT+ZPWXbYrci8chcARI3OmI/qgd+f6WtuLOoaIA8PR0=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.4 h1:70PVAiL15/aBMh5LThwgXdSQorVr91L127ttckI9QQU=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.4/go.mod h1:/MQxMqci8tlqDH+pjmoLu1i0tbWCUP1hhyMRuFxpQCw=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 h1:TNyt/+X43KJ9IJJMjKfa3bNTiZbUP7DeCxfbTROESwY=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16/go.mod h1:2DwJF39FlNAUiX5pAc0UNeiz16lK2t7IaFcm0LFHEgc=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 h1:jYfy8UPmd+6kJW5YhY0L1/KftReOGxI/4NtVSTh9O/I=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16/go.mod h1:7ZfEPZxkW42Afq4uQB8H2E2e6ebh6mXTueEpYzjCzcs=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.16 h1:mimdLQkIX1zr8GIPY1ZtALdBQGxcASiBd2MOp8m/dMc=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.16/go.mod h1:YHk6owoSwrIsok+cAH9PENCOGoH5PU2EllX4vLtSrsY=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 h1:KypMCbLPPHEmf9DgMGw51jMj77VfGPAN2Kv4cfhlfgI=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4/go.mod h1:Vz1JQXliGcQktFTN/LN6uGppAIRoLBR2bMvIMP0gOjc=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.18 h1:GckUnpm4EJOAio1c8o25a+b3lVfwVzC9gnSBqiiNmZM=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.18/go.mod h1:Br6+bxfG33Dk3ynmkhsW2Z/t9D4+lRqdLDNCKi85w0U=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 h1:tJ5RnkHCiSH0jyd6gROjlJtNwov0eGYNz8s8nFcR0jQ=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18/go.mod h1:++NHzT+nAF7ZPrHPsA+ENvsXkOO8wEu+C6RXltAG4/c=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.16 h1:jg16PhLPUiHIj8zYIW6bqzeQSuHVEiWnGA0Brz5Xv2I=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.16/go.mod h1:Uyk1zE1VVdsHSU7096h/rwnXDzOzYQVl+FNPhPw7ShY=
github.com/aws/aws-sdk-go-v2/service/s3 v1.60.1 h1:mx2ucgtv+MWzJesJY9Ig/8AFHgoE5FwLXwUVgW/FGdI=
github.com/aws/aws-sdk-go-v2/service/s3 v1.60.1/go.mod h1:BSPI0EfnYUuNHPS0uqIo5VrRwzie+Fp+YhQOUs16sKI=
github.com/aws/smithy-go v1.20.4 h1:2HK1zBdPgRbjFOHlfeQZfpC4r72MOb9bZkiFwggKO+4=
github.com/aws/smithy-go v1.20.4/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E=
Expand Down
22 changes: 22 additions & 0 deletions go/common/localdate.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,25 @@ func (ld *LocalDate) UnmarshalJSON(data []byte) error {
func (ld LocalDate) MarshalJSON() ([]byte, error) {
return json.Marshal(ld.String())
}

type LocalDateRange [2]LocalDate

func (ldr LocalDateRange) Iter() iter.Seq[LocalDate] {
return ldr[0].Until(ldr[1])
}

func (ldr LocalDateRange) Contains(d LocalDate) bool {
return ldr[0].Compare(d) <= 0 && ldr[1].Compare(d) >= 0
}

type LocalDateRanges []LocalDateRange

func (ldrs LocalDateRanges) Contains(d LocalDate) bool {
for _, ldr := range ldrs {
if ldr.Contains(d) {
return true
}
}

return false
}
79 changes: 79 additions & 0 deletions go/common/time.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package common

import (
"encoding/json"
"time"
)

const offsetTimeFormat = "15:04:05Z07:00"

type OffsetTime struct {
Hour int
Min int
Sec int
Loc *time.Location
}

func NewOffsetTime(t time.Time) OffsetTime {
hour, minute, sec := t.Clock()
return OffsetTime{
Hour: hour,
Min: minute,
Sec: sec,
Loc: t.Location(),
}
}

func ParseOffsetTime(v string) (OffsetTime, error) {
t, err := time.Parse(offsetTimeFormat, v)
if err != nil {
return OffsetTime{}, err
}

return OffsetTime{
Hour: t.Hour(),
Min: t.Minute(),
Sec: t.Second(),
Loc: t.Location(),
}, nil
}

func MustParseOffsetTime(v string) OffsetTime {
t, err := ParseOffsetTime(v)
if err != nil {
panic(err)
}

return t
}

func (t OffsetTime) Time(d LocalDate) time.Time {
return time.Date(d.Year, d.Month, d.Day, t.Hour, t.Min, t.Sec, 0, t.Loc)
}

func (t OffsetTime) String() string {
return t.Time(LocalDate{}).Format(offsetTimeFormat)
}

func (t *OffsetTime) UnmarshalJSON(data []byte) error {
var v string
if err := json.Unmarshal(data, &v); err != nil {
return err
}

r, err := time.Parse(offsetTimeFormat, v)
if err != nil {
return err
}

*t = NewOffsetTime(r)
return nil
}

func (t OffsetTime) MarshalJSON() ([]byte, error) {
return json.Marshal(t.String())
}

func SplitTime(t time.Time) (LocalDate, OffsetTime) {
return NewLocalDate(t), NewOffsetTime(t)
}
17 changes: 17 additions & 0 deletions go/common/time_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package common

import (
"testing"
"time"
)

func TestSplitTime(t *testing.T) {
now := time.Now().Truncate(time.Second)
d, ot := SplitTime(now)
restored := ot.Time(d)

if now != restored {
t.Fatalf("Restored time does not match the original time: %v != %v", now, restored)
return
}
}
Loading

0 comments on commit 850ea7a

Please sign in to comment.