Merge in --foil feature

This commit is contained in:
Florian Baumann 2023-04-21 11:44:54 +02:00
commit 8258bca36b
11 changed files with 171 additions and 40 deletions

View File

@ -15,6 +15,7 @@ func init() {
addCmd.Flags().BoolVarP(&unique, "unique", "u", false, "Only add card if not existent yet") addCmd.Flags().BoolVarP(&unique, "unique", "u", false, "Only add card if not existent yet")
addCmd.Flags().BoolVarP(&interactive, "interactive", "i", false, "Spin up interactive terminal") addCmd.Flags().BoolVarP(&interactive, "interactive", "i", false, "Spin up interactive terminal")
addCmd.Flags().StringVarP(&set, "set", "s", "", "Filter by set code (usg/mmq/vow)") addCmd.Flags().StringVarP(&set, "set", "s", "", "Filter by set code (usg/mmq/vow)")
addCmd.Flags().BoolVarP(&foil, "foil", "f", false, "Add foil variant of card")
rootCmd.AddCommand(addCmd) rootCmd.AddCommand(addCmd)
} }
@ -78,13 +79,20 @@ func addCards(cards []string, unique bool, count int64) error {
c := co[0] c := co[0]
if unique { if unique {
LogMessage(fmt.Sprintf("Not adding \"%s\" (%s, %.2f %s) to Collection because it already exists.", c.Name, c.Rarity, c.getValue(), getCurrency()), "red") LogMessage(fmt.Sprintf("Not adding \"%s\" (%s, %.2f %s) to Collection because it already exists.", c.Name, c.Rarity, c.getValue(foil), getCurrency()), "red")
continue continue
} }
modify_count_of_card(coll, &c, count) modify_count_of_card(coll, &c, count, foil)
var total int64 = 0
if foil {
total = c.SerraCountFoil + count
} else {
total = c.SerraCount + count
}
// Give feedback of successfully added card // Give feedback of successfully added card
LogMessage(fmt.Sprintf("%dx \"%s\" (%s, %.2f %s) added to Collection.", c.SerraCount, c.Name, c.Rarity, c.getValue(), getCurrency()), "green") LogMessage(fmt.Sprintf("%dx \"%s\" (%s, %.2f %s) added to Collection.", total, c.Name, c.Rarity, c.getValue(foil), getCurrency()), "green")
// If card is not already in collection, fetching from scyfall // If card is not already in collection, fetching from scyfall
} else { } else {
@ -97,7 +105,14 @@ func addCards(cards []string, unique bool, count int64) error {
} }
// Write card to mongodb // Write card to mongodb
c.SerraCount = count var total int64 = 0
if foil {
c.SerraCountFoil = count
total = c.SerraCountFoil
} else {
c.SerraCount = count
total = c.SerraCount
}
err = coll.storage_add(c) err = coll.storage_add(c)
if err != nil { if err != nil {
LogMessage(fmt.Sprintf("%v", err), "red") LogMessage(fmt.Sprintf("%v", err), "red")
@ -105,7 +120,7 @@ func addCards(cards []string, unique bool, count int64) error {
} }
// Give feedback of successfully added card // Give feedback of successfully added card
LogMessage(fmt.Sprintf("%dx \"%s\" (%s, %.2f %s) added to Collection.", c.SerraCount, c.Name, c.Rarity, c.getValue(), getCurrency()), "green") LogMessage(fmt.Sprintf("%dx \"%s\" (%s, %.2f %s) added to Collection.", total, c.Name, c.Rarity, c.getValue(foil), getCurrency()), "green")
} }
} }
storage_disconnect(client) storage_disconnect(client)

View File

