From 79e067a8f5758a3eb1957403be90ef1a9a4c4d17 Mon Sep 17 00:00:00 2001 From: Florian Baumann Date: Mon, 6 Feb 2023 17:07:51 +0100 Subject: [PATCH] Add dynamic currency picking mechanics --- readme.md | 1 + src/serra/card.go | 12 ++++++++---- src/serra/env.go | 28 ++++++++++++++++++++++++++++ src/serra/gains.go | 1 + src/serra/helpers.go | 14 +++++++++----- src/serra/scryfall.go | 8 ++++++++ src/serra/set.go | 16 +++++++++------- src/serra/stats.go | 4 ++-- src/serra/storage.go | 20 +++++++++++++++----- 9 files changed, 81 insertions(+), 23 deletions(-) create mode 100644 src/serra/env.go diff --git a/readme.md b/readme.md index e4b0979..0a0fbce 100644 --- a/readme.md +++ b/readme.md @@ -41,6 +41,7 @@ setup included in this Repo: docker-compose up -d export MONGODB_URI='mongodb://root:root@localhost:27017' + export SERRA_CURRENCY=USD # or EUR After that, you can add a card diff --git a/src/serra/card.go b/src/serra/card.go index 43bdde6..4df2cbb 100644 --- a/src/serra/card.go +++ b/src/serra/card.go @@ -71,7 +71,11 @@ func Cards(rarity, set, sort, name string) { var sortStage bson.D switch sort { case "value": - sortStage = bson.D{{"prices.eur", 1}} + if getCurrency() == "USD" { + sortStage = bson.D{{"prices.usd", 1}} + } else { + sortStage = bson.D{{"prices.eur", 1}} + } case "number": sortStage = bson.D{{"collectornumber", 1}} case "name": @@ -93,9 +97,9 @@ func Cards(rarity, set, sort, name string) { cards, _ := coll.storage_find(filter, sortStage) for _, card := range cards { - LogMessage(fmt.Sprintf("* %dx %s%s%s (%s/%s) %s%.2f EUR%s", card.SerraCount, Purple, card.Name, Reset, card.Set, card.CollectorNumber, Yellow, card.Prices.Eur, Reset), "normal") - total = total + card.Prices.Eur*float64(card.SerraCount) + LogMessage(fmt.Sprintf("* %dx %s%s%s (%s/%s) %s%.2f %s%s", card.SerraCount, Purple, card.Name, Reset, card.Set, card.CollectorNumber, Yellow, card.getValue(), getCurrency(), Reset), "normal") + total = total + card.getValue()*float64(card.SerraCount) } - fmt.Printf("\nTotal Value: %s%.2f EUR%s\n", Yellow, total, Reset) + fmt.Printf("\nTotal Value: %s%.2f %s%s\n", Yellow, total, getCurrency(), Reset) } diff --git a/src/serra/env.go b/src/serra/env.go new file mode 100644 index 0000000..d4c48f4 --- /dev/null +++ b/src/serra/env.go @@ -0,0 +1,28 @@ +package serra + +import ( + "log" + "os" +) + +func getMongoDBURI() string { + uri := os.Getenv("MONGODB_URI") + if uri == "" { + log.Fatal("You must set your 'MONGODB_URI' environmental variable. See\n\t https://docs.mongodb.com/drivers/go/current/usage-examples/#environment-variable") + } + return uri +} + +// Returns configured human readable name for +// the configured currency of the user +func getCurrency() string { + switch os.Getenv("SERRA_CURRENCY") { + case "EUR": + return "EUR" + case "USD": + return "USD" + } + // default + LogMessage("Warning: You did not configure SERRA_CURRENCY. Assuming \"USD\"", "yellow") + return "USD" +} diff --git a/src/serra/gains.go b/src/serra/gains.go index 645ebe8..9709eef 100644 --- a/src/serra/gains.go +++ b/src/serra/gains.go @@ -49,6 +49,7 @@ func Gains(limit float64, sort int, since string) error { old, _ := strconv.Atoi(since) + // TODO redo this calculation raise_pipeline := mongo.Pipeline{ bson.D{{"$project", bson.D{ diff --git a/src/serra/helpers.go b/src/serra/helpers.go index b781b86..ee252a7 100644 --- a/src/serra/helpers.go +++ b/src/serra/helpers.go @@ -95,7 +95,7 @@ func show_card_details(card *Card) error { fmt.Printf("Count: %dx\n", card.SerraCount) fmt.Printf("Rarity: %s\n", card.Rarity) fmt.Printf("Scryfall: %s\n", strings.Replace(card.ScryfallURI, "?utm_source=api", "", 1)) - fmt.Printf("Current Value: %s%.2f EUR%s\n", Yellow, card.Prices.Eur, Reset) + fmt.Printf("Current Value: %s%.2f %s%s\n", Yellow, card.getValue(), getCurrency(), Reset) fmt.Printf("\n%sHistory%s\n", Green, Reset) print_price_history(card.SerraPrices, "* ") @@ -167,13 +167,17 @@ func print_price_history(prices []PriceEntry, prefix string) { for _, e := range prices { // TODO: Make currency configurable - value := e.Eur + value := e.Usd + if getCurrency() == "EUR" { + value = e.Eur + } + if value > before && before != 0 { - fmt.Printf("%s%s%s %.2f EUR%s (%+.2f%%)\n", prefix, stringToTime(e.Date), Green, value, Reset, (value/before*100)-100) + fmt.Printf("%s%s%s %.2f %s%s (%+.2f%%)\n", prefix, stringToTime(e.Date), Green, value, getCurrency(), Reset, (value/before*100)-100) } else if value < before { - fmt.Printf("%s%s%s %.2f EUR%s (%+.2f%%)\n", prefix, stringToTime(e.Date), Red, value, Reset, (value/before*100)-100) + fmt.Printf("%s%s%s %.2f %s%s (%+.2f%%)\n", prefix, stringToTime(e.Date), Red, value, getCurrency(), Reset, (value/before*100)-100) } else { - fmt.Printf("%s%s %.2f EUR%s\n", prefix, stringToTime(e.Date), value, Reset) + fmt.Printf("%s%s %.2f %s%s\n", prefix, stringToTime(e.Date), value, getCurrency(), Reset) } before = value } diff --git a/src/serra/scryfall.go b/src/serra/scryfall.go index 79f0839..80beb27 100644 --- a/src/serra/scryfall.go +++ b/src/serra/scryfall.go @@ -119,6 +119,14 @@ type Card struct { Variation bool `json:"variation"` } +// Getter for currency specific value +func (c Card) getValue() float64 { + if getCurrency() == "EUR" { + return c.Prices.Eur + } + return c.Prices.Usd +} + type PriceEntry struct { Date primitive.DateTime `bson:"date"` Eur float64 `json:"eur,string" bson:"eur,float64"` diff --git a/src/serra/set.go b/src/serra/set.go index 4681469..eed5701 100644 --- a/src/serra/set.go +++ b/src/serra/set.go @@ -41,7 +41,7 @@ func Sets() { groupStage := bson.D{ {"$group", bson.D{ {"_id", "$setname"}, - {"value", bson.D{{"$sum", bson.D{{"$multiply", bson.A{"$prices.eur", "$serra_count"}}}}}}, + {"value", bson.D{{"$sum", bson.D{{"$multiply", bson.A{getCurrencyField(), "$serra_count"}}}}}}, {"count", bson.D{{"$sum", bson.D{{"$multiply", bson.A{1.0, "$serra_count"}}}}}}, {"unique", bson.D{{"$sum", 1}}}, {"code", bson.D{{"$last", "$set"}}}, @@ -68,7 +68,7 @@ func Sets() { setobj, _ := find_set_by_code(setscoll, set["code"].(string)) fmt.Printf("* %s %s%s%s (%s%s%s)\n", set["release"].(string)[0:4], Purple, set["_id"], Reset, Cyan, set["code"], Reset) fmt.Printf(" Cards: %s%d/%d%s Total: %.0f \n", Yellow, set["unique"], setobj.CardCount, Reset, set["count"]) - fmt.Printf(" Value: %s%.2f EUR%s\n", Pink, set["value"], Reset) + fmt.Printf(" Value: %s%.2f %s%s\n", Pink, set["value"], getCurrency(), Reset) fmt.Println() } @@ -81,7 +81,7 @@ func ShowSet(setname string) error { defer storage_disconnect(client) // fetch all cards in set - cards, err := coll.storage_find(bson.D{{"set", setname}}, bson.D{{"prices.eur", -1}}) + cards, err := coll.storage_find(bson.D{{"set", setname}}, bson.D{{getCurrencyField(), -1}}) if (err != nil) || len(cards) == 0 { LogMessage(fmt.Sprintf("Error: Set %s not found or no card in your collection.", setname), "red") return err @@ -100,7 +100,7 @@ func ShowSet(setname string) error { groupStage := bson.D{ {"$group", bson.D{ {"_id", "$setname"}, - {"value", bson.D{{"$sum", bson.D{{"$multiply", bson.A{"$prices.eur", "$serra_count"}}}}}}, + {"value", bson.D{{"$sum", bson.D{{"$multiply", bson.A{getCurrencyField(), "$serra_count"}}}}}}, {"count", bson.D{{"$sum", bson.D{{"$multiply", bson.A{1.0, "$serra_count"}}}}}}, }}, } @@ -125,11 +125,12 @@ func ShowSet(setname string) error { rar, _ := coll.storage_aggregate(mongo.Pipeline{matchStage, groupStage, sortStage}) ri := convert_rarities(rar) + c := getCurrency() LogMessage(fmt.Sprintf("%s", sets[0].Name), "green") LogMessage(fmt.Sprintf("Set Cards: %d/%d", len(cards), sets[0].CardCount), "normal") LogMessage(fmt.Sprintf("Total Cards: %.0f", stats[0]["count"]), "normal") - LogMessage(fmt.Sprintf("Total Value: %.2f EUR", stats[0]["value"]), "normal") + LogMessage(fmt.Sprintf("Total Value: %.2f %s", stats[0]["value"], c), "normal") LogMessage(fmt.Sprintf("Released: %s", sets[0].ReleasedAt), "normal") LogMessage(fmt.Sprintf("Mythics: %.0f", ri.Mythics), "normal") LogMessage(fmt.Sprintf("Rares: %.0f", ri.Rares), "normal") @@ -139,17 +140,18 @@ func ShowSet(setname string) error { print_price_history(sets[0].SerraPrices, "* ") fmt.Printf("\n%sMost valuable cards%s\n", Pink, Reset) + + // Calc counter to show 10 cards or less ccards := 0 if len(cards) < 10 { ccards = len(cards) - } else { ccards = 10 } for i := 0; i < ccards; i++ { card := cards[i] - fmt.Printf("* %dx %s%s%s (%s/%s) %s%.2f EUR%s\n", card.SerraCount, Purple, card.Name, Reset, sets[0].Code, card.CollectorNumber, Yellow, card.Prices.Eur, Reset) + fmt.Printf("* %dx %s%s%s (%s/%s) %s%.2f %s%s\n", card.SerraCount, Purple, card.Name, Reset, sets[0].Code, card.CollectorNumber, Yellow, card.getValue(), c, Reset) } return nil diff --git a/src/serra/stats.go b/src/serra/stats.go index 51cba3e..48d69a5 100644 --- a/src/serra/stats.go +++ b/src/serra/stats.go @@ -50,7 +50,7 @@ var statsCmd = &cobra.Command{ bson.D{ {"$group", bson.D{ {"_id", nil}, - {"value", bson.D{{"$sum", bson.D{{"$multiply", bson.A{"$prices.eur", "$serra_count"}}}}}}, + {"value", bson.D{{"$sum", bson.D{{"$multiply", bson.A{getCurrencyField(), "$serra_count"}}}}}}, {"count", bson.D{{"$sum", bson.D{{"$multiply", bson.A{1.0, "$serra_count"}}}}}}, {"count_foil", bson.D{{"$sum", "$serra_count_foil"}}}, {"count_etched", bson.D{{"$sum", "$serra_count_etched"}}}, @@ -83,7 +83,7 @@ var statsCmd = &cobra.Command{ fmt.Printf("Commons: %s%.0f%s\n", Purple, ri.Commons, Reset) fmt.Printf("\n%sTotal Value%s\n", Green, Reset) - fmt.Printf("Current: %s%.2f%s\n", Pink, stats[0]["value"], Reset) + fmt.Printf("Current: %s%.2f %s%s\n", Pink, stats[0]["value"], getCurrency(), Reset) total, _ := totalcoll.storage_find_total() fmt.Printf("History: \n") diff --git a/src/serra/storage.go b/src/serra/storage.go index e5f745e..9afa4a6 100644 --- a/src/serra/storage.go +++ b/src/serra/storage.go @@ -23,13 +23,22 @@ type Collection struct { *mongo.Collection } +// Returns configured human readable name for +// the configured currency of the user +func getCurrencyField() string { + switch os.Getenv("SERRA_CURRENCY") { + case "EUR": + return "$prices.eur" + case "USD": + return "$prices.usd" + } + // default + return "$prices.usd" +} + func storage_connect() *mongo.Client { - uri := os.Getenv("MONGODB_URI") - if uri == "" { - log.Fatal("You must set your 'MONGODB_URI' environmental variable. See\n\t https://docs.mongodb.com/drivers/go/current/usage-examples/#environment-variable") - } - + uri := getMongoDBURI() client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(uri)) if err != nil { LogMessage(fmt.Sprintf("Could not connect to mongodb at %s", uri), "red") @@ -37,6 +46,7 @@ func storage_connect() *mongo.Client { } return client + } func (coll Collection) storage_add(card *Card) error {