genofire/hs_monolith
genofire
/
hs_monolith
Archived
1
0
Fork 0

[TASK] response available as json or svg template

This commit is contained in:
Martin Geno 2017-04-04 23:21:05 +02:00
parent 9b10999cde
commit 21859eec82
No known key found for this signature in database
GPG Key ID: F0D39A37E925E941
13 changed files with 164 additions and 6 deletions

View File

@ -26,6 +26,7 @@ func main() {
// load config
config = models.ReadConfigFile(configFile)
web.GoodAvailablityTemplate = config.GoodAvailablityTemplate
log.Log.Info("Starting rezension monolith")

View File

@ -1,5 +1,7 @@
webserver_bind = ":8080"
good_availablity_template = "contrib/good_availablity.svg"
[database]
type = "sqlite3"
# logging = true

View File

@ -0,0 +1,7 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<g class="arcs">
<circle cx="50" cy="50" r="40" fill="#fff" stroke="#aaa" stroke-width="5"/>
<circle cx="50" cy="50" r="40" fill="none" stroke="#26b" stroke-width="5" stroke-dasharray="251.33" stroke-dashoffset="{{process_radius .Count 10 40}}"/>
</g>
<text x="50" y="58" fill="#555" text-anchor="middle" style="font: 500 20px Roboto,Verdana,sans-serif;">{{procent .Count 10}}%</text>
</svg>

After

Width:  |  Height:  |  Size: 495 B

View File

@ -4,6 +4,7 @@ import (
"net/http"
"strconv"
logrus "github.com/Sirupsen/logrus"
"goji.io/pat"
"github.com/genofire/hs_master-kss-monolith/lib/database"
@ -31,3 +32,42 @@ func listGoods(w http.ResponseWriter, r *http.Request) {
lib.Write(w, list)
log.Info("done")
}
func getGoodAvailablityCount(w http.ResponseWriter, r *http.Request) (int, *logrus.Entry) {
log := logger.HTTP(r)
id, err := strconv.ParseInt(pat.Param(r, "productid"), 10, 64)
if err != nil {
log.Warn("wrong productid format")
http.Error(w, "wrong productid", http.StatusNotAcceptable)
return -1, log
}
log = log.WithField("productid", id)
product := models.Product{ID: id}
ok, err := product.Exists()
if err != nil {
log.Warn("product could not verified on other microservice")
http.Error(w, "product could not verified on other microservice", http.StatusGatewayTimeout)
}
if !ok {
log.Warn("product did not exists anymore")
http.Error(w, "product did not exists anymore", http.StatusNotFound)
return -1, log
}
var count float64
(&models.Good{}).FilterAvailable(database.Read.Where("product_id = ?", product.ID)).Count(&count)
return int(count), log
}
func getGoodAvailablity(w http.ResponseWriter, r *http.Request) {
count, log := getGoodAvailablityCount(w, r)
if count < 0 {
return
}
log = log.WithField("type", r.Header.Get("Content-Type"))
switch r.Header.Get("Content-Type") {
case "application/json":
lib.Write(w, count)
default:
getGoodAvailablitySVG(w, count)
}
log.Info("done")
}

37
http/good_temp.go Normal file
View File

@ -0,0 +1,37 @@
package http
import (
"bytes"
"io"
"net/http"
"os"
"text/template"
)
var GoodAvailablityTemplate string
func tempProcent(value, max int) int {
return value * 100 / max
}
func tempProcessRadius(value, max, radius int) float64 {
return (1 - float64(value)/float64(max)) * float64(radius) * 2 * 3.14
}
func getGoodAvailablitySVG(w http.ResponseWriter, count int) {
t := template.New("some")
t = t.Funcs(template.FuncMap{"procent": tempProcent,
"process_radius": tempProcessRadius,
})
buf := bytes.NewBuffer(nil)
f, _ := os.Open(GoodAvailablityTemplate) // Error handling elided for brevity.
io.Copy(buf, f) // Error handling elided for brevity.
f.Close()
s := string(buf.Bytes())
t.Parse(s)
w.Header().Set("Content-Type", "image/svg+xml")
t.Execute(w, map[string]interface{}{"Count": count})
}

17
http/good_temp_test.go Normal file
View File

@ -0,0 +1,17 @@
package http
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestTempFuncs(t *testing.T) {
assert := assert.New(t)
resultInt := tempProcent(3, 9)
assert.Equal(33, resultInt)
// TODO is there a other way to calc this?
resultFloat := tempProcessRadius(3, 9, 0)
assert.Equal(float64(0), resultFloat)
}

View File

@ -2,7 +2,9 @@ package http
import (
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/genofire/hs_master-kss-monolith/lib/database"
"github.com/genofire/hs_master-kss-monolith/models"
@ -10,7 +12,7 @@ import (
"github.com/genofire/hs_master-kss-monolith/test"
)
func TestGood(t *testing.T) {
func TestListGood(t *testing.T) {
assertion, router := test.Init(t)
BindAPI(router)
@ -33,3 +35,45 @@ func TestGood(t *testing.T) {
test.Close()
}
func TestGetGoodAvailable(t *testing.T) {
now := time.Now()
assertion, router := test.Init(t)
BindAPI(router)
session := test.NewSession(router)
result, w := session.JSONRequest("GET", "/api/good/availablity/a", nil)
assertion.Equal(http.StatusNotAcceptable, w.StatusCode)
result, w = session.JSONRequest("GET", "/api/good/availablity/1", nil)
assertion.Equal(http.StatusOK, w.StatusCode)
assertion.Equal(float64(0), result)
database.Write.Create(&models.Good{
ProductID: 3,
Comment: "blub",
LockedAt: &now,
LockedSecret: "hidden",
})
database.Write.Create(&models.Good{
ProductID: 3,
Comment: "blub",
})
database.Write.Create(&models.Good{
ProductID: 3,
Comment: "blub",
})
result, w = session.JSONRequest("GET", "/api/good/availablity/3", nil)
assertion.Equal(http.StatusOK, w.StatusCode)
assertion.Equal(float64(2), result)
req, _ := http.NewRequest("GET", "/api/good/availablity/3", nil)
req.Header.Set("Content-Type", "image/svg+xml")
rec := httptest.NewRecorder()
router.ServeHTTP(rec, req)
assertion.Equal(http.StatusOK, w.StatusCode)
test.Close()
}

View File

@ -8,4 +8,5 @@ import (
func BindAPI(router *goji.Mux) {
router.HandleFunc(pat.Get("/api/status"), status)
router.HandleFunc(pat.Get("/api/good/:productid"), listGoods)
router.HandleFunc(pat.Get("/api/good/availablity/:productid"), getGoodAvailablity)
}

View File

@ -9,6 +9,8 @@ import (
var Log *logger.Logger
type Logger logger.Entry
func init() {
Log = logger.New()
// Enable fallback if core logger is used:

View File

@ -11,9 +11,10 @@ import (
//Config the config File of this daemon
type Config struct {
WebserverBind string `toml:"webserver_bind"`
Database database.Config `toml:"database"`
GoodRelease struct {
WebserverBind string `toml:"webserver_bind"`
Database database.Config `toml:"database"`
GoodAvailablityTemplate string `toml:"good_availablity_template"`
GoodRelease struct {
After Duration `toml:"after"`
Timer Duration `toml:"timer"`
} `toml:"good_release"`

View File

@ -11,11 +11,13 @@ func TestDuration(t *testing.T) {
assert := assert.New(t)
var tests = []struct {
input string
input interface{}
err string
duration time.Duration
}{
{3, "invalid duration: \"%!s(int=3)\"", 0},
{"", "invalid duration: \"\"", 0},
{"am", "unable to parse duration am: strconv.Atoi: parsing \"a\": invalid syntax", 0},
{"1x", "invalid duration unit: x", 0},
{"1s", "", time.Second},
{"73s", "", time.Second * 73},

View File

@ -26,7 +26,7 @@ type Good struct {
}
func (g *Good) FilterAvailable(db *gorm.DB) *gorm.DB {
return db.Where("locked_secret is NULL deleted_at is NULL and send_at is NULL")
return db.Model(g).Where("locked_secret == '' OR locked_secret is NULL")
}
func (g *Good) Lock(secret string) {

View File

@ -3,6 +3,7 @@ package models
import (
"testing"
"github.com/genofire/hs_master-kss-monolith/lib/database"
"github.com/stretchr/testify/assert"
)
@ -21,4 +22,7 @@ func TestGood(t *testing.T) {
good.Unlock("blub_secret")
assert.False(good.IsLock())
assert.NotNil(good.FilterAvailable(database.Read))
}