-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add lookup support for terminals; recompile data
- Loading branch information
thisisaaronland
committed
Jun 14, 2022
1 parent
58a0156
commit 54a5224
Showing
14 changed files
with
697 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"flag" | ||
"fmt" | ||
"github.com/sfomuseum/go-sfomuseum-architecture/terminals" | ||
"io" | ||
"log" | ||
"os" | ||
) | ||
|
||
func main() { | ||
|
||
default_target := fmt.Sprintf("data/%s", terminals.DATA_JSON) | ||
|
||
iterator_uri := flag.String("iterator-uri", "repo://?include=properties.sfomuseum:placetype=terminal", "A valid whosonfirst/go-whosonfirst-iterate URI") | ||
iterator_source := flag.String("iterator-source", "/usr/local/data/sfomuseum-data-architecture", "The URI containing documents to iterate.") | ||
|
||
target := flag.String("target", default_target, "The path to write SFO Museum terminals data.") | ||
stdout := flag.Bool("stdout", false, "Emit SFO Museum terminals data to SDOUT.") | ||
|
||
flag.Parse() | ||
|
||
ctx := context.Background() | ||
|
||
writers := make([]io.Writer, 0) | ||
|
||
fh, err := os.OpenFile(*target, os.O_RDWR|os.O_CREATE, 0644) | ||
|
||
if err != nil { | ||
log.Fatalf("Failed to open '%s', %v", *target, err) | ||
} | ||
|
||
writers = append(writers, fh) | ||
|
||
if *stdout { | ||
writers = append(writers, os.Stdout) | ||
} | ||
|
||
wr := io.MultiWriter(writers...) | ||
|
||
lookup, err := terminals.CompileTerminalsData(ctx, *iterator_uri, *iterator_source) | ||
|
||
if err != nil { | ||
log.Fatalf("Failed to compile terminals data, %v", err) | ||
} | ||
|
||
enc := json.NewEncoder(wr) | ||
err = enc.Encode(lookup) | ||
|
||
if err != nil { | ||
log.Fatalf("Failed to marshal results, %v", err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
[{"wof:id":1729792579,"sfomuseum:terminal_id":"ITB","wof:name":"International Terminal","mz:is_current":0,"name:preferred":["International Terminal Building","ITB"]},{"wof:id":1745882085,"sfomuseum:terminal_id":"T2","wof:name":"Terminal 2","mz:is_current":0,"name:preferred":["Terminal 2"],"name:variant":["T2"]},{"wof:id":1745882137,"sfomuseum:terminal_id":"T1","wof:name":"Terminal 1","mz:is_current":0,"name:preferred":["T1"]},{"wof:id":1763588123,"sfomuseum:terminal_id":"T2","wof:name":"Terminal 2","mz:is_current":1,"name:preferred":["Terminal 2"],"name:variant":["T2"]},{"wof:id":1763588175,"sfomuseum:terminal_id":"T1","wof:name":"Terminal 1","mz:is_current":1,"name:preferred":["T1"]},{"wof:id":1745882335,"sfomuseum:terminal_id":"ITB","wof:name":"International Terminal","mz:is_current":0,"name:preferred":["International Terminal Building","ITB"]},{"wof:id":1763588269,"sfomuseum:terminal_id":"T3","wof:name":"Terminal 3","mz:is_current":1,"name:preferred":["T3"]},{"wof:id":1763588369,"sfomuseum:terminal_id":"ITB","wof:name":"International Terminal","mz:is_current":1,"name:preferred":["International Terminal Building","ITB"]},{"wof:id":1360521543,"sfomuseum:terminal_id":"T2","wof:name":"Terminal 2","mz:is_current":0,"name:preferred":["Terminal 2"],"name:variant":["T2"]},{"wof:id":1360521545,"sfomuseum:terminal_id":"T2","wof:name":"Terminal 2","mz:is_current":0,"name:preferred":["Terminal 2"],"name:variant":["T2"]},{"wof:id":1159554815,"sfomuseum:terminal_id":"SOUTH","wof:name":"South Terminal","mz:is_current":0},{"wof:id":1159554817,"sfomuseum:terminal_id":"SOUTH","wof:name":"South Terminal","mz:is_current":0},{"wof:id":1159554819,"sfomuseum:terminal_id":"NORTH","wof:name":"North Terminal","mz:is_current":0},{"wof:id":1159554827,"sfomuseum:terminal_id":"INTL","wof:name":"International Terminal","mz:is_current":0},{"wof:id":1159554821,"sfomuseum:terminal_id":"NORTH","wof:name":"North Terminal","mz:is_current":0},{"wof:id":1159396107,"sfomuseum:terminal_id":"ITB","wof:name":"International Terminal","mz:is_current":0},{"wof:id":1159554829,"sfomuseum:terminal_id":"INTL","wof:name":"International Terminal","mz:is_current":0},{"wof:id":1159396109,"sfomuseum:terminal_id":"T2","wof:name":"Terminal 2","mz:is_current":0},{"wof:id":1159396115,"sfomuseum:terminal_id":"T1","wof:name":"Terminal 1","mz:is_current":0},{"wof:id":1159396127,"sfomuseum:terminal_id":"SOUTH","wof:name":"South Terminal","mz:is_current":0},{"wof:id":1159396129,"sfomuseum:terminal_id":"NORTH","wof:name":"North Terminal","mz:is_current":0},{"wof:id":1159396123,"sfomuseum:terminal_id":"T3","wof:name":"Terminal 3","mz:is_current":0},{"wof:id":1159396121,"sfomuseum:terminal_id":"T2","wof:name":"Terminal 2","mz:is_current":0,"name:preferred":["Terminal 2"],"name:variant":["T2"]},{"wof:id":1159396131,"sfomuseum:terminal_id":"CENTRAL","wof:name":"Central Terminal","mz:is_current":0},{"wof:id":1159396133,"sfomuseum:terminal_id":"CENTRAL","wof:name":"Central Terminal","mz:is_current":0},{"wof:id":1159396135,"sfomuseum:terminal_id":"SOUTH","wof:name":"South Terminal","mz:is_current":0},{"wof:id":1159396139,"sfomuseum:terminal_id":"T1","wof:name":"Terminal 1","mz:is_current":0},{"wof:id":1159396143,"sfomuseum:terminal_id":"SOUTH","wof:name":"South Terminal","mz:is_current":0},{"wof:id":1159396145,"sfomuseum:terminal_id":"NORTH","wof:name":"North Terminal","mz:is_current":0},{"wof:id":1159396141,"sfomuseum:terminal_id":"T3","wof:name":"Terminal 3","mz:is_current":0},{"wof:id":1159396149,"sfomuseum:terminal_id":"CENTRAL","wof:name":"Central Terminal","mz:is_current":0},{"wof:id":1159396147,"sfomuseum:terminal_id":"ITB","wof:name":"International Terminal","mz:is_current":0},{"wof:id":1159396151,"sfomuseum:terminal_id":"T1","wof:name":"Terminal 1","mz:is_current":0},{"wof:id":1159396153,"sfomuseum:terminal_id":"ITB","wof:name":"International Terminal","mz:is_current":0},{"wof:id":1159396163,"sfomuseum:terminal_id":"T1","wof:name":"Terminal 1","mz:is_current":0},{"wof:id":1159396157,"sfomuseum:terminal_id":"T3","wof:name":"Terminal 3","mz:is_current":0},{"wof:id":1159396165,"sfomuseum:terminal_id":"CENTRAL","wof:name":"Central Terminal","mz:is_current":0},{"wof:id":1159157307,"sfomuseum:terminal_id":"T3","wof:name":"Terminal 3","mz:is_current":0,"name:preferred":["T3"]},{"wof:id":1159396167,"sfomuseum:terminal_id":"T3","wof:name":"Terminal 3","mz:is_current":0},{"wof:id":1159396169,"sfomuseum:terminal_id":"SOUTH","wof:name":"South Terminal","mz:is_current":0},{"wof:id":1159396159,"sfomuseum:terminal_id":"ITB","wof:name":"International Terminal","mz:is_current":0},{"wof:id":1159396171,"sfomuseum:terminal_id":"CENTRAL","wof:name":"Central Terminal","mz:is_current":0},{"wof:id":1159157317,"sfomuseum:terminal_id":"T1","wof:name":"Terminal 1","mz:is_current":0,"name:preferred":["T1"]},{"wof:id":1159157325,"sfomuseum:terminal_id":"T2","wof:name":"Terminal 2","mz:is_current":0,"name:preferred":["Terminal 2"],"name:variant":["T2"]},{"wof:id":1159157333,"sfomuseum:terminal_id":"ITB","wof:name":"International Terminal","mz:is_current":0,"name:preferred":["International Terminal Building","ITB"]},{"wof:id":1477855607,"sfomuseum:terminal_id":"T2","wof:name":"Terminal 2","mz:is_current":0,"name:preferred":["Terminal 2"],"name:variant":["T2"]},{"wof:id":1477855657,"sfomuseum:terminal_id":"T1","wof:name":"Terminal 1","mz:is_current":0,"name:preferred":["T1"]},{"wof:id":1477855699,"sfomuseum:terminal_id":"T3","wof:name":"Terminal 3","mz:is_current":0,"name:preferred":["T3"]},{"wof:id":1477855833,"sfomuseum:terminal_id":"ITB","wof:name":"International Terminal","mz:is_current":0,"name:preferred":["International Terminal Building","ITB"]},{"wof:id":1729792389,"sfomuseum:terminal_id":"T2","wof:name":"Terminal 2","mz:is_current":0,"name:preferred":["Terminal 2"],"name:variant":["T2"]},{"wof:id":1729792435,"sfomuseum:terminal_id":"T1","wof:name":"Terminal 1","mz:is_current":0,"name:preferred":["T1"]},{"wof:id":1729792487,"sfomuseum:terminal_id":"T3","wof:name":"Terminal 3","mz:is_current":0,"name:preferred":["T3"]},{"wof:id":1745882233,"sfomuseum:terminal_id":"T3","wof:name":"Terminal 3","mz:is_current":0,"name:preferred":["T3"]}] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
package terminals | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"github.com/tidwall/gjson" | ||
"github.com/whosonfirst/go-whosonfirst-feature/properties" | ||
"github.com/whosonfirst/go-whosonfirst-iterate/v2/iterator" | ||
"github.com/whosonfirst/go-whosonfirst-uri" | ||
"io" | ||
"strings" | ||
"sync" | ||
) | ||
|
||
// CompileTerminalsData will generate a list of `Terminal` struct to be used as the source data for an `SFOMuseumLookup` instance. | ||
// The list of terminal are compiled by iterating over one or more source. `iterator_uri` is a valid `whosonfirst/go-whosonfirst-iterate` URI | ||
// and `iterator_sources` are one more (iterator) URIs to process. | ||
func CompileTerminalsData(ctx context.Context, iterator_uri string, iterator_sources ...string) ([]*Terminal, error) { | ||
|
||
lookup := make([]*Terminal, 0) | ||
mu := new(sync.RWMutex) | ||
|
||
iter_cb := func(ctx context.Context, path string, fh io.ReadSeeker, args ...interface{}) error { | ||
|
||
select { | ||
case <-ctx.Done(): | ||
return nil | ||
default: | ||
// pass | ||
} | ||
|
||
_, uri_args, err := uri.ParseURI(path) | ||
|
||
if err != nil { | ||
return fmt.Errorf("Failed to parse %s, %w", path, err) | ||
} | ||
|
||
if uri_args.IsAlternate { | ||
return nil | ||
} | ||
|
||
body, err := io.ReadAll(fh) | ||
|
||
if err != nil { | ||
return fmt.Errorf("Failed to read %s, %w", path, err) | ||
} | ||
|
||
wof_id, err := properties.Id(body) | ||
|
||
if err != nil { | ||
return fmt.Errorf("Failed to derive ID for %s, %w", path, err) | ||
} | ||
|
||
wof_name, err := properties.Name(body) | ||
|
||
if err != nil { | ||
return fmt.Errorf("Failed to derive name for %s, %w", path, err) | ||
} | ||
|
||
fl, err := properties.IsCurrent(body) | ||
|
||
if err != nil { | ||
return fmt.Errorf("Failed to determine is current for %s, %v", path, err) | ||
} | ||
|
||
preferred_names := make([]string, 0) | ||
variant_names := make([]string, 0) | ||
|
||
names := properties.Names(body) | ||
|
||
for k, k_names := range names { | ||
|
||
if strings.HasSuffix(k, "_preferred") { | ||
|
||
for _, n := range k_names { | ||
preferred_names = append(preferred_names, n) | ||
} | ||
} else if strings.HasSuffix(k, "_variant") { | ||
|
||
for _, n := range k_names { | ||
variant_names = append(variant_names, n) | ||
} | ||
} else { | ||
} | ||
|
||
} | ||
|
||
g := &Terminal{ | ||
WhosOnFirstId: wof_id, | ||
Name: wof_name, | ||
IsCurrent: fl.Flag(), | ||
PreferredNames: preferred_names, | ||
VariantNames: variant_names, | ||
} | ||
|
||
sfom_rsp := gjson.GetBytes(body, "properties.sfomuseum:terminal_id") | ||
|
||
if sfom_rsp.Exists() { | ||
g.SFOMuseumId = sfom_rsp.String() | ||
} | ||
|
||
mu.Lock() | ||
lookup = append(lookup, g) | ||
mu.Unlock() | ||
|
||
return nil | ||
} | ||
|
||
iter, err := iterator.NewIterator(ctx, iterator_uri, iter_cb) | ||
|
||
if err != nil { | ||
return nil, fmt.Errorf("Failed to create iterator, %w", err) | ||
} | ||
|
||
err = iter.IterateURIs(ctx, iterator_sources...) | ||
|
||
if err != nil { | ||
return nil, fmt.Errorf("Failed to iterate sources, %w", err) | ||
} | ||
|
||
return lookup, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package terminals | ||
|
||
import ( | ||
"fmt" | ||
) | ||
|
||
type NotFound struct{ code string } | ||
|
||
func (e NotFound) Error() string { | ||
return fmt.Sprintf("Terminal '%s' not found", e.code) | ||
} | ||
|
||
func (e NotFound) String() string { | ||
return e.Error() | ||
} | ||
|
||
type MultipleCandidates struct{ code string } | ||
|
||
func (e MultipleCandidates) Error() string { | ||
return fmt.Sprintf("Multiple candidates for terminal '%s'", e.code) | ||
} | ||
|
||
func (e MultipleCandidates) String() string { | ||
return e.Error() | ||
} | ||
|
||
func IsNotFound(e error) bool { | ||
|
||
switch e.(type) { | ||
case NotFound, *NotFound: | ||
return true | ||
default: | ||
return false | ||
} | ||
} | ||
|
||
func IsMultipleCandidates(e error) bool { | ||
|
||
switch e.(type) { | ||
case MultipleCandidates, *MultipleCandidates: | ||
return true | ||
default: | ||
return false | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package terminals | ||
|
||
import ( | ||
_ "fmt" | ||
"testing" | ||
) | ||
|
||
func TestNotFound(t *testing.T) { | ||
|
||
e := NotFound{"T2"} | ||
|
||
if !IsNotFound(e) { | ||
t.Fatalf("Expected NotFound error") | ||
} | ||
|
||
if e.String() != "Terminal 'T2' not found" { | ||
t.Fatalf("Invalid stringification") | ||
} | ||
} | ||
|
||
func TestMultipleCandidates(t *testing.T) { | ||
|
||
e := MultipleCandidates{"T2"} | ||
|
||
if !IsMultipleCandidates(e) { | ||
t.Fatalf("Expected MultipleCandidates error") | ||
} | ||
|
||
if e.String() != "Multiple candidates for terminal 'T2'" { | ||
t.Fatalf("Invalid stringification") | ||
} | ||
} |
Oops, something went wrong.