Skip to content

Commit

Permalink
Add "find for date" methods (#3)
Browse files Browse the repository at this point in the history
* snapshot: start blocking out FindGateForDateWithLookup, still not sure how/where to deal with dates

* snapshot: store inception/cessation for gates and terminals just like galleries; still need to update compile code

* snapshot: compile terminals and gates with EDTF dates

* snapshot: start working on TestFindGateForDate

* snapshot: working through gates for date stuff, found a hiccup in EDTF code

* update sfomuseum/go-edtf

* current galleries

* terminals for date

* snapshot: better printing

* sort by inception/cessation in Find implementations

---------

Co-authored-by: sfomuseumbot <sfomuseumbot@localhost>
  • Loading branch information
thisisaaronland and sfomuseumbot authored Jul 25, 2024
1 parent e29025f commit 234b22c
Show file tree
Hide file tree
Showing 23 changed files with 564 additions and 32 deletions.
4 changes: 2 additions & 2 deletions cmd/lookup/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ func main() {
log.Fatal(err)
}

for _, a := range results {
fmt.Println(a)
for _, r := range results {
fmt.Println(r)
}
}
}
4 changes: 2 additions & 2 deletions data/galleries.json

Large diffs are not rendered by default.

7 changes: 2 additions & 5 deletions data/gates.json

Large diffs are not rendered by default.

6 changes: 2 additions & 4 deletions data/terminals.json

Large diffs are not rendered by default.

87 changes: 86 additions & 1 deletion galleries/galleries.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ package galleries
import (
"context"
"fmt"
"log/slog"

"github.com/sfomuseum/go-edtf/cmp"
"github.com/sfomuseum/go-sfomuseum-architecture"
)

Expand All @@ -28,7 +30,31 @@ type Gallery struct {

// String() will return the name of the gallery.
func (g *Gallery) String() string {
return fmt.Sprintf("%d#%d %s-%s %s", g.WhosOnFirstId, g.SFOMuseumId, g.Inception, g.Cessation, g.Name)
return fmt.Sprintf("%d#%d %s %s-%s (%d)", g.WhosOnFirstId, g.SFOMuseumId, g.Name, g.Inception, g.Cessation, g.IsCurrent)
}

// Return the Gallery matching 'code' that was active for 'date'. Multiple matches throw an error.
func FindGalleryForDate(ctx context.Context, code string, date string) (*Gallery, error) {

lookup, err := NewLookup(ctx, "")

if err != nil {
return nil, fmt.Errorf("Failed to create new lookup, %w", err)
}

return FindGalleryForDateWithLookup(ctx, lookup, code, date)
}

// Return all the Galleries matching 'code' that were active for 'date'.
func FindAllGalleriesForDate(ctx context.Context, code string, date string) ([]*Gallery, error) {

lookup, err := NewLookup(ctx, "")

if err != nil {
return nil, fmt.Errorf("Failed to create new lookup, %w", err)
}

return FindAllGalleriesForDateWithLookup(ctx, lookup, code, date)
}

// Return the current Gallery matching 'code'. Multiple matches throw an error.
Expand Down Expand Up @@ -100,3 +126,62 @@ func FindGalleriesCurrentWithLookup(ctx context.Context, lookup architecture.Loo

return current, nil
}

// Return the Gallery matching 'code' that was active for 'date' using 'lookup'. Multiple matches throw an error.
func FindGalleryForDateWithLookup(ctx context.Context, lookup architecture.Lookup, code string, date string) (*Gallery, error) {

galleries, err := FindAllGalleriesForDateWithLookup(ctx, lookup, code, date)

if err != nil {
return nil, err
}

switch len(galleries) {
case 0:
return nil, NotFound{code}
case 1:
return galleries[0], nil
default:
return nil, MultipleCandidates{code}
}

}

// Return all the Gallerys matching 'code' that were active for 'date' using 'lookup'.
func FindAllGalleriesForDateWithLookup(ctx context.Context, lookup architecture.Lookup, code string, date string) ([]*Gallery, error) {

rsp, err := lookup.Find(ctx, code)

if err != nil {
return nil, fmt.Errorf("Failed to find gallerys for code, %w", err)
}

galleries := make([]*Gallery, 0)

for _, r := range rsp {

g := r.(*Gallery)

inception := g.Inception
cessation := g.Cessation

is_between, err := cmp.IsBetween(date, inception, cessation)

if err != nil {
slog.Debug("Failed to determine whether gallery matches date conditions", "code", code, "date", date, "gallery", g.Name, "inception", inception, "cessation", cessation, "error", err)
continue
}

if !is_between {
slog.Debug("Gallery does not match date conditions", "code", code, "date", date, "gallery", g.Name, "inception", inception, "cessation", cessation)
continue
}

slog.Debug("Gallery DOES match date conditions", "code", code, "date", date, "gallery", g.Name, "inception", inception, "cessation", cessation)
galleries = append(galleries, g)
break
}

slog.Debug("Return galleries", "code", code, "date", date, "count", len(galleries))
return galleries, nil
}
39 changes: 38 additions & 1 deletion galleries/galleries_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,20 @@ package galleries
import (
"context"
"testing"
// "log/slog"
)

type galleryTest struct {
Id int64
Code string
Date string
}

func TestFindCurrentGallery(t *testing.T) {

tests := map[string]int64{
"2E": 1763594985, // Kadish Gallery
// "2E": 1763594985, // Kadish Gallery
"2E": 1914601395,
}

ctx := context.Background()
Expand All @@ -26,3 +34,32 @@ func TestFindCurrentGallery(t *testing.T) {
}
}
}

