find-stone-beer / commit
Renames, cleanup, and reading env vars for some settings.
.vscode/settings.json | 8 ++++++ README.md | 2 +- find-stone.go | 30 +++++++++++----------- main.go | 70 +++++++++++++++++++++++++++++++++++++++++++-------- pushover.go | 40 +++++++++++++++++++++++++++++ 5 files changed, 123 insertions(+), 27 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..bb71aa4 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "cSpell.words": [ + "findstone", + "geodist", + "jftuga", + "Vincenty" + ] +} \ No newline at end of file diff --git a/README.md b/README.md index 5a785b0..5886983 100755 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ secret data is in gitlab ## removed code -``` +```go testSeller, err := getSellerInfo("16826826") if err != nil { panic(err) diff --git a/find-stone.go b/find-stone.go index a721410..eb37cd9 100644 --- a/find-stone.go +++ b/find-stone.go @@ -5,18 +5,18 @@ import ( ) type Core struct { - Findstone Findstone `json:"findstone"` + Beers BeersInfo } func (c *Core) UnmarshalJSON(data []byte) error { - var objmap map[string]json.RawMessage - err := json.Unmarshal(data, &objmap) + var rawMap map[string]json.RawMessage + err := json.Unmarshal(data, &rawMap) if err != nil { return err } - for key, value := range objmap { + for key, value := range rawMap { if key == "findstone" { - err = json.Unmarshal(value, &c.Findstone) + err = json.Unmarshal(value, &c.Beers) if err != nil { return err } @@ -25,20 +25,20 @@ func (c *Core) UnmarshalJSON(data []byte) error { return nil } -type Findstone struct { - Brands map[string]Brand `json:"brands"` - PackageTypes map[string]PackageType `json:"package_types"` +type BeersInfo struct { + brands map[string]Brand + PackageTypes map[string]PackageType } -func (f *Findstone) UnmarshalJSON(data []byte) error { - var objmap map[string]json.RawMessage - err := json.Unmarshal(data, &objmap) +func (f *BeersInfo) UnmarshalJSON(data []byte) error { + var rawMap map[string]json.RawMessage + err := json.Unmarshal(data, &rawMap) if err != nil { return err } - for key, value := range objmap { + for key, value := range rawMap { if key == "brands" { - err = json.Unmarshal(value, &f.Brands) + err = json.Unmarshal(value, &f.brands) if err != nil { return err } @@ -51,8 +51,8 @@ func (f *Findstone) UnmarshalJSON(data []byte) error { } return nil } -func (f *Findstone) FindBrandById(targetId string) (bool, Brand) { - for id, brand := range f.Brands { +func (f *BeersInfo) FindBrandById(targetId string) (bool, Brand) { + for id, brand := range f.brands { if id == targetId { return true, brand } diff --git a/main.go b/main.go index 617bd1d..3faa244 100644 --- a/main.go +++ b/main.go @@ -10,6 +10,7 @@ import ( "net/http" "os" "path/filepath" + "strconv" "strings" "time" @@ -17,16 +18,31 @@ import ( "golang.org/x/net/html" ) -var coords = geodist.Coord{Lat: 47.632, Lon: -122.153} -var rangeMiles = 10 -var maxDeliveryWindowDays = 14 +const ( + COORDINATE_LAT_ENV_VAR = "COORDINATE_LAT" + COORDINATE_LON_ENV_VAR = "COORDINATE_LON" + RANGE_MILES_ENV_VAR = "RANGE_MILES" + MAX_DELIVERY_DAYS_ENV_VAR = "MAX_DELIVERY_DAYS" +) func main() { - findStoneInfo, err := getFindstoneInfo() + // coords for search area + coords, err := getCoordsFromEnvVars() if err != nil { panic(err) } + // load other settings from env vars + var rangeMiles = getEnvVarInteger(RANGE_MILES_ENV_VAR, 10) + var maxDeliveryWindowDays = getEnvVarInteger(MAX_DELIVERY_DAYS_ENV_VAR, 14) + + // descriptions of the beers and packaging + beersInfo, err := getBeersInfo() + if err != nil { + panic(err) + } + + // get sellers by location sellers, err := getSellers(coords) if err != nil { panic(err) @@ -36,7 +52,7 @@ func main() { arrogantBastardSellers := []Seller{} for _, seller := range sellers { for _, brandId := range seller.AllBrands { - foundBrand, brand := findStoneInfo.FindBrandById(brandId) + foundBrand, brand := beersInfo.FindBrandById(brandId) if foundBrand { if strings.Contains(strings.ToLower(brand.Name), "arrogant") { arrogantBastardSellers = append(arrogantBastardSellers, seller) @@ -49,7 +65,6 @@ func main() { messageSB := strings.Builder{} now := time.Now() - messageSB.WriteString(fmt.Sprintf("Found %d sellers and %d Arrogant Bastard sellers\n", len(sellers), len(arrogantBastardSellers))) for _, seller := range arrogantBastardSellers { dist, _, err := geodist.VincentyDistance(coords, seller.Pos) if err != nil { @@ -68,7 +83,7 @@ func main() { panic(err) } for _, beer := range sellerInfo.Beers { - ok, brand := findStoneInfo.FindBrandById(beer.Brand) + ok, brand := beersInfo.FindBrandById(beer.Brand) if !ok { panic("Could not find brand") } @@ -93,6 +108,39 @@ func main() { } +func getEnvVarInteger(envVarName string, defaultIfNotSet int) int { + envVarValue := os.Getenv(envVarName) + if envVarValue == "" { + fmt.Printf("Environment variable %s not set, using default value of %d\n", envVarName, defaultIfNotSet) + return defaultIfNotSet + } + intValue, err := strconv.Atoi(envVarValue) + if err != nil { + fmt.Printf("Could not parse environment variable %s as integer: %s, using default value of %d\n", envVarName, err, defaultIfNotSet) + return defaultIfNotSet + } + fmt.Printf("Using environment variable %s value of %d\n", envVarName, intValue) + return intValue +} + +func getCoordsFromEnvVars() (geodist.Coord, error) { + latStr := os.Getenv(COORDINATE_LAT_ENV_VAR) + lonStr := os.Getenv(COORDINATE_LON_ENV_VAR) + if latStr == "" || lonStr == "" { + return geodist.Coord{}, fmt.Errorf("missing environment variable %s or %s", COORDINATE_LAT_ENV_VAR, COORDINATE_LON_ENV_VAR) + } + lat, err := strconv.ParseFloat(latStr, 64) + if err != nil { + return geodist.Coord{}, err + } + lon, err := strconv.ParseFloat(lonStr, 64) + if err != nil { + return geodist.Coord{}, err + } + coords := geodist.Coord{Lat: lat, Lon: lon} + return coords, nil +} + func getSellers(coords geodist.Coord) ([]Seller, error) { lat := coords.Lat latInt := int(lat) @@ -125,7 +173,7 @@ func getSellerInfo(id string) (SellerInfo, error) { } return sellerInfo, nil } -func getFindstoneInfo() (Findstone, error) { +func getBeersInfo() (BeersInfo, error) { data, err := getCachedUrlFunc( "https://find.stonebrewing.com", "find-stone-beer-core", @@ -170,15 +218,15 @@ func getFindstoneInfo() (Findstone, error) { return []byte(jsonText), nil }) if err != nil { - return Findstone{}, err + return BeersInfo{}, err } var core = Core{} err = json.Unmarshal(data, &core) if err != nil { - return Findstone{}, err + return BeersInfo{}, err } - return core.Findstone, nil + return core.Beers, nil } func getCachedUrl(url string, id string, cacheFileTimeFormat string) ([]byte, error) { diff --git a/pushover.go b/pushover.go new file mode 100644 index 0000000..93f2a4f --- /dev/null +++ b/pushover.go @@ -0,0 +1,40 @@ +package main + +import ( + "fmt" + "net/http" + "net/url" + "os" +) + +const ( + PushoverTokenEnvVar = "PUSHOVER_TOKEN" + PushoverUserTokenEnvVar = "PUSHOVER_USER_TOKEN" +) + +func SendPushoverMessage(message string) error { + postUrl := "https://api.pushover.net/1/messages.json" + + pushoverToken := os.Getenv(PushoverTokenEnvVar) + pushoverUser := os.Getenv(PushoverUserTokenEnvVar) + if pushoverUser == "" || pushoverToken == "" { + return fmt.Errorf("missing environment variable %s or %s", PushoverUserTokenEnvVar, PushoverTokenEnvVar) + } + + response, err := http.PostForm(postUrl, url.Values{ + "token": {pushoverToken}, + "user": {pushoverUser}, + "message": {message}, + }) + + if err != nil { + return err + } + defer response.Body.Close() + + isNot200 := response.StatusCode != 200 + if isNot200 { + return fmt.Errorf("pushover returned status code %d: %s", response.StatusCode, response.Status) + } + return nil +}