Files
old-bilal-vjezba-golang/server.go

176 lines
3.9 KiB
Go
Raw Normal View History

package main
import (
"fmt"
"log"
"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
const sizeParamIndex = 3
const countParamIndex = 4
const validNumberOfSizeParams = 2
const maxExpectedNumberOfQuantities = 15
const stickerMuleURL = "https://www.stickermule.com/uk/products/die-cut-stickers"
const (
invalidURL = "URL is not valid"
invalidNumberOfParamsError = "Number of params not correct, expected /WIDTHxLENGTH/count"
invalidNumberOfSizeParamError = "Size not correct, expected /WIDTHxLENGTH/count"
invalidParamsType = "Params should be numbers"
tooManyQuantities = "Too many quantities. Didn't expect this"
)
var listOfValidQuantities []int16
var stickerMuleWebPage *phantomjs.WebPage
var stickerMuleWebPageDocument *goquery.Document
func getListOfQuantities() error {
result := make([]int16, maxExpectedNumberOfQuantities)
resultCount := 0
wasError := false
whichError := error(nil)
stickerMuleWebPageDocument.Find("label.quantity").Each(func(_ int, s *goquery.Selection){
if wasError{
return
}
numberWithoutComma := strings.Replace(s.Text(), ",","",-1)
trimmedNumber := strings.TrimSpace(numberWithoutComma)
if sizeInt64, err := strconv.ParseInt(trimmedNumber,10,16) ; err != nil {
wasError = true
whichError = err
}else{
result[resultCount] = int16(sizeInt64)
}
resultCount+=1
if resultCount == 15 {
wasError = true
whichError = fmt.Errorf(tooManyQuantities)
}
})
if wasError {
return whichError
}
listOfValidQuantities = result[:resultCount]
return nil
}
func errorResponse(w http.ResponseWriter, errType string) {
fmt.Fprintf(w, errType)
}
func diecutHandler(w http.ResponseWriter, r *http.Request) {
if params := strings.Split(r.URL.Path, "/"); len(params) == validNumberOfURLParams {
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)
countNumber, cOk := strconv.ParseInt(count, 10, 16)
countNumber16 := int16(countNumber)
foundValidQuantity := false
for _, value := range(listOfValidQuantities){
if value == countNumber16 {
foundValidQuantity = true
break
}
}
if wOk != nil || hOk != nil || cOk != nil || !foundValidQuantity {
errorResponse(w, invalidParamsType)
} else {
fmt.Fprintf(w, "%dx%d | %d", width, height, countNumber)
}
} else {
errorResponse(w, invalidNumberOfSizeParamError)
}
} else {
errorResponse(w, invalidNumberOfParamsError)
}
}
func defaultHandler(w http.ResponseWriter, r *http.Request) {
errorResponse(w, invalidURL)
}
func initWebPage() error{
p := phantomjs.DefaultProcess
stickerMuleWebPage, err := p.CreateWebPage()
if err != nil {
return err
}
// Open a URL.
if err := stickerMuleWebPage.Open(stickerMuleURL); err != nil {
return err
}
content, err := stickerMuleWebPage.Content()
if err != nil {
return err
}
stickerMuleWebPageDocument,err = goquery.NewDocumentFromReader(strings.NewReader(content))
if err != nil {
return err
}
return nil
}
func closingCleanUp(){
phantomjs.DefaultProcess.Close()
stickerMuleWebPage.Close()
}
func main() {
//init phantomJS
if err:= phantomjs.DefaultProcess.Open(); err != nil {
fmt.Println("Error : ", err)
return
}
defer closingCleanUp()
//init web page and document
if err:= initWebPage() ; err != nil {
fmt.Println("Error : ", err)
return
}
//init valid values for stickers quantity
if err:= getListOfQuantities() ; err != nil {
fmt.Println("Error : ", err)
return
}
http.HandleFunc("/prices/diecut/", diecutHandler)
http.HandleFunc("/", defaultHandler)
fmt.Println("Server running on localhost:8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}