TheMathemagicians/sevenkeys/main.go

307 lines
8.4 KiB
Go

package main
import (
"bufio"
"encoding/json"
"errors"
"flag"
"fmt"
"io/ioutil"
"log"
"os"
"sevenkeys/database"
"sevenkeys/delverlens"
"sevenkeys/logic"
"sevenkeys/logic/scryfall"
"strings"
"github.com/mtgban/go-mtgban/cardtrader"
)
func GetStringResponse(prompt string) string {
fmt.Print(prompt + " ")
var response string
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
response = scanner.Text()
return response
}
func GetYesNoResponse(prompt string) bool {
response := GetStringResponse(prompt)
return strings.ToUpper(response) == "Y"
}
const (
UpdateSubcommand string = "update"
CreateStorageAreaSubcommand string = "createstorage"
StoreSubcommand string = "store"
ImportSubcommand string = "import"
SearchPrintingsSubcommand string = "search-printings"
SearchStorageSubcommand string = "search-storage"
AddSubcommand string = "add"
RemoveSubcommand string = "remove"
ReplaceSubcommand string = "replace"
DeckSubcommand string = "deck"
GetProductIdSubcommand string = "products"
)
func main() {
var profile string
flag.StringVar(&profile, "profile", "development", "The database profile to use.")
flag.Parse()
db := database.GetDatabaseFromConfig("config." + profile + ".json")
/* Sad.
figlet.ReadFigletFonts()
cli.ShowSplashScreen()
*/
// TODO: Decide in what form we need to retain this functionality if any
//cli.MainCliLoop(db)
//searchCmd := flag.NewFlagSet(SearchSubcommand, flag.ExitOnError)
//name := searchCmd.String("name", "", "The card name to search for.")
if len(flag.Args()) == 0 {
fmt.Fprintln(os.Stderr, "Please specify a subcommand.")
os.Exit(1)
}
switch flag.Args()[0] {
case UpdateSubcommand:
fmt.Println("Checking for updates...")
bulkData, err := scryfall.GetBulkDataByType(scryfall.BulkDataTypeAllCards)
logic.Check(err)
needsUpdate, err := logic.CheckForUpdates(db, bulkData)
logic.Check(err)
if !needsUpdate {
fmt.Println("No update required.")
return
}
fmt.Println("Update required.")
if GetYesNoResponse("Run update? (y/N)") {
fmt.Println("Running update...")
logic.CreateCacheDirectories()
err = logic.UpdateSets(db)
logic.Check(err)
err = logic.UpdateCards(db, bulkData)
logic.Check(err)
fmt.Println("Update finished.")
}
break
case CreateStorageAreaSubcommand:
createStorageCmd := flag.NewFlagSet(CreateStorageAreaSubcommand, flag.ExitOnError)
storageAreaName := createStorageCmd.String("name", "",
"The name of the StorageArea to create.")
storageAreaType := createStorageCmd.String("type", "",
"The name of the StorageArea to create.")
createStorageCmd.Parse(flag.Args()[1:])
storageArea := database.StorageArea{Name: *storageAreaName, StorageType: *storageAreaType}
err := logic.CreateStorageArea(db, storageArea)
logic.Check(err)
break
case StoreSubcommand:
storeCmd := flag.NewFlagSet(StoreSubcommand, flag.ExitOnError)
storageArea := storeCmd.String("storagearea", "",
"The name of the StorageArea the card should be inserted to.")
id := storeCmd.String("id", "", "The CardPrintingId of the card to store.")
storeCmd.Parse(flag.Args()[1:])
storageAreaId, err := logic.GetStorageAreaId(db, *storageArea)
if err == logic.ErrCouldNotGetStorageAreaId {
fmt.Fprintf(os.Stderr, "[sevenkeys] No storage area was selected, exiting.\n")
os.Exit(1)
}
cardLocation := database.CardLocation{
CardPrintingId: *id,
StorageAreaId: storageAreaId,
}
cardLocationId, err := logic.StoreCard(db, cardLocation)
logic.Check(err)
fmt.Printf("%d\n", cardLocationId)
break
case ImportSubcommand:
importCmd := flag.NewFlagSet(ImportSubcommand, flag.ExitOnError)
storageArea := importCmd.String("storagearea", "",
"The name of the StorageArea where cards should be imported.")
importCmd.Parse(flag.Args()[1:])
storageAreaId, err := logic.GetStorageAreaId(db, *storageArea)
if err == logic.ErrCouldNotGetStorageAreaId {
fmt.Fprintf(os.Stderr, "[sevenkeys] No storage area was selected, exiting.\n")
os.Exit(1)
}
logic.Check(err)
delverLensCards, err := delverlens.ParseExportFile(importCmd.Args()[0])
logic.Check(err)
err = logic.ImportDelverLensCards(db, delverLensCards, storageAreaId)
logic.Check(err)
break
case SearchPrintingsSubcommand:
searchPrintingsCmd := flag.NewFlagSet(SearchPrintingsSubcommand, flag.ExitOnError)
setCode := searchPrintingsCmd.String("set-code", "", "The code for the set the card we're searching for belongs to.")
collectorNumber := searchPrintingsCmd.String("collector-number", "", "The collector number of the card we're searching for.")
foil := searchPrintingsCmd.String("foil", "E", "Whether the card we're searching for is foil.")
searchPrintingsCmd.Parse(flag.Args()[1:])
searchCriteria := logic.SearchCriteria{
SetCode: *setCode,
CollectorNumber: *collectorNumber,
Promo: logic.Either,
Language: "en",
}
if *foil == "Y" {
searchCriteria.Foil = logic.True
} else if *foil == "N" {
searchCriteria.Foil = logic.False
} else {
searchCriteria.Foil = logic.Either
}
searchOptions, err := logic.GetAllCardPrintingSearchOptions(db, searchCriteria)
logic.Check(err)
id, _, err := logic.GenericSearch(searchOptions)
logic.Check(err)
fmt.Println(id)
break
case SearchStorageSubcommand:
searchOptions, err := logic.GetAllStorageSearchOptions(db)
logic.Check(err)
id, _, err := logic.GenericSearch(searchOptions)
logic.Check(err)
fmt.Println(id)
break
case AddSubcommand:
addCmd := flag.NewFlagSet(AddSubcommand, flag.ExitOnError)
cardPrintingId := addCmd.String("card-printing-id", "", "The ID of the card printing to add to storage.")
storageArea := addCmd.String("storagearea", "",
"The name of the StorageArea where cards should be imported.")
addCmd.Parse(flag.Args()[1:])
storageAreaId, err := logic.GetStorageAreaId(db, *storageArea)
if err == logic.ErrCouldNotGetStorageAreaId {
fmt.Fprintf(os.Stderr, "[sevenkeys] No storage area was selected, exiting.\n")
os.Exit(1)
}
logic.Check(err)
cardLocation := database.CardLocation{
CardPrintingId: *cardPrintingId,
StorageAreaId: storageAreaId,
}
logic.StoreCard(db, cardLocation)
break
case RemoveSubcommand:
removeCmd := flag.NewFlagSet(RemoveSubcommand, flag.ExitOnError)
cardLocationId := removeCmd.Int("card-location-id", -1, "The card location to remove the card at.")
removeCmd.Parse(flag.Args()[1:])
if *cardLocationId == -1 {
log.Fatal(errors.New("No CardLocationId given."))
}
location, err := logic.GetCardAtLocation(db, *cardLocationId)
logic.Check(err)
err = logic.RemoveFromStorage(db, location)
logic.Check(err)
break
case ReplaceSubcommand:
replaceCmd := flag.NewFlagSet(ReplaceSubcommand, flag.ExitOnError)
cardLocationId := replaceCmd.Int("card-location-id", -1, "The card location to replace the card at.")
cardPrintingId := replaceCmd.String("card-printing-id", "", "The card printing to put at the specified location.")
replaceCmd.Parse(flag.Args()[1:])
if *cardLocationId == -1 {
log.Fatal(errors.New("No CardLocationId given."))
}
if *cardPrintingId == "" {
log.Fatal(errors.New("No CardPrintingId given."))
}
err := logic.Replace(db, *cardLocationId, *cardPrintingId)
logic.Check(err)
break
case DeckSubcommand:
deckCmd := flag.NewFlagSet(DeckSubcommand, flag.ExitOnError)
deckCmd.Parse(flag.Args()[1:])
//filename := deckCmd.Args()[0]
break
case GetProductIdSubcommand:
blbBlueprintsBytes, err := ioutil.ReadFile("blb_blueprints.json")
logic.Check(err)
var blbBlueprints []cardtrader.Blueprint
err = json.Unmarshal(blbBlueprintsBytes, &blbBlueprints)
logic.Check(err)
productsBytes, err := ioutil.ReadFile("products.json")
logic.Check(err)
var products []cardtrader.Product
err = json.Unmarshal(productsBytes, &products)
logic.Check(err)
for _, product := range products {
var productBlueprint cardtrader.Blueprint
for _, blueprint := range blbBlueprints {
if blueprint.Id == product.BlueprintId {
productBlueprint = blueprint
break
}
}
fmt.Printf("%s %s %d ",
productBlueprint.Name,
product.Properties.Number,
product.Id,
)
if product.Properties.MTGFoil {
fmt.Printf("FOIL ")
} else {
fmt.Printf("NONFOIL ")
}
fmt.Printf("x%d\n", product.Quantity)
}
break
default:
fmt.Fprintf(os.Stderr, "Unrecognized subcommand: %s\n", os.Args[1])
break
}
}