From bb833561aa74f02970aee13cdc75973b29716491 Mon Sep 17 00:00:00 2001 From: leshe4ka46 Date: Mon, 27 Oct 2025 20:36:28 +0300 Subject: # This is a combination of 2 commits. # This is the 1st commit message: unmarshal all formats, merge them in the single table, users are truly unique # This is the commit message #2: i --- pkg/adapters/yaml/yaml.go | 180 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 pkg/adapters/yaml/yaml.go (limited to 'pkg/adapters/yaml') diff --git a/pkg/adapters/yaml/yaml.go b/pkg/adapters/yaml/yaml.go new file mode 100644 index 0000000..9a79a72 --- /dev/null +++ b/pkg/adapters/yaml/yaml.go @@ -0,0 +1,180 @@ +package yaml + +import ( + "errors" + "fmt" + "io" + "os" + "strings" + "sync" + "time" + + "airlines/pkg/airports" + "airlines/pkg/model" + + "github.com/schollz/progressbar/v3" + "gopkg.in/yaml.v3" +) + +// ---------- Data model ---------- + +type FareInfo struct { + Class string `yaml:"CLASS" json:"class"` + Fare string `yaml:"FARE" json:"fare"` +} + +type Flight struct { + FF map[string]FareInfo `yaml:"FF" json:"ff"` + From string `yaml:"FROM" json:"from"` + Status string `yaml:"STATUS" json:"status"` + To string `yaml:"TO" json:"to"` +} + +type Schedule struct { + data map[string]map[string]Flight +} + +// ParseSchedule reads YAML from r into a Schedule. +func ParseSchedule(r io.Reader) (*Schedule, error) { + s := &Schedule{ + data: make(map[string]map[string]Flight), + } + dec := yaml.NewDecoder(r) + // dec.KnownFields(true) // enable if you want strict field checking + if err := dec.Decode(&s.data); err != nil { + return nil, err + } + + for date, flights := range s.data { + if flights == nil { + s.data[date] = map[string]Flight{} + } + } + return s, nil +} + +func UnmarshallYaml(path string) (*Schedule, error) { + f, err := os.Open(path) + if err != nil { + return nil, err + } + + sched, err := ParseSchedule(f) + if err != nil { + return nil, err + } + + // for date, flights := range sched.data { + // fmt.Printf("Date: %s (flights: %d)\n", date, len(flights)) + // for flightNo, fl := range flights { + // fmt.Printf(" %s: %s -> %s, %s\n", flightNo, fl.From, fl.To, fl.Status) + // for ffKey, fi := range fl.FF { + // fmt.Printf(" FF %s: class=%s fare=%s\n", ffKey, fi.Class, fi.Fare) + // } + // } + // } + + // if b, err := json.MarshalIndent(sched, "", " "); err == nil { + // fmt.Println("\nAs JSON:") + // fmt.Println(string(b)) + // } + return sched, nil +} + +func createFlight(num, from, to, date string, cardID uint64) (*model.Flight, error) { + f := &model.Flight{ + Number: num, + From: from, + To: to, + } + + ap, _ := airports.LookupIATA(f.From) + f.FromCoords.Lat = ap.Latitude + f.FromCoords.Long = ap.Longitude + + d, err := time.Parse("2006-01-02", strings.TrimSpace(date)) + if err != nil { + return nil, fmt.Errorf("invalid Date %q: %w", date, err) + } + + loc := model.TzFromAirportRecord(ap) + departLocal := time.Date(d.Year(), d.Month(), d.Day(), 0, 0, 0, 0, loc) + f.Date = departLocal.UTC() + + ap, _ = airports.LookupIATA(f.To) + f.ToCoords.Lat = ap.Latitude + f.ToCoords.Long = ap.Longitude + + return f, nil +} + +func createCard(info string) (*model.Card, error) { + prefix, number, _ := model.ParseCardLine(info) + if prefix == "" && number == 0 { + return nil, errors.New("bad card id") + } + + return &model.Card{ + Prefix: prefix, + Number: number, + }, nil +} + +func (s *Schedule) DumpToDb(store model.Store) error { + // var err error + count := int64(0) + for i := range s.data { + count += int64(len(s.data[i])) + } + + bar := progressbar.Default(count, "dumping yaml flights") + + for date := range s.data { + for flightID, flightInfo := range s.data[date] { + + // fmt.Printf("%+v %+v %+v\n", date, flightID, flightInfo) + var wg sync.WaitGroup + sem := make(chan struct{}, 8) + for cardID := range flightInfo.FF { + wg.Add(1) + sem <- struct{}{} + go func() { + defer func() { <-sem }() + defer wg.Done() + defer bar.Add(1) + + card, err := createCard(cardID) + if err != nil { + fmt.Println(err) + // return + } + if card != nil { + card, err = store.SaveCard(card) + if err != nil { + fmt.Println(err) + // return + } + } + + f, err := createFlight(flightID, flightInfo.From, flightInfo.To, date, card.ID) + if err != nil { + fmt.Println(err) + return + } + if card != nil { + f.UserID = card.UserID + } + if f != nil { + _, err = store.SaveFlight(f) + if err != nil { + fmt.Println(err) + return + } + } + }() + } + wg.Wait() + } + } + return nil +} -- cgit v1.2.3