return price on api call, price hardcoded

This commit is contained in:
GotPPay
2018-04-24 22:47:50 +02:00
parent 8e34bbab63
commit 239ea7135f

123
server.go
View File

@@ -2,14 +2,13 @@ package main
import (
"fmt"
"github.com/PuerkitoBio/goquery"
"github.com/benbjohnson/phantomjs"
"log"
"math"
"net/http"
"strconv"
"strings"
//"gopkg.in/headzoo/surf.v1"
"github.com/PuerkitoBio/goquery"
//"sourcegraph.com/sourcegraph/go-selenium"
"github.com/benbjohnson/phantomjs"
)
const validNumberOfURLParams = 5
@@ -18,6 +17,15 @@ const countParamIndex = 4
const validNumberOfSizeParams = 2
const maxExpectedNumberOfQuantities = 15
const numberOfTabsToSizeGroup = 12
const numberOfArrowDownToCustomSize = 4
const validMinWidth = 25.4
const validMaxWidth = 914.4
const validMinHeight = 25.4
const validMaxHeigh = 609.59
const epsilon = 0.1
const stickerMuleURL = "https://www.stickermule.com/uk/products/die-cut-stickers"
@@ -26,15 +34,19 @@ const (
invalidNumberOfParamsError = "Number of params not correct, expected /WIDTHxLENGTH/count"
invalidNumberOfSizeParamError = "Size not correct, expected /WIDTHxLENGTH/count"
invalidParamsType = "Params should be numbers"
invalidParamsSize = "Params should be in range"
errorSimulatingInput = "Error with simulating user input"
tooManyQuantities = "Too many quantities. Didn't expect this"
failedToGetPrice = "Failed to get price"
)
var listOfValidQuantities []int16
var stickerMuleWebPage *phantomjs.WebPage
var stickerMuleWebPageDocument *goquery.Document
func getListOfQuantities() error {
result := make([]int16, maxExpectedNumberOfQuantities)
resultCount := 0
@@ -48,7 +60,6 @@ func getListOfQuantities() error {
numberWithoutComma := strings.Replace(s.Text(), ",", "", -1)
trimmedNumber := strings.TrimSpace(numberWithoutComma)
if sizeInt64, err := strconv.ParseInt(trimmedNumber, 10, 16); err != nil {
wasError = true
whichError = err
@@ -70,6 +81,80 @@ func getListOfQuantities() error {
return nil
}
func floatToString(number float64) string {
return strconv.FormatFloat(number, 'f', 1, 64)
}
func getStickerPrice(width, height float64, quantity int) (int, error) {
//simulate click on "Custom size radio button"
if _, err := stickerMuleWebPage.Evaluate("function(){document.getElementById('variant_77').click();}"); err != nil {
return 0, err
}
//set value for width
if _, err := stickerMuleWebPage.Evaluate("function(){document.getElementById('width').value = " + floatToString(width) + ";}"); err != nil {
return 0, err
}
//set value for height
if _, err := stickerMuleWebPage.Evaluate("function(){document.getElementById('height').value = " + floatToString(height) + ";}"); err != nil {
return 0, err
}
//check if input boxes accepted passed values
valuesFromInputBoxes, err := stickerMuleWebPage.Evaluate("function(){return {width: document.getElementById('width').value, height: document.getElementById('height').value};}")
if err != nil {
return 0, err
}
valuesMap, ok := valuesFromInputBoxes.(map[string]interface{})
if !ok {
return 0, fmt.Errorf(invalidParamsType)
}
redWidthString, ok := valuesMap["width"].(string)
if !ok {
return 0, fmt.Errorf(invalidParamsType)
}
redHeightString, ok := valuesMap["height"].(string)
if !ok {
return 0, fmt.Errorf(invalidParamsType)
}
widthValue, err := strconv.ParseFloat(redWidthString, 64)
if err != nil {
return 0, fmt.Errorf(invalidParamsType)
}
heightValue, err := strconv.ParseFloat(redHeightString, 64)
if err != nil {
return 0, fmt.Errorf(invalidParamsType)
}
if math.Abs(widthValue-width) > epsilon || math.Abs(heightValue-height) > epsilon {
return 0, fmt.Errorf(invalidParamsType)
}
//Now read price for selected quantity
priceValue, err := stickerMuleWebPage.Evaluate("function(){return {price: document.getElementById('price_200_id').innerHTML};}")
//TODO : price is empty because setting value for width and height doesn't fire event listener
//on input fields and prices are not loaded. Find another way to simulate user input
priceMap, ok := priceValue.(map[string]interface{})
if !ok {
return 0, fmt.Errorf(failedToGetPrice)
}
_, ok = priceMap["price"].(string)
if !ok {
return 0, fmt.Errorf(failedToGetPrice)
}
return 100, nil
}
func errorResponse(w http.ResponseWriter, errType string) {
fmt.Fprintf(w, errType)
}
@@ -79,26 +164,34 @@ func diecutHandler(w http.ResponseWriter, r *http.Request) {
if size := strings.Split(params[sizeParamIndex], "x"); len(size) == validNumberOfSizeParams {
count := params[countParamIndex]
width, wOk := strconv.ParseInt(size[0], 10, 16)
height, hOk := strconv.ParseInt(size[1], 10, 16)
width, wOk := strconv.ParseFloat(size[0], 64)
height, hOk := strconv.ParseFloat(size[1], 64)
countNumber, cOk := strconv.ParseInt(count, 10, 16)
countNumber16 := int16(countNumber)
foundValidQuantity := false
for _, value := range(listOfValidQuantities){
for _, value := range listOfValidQuantities {
if value == countNumber16 {
foundValidQuantity = true
break
}
}
if wOk != nil || hOk != nil || cOk != nil || !foundValidQuantity {
validWidth := width >= validMinWidth && width <= validMaxWidth
validHeight := height >= validMinHeight && height <= validMaxHeigh
if wOk != nil || hOk != nil || cOk != nil || !foundValidQuantity || !validWidth || !validHeight {
errorResponse(w, invalidParamsType)
} else {
fmt.Fprintf(w, "%dx%d | %d", width, height, countNumber)
price, err := getStickerPrice(width, height, int(countNumber))
if err != nil {
errorResponse(w, failedToGetPrice)
} else {
w.Header().Set("Content-Type", "application/json")
fmt.Fprintf(w, "{price:%d, currency: \"USD\"}", price)
}
}
} else {
@@ -116,11 +209,14 @@ func defaultHandler(w http.ResponseWriter, r *http.Request) {
func initWebPage() error {
p := phantomjs.DefaultProcess
stickerMuleWebPage, err := p.CreateWebPage()
localStickerMuleWebPage, err := p.CreateWebPage()
if err != nil {
return err
}
//keep pointer to web page in global space, so page is not re-created every time API is called
stickerMuleWebPage = localStickerMuleWebPage
// Open a URL.
if err := stickerMuleWebPage.Open(stickerMuleURL); err != nil {
return err
@@ -171,5 +267,4 @@ func main() {
fmt.Println("Server running on localhost:8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}