aboutsummaryrefslogtreecommitdiff
path: root/pkg/adapters/yaml/yaml.go
diff options
context:
space:
mode:
authorleshe4ka46 <alex9102naid1@ya.ru>2025-10-27 20:36:28 +0300
committerleshe4ka46 <alex9102naid1@ya.ru>2025-10-28 13:42:21 +0300
commitbb833561aa74f02970aee13cdc75973b29716491 (patch)
tree0914668e11dbf825979f7419ce1bc78294cd3f7f /pkg/adapters/yaml/yaml.go
parente17a425dfb3382310fb5863f516dacdca9f44956 (diff)
# 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
Diffstat (limited to 'pkg/adapters/yaml/yaml.go')
-rw-r--r--pkg/adapters/yaml/yaml.go180
1 files changed, 180 insertions, 0 deletions
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
+}