@ -127,8 +127,8 @@ func show_card_list(cards []Card) {
var total float64 var total float64
for _, card := range cards { for _, card := range cards {
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") LogMessage(fmt.Sprintf("* %dx %s%s%s (%s/%s) %s%.2f %s%s", card.SerraCount+card.SerraCountFoil+card.SerraCountEtched, Purple, card.Name, Reset, card.Set, card.CollectorNumber, Yellow, card.getValue(false), getCurrency(), Reset), "normal")
total = total + card.getValue()*float64(card.SerraCount) total = total + card.getValue(false)*float64(card.SerraCount) + card.getValue(true)*float64(card.SerraCountFoil)
} }
fmt.Printf("\nTotal Value: %s%.2f %s%s\n", Yellow, total, getCurrency(), Reset) fmt.Printf("\nTotal Value: %s%.2f %s%s\n", Yellow, total, getCurrency(), Reset)
@ -137,13 +137,22 @@ func show_card_list(cards []Card) {
func show_card_details(card *Card) error { func show_card_details(card *Card) error {
fmt.Printf("%s%s%s (%s/%s)\n", Purple, card.Name, Reset, card.Set, card.CollectorNumber) fmt.Printf("%s%s%s (%s/%s)\n", Purple, card.Name, Reset, card.Set, card.CollectorNumber)
fmt.Printf("Added: %s\n", stringToTime(card.SerraCreated)) fmt.Printf("Added: %s\n", stringToTime(card.SerraCreated))
fmt.Printf("Count: %dx\n", card.SerraCount) fmt.Printf("Count Normal: %dx\n", card.SerraCount)
if card.SerraCountFoil > 0 {
fmt.Printf("Count Foil: %dx\n", card.SerraCountFoil)
}
if card.SerraCountEtched > 0 {
fmt.Printf("Count Etched: %dx\n", card.SerraCountFoil)
}
fmt.Printf("Rarity: %s\n", card.Rarity) fmt.Printf("Rarity: %s\n", card.Rarity)
fmt.Printf("Scryfall: %s\n", strings.Replace(card.ScryfallURI, "?utm_source=api", "", 1)) fmt.Printf("Scryfall: %s\n", strings.Replace(card.ScryfallURI, "?utm_source=api", "", 1))
fmt.Printf("Current Value: %s%.2f %s%s\n", Yellow, card.getValue(), getCurrency(), Reset) fmt.Printf("Current Value: %s%.2f %s%s\n", Yellow, card.getValue(false), getCurrency(), Reset)
if card.SerraCountFoil > 0 {
fmt.Printf("Foil Value: %s%.2f %s%s\n", Yellow, card.getValue(true), getCurrency(), Reset)
}
fmt.Printf("\n%sHistory%s\n", Green, Reset) fmt.Printf("\n%sHistory%s\n", Green, Reset)
print_price_history(card.SerraPrices, "* ") print_price_history(card.SerraPrices, "* ", false)
fmt.Println() fmt.Println()
return nil return nil
} }

View File

@ -3,6 +3,7 @@ package serra
import ( import (
"errors" "errors"
"fmt" "fmt"
"math"
"strconv" "strconv"
"time" "time"
"unicode" "unicode"
@ -15,7 +16,7 @@ type Rarities struct {
Rares, Uncommons, Commons, Mythics float64 Rares, Uncommons, Commons, Mythics float64
} }
func modify_count_of_card(coll *Collection, c *Card, amount int64) error { func modify_count_of_card(coll *Collection, c *Card, amount int64, foil bool) error {
// find already existing card // find already existing card
sort := bson.D{{"_id", 1}} sort := bson.D{{"_id", 1}}
@ -28,12 +29,26 @@ func modify_count_of_card(coll *Collection, c *Card, amount int64) error {
// update card amount // update card amount
update_filter := bson.M{"_id": bson.M{"$eq": c.ID}} update_filter := bson.M{"_id": bson.M{"$eq": c.ID}}
update := bson.M{ var update bson.M
"$set": bson.M{"serra_count": stored_card.SerraCount + amount}, if foil {
update = bson.M{
"$set": bson.M{"serra_count_foil": stored_card.SerraCountFoil + amount},
}
} else {
update = bson.M{
"$set": bson.M{"serra_count": stored_card.SerraCount + amount},
}
} }
coll.storage_update(update_filter, update) coll.storage_update(update_filter, update)
LogMessage(fmt.Sprintf("Updating Card \"%s\" amount to %d", stored_card.Name, stored_card.SerraCount+amount), "purple") var total int64
if foil {
total = stored_card.SerraCountFoil + amount
} else {
total = stored_card.SerraCount + amount
}
LogMessage(fmt.Sprintf("Updating Card \"%s\" amount to %d", stored_card.Name, total), "purple")
return nil return nil
} }
@ -148,15 +163,22 @@ func convert_rarities(rar []primitive.M) Rarities {
} }
func print_price_history(prices []PriceEntry, prefix string) { func print_price_history(prices []PriceEntry, prefix string, total bool) {
var before float64 var before float64
for _, e := range prices { for _, e := range prices {
// TODO: Make currency configurable var value float64
value := e.Usd if total {
if getCurrency() == "EUR" { value = e.Usd + e.UsdFoil + e.UsdEtched
value = e.Eur if getCurrency() == "EUR" {
value = e.Eur + e.EurFoil
}
} else {
value = e.Usd
if getCurrency() == "EUR" {
value = e.Eur
}
} }
if value > before && before != 0 { if value > before && before != 0 {
@ -180,3 +202,26 @@ func filterForDigits(str string) int {
s, _ := strconv.Atoi(numStr) s, _ := strconv.Atoi(numStr)
return s return s
} }
func getFloat64(unknown interface{}) (float64, error) {
switch i := unknown.(type) {
case float64:
return i, nil
case float32:
return float64(i), nil
case int64:
return float64(i), nil
case int32:
return float64(i), nil
case int:
return float64(i), nil
case uint64:
return float64(i), nil
case uint32:
return float64(i), nil
case uint:
return float64(i), nil
default:
return math.NaN(), errors.New("Non-numeric type could not be converted to float")
}
}

View File

@ -58,7 +58,7 @@ cards you dont own (yet) :)`,
if err != nil { if err != nil {
continue continue
} }
fmt.Printf("%.02f %s\t%s (%s)\n", ncard.getValue(), getCurrency(), ncard.Name, ncard.SetName) fmt.Printf("%.02f %s\t%s (%s)\n", ncard.getValue(false), getCurrency(), ncard.Name, ncard.SetName)
} }
return nil return nil
}, },

View File

@ -14,6 +14,7 @@ func init() {
removeCmd.Flags().Int64VarP(&count, "count", "c", 1, "Amount of cards to remove") removeCmd.Flags().Int64VarP(&count, "count", "c", 1, "Amount of cards to remove")
removeCmd.Flags().BoolVarP(&interactive, "interactive", "i", false, "Spin up interactive terminal") removeCmd.Flags().BoolVarP(&interactive, "interactive", "i", false, "Spin up interactive terminal")
removeCmd.Flags().StringVarP(&set, "set", "s", "", "Filter by set code (usg/mmq/vow)") removeCmd.Flags().StringVarP(&set, "set", "s", "", "Filter by set code (usg/mmq/vow)")
removeCmd.Flags().BoolVarP(&foil, "foil", "f", false, "Remove foil variant of card")
rootCmd.AddCommand(removeCmd) rootCmd.AddCommand(removeCmd)
} }
@ -77,11 +78,21 @@ func removeCards(cards []string, count int64) error {
continue continue
} }
if c.SerraCount > 1 { if foil && c.SerraCountFoil < 1 {
modify_count_of_card(coll, c, -1) LogMessage(fmt.Sprintf("Error: No Foil \"%s\" in the Collection.", c.Name), "red")
} else { continue
}
if !foil && c.SerraCount < 1 {
LogMessage(fmt.Sprintf("Error: No Non-Foil \"%s\" in the Collection.", c.Name), "red")
continue
}
if foil && c.SerraCountFoil == 1 && c.SerraCount == 0 || !foil && c.SerraCount == 1 && c.SerraCountFoil == 0 {
coll.storage_remove(bson.M{"_id": c.ID}) coll.storage_remove(bson.M{"_id": c.ID})
LogMessage(fmt.Sprintf("\"%s\" (%.2f %s) removed from the Collection.", c.Name, c.getValue(), getCurrency()), "green") LogMessage(fmt.Sprintf("\"%s\" (%.2f %s) removed from the Collection.", c.Name, c.getValue(foil), getCurrency()), "green")
} else {
modify_count_of_card(coll, c, -1, foil)
} }
} }

View File

@ -21,6 +21,7 @@ var sinceLastUpdate bool
var sortby string var sortby string
var cardType string var cardType string
var unique bool var unique bool
var foil bool
var rootCmd = &cobra.Command{ var rootCmd = &cobra.Command{
Version: Version, Version: Version,

View File

@ -120,10 +120,16 @@ type Card struct {
} }
// Getter for currency specific value // Getter for currency specific value
func (c Card) getValue() float64 { func (c Card) getValue(foil bool) float64 {
if getCurrency() == "EUR" { if getCurrency() == "EUR" {
if foil {
return c.Prices.EurFoil
}
return c.Prices.Eur return c.Prices.Eur
} }
if foil {
return c.Prices.UsdFoil
}
return c.Prices.Usd return c.Prices.Usd
} }

View File

@ -42,7 +42,8 @@ func Sets(sort string) []primitive.M {
groupStage := bson.D{ groupStage := bson.D{
{"$group", bson.D{ {"$group", bson.D{
{"_id", "$setname"}, {"_id", "$setname"},
{"value", bson.D{{"$sum", bson.D{{"$multiply", bson.A{getCurrencyField(), "$serra_count"}}}}}}, {"value", bson.D{{"$sum", bson.D{{"$multiply", bson.A{getCurrencyField(false), "$serra_count"}}}}}},
{"value_foil", bson.D{{"$sum", bson.D{{"$multiply", bson.A{getCurrencyField(true), "$serra_count_foil"}}}}}},
{"count", bson.D{{"$sum", bson.D{{"$multiply", bson.A{1.0, "$serra_count"}}}}}}, {"count", bson.D{{"$sum", bson.D{{"$multiply", bson.A{1.0, "$serra_count"}}}}}},
{"unique", bson.D{{"$sum", 1}}}, {"unique", bson.D{{"$sum", 1}}},
{"code", bson.D{{"$last", "$set"}}}, {"code", bson.D{{"$last", "$set"}}},
@ -113,7 +114,8 @@ func ShowSet(setname string) error {
groupStage := bson.D{ groupStage := bson.D{
{"$group", bson.D{ {"$group", bson.D{
{"_id", "$setname"}, {"_id", "$setname"},
{"value", bson.D{{"$sum", bson.D{{"$multiply", bson.A{getCurrencyField(), "$serra_count"}}}}}}, {"value", bson.D{{"$sum", bson.D{{"$multiply", bson.A{getCurrencyField(false), "$serra_count"}}}}}},
{"value_foil", bson.D{{"$sum", bson.D{{"$multiply", bson.A{getCurrencyField(true), "$serra_count_foil"}}}}}},
{"count", bson.D{{"$sum", bson.D{{"$multiply", bson.A{1.0, "$serra_count"}}}}}}, {"count", bson.D{{"$sum", bson.D{{"$multiply", bson.A{1.0, "$serra_count"}}}}}},
}}, }},
} }
@ -142,14 +144,25 @@ func ShowSet(setname string) error {
LogMessage(fmt.Sprintf("%s", sets[0].Name), "green") LogMessage(fmt.Sprintf("%s", sets[0].Name), "green")
LogMessage(fmt.Sprintf("Set Cards: %d/%d", len(cards), sets[0].CardCount), "normal") 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 Cards: %.0f", stats[0]["count"]), "normal")
LogMessage(fmt.Sprintf("Total Value: %.2f %s", stats[0]["value"], getCurrency()), "normal") nf_value, err := getFloat64(stats[0]["value"])
if err != nil {
LogMessage(fmt.Sprintf("Error: %v", err), "red")
nf_value = 0
}
foil_value, err := getFloat64(stats[0]["value_foil"])
if err != nil {
LogMessage(fmt.Sprintf("Error: %v", err), "red")
foil_value = 0
}
total_value := nf_value + foil_value
LogMessage(fmt.Sprintf("Total Value: %.2f %s", total_value, getCurrency()), "normal")
LogMessage(fmt.Sprintf("Released: %s", sets[0].ReleasedAt), "normal") LogMessage(fmt.Sprintf("Released: %s", sets[0].ReleasedAt), "normal")
LogMessage(fmt.Sprintf("Mythics: %.0f", ri.Mythics), "normal") LogMessage(fmt.Sprintf("Mythics: %.0f", ri.Mythics), "normal")
LogMessage(fmt.Sprintf("Rares: %.0f", ri.Rares), "normal") LogMessage(fmt.Sprintf("Rares: %.0f", ri.Rares), "normal")
LogMessage(fmt.Sprintf("Uncommons: %.0f", ri.Uncommons), "normal") LogMessage(fmt.Sprintf("Uncommons: %.0f", ri.Uncommons), "normal")
LogMessage(fmt.Sprintf("Commons: %.0f", ri.Commons), "normal") LogMessage(fmt.Sprintf("Commons: %.0f", ri.Commons), "normal")
fmt.Printf("\n%sPrice History:%s\n", Pink, Reset) fmt.Printf("\n%sPrice History:%s\n", Pink, Reset)
print_price_history(sets[0].SerraPrices, "* ") print_price_history(sets[0].SerraPrices, "* ", true)
fmt.Printf("\n%sMost valuable cards%s\n", Pink, Reset) fmt.Printf("\n%sMost valuable cards%s\n", Pink, Reset)
@ -163,7 +176,8 @@ func ShowSet(setname string) error {
for i := 0; i < ccards; i++ { for i := 0; i < ccards; i++ {
card := cards[i] card := cards[i]
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(), getCurrency(), 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(false), getCurrency(), Reset)
fmt.Printf("* %dx %s%s%s (%s/%s) %s%.2f %s%s\n", card.SerraCountFoil, Purple, card.Name, Reset, sets[0].Code, card.CollectorNumber, Yellow, card.getValue(true), getCurrency(), Reset)
} }
return nil return nil

View File

@ -50,18 +50,26 @@ var statsCmd = &cobra.Command{
bson.D{ bson.D{
{"$group", bson.D{ {"$group", bson.D{
{"_id", nil}, {"_id", nil},
{"value", bson.D{{"$sum", bson.D{{"$multiply", bson.A{getCurrencyField(), "$serra_count"}}}}}}, {"value", bson.D{{"$sum", bson.D{{"$multiply", bson.A{getCurrencyField(false), "$serra_count"}}}}}},
{"value_foil", bson.D{{"$sum", bson.D{{"$multiply", bson.A{getCurrencyField(true), "$serra_count_foil"}}}}}},
{"count", bson.D{{"$sum", bson.D{{"$multiply", bson.A{1.0, "$serra_count"}}}}}}, {"count", bson.D{{"$sum", bson.D{{"$multiply", bson.A{1.0, "$serra_count"}}}}}},
{"count_foil", bson.D{{"$sum", "$serra_count_foil"}}}, {"count_foil", bson.D{{"$sum", "$serra_count_foil"}}},
{"count_etched", bson.D{{"$sum", "$serra_count_etched"}}}, {"count_etched", bson.D{{"$sum", "$serra_count_etched"}}},
{"rarity", bson.D{{"$sum", "$rarity"}}}, {"rarity", bson.D{{"$sum", "$rarity"}}},
{"unique", bson.D{{"$sum", 1}}}, {"unique", bson.D{{"$sum", 1}}},
}}}, }},
},
bson.D{
{"$addFields", bson.D{
{"count_all", bson.D{{"$sum", bson.A{"$count", "$count_foil", "$count_etched"}}}},
}},
},
}) })
fmt.Printf("\n%sCards %s\n", Green, Reset) fmt.Printf("\n%sCards %s\n", Green, Reset)
fmt.Printf("Total: %s%.0f%s\n", Yellow, stats[0]["count"], Reset) fmt.Printf("Total: %s%.0f%s\n", Yellow, stats[0]["count_all"], Reset)
fmt.Printf("Unique: %s%d%s\n", Purple, stats[0]["unique"], Reset) fmt.Printf("Unique: %s%d%s\n", Purple, stats[0]["unique"], Reset)
fmt.Printf("Normal: %s%.0f%s\n", Purple, stats[0]["count"], Reset)
fmt.Printf("Foil: %s%d%s\n", Purple, stats[0]["count_foil"], Reset) fmt.Printf("Foil: %s%d%s\n", Purple, stats[0]["count_foil"], Reset)
fmt.Printf("Etched: %s%d%s\n", Purple, stats[0]["count_etched"], Reset) fmt.Printf("Etched: %s%d%s\n", Purple, stats[0]["count_etched"], Reset)
@ -76,11 +84,11 @@ var statsCmd = &cobra.Command{
}}}, }}},
}) })
var count_reserved float64 var count_reserved int32
if len(reserved) > 0 { if len(reserved) > 0 {
count_reserved = reserved[0]["count"].(float64) count_reserved = reserved[0]["count"].(int32)
} }
fmt.Printf("Reserved List: %s%.0f%s\n", Yellow, count_reserved, Reset) fmt.Printf("Reserved List: %s%d%s\n", Yellow, count_reserved, Reset)
rar, _ := coll.storage_aggregate(mongo.Pipeline{ rar, _ := coll.storage_aggregate(mongo.Pipeline{
bson.D{ bson.D{
@ -101,11 +109,24 @@ var statsCmd = &cobra.Command{
fmt.Printf("Commons: %s%.0f%s\n", Purple, ri.Commons, Reset) fmt.Printf("Commons: %s%.0f%s\n", Purple, ri.Commons, Reset)
fmt.Printf("\n%sTotal Value%s\n", Green, Reset) fmt.Printf("\n%sTotal Value%s\n", Green, Reset)
fmt.Printf("Current: %s%.2f %s%s\n", Pink, stats[0]["value"], getCurrency(), Reset) nf_value, err := getFloat64(stats[0]["value"])
if err != nil {
LogMessage(fmt.Sprintf("Error: %v", err), "red")
nf_value = 0
}
foil_value, err := getFloat64(stats[0]["value_foil"])
if err != nil {
LogMessage(fmt.Sprintf("Error: %v", err), "red")
foil_value = 0
}
total_value := nf_value + foil_value
fmt.Printf("Total: %s%.2f %s%s\n", Pink, total_value, getCurrency(), Reset)
fmt.Printf("Normal: %s%.2f %s%s\n", Pink, nf_value, getCurrency(), Reset)
fmt.Printf("Foils: %s%.2f %s%s\n", Pink, foil_value, getCurrency(), Reset)
total, _ := totalcoll.storage_find_total() total, _ := totalcoll.storage_find_total()
fmt.Printf("History: \n") fmt.Printf("History: \n")
print_price_history(total.Value, "* ") print_price_history(total.Value, "* ", true)
return nil return nil
}, },
} }

View File

@ -25,13 +25,22 @@ type Collection struct {
// Returns configured human readable name for // Returns configured human readable name for
// the configured currency of the user // the configured currency of the user
func getCurrencyField() string { func getCurrencyField(foil bool) string {
switch os.Getenv("SERRA_CURRENCY") { switch os.Getenv("SERRA_CURRENCY") {
case "EUR": case "EUR":
if foil {
return "$prices.eur_foil"
}
return "$prices.eur" return "$prices.eur"
case "USD": case "USD":
if foil {
return "$prices.usd_foil"
}
return "$prices.usd" return "$prices.usd"
default: default:
if foil {
return "$prices.usd_foil"
}
return "$prices.usd" return "$prices.usd"
} }
} }

View File

@ -129,7 +129,7 @@ var updateCmd = &cobra.Command{
tmpCard := Card{} tmpCard := Card{}
tmpCard.Prices = t tmpCard.Prices = t
fmt.Printf("\n%sUpdating total value of collection to: %s%.02f %s%s\n", Green, Yellow, tmpCard.getValue(), getCurrency(), Reset) fmt.Printf("\n%sUpdating total value of collection to: %s%.02f %s%s\n", Green, Yellow, tmpCard.getValue(false)+tmpCard.getValue(true), getCurrency(), Reset)
totalcoll.storage_add_total(t) totalcoll.storage_add_total(t)
return nil return nil