2024-05-30 14:19:31 +00:00
|
|
|
package logic
|
|
|
|
|
|
|
|
import (
|
|
|
|
"database/sql"
|
|
|
|
"fmt"
|
2024-05-31 19:32:44 +00:00
|
|
|
"io"
|
|
|
|
"os"
|
|
|
|
"os/exec"
|
2024-05-30 14:19:31 +00:00
|
|
|
"sevenkeys/database"
|
2024-05-31 19:32:44 +00:00
|
|
|
"strings"
|
2024-05-30 14:19:31 +00:00
|
|
|
)
|
|
|
|
|
2024-06-11 11:47:55 +00:00
|
|
|
type Triadic int
|
|
|
|
|
|
|
|
const (
|
|
|
|
True Triadic = iota
|
|
|
|
False
|
|
|
|
Either
|
|
|
|
)
|
|
|
|
|
|
|
|
type SearchCriteria struct {
|
|
|
|
SetCode string
|
|
|
|
Foil Triadic
|
|
|
|
Promo Triadic
|
|
|
|
Language string
|
|
|
|
}
|
|
|
|
|
2024-09-07 18:07:48 +00:00
|
|
|
// The InsertSearchOptions type is a map of `string` keys (which can be searched using
|
|
|
|
// fzf) to `string` values (which represent a primary key in the CardPrintings table)
|
|
|
|
type InsertSearchOptions map[string]string
|
2024-05-30 14:19:31 +00:00
|
|
|
|
2024-06-11 11:47:55 +00:00
|
|
|
func filterPrinting(printing database.CardPrinting, searchCriteria SearchCriteria) bool {
|
|
|
|
if searchCriteria.SetCode != "" && printing.SetCode != searchCriteria.SetCode {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
if searchCriteria.Foil == False && printing.IsFoil {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
if searchCriteria.Foil == True && !printing.IsFoil {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
if searchCriteria.Promo == False && printing.IsPromo {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
if searchCriteria.Promo == True && !printing.IsPromo {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
if searchCriteria.Language != "" && printing.Language != searchCriteria.Language {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2024-09-07 18:07:48 +00:00
|
|
|
func GetAllSearchOptions(db *sql.DB, searchCriteria SearchCriteria) (InsertSearchOptions, error) {
|
|
|
|
var searchOptions InsertSearchOptions = make(map[string]string)
|
2024-05-30 14:19:31 +00:00
|
|
|
|
|
|
|
cardPrintings, err := database.GetAllCardPrintings(db)
|
|
|
|
if err != nil {
|
|
|
|
return searchOptions, err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, printing := range cardPrintings {
|
2024-06-11 11:47:55 +00:00
|
|
|
// Filter based on search criteria
|
|
|
|
filter := filterPrinting(printing, searchCriteria)
|
|
|
|
if filter {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
// Construct search option string
|
2024-05-30 14:19:31 +00:00
|
|
|
searchString := fmt.Sprintf("%s (%s %s) [%s]", printing.Name, printing.SetCode, printing.CollectorNumber, printing.Language)
|
|
|
|
|
|
|
|
if printing.IsFoil {
|
|
|
|
searchString += " FOIL"
|
|
|
|
}
|
|
|
|
|
|
|
|
if printing.IsPromo {
|
|
|
|
searchString += " PROMO"
|
|
|
|
}
|
|
|
|
|
|
|
|
searchOptions[searchString] = printing.Id
|
|
|
|
}
|
|
|
|
|
|
|
|
return searchOptions, err
|
|
|
|
}
|
2024-05-31 19:32:44 +00:00
|
|
|
|
2024-09-07 18:07:48 +00:00
|
|
|
func GenericSearch[pk string | int](options map[string]pk) (pk, error) {
|
|
|
|
var value pk
|
|
|
|
|
2024-05-31 19:32:44 +00:00
|
|
|
cmd := exec.Command("fzf")
|
|
|
|
cmd.Stderr = os.Stderr
|
|
|
|
|
|
|
|
fzfStdin, err := cmd.StdinPipe()
|
|
|
|
if err != nil {
|
2024-09-07 18:07:48 +00:00
|
|
|
return value, err
|
2024-05-31 19:32:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
defer fzfStdin.Close()
|
2024-09-07 18:07:48 +00:00
|
|
|
for option, _ := range options {
|
|
|
|
io.WriteString(fzfStdin, option+"\n")
|
2024-05-31 19:32:44 +00:00
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
fzfOutput, err := cmd.Output()
|
|
|
|
if err != nil {
|
2024-09-07 18:07:48 +00:00
|
|
|
return value, err
|
2024-05-31 19:32:44 +00:00
|
|
|
}
|
|
|
|
|
2024-09-07 18:07:48 +00:00
|
|
|
searchResult := strings.TrimSuffix(string(fzfOutput), "\n")
|
|
|
|
value = options[searchResult]
|
|
|
|
return value, nil
|
2024-05-31 19:32:44 +00:00
|
|
|
}
|