func TestFindGalleryForDate(t *testing.T) {

// slog.SetLogLoggerLevel(slog.LevelDebug)

tests := []*galleryTest{
&galleryTest{Id: 1763594985, Code: "2E", Date: "2022"},
&galleryTest{Id: 1914650743, Code: "1G", Date: "2024-07-23"},
&galleryTest{Id: 1914600907, Code: "3F", Date: "2024-06-18"},
&galleryTest{Id: 1360392589, Code: "F04", Date: "2002"},
// &galleryTest{Id: 1159157059, Code: "F-04", Date: "2017-12~"},
}

ctx := context.Background()

for _, gallery := range tests {

g, err := FindGalleryForDate(ctx, gallery.Code, gallery.Date)

if err != nil {
t.Fatalf("Failed to find gallery %s for %s, %v", gallery.Code, gallery.Date, err)
}

if g.WhosOnFirstId != gallery.Id {
t.Fatalf("Unexpected ID for gallery %s. Got %d but expected %d", gallery.Code, g.WhosOnFirstId, gallery.Id)
}
}

}
26 changes: 23 additions & 3 deletions galleries/lookup.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import (
"encoding/json"
"fmt"
"io"
_ "log"
"net/http"
"net/url"
"sort"
"strconv"
"strings"
"sync"
Expand Down Expand Up @@ -180,7 +180,7 @@ func (l *GalleriesLookup) Find(ctx context.Context, code string) ([]interface{},
return nil, fmt.Errorf("Code '%s' not found", code)
}

galleries_list := make([]interface{}, 0)
galleries := make([]*Gallery, 0)

for _, p := range pointers.([]string) {

Expand All @@ -194,7 +194,27 @@ func (l *GalleriesLookup) Find(ctx context.Context, code string) ([]interface{},
return nil, fmt.Errorf("Invalid pointer '%s'", p)
}

galleries_list = append(galleries_list, row.(*Gallery))
galleries = append(galleries, row.(*Gallery))
}

sort.Slice(galleries, func(i, j int) bool {

inception_i := galleries[i].Inception
cessation_i := galleries[i].Cessation

inception_j := galleries[j].Inception
cessation_j := galleries[j].Cessation

date_i := fmt.Sprintf("%s - %s", inception_i, cessation_i)
date_j := fmt.Sprintf("%s - %s", inception_j, cessation_j)

return date_i < date_j
})

galleries_list := make([]interface{}, len(galleries))

for idx, g := range galleries {
galleries_list[idx] = g
}

return galleries_list, nil
Expand Down
3 changes: 2 additions & 1 deletion galleries/lookup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ func TestGalleriesLookup(t *testing.T) {
*/

wofid_tests := map[string]int64{
"2D": 1745882459, // 2D Sky Terrace Platform
// "2D": 1745882459, // 2D Sky Terrace Platform
"2D": 1729813701,
}

ctx := context.Background()
Expand Down
5 changes: 5 additions & 0 deletions gates/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,15 @@ func CompileGatesData(ctx context.Context, iterator_uri string, iterator_sources
return fmt.Errorf("Failed to determine is current for %s, %v", path, err)
}

inception := properties.Inception(body)
cessation := properties.Cessation(body)

g := &Gate{
WhosOnFirstId: wof_id,
Name: wof_name,
IsCurrent: fl.Flag(),
Inception: inception,
Cessation: cessation,
}

mu.Lock()
Expand Down
94 changes: 93 additions & 1 deletion gates/gates.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@ package gates
import (
"context"
"fmt"
"log/slog"

"github.com/sfomuseum/go-edtf/cmp"
"github.com/sfomuseum/go-sfomuseum-architecture"
)

// To do: Make these sortable by inception/cessation
type Gates []*Gate

// type Gate is a struct representing a passenger gate at SFO.
type Gate struct {
// The Who's On First ID associated with this gate.
Expand All @@ -16,11 +21,39 @@ type Gate struct {
Name string `json:"wof:name"`
// A Who's On First "existential" (`KnownUnknownFlag`) flag signaling the gate's status
IsCurrent int64 `json:"mz:is_current"`
// The (EDTF) inception date for the gallery
Inception string `json:"edtf:inception"`
// The (EDTF) cessation date for the gallery
Cessation string `json:"edtf:cessation"`
}

// String() will return the name of the gate.
func (g *Gate) String() string {
return fmt.Sprintf("%d %s (%d)", g.WhosOnFirstId, g.Name, g.IsCurrent)
return fmt.Sprintf("%d %s %s-%s (%d)", g.WhosOnFirstId, g.Name, g.Inception, g.Cessation, g.IsCurrent)
}

// Return the Gate matching 'code' that was active for 'date'. Multiple matches throw an error.
func FindGateForDate(ctx context.Context, code string, date string) (*Gate, error) {

lookup, err := NewLookup(ctx, "")

if err != nil {
return nil, fmt.Errorf("Failed to create new lookup, %w", err)
}

return FindGateForDateWithLookup(ctx, lookup, code, date)
}

// Return all the Gates matching 'code' that were active for 'date'.
func FindAllGatesForDate(ctx context.Context, code string, date string) ([]*Gate, error) {

lookup, err := NewLookup(ctx, "")

if err != nil {
return nil, fmt.Errorf("Failed to create new lookup, %w", err)
}

return FindAllGatesForDateWithLookup(ctx, lookup, code, date)
}

// Return the current Gate matching 'code'. Multiple matches throw an error.
Expand Down Expand Up @@ -92,3 +125,62 @@ func FindGatesCurrentWithLookup(ctx context.Context, lookup architecture.Lookup,

return current, nil
}

// Return the Gate matching 'code' that was active for 'date' using 'lookup'. Multiple matches throw an error.
func FindGateForDateWithLookup(ctx context.Context, lookup architecture.Lookup, code string, date string) (*Gate, error) {

gates, err := FindAllGatesForDateWithLookup(ctx, lookup, code, date)

if err != nil {
return nil, err
}

switch len(gates) {
case 0:
return nil, NotFound{code}
case 1:
return gates[0], nil
default:
return nil, MultipleCandidates{code}
}

}

// Return all the Gates matching 'code' that were active for 'date' using 'lookup'.
func FindAllGatesForDateWithLookup(ctx context.Context, lookup architecture.Lookup, code string, date string) ([]*Gate, error) {

rsp, err := lookup.Find(ctx, code)

if err != nil {
return nil, fmt.Errorf("Failed to find gates for code, %w", err)
}

gates := make([]*Gate, 0)

for _, r := range rsp {

g := r.(*Gate)

inception := g.Inception
cessation := g.Cessation

is_between, err := cmp.IsBetween(date, inception, cessation)

if err != nil {
slog.Debug("Failed to determine whether gate matches date conditions", "code", code, "date", date, "gate", g.Name, "inception", inception, "cessation", cessation, "error", err)
continue
}

if !is_between {
slog.Debug("Gate does not match date conditions", "code", code, "date", date, "gate", g.Name, "inception", inception, "cessation", cessation)
continue
}

slog.Debug("Gate DOES match date conditions", "code", code, "date", date, "gate", g.Name, "inception", inception, "cessation", cessation)
gates = append(gates, g)
break
}

slog.Debug("Return gates", "code", code, "date", date, "count", len(gates))
return gates, nil
}
Loading

0 comments on commit 234b22c

Please sign in to comment.