From ba7ee88e5c5cdb4f382c44da384ba1d11709d944 Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Sat, 22 Jun 2024 12:18:08 -0700 Subject: [PATCH] Create parents in airtable --- airtable.go | 45 ++++++++++++++++++++++++++++++++++++++ go.mod | 2 ++ go.sum | 2 ++ sync.go | 62 ++++++++++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 106 insertions(+), 5 deletions(-) create mode 100644 airtable.go create mode 100644 go.sum diff --git a/airtable.go b/airtable.go new file mode 100644 index 0000000..4341368 --- /dev/null +++ b/airtable.go @@ -0,0 +1,45 @@ +package main + +import ( + "fmt" + "os" + + "github.com/mehanizm/airtable" +) + +type AirtableRecord = airtable.Record +type AirtableRecords = airtable.Records + +type Airtable struct { + c *airtable.Client +} + +func NewAirtableFromEnv() (*Airtable, error) { + airtableToken := os.Getenv("AIRTABLE_TOKEN") + if airtableToken == "" { + return nil, fmt.Errorf("please set $AIRTABLE_TOKEN") + } + + return &Airtable{ + c: airtable.NewClient(airtableToken), + }, nil +} + +func (at *Airtable) GetBaseID(name string) (string, error) { + bases, err := at.c.GetBases().WithOffset("").Do() + if err != nil { + return "", fmt.Errorf("failed to get bases: %w", err) + } + + for _, base := range bases.Bases { + if base.Name == name { + return base.ID, nil + } + } + + return "", fmt.Errorf("base not found: %s", name) +} + +func (at *Airtable) GetTable(baseID, name string) (*airtable.Table, error) { + return at.c.GetTable(baseID, name), nil +} diff --git a/go.mod b/go.mod index 3ffcbf9..c3093ad 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module github.com/flamingcow66/helios-data-pipeline go 1.22.4 + +require github.com/mehanizm/airtable v0.3.1 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..f1cdaa3 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/mehanizm/airtable v0.3.1 h1:PyuSukkZScm9/onHqJWA1/kscDjp/3c0ANsQiCdJTws= +github.com/mehanizm/airtable v0.3.1/go.mod h1:0wD9HInozzelKMw8XiY6czjsDygmAg1bzxSqAha/WLg= diff --git a/sync.go b/sync.go index 22f9b8b..541f9c3 100644 --- a/sync.go +++ b/sync.go @@ -17,8 +17,8 @@ type Directory struct { } type Person struct { - Name string Email string + Name string } type Student struct { @@ -49,6 +49,43 @@ func main() { } l.Info("loaded directory", "directory", dir) + + at, err := NewAirtableFromEnv() + if err != nil { + fatal(l, "failed to create airtable client", "error", err) + } + + dirBaseID, err := at.GetBaseID("Directory") + if err != nil { + fatal(l, "failed to find Directory base in Airtable", "error", err) + } + + parentsTable, err := at.GetTable(dirBaseID, "Parents") + if err != nil { + fatal(l, "failed to get Parents table", "error", err) + } + + remoteParentsRecords, err := parentsTable. + GetRecords(). + FromView("Primary"). + ReturnFields("Email", "Name"). + Do() + if err != nil { + fatal(l, "failed to fetch Parents", "error", err) + } + + l.Info("tmp", "parents", remoteParentsRecords) + + localParentRecords := dir.GetParentRecords() + + for _, record := range localParentRecords { + _, err = parentsTable.AddRecords(&AirtableRecords{ + Records: []*AirtableRecord{record}, + }) + if err != nil { + fatal(l, "failed to add Parents", "error", err) + } + } } func loadDirectory(l *slog.Logger, path string) (*Directory, error) { @@ -136,7 +173,7 @@ func loadDirectory(l *slog.Logger, path string) (*Directory, error) { parents := []*Parent{} parent1 := d.AddParent( - row[iParent1Email], + strings.ToLower(row[iParent1Email]), fmt.Sprintf("%s %s", row[iParent1FirstName], row[iParent1LastName]), ) @@ -144,7 +181,7 @@ func loadDirectory(l *slog.Logger, path string) (*Directory, error) { if row[iParent2Email] != "" { parent2 := d.AddParent( - row[iParent2Email], + strings.ToLower(row[iParent2Email]), fmt.Sprintf("%s %s", row[iParent2FirstName], row[iParent2LastName]), ) @@ -182,8 +219,8 @@ func (d *Directory) AddParent(email, name string) *Parent { p = &Parent{ Person: Person{ - Name: name, Email: email, + Name: name, }, } @@ -195,8 +232,8 @@ func (d *Directory) AddParent(email, name string) *Parent { func (d *Directory) AddStudent(email, name, class, grade string, parents []*Parent) *Student { s := &Student{ Person: Person{ - Name: name, Email: email, + Name: name, }, Class: class, Grade: grade, @@ -208,6 +245,21 @@ func (d *Directory) AddStudent(email, name, class, grade string, parents []*Pare return s } +func (d *Directory) GetParentRecords() []*AirtableRecord { + records := []*AirtableRecord{} + + for _, parent := range d.Parents { + records = append(records, &AirtableRecord{ + Fields: map[string]any{ + "Email": parent.Email, + "Name": parent.Name, + }, + }) + } + + return records +} + func (p Person) String() string { return fmt.Sprintf( "%s <%s>",