Create parents in airtable
This commit is contained in:
45
airtable.go
Normal file
45
airtable.go
Normal file
@@ -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
|
||||||
|
}
|
||||||
2
go.mod
2
go.mod
@@ -1,3 +1,5 @@
|
|||||||
module github.com/flamingcow66/helios-data-pipeline
|
module github.com/flamingcow66/helios-data-pipeline
|
||||||
|
|
||||||
go 1.22.4
|
go 1.22.4
|
||||||
|
|
||||||
|
require github.com/mehanizm/airtable v0.3.1
|
||||||
|
|||||||
2
go.sum
Normal file
2
go.sum
Normal file
@@ -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=
|
||||||
62
sync.go
62
sync.go
@@ -17,8 +17,8 @@ type Directory struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Person struct {
|
type Person struct {
|
||||||
Name string
|
|
||||||
Email string
|
Email string
|
||||||
|
Name string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Student struct {
|
type Student struct {
|
||||||
@@ -49,6 +49,43 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
l.Info("loaded directory", "directory", dir)
|
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) {
|
func loadDirectory(l *slog.Logger, path string) (*Directory, error) {
|
||||||
@@ -136,7 +173,7 @@ func loadDirectory(l *slog.Logger, path string) (*Directory, error) {
|
|||||||
parents := []*Parent{}
|
parents := []*Parent{}
|
||||||
|
|
||||||
parent1 := d.AddParent(
|
parent1 := d.AddParent(
|
||||||
row[iParent1Email],
|
strings.ToLower(row[iParent1Email]),
|
||||||
fmt.Sprintf("%s %s", row[iParent1FirstName], row[iParent1LastName]),
|
fmt.Sprintf("%s %s", row[iParent1FirstName], row[iParent1LastName]),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -144,7 +181,7 @@ func loadDirectory(l *slog.Logger, path string) (*Directory, error) {
|
|||||||
|
|
||||||
if row[iParent2Email] != "" {
|
if row[iParent2Email] != "" {
|
||||||
parent2 := d.AddParent(
|
parent2 := d.AddParent(
|
||||||
row[iParent2Email],
|
strings.ToLower(row[iParent2Email]),
|
||||||
fmt.Sprintf("%s %s", row[iParent2FirstName], row[iParent2LastName]),
|
fmt.Sprintf("%s %s", row[iParent2FirstName], row[iParent2LastName]),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -182,8 +219,8 @@ func (d *Directory) AddParent(email, name string) *Parent {
|
|||||||
|
|
||||||
p = &Parent{
|
p = &Parent{
|
||||||
Person: Person{
|
Person: Person{
|
||||||
Name: name,
|
|
||||||
Email: email,
|
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 {
|
func (d *Directory) AddStudent(email, name, class, grade string, parents []*Parent) *Student {
|
||||||
s := &Student{
|
s := &Student{
|
||||||
Person: Person{
|
Person: Person{
|
||||||
Name: name,
|
|
||||||
Email: email,
|
Email: email,
|
||||||
|
Name: name,
|
||||||
},
|
},
|
||||||
Class: class,
|
Class: class,
|
||||||
Grade: grade,
|
Grade: grade,
|
||||||
@@ -208,6 +245,21 @@ func (d *Directory) AddStudent(email, name, class, grade string, parents []*Pare
|
|||||||
return s
|
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 {
|
func (p Person) String() string {
|
||||||
return fmt.Sprintf(
|
return fmt.Sprintf(
|
||||||
"%s <%s>",
|
"%s <%s>",
|
||||||
|
|||||||
Reference in New Issue
Block a user