fuzzyworld

find-stone-beer / commit

Renames, cleanup, and reading env vars for some settings.

74d9b69267802d8186260609df6f805b59222203 · Pavel Safronov · 2023-08-23 10:43:04 -0700 · parents c92576c819ec

Renames, cleanup, and reading env vars for some settings.
Pushover logic is now in its own file.
 .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
+}