From 1af9226764551d5e67abe369c5e56243947fbe7d Mon Sep 17 00:00:00 2001 From: Artyom Belousov Date: Fri, 10 May 2019 14:59:37 +0300 Subject: [PATCH] Initial commit Includes: SCG parser MTG cards search --- .gitignore | 2 ++ cardsinfo/internals_test.go | 21 ++++++++++++++ cardsinfo/names.go | 42 ++++++++++++++++++++++++++++ cardsinfo/scgprices.go | 56 +++++++++++++++++++++++++++++++++++++ cardsinfo/structs.go | 6 ++++ main.go | 4 +++ tests/names_test.go | 37 ++++++++++++++++++++++++ tests/prices_test.go | 13 +++++++++ 8 files changed, 181 insertions(+) create mode 100644 .gitignore create mode 100644 cardsinfo/internals_test.go create mode 100644 cardsinfo/names.go create mode 100644 cardsinfo/scgprices.go create mode 100644 cardsinfo/structs.go create mode 100644 main.go create mode 100644 tests/names_test.go create mode 100644 tests/prices_test.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e3a1c23 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +mtg-price-vk +*/.swp diff --git a/cardsinfo/internals_test.go b/cardsinfo/internals_test.go new file mode 100644 index 0000000..c446c2e --- /dev/null +++ b/cardsinfo/internals_test.go @@ -0,0 +1,21 @@ +package cardsinfo + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestFetchPriceOne(t *testing.T) { + price, _ := fetchPrice("$2.28") + assert.Equal(t, 2.28, price) +} + +func TestFetchPriceTwo(t *testing.T) { + price, _ := fetchPrice("$2.28$1.14") + assert.Equal(t, 2.28, price) +} + +func TestFetchPriceNo(t *testing.T) { + _, err := fetchPrice("") + assert.NotNil(t, err) +} diff --git a/cardsinfo/names.go b/cardsinfo/names.go new file mode 100644 index 0000000..10237ea --- /dev/null +++ b/cardsinfo/names.go @@ -0,0 +1,42 @@ +package cardsinfo + +import ( + mtg "github.com/MagicTheGathering/mtg-sdk-go" + "strings" +) + +func getCardName(card *mtg.Card) string { + switch card.Layout { + case "split": + return strings.Join(card.Names, " // ") + case "transform": + return strings.Join(card.Names, " | ") + default: + return card.Name + } +} + +func getOriginalNameFromLang(name, lang string, channel chan string) { + cards, _, _ := mtg.NewQuery().Where(mtg.CardLanguage, lang).Where(mtg.CardName, name).PageS(1, 1) + if len(cards) > 0 { + name := getCardName(cards[0]) + channel <- name + } else { + channel <- "" + } +} + +func GetOriginalName(name string) string { + langs := []string{"Russian", ""} + channel := make(chan string) + for i := range langs { + go getOriginalNameFromLang(name, langs[i], channel) + } + for i := 0; i < len(langs); i++ { + name := <-channel + if name != "" { + return name + } + } + return "" +} diff --git a/cardsinfo/scgprices.go b/cardsinfo/scgprices.go new file mode 100644 index 0000000..8c3cc6d --- /dev/null +++ b/cardsinfo/scgprices.go @@ -0,0 +1,56 @@ +package cardsinfo + +import ( + "errors" + "github.com/antchfx/htmlquery" + "strconv" + "strings" +) + +const SCGURL = "http://www.starcitygames.com/results?name=" + +func GetSCGPrices(name string) ([]CardPrice, error) { + splitted := strings.Split(name, " ") + scgName := strings.Join(splitted, "+") + url := SCGURL + scgName + doc, err := htmlquery.LoadURL(url) + if err != nil { + return nil, err + } + nodesOdd := htmlquery.Find(doc, "//tr[contains(@class, 'deckdbbody_row')]") + nodesEven := htmlquery.Find(doc, "//tr[contains(@class, 'deckdbbody2_row')]") + nodes := append(nodesOdd, nodesEven...) + prices := make([]CardPrice, 0) + for _, node := range nodes { + nameNode := htmlquery.FindOne(node, "//td[contains(@class, 'search_results_1')]") + if nameNode == nil { + continue + } + name := htmlquery.InnerText(nameNode) + priceNode := htmlquery.FindOne(node, "//td[contains(@class, 'search_results_9')]") + if priceNode == nil { + continue + } + priceS := htmlquery.InnerText(priceNode) + price, err := fetchPrice(priceS) + if err != nil { + continue + } + obj := CardPrice{ + Name: name, + Price: price, + } + prices = append(prices, obj) + } + return prices, nil +} + +func fetchPrice(price string) (float64, error) { + split := strings.Split(price, "$") + if len(split) < 2 { + return 0, errors.New("Not enough values") + } + p := split[1] + v, err := strconv.ParseFloat(p, 64) + return v, err +} diff --git a/cardsinfo/structs.go b/cardsinfo/structs.go new file mode 100644 index 0000000..a55b9a6 --- /dev/null +++ b/cardsinfo/structs.go @@ -0,0 +1,6 @@ +package cardsinfo + +type CardPrice struct { + Name string + Price float64 +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..da29a2c --- /dev/null +++ b/main.go @@ -0,0 +1,4 @@ +package main + +func main() { +} diff --git a/tests/names_test.go b/tests/names_test.go new file mode 100644 index 0000000..8d479c9 --- /dev/null +++ b/tests/names_test.go @@ -0,0 +1,37 @@ +package tests + +import ( + "github.com/flygrounder/mtg-price-vk/cardsinfo" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestGetCardByStringFull(t *testing.T) { + name := cardsinfo.GetOriginalName("Шок") + assert.Equal(t, "Shock", name) +} + +func TestGetCardByStringSplit(t *testing.T) { + name := cardsinfo.GetOriginalName("commit") + assert.Equal(t, "Commit // Memory", name) +} + +func TestGetCardByStringDouble(t *testing.T) { + name := cardsinfo.GetOriginalName("Legion's landing") + assert.Equal(t, "Legion's Landing | Adanto, the First Fort", name) +} + +func TestGetCardByStringPrefix(t *testing.T) { + name := cardsinfo.GetOriginalName("Тефери, герой") + assert.Equal(t, "Teferi, Hero of Dominaria", name) +} + +func TestGetCardByStringEnglish(t *testing.T) { + name := cardsinfo.GetOriginalName("Teferi, Hero of Dominaria") + assert.Equal(t, "Teferi, Hero of Dominaria", name) +} + +func TestGetCardByStringWrong(t *testing.T) { + name := cardsinfo.GetOriginalName("fwijefiwjfew") + assert.Equal(t, "", name) +} diff --git a/tests/prices_test.go b/tests/prices_test.go new file mode 100644 index 0000000..714de28 --- /dev/null +++ b/tests/prices_test.go @@ -0,0 +1,13 @@ +package tests + +import ( + "github.com/flygrounder/mtg-price-vk/cardsinfo" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestParser(t *testing.T) { + prices, err := cardsinfo.GetSCGPrices("shock") + assert.Nil(t, err) + assert.NotEmpty(t, prices) +}