Add "locate from file" feature

This commit is contained in:
The Magician 2024-09-08 00:24:24 +01:00
parent 0d4d171edf
commit 4f14040747
7 changed files with 141 additions and 20 deletions

View File

@ -26,6 +26,14 @@ func MainCliLoop(db *sql.DB) {
} }
var insertSearchOptions logic.InsertSearchOptions var insertSearchOptions logic.InsertSearchOptions
// TODO: Make these do something and add the ability to modify them
var locateSearchCriteria logic.SearchCriteria = logic.SearchCriteria{
SetCode: "",
Foil: logic.True,
Promo: logic.Either,
Language: "en",
}
for { for {
ShowSplashScreen() ShowSplashScreen()
showStorageInfo(os.Stdout, selectedStorageArea) showStorageInfo(os.Stdout, selectedStorageArea)
@ -81,23 +89,15 @@ func MainCliLoop(db *sql.DB) {
insertSelectedCard(db, selectedStorageArea, cardLocation) insertSelectedCard(db, selectedStorageArea, cardLocation)
break break
case "l", "locate": case "l", "locate":
cardName := GetStringResponse("Card name:") filename := GetStringResponse("Filename:")
cardNames, err := logic.GetCardNamesFromFile(filename)
logic.Check(err)
locations, err := logic.LocateCards(db, cardName) locations, err := logic.LocateCards(db, cardNames, locateSearchCriteria)
logic.Check(err) logic.Check(err)
for _, location := range locations { for _, location := range locations {
fmt.Printf("%s (%s %s) [%s]", location.CardName, location.SetCode, location.CollectorNumber, location.Language) fmt.Println(location)
if location.IsFoil {
fmt.Printf(" FOIL")
}
if location.IsPromo {
fmt.Printf(" PROMO")
}
fmt.Printf(" in %s \"%s\" at position %d\n", location.StorageAreaType, location.StorageAreaName, location.Position)
} }
fmt.Scanln() fmt.Scanln()

View File

@ -1,6 +1,10 @@
package database package database
import "database/sql" import (
"database/sql"
"github.com/jmoiron/sqlx"
)
type LocateCardResult struct { type LocateCardResult struct {
CardName string CardName string
@ -14,11 +18,16 @@ type LocateCardResult struct {
Position int Position int
} }
func GetLocateCardResultsByCardName(db *sql.DB, cardName string) ([]LocateCardResult, error) { func GetLocateResults(db *sql.DB, cardNames []string) ([]LocateCardResult, error) {
var results []LocateCardResult var results []LocateCardResult
query := "SELECT CardPrinting.Name, CardPrinting.SetCode, CardPrinting.IsFoil, CardPrinting.IsPromo, CardPrinting.CollectorNumber, CardPrinting.Language, StorageArea.StorageType, StorageArea.Name, CardLocation.Position FROM CardLocation JOIN CardPrinting ON CardLocation.CardPrintingId = CardPrinting.Id JOIN StorageArea ON CardLocation.StorageAreaId = StorageArea.Id WHERE CardPrinting.Name = ?;" query := "SELECT CardPrinting.Name, CardPrinting.SetCode, CardPrinting.IsFoil, CardPrinting.IsPromo, CardPrinting.CollectorNumber, CardPrinting.Language, StorageArea.StorageType, StorageArea.Name, CardLocation.Position FROM CardLocation JOIN CardPrinting ON CardLocation.CardPrintingId = CardPrinting.Id JOIN StorageArea ON CardLocation.StorageAreaId = StorageArea.Id WHERE CardPrinting.Name IN (?);"
rows, err := db.Query(query, cardName) query, args, err := sqlx.In(query, cardNames)
if err != nil {
return results, err
}
rows, err := db.Query(query, args...)
defer rows.Close() defer rows.Close()
if err != nil { if err != nil {
return results, err return results, err

View File

@ -17,6 +17,7 @@ require (
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/inancgumus/screen v0.0.0-20190314163918-06e984b86ed3 // indirect github.com/inancgumus/screen v0.0.0-20190314163918-06e984b86ed3 // indirect
github.com/jmoiron/sqlx v1.4.0 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/lukesampson/figlet v0.0.0-20190211215653-8a3ef4a6ac42 // indirect github.com/lukesampson/figlet v0.0.0-20190211215653-8a3ef4a6ac42 // indirect
github.com/mattn/go-isatty v0.0.18 // indirect github.com/mattn/go-isatty v0.0.18 // indirect

View File

@ -20,6 +20,9 @@ github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpv
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/inancgumus/screen v0.0.0-20190314163918-06e984b86ed3 h1:fO9A67/izFYFYky7l1pDP5Dr0BTCRkaQJUG6Jm5ehsk= github.com/inancgumus/screen v0.0.0-20190314163918-06e984b86ed3 h1:fO9A67/izFYFYky7l1pDP5Dr0BTCRkaQJUG6Jm5ehsk=
github.com/inancgumus/screen v0.0.0-20190314163918-06e984b86ed3/go.mod h1:Ey4uAp+LvIl+s5jRbOHLcZpUDnkjLBROl15fZLwPlTM= github.com/inancgumus/screen v0.0.0-20190314163918-06e984b86ed3/go.mod h1:Ey4uAp+LvIl+s5jRbOHLcZpUDnkjLBROl15fZLwPlTM=
github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/lukesampson/figlet v0.0.0-20190211215653-8a3ef4a6ac42 h1:UtyD+eBVdLYSj5/pjfSR6mtnzMgIiOVcFT024G2l4CY= github.com/lukesampson/figlet v0.0.0-20190211215653-8a3ef4a6ac42 h1:UtyD+eBVdLYSj5/pjfSR6mtnzMgIiOVcFT024G2l4CY=
@ -31,6 +34,7 @@ github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+Ei
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b h1:1XF24mVaiu7u+CFywTdcDo2ie1pzzhwjt6RHqzpMU34= github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b h1:1XF24mVaiu7u+CFywTdcDo2ie1pzzhwjt6RHqzpMU34=
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho= github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho=
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=

25
sevenkeys/logic/file.go Normal file
View File

@ -0,0 +1,25 @@
package logic
import (
"bufio"
"os"
)
func GetCardNamesFromFile(filename string) ([]string, error) {
var cardNames []string
file, err := os.Open(filename)
defer file.Close()
if err != nil {
return cardNames, err
}
scanner := bufio.NewScanner(file)
scanner.Split(bufio.ScanLines)
for scanner.Scan() {
cardNames = append(cardNames, scanner.Text())
}
return cardNames, nil
}

View File

@ -2,10 +2,67 @@ package logic
import ( import (
"database/sql" "database/sql"
"fmt"
"sevenkeys/database" "sevenkeys/database"
) )
func LocateCards(db *sql.DB, cardName string) ([]database.LocateCardResult, error) { const SLOTS_PER_BINDER_PAGE = 18 // TODO: Make this configurable
results, err := database.GetLocateCardResultsByCardName(db, cardName)
return results, err func GetBinderLocationDescription(position int) string {
var page int = (position / SLOTS_PER_BINDER_PAGE) + 1
var pagePosition int = position % SLOTS_PER_BINDER_PAGE
var slot int
var frontOrBack string
if pagePosition <= (SLOTS_PER_BINDER_PAGE / 2) {
slot = pagePosition
frontOrBack = "front"
} else {
slot = pagePosition - (SLOTS_PER_BINDER_PAGE / 2)
frontOrBack = "back"
}
return fmt.Sprintf(" on page %d in %s slot %d", page, frontOrBack, slot)
}
func LocateCards(db *sql.DB, cardNames []string, criteria SearchCriteria) ([]string, error) {
var locations []string
results, err := database.GetLocateResults(db, cardNames)
if err != nil {
return locations, err
}
// TODO: Filter by search criteria
var location string
for _, result := range results {
location = fmt.Sprintf("%s (%s %s) [%s]",
result.CardName,
result.SetCode,
result.CollectorNumber,
result.Language)
if result.IsFoil {
location += " FOIL"
}
if result.IsPromo {
location += " PROMO"
}
location += fmt.Sprintf(" in %s \"%s\"",
result.StorageAreaType,
result.StorageAreaName)
if result.StorageAreaType == "Binder" {
location += GetBinderLocationDescription(result.Position)
} else if result.StorageAreaType == "Box" {
location += fmt.Sprintf(" at position %d", result.Position)
}
locations = append(locations, location)
}
return locations, nil
} }

View File

@ -0,0 +1,25 @@
package logic
import "testing"
func Test_GetBinderLocationDescription_ReturnsCorrectFormat_ForFrontSlots(t *testing.T) {
var position int = 24
var expected string = "on page 2 in front slot 6"
description := GetBinderLocationDescription(position)
if description != expected {
t.Errorf("expected %s, got %s\n", expected, description)
}
}
func Test_GetBinderLocationDescription_ReturnsCorrectFormat_ForBackSlots(t *testing.T) {
var position int = 17
var expected string = "on page 1 in back slot 8"
description := GetBinderLocationDescription(position)
if description != expected {
t.Errorf("expected %s, got %s\n", expected, description)
}
}