Add dynamic currency picking mechanics

This commit is contained in:
Florian Baumann 2023-02-06 17:07:51 +01:00
parent 5eddcf6f3d
commit 79e067a8f5
9 changed files with 81 additions and 23 deletions

View File

@ -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

View File

@ -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)
}

28
src/serra/env.go Normal file
View File

@ -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"
}

View File

@ -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{

View File

@ -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
}

View File

@ -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"`

View File

@ -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

View File

@ -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")

View File

@ -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 {