Merge tag '0.3.0' into production
This commit is contained in:
commit
e92b71e0b1
38 changed files with 1877 additions and 88 deletions
23
Makefile
23
Makefile
|
@ -1,14 +1,21 @@
|
|||
PHONY: all
|
||||
|
||||
dockerized:
|
||||
docker-compose -f compose/docker-compose.yml down
|
||||
docker-compose -f compose/docker-compose.yml up --build -d
|
||||
prod:
|
||||
docker-compose -f docker/oef_prod/docker-compose.yml down
|
||||
docker-compose -f docker/oef_prod/docker-compose.yml up --build -d
|
||||
|
||||
dev:
|
||||
killall main || echo "Process was not running."
|
||||
docker-compose -f compose/docker-compose_outside_docker.yml down
|
||||
docker-compose -f compose/docker-compose_outside_docker.yml up -d db
|
||||
docker-compose -f compose/docker-compose_outside_docker.yml up -d smtp
|
||||
go run -race main.go --config=config/config_dev.yaml &
|
||||
docker-compose -f docker/oef_dev/docker-compose.yaml down
|
||||
docker-compose -f docker/oef_dev/docker-compose.yaml up -d db
|
||||
docker-compose -f docker/oef_dev/docker-compose.yaml up -d smtp
|
||||
go run -race main.go --config=docker/oef_dev/config/config.yaml &
|
||||
|
||||
all: dockerized
|
||||
test:
|
||||
killall main || echo "Process was not running."
|
||||
docker-compose -f docker/oef_test/docker-compose.yaml down
|
||||
docker-compose -f docker/oef_test/docker-compose.yaml up -d db
|
||||
docker-compose -f docker/oef_test/docker-compose.yaml up -d smtp
|
||||
go run -race main.go --config=docker/oef_test/config/config.yaml &
|
||||
|
||||
all: prod
|
||||
|
|
3
VERSION
3
VERSION
|
@ -1 +1,2 @@
|
|||
0.2.1-10-gac64cee-production
|
||||
0.2.1-26-g368de33-master
|
||||
|
||||
|
|
3
benchmarks/.gitignore
vendored
Normal file
3
benchmarks/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
benchmarks
|
||||
targets/*
|
||||
results/*
|
187
benchmarks/gen_targets.go
Normal file
187
benchmarks/gen_targets.go
Normal file
|
@ -0,0 +1,187 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"git.andreafazzi.eu/andrea/oef/client"
|
||||
"git.andreafazzi.eu/andrea/oef/orm"
|
||||
"github.com/gocarina/gocsv"
|
||||
vegeta "github.com/tsenart/vegeta/lib"
|
||||
)
|
||||
|
||||
type config struct {
|
||||
Url string
|
||||
}
|
||||
|
||||
type genFunc func(string, *config) error
|
||||
|
||||
var (
|
||||
generators map[string]genFunc
|
||||
templateDir string = "./templates"
|
||||
)
|
||||
|
||||
func incr(value int) int {
|
||||
return value + 1
|
||||
}
|
||||
|
||||
func genPOSTResponseTargets(targetName string, conf *config) error {
|
||||
var (
|
||||
participants []*orm.Participant
|
||||
tokens map[string]string
|
||||
)
|
||||
|
||||
log.Println("Read participants.csv...")
|
||||
|
||||
input, err := ioutil.ReadFile("./testdata/participants.csv")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := gocsv.Unmarshal(strings.NewReader(string(input)), &participants); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
log.Println("Obtaining tokens for each participants...")
|
||||
tokens = make(map[string]string, 0)
|
||||
for _, participant := range participants {
|
||||
token, err := client.GetToken(conf.Url, participant.FiscalCode, participant.Password)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tokens[participant.FiscalCode] = token
|
||||
}
|
||||
|
||||
targets := make([]*vegeta.Target, 0)
|
||||
form := url.Values{}
|
||||
form.Set("Singleresponses.0", "32")
|
||||
|
||||
for i, participant := range participants {
|
||||
targets = append(targets, &vegeta.Target{
|
||||
Method: "POST",
|
||||
URL: fmt.Sprintf("%s/responses/%d/update?format=html&tpl_content=responses_add_update&tpl_layout=base&update=true&login_session=%s", conf.Url, i+1, tokens[participant.FiscalCode]),
|
||||
Body: []byte(form.Encode()),
|
||||
Header: http.Header{"Content-Type": []string{"application/x-www-form-urlencoded"}},
|
||||
})
|
||||
}
|
||||
|
||||
err = os.Mkdir("targets", 0777)
|
||||
if errors.Is(err, &os.PathError{}) {
|
||||
return err
|
||||
}
|
||||
output, err := os.Create("./targets/post_response_targets.txt")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer output.Close()
|
||||
|
||||
for _, t := range targets {
|
||||
var line string
|
||||
buf := bytes.NewBufferString(line)
|
||||
encoder := json.NewEncoder(buf)
|
||||
encoder.SetEscapeHTML(false)
|
||||
err := encoder.Encode(t)
|
||||
// jsonData, err := json.Marshal(t)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = output.WriteString(buf.String() + "\n\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func genGETResponseTargets(targetName string, conf *config) error {
|
||||
var data struct {
|
||||
Participants []*orm.Participant
|
||||
Tokens map[string]string
|
||||
Config *config
|
||||
}
|
||||
|
||||
data.Config = conf
|
||||
|
||||
log.Println("Read participants.csv...")
|
||||
|
||||
input, err := ioutil.ReadFile("./testdata/participants.csv")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := gocsv.Unmarshal(strings.NewReader(string(input)), &data.Participants); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
log.Println("Obtaining tokens for each participants...")
|
||||
data.Tokens = make(map[string]string, 0)
|
||||
for _, participant := range data.Participants {
|
||||
token, err := client.GetToken(data.Config.Url, participant.FiscalCode, participant.Password)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
data.Tokens[participant.FiscalCode] = token
|
||||
}
|
||||
|
||||
tmplPath := path.Join(templateDir, targetName+".tpl")
|
||||
|
||||
log.Printf("Parse %s template", tmplPath)
|
||||
tmpl, err := template.New(filepath.Base(tmplPath)).Funcs(template.FuncMap{"incr": incr}).ParseFiles(tmplPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = os.Mkdir("targets", 0777)
|
||||
if errors.Is(err, &os.PathError{}) {
|
||||
return err
|
||||
}
|
||||
output, err := os.Create("./targets/response_targets.txt")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer output.Close()
|
||||
|
||||
log.Printf("Execute %s template and generate targets...", targetName)
|
||||
err = tmpl.Execute(output, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
generators = map[string]genFunc{
|
||||
"responses": genGETResponseTargets,
|
||||
"post_responses": genPOSTResponseTargets,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func main() {
|
||||
target := flag.String("targets", "responses", "Generate targets for participants responses.")
|
||||
url := flag.String("url", "http://localhost:3000", "The URL of the host.")
|
||||
flag.Parse()
|
||||
|
||||
fn, ok := generators[*target]
|
||||
if !ok {
|
||||
log.Fatal(errors.New("Unknown target"))
|
||||
}
|
||||
|
||||
err := fn(*target, &config{Url: *url})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
token=`curl -u admin:aolieVooju https://test.olimpiadi-economiaefinanza.it/get_token | jq -r '.Token'`
|
||||
url="https://test.olimpiadi-economiaefinanza.it/responses/1/update?format=html&tpl_content=responses_add_update&tpl_layout=base&update=true&login_session=${token}"
|
||||
ab -n 100 -c 10 $url
|
||||
|
4
benchmarks/templates/responses.tpl
Normal file
4
benchmarks/templates/responses.tpl
Normal file
|
@ -0,0 +1,4 @@
|
|||
{{range $id, $participant := .Participants -}}
|
||||
{{- $username := $participant.FiscalCode -}}
|
||||
GET {{$.Config.Url}}/responses/{{$id|incr}}/update?format=html&tpl_content=responses_add_update&tpl_layout=base&update=true&login_session={{index $.Tokens $username}}
|
||||
{{end}}
|
1001
benchmarks/testdata/participants.csv
vendored
Normal file
1001
benchmarks/testdata/participants.csv
vendored
Normal file
File diff suppressed because it is too large
Load diff
|
@ -60,6 +60,13 @@ func Dial(host, username, password string) (*Client, error) {
|
|||
return client, nil
|
||||
}
|
||||
|
||||
// GetToken get the token associated with the user.
|
||||
func GetToken(host, username, password string) (string, error) {
|
||||
client, err := Dial(host, username, password)
|
||||
|
||||
return client.token, err
|
||||
}
|
||||
|
||||
func (c *Client) SendRequest(method string, path string, data []byte) ([]byte, error) {
|
||||
// Create the https request
|
||||
|
||||
|
@ -228,27 +235,3 @@ func (c *Client) Exists(model orm.IDer) bool {
|
|||
_, err := c.Read(model)
|
||||
return err != gorm.ErrRecordNotFound
|
||||
}
|
||||
|
||||
// // FIXME: refactor this (it's duplicated across the code)
|
||||
// func pluralizedModelName(value interface{}) string {
|
||||
// return inflection.Plural(strings.ToLower(reflect.ModelName(value)))
|
||||
// }
|
||||
|
||||
// // FIXME: refactor this (it's duplicated across the code)
|
||||
// func callString(value interface{}) string {
|
||||
// if value != nil {
|
||||
// switch reflect.ValueOf(value).Kind() {
|
||||
// case reflect.String:
|
||||
// return value.(string)
|
||||
// case reflect.Bool:
|
||||
// if value.(bool) {
|
||||
// return i18n.Text["answerCorrect"]["it"]
|
||||
// }
|
||||
// return "false"
|
||||
// default:
|
||||
// return reflect.ValueOf(value).MethodByName("String").Interface().(func() string)()
|
||||
// }
|
||||
// } else {
|
||||
// return ""
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -45,6 +45,9 @@ type ConfigT struct {
|
|||
|
||||
LogLevel int `yaml:"log_level"`
|
||||
|
||||
// Enable profiling
|
||||
Profiling bool
|
||||
|
||||
// Secret keys
|
||||
|
||||
Keys struct {
|
||||
|
@ -68,9 +71,9 @@ type ConfigT struct {
|
|||
// Handlers
|
||||
|
||||
Handlers struct {
|
||||
PathPatterns map[string]PathPattern
|
||||
APIPathPatterns map[string]PathPattern
|
||||
Permissions map[string]map[string][]int
|
||||
PathPatterns map[string]PathPattern
|
||||
APIPathPatterns map[string]PathPattern
|
||||
Permissions map[string]map[string][]int
|
||||
AllowSessionURLQuery bool `yaml:"allow_session_url_query"`
|
||||
}
|
||||
|
||||
|
|
10
dist/main.bundle.js
vendored
10
dist/main.bundle.js
vendored
File diff suppressed because one or more lines are too long
5
dist/styles.css
vendored
5
dist/styles.css
vendored
|
@ -4,6 +4,7 @@ html {
|
|||
|
||||
body {
|
||||
padding-top: 60px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
div.login {
|
||||
|
@ -103,7 +104,7 @@ ul.karmen-related-elements {
|
|||
}
|
||||
|
||||
.sticky-offset {
|
||||
top: 56px;
|
||||
top: 60px;
|
||||
}
|
||||
|
||||
.oef-anchor-selection:target {
|
||||
|
@ -121,7 +122,7 @@ ul.karmen-related-elements {
|
|||
div.oef-anchor {
|
||||
display: block;
|
||||
position: relative;
|
||||
top: -56px;
|
||||
top: -60px;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
|
|
31
docker/oef_dev/config/config.yaml
Normal file
31
docker/oef_dev/config/config.yaml
Normal file
|
@ -0,0 +1,31 @@
|
|||
url: "http://localhost:3000"
|
||||
log_level: 2
|
||||
language: "it"
|
||||
|
||||
keys:
|
||||
cookie_store_key: "something-very-secret"
|
||||
jwt_signing_key: "secret"
|
||||
|
||||
handlers:
|
||||
allow_session_url_query: true
|
||||
|
||||
orm:
|
||||
connection: "oef:oef@tcp(localhost:3307)/oef_dev"
|
||||
options: "charset=utf8&parseTime=True&loc=Local"
|
||||
automigrate: true
|
||||
regenerate: false
|
||||
|
||||
admin:
|
||||
username: "admin"
|
||||
password: "admin"
|
||||
|
||||
subscriber:
|
||||
password: "subscribe"
|
||||
|
||||
smtp:
|
||||
host: "localhost"
|
||||
port: 1025
|
||||
username: ""
|
||||
password: ""
|
||||
from: "no-reply@olimpiadi-economiaefinanza.it"
|
||||
bcc: "bcc@fake.org"
|
|
@ -3,7 +3,7 @@ version: "3.3"
|
|||
services:
|
||||
|
||||
app:
|
||||
build: ../
|
||||
build: ../../
|
||||
ports:
|
||||
- 3000:3000
|
||||
environment:
|
||||
|
@ -19,7 +19,6 @@ services:
|
|||
restart: always
|
||||
volumes:
|
||||
- db:/var/lib/mysql
|
||||
# - ./sql:/docker-entrypoint-initdb.d
|
||||
env_file:
|
||||
- db.env
|
||||
ports:
|
17
docker/oef_prod/config/config.yaml
Normal file
17
docker/oef_prod/config/config.yaml
Normal file
|
@ -0,0 +1,17 @@
|
|||
url: "http://localhost:3000"
|
||||
log_level: 2
|
||||
language: "it"
|
||||
|
||||
keys:
|
||||
cookie_store_key: "something-very-secret"
|
||||
jwt_signing_key: "secret"
|
||||
|
||||
orm:
|
||||
connection: "oef:oef@tcp(db:3306)/oef_dev"
|
||||
options: "charset=utf8&parseTime=True&loc=Local"
|
||||
automigrate: true
|
||||
regenerate: false
|
||||
|
||||
admin:
|
||||
username: "admin"
|
||||
password: "admin"
|
10
docker/oef_prod/db.env
Normal file
10
docker/oef_prod/db.env
Normal file
|
@ -0,0 +1,10 @@
|
|||
MYSQL_ROOT_PASSWORD=oef
|
||||
MYSQL_PASSWORD=oef
|
||||
MYSQL_DATABASE=oef_prod
|
||||
MYSQL_USER=oef
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -3,7 +3,7 @@ version: "3.3"
|
|||
services:
|
||||
|
||||
app:
|
||||
build: ../
|
||||
build: ../../
|
||||
ports:
|
||||
- 3000:3000
|
||||
environment:
|
||||
|
@ -11,7 +11,7 @@ services:
|
|||
- DB_PORT=3306
|
||||
volumes:
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- ../config/config.yaml:/src/oef/config/config.yaml
|
||||
- ./config/config.yaml:/src/oef/config/config.yaml
|
||||
|
||||
db:
|
||||
image: mariadb
|
32
docker/oef_test/config/config.yaml
Normal file
32
docker/oef_test/config/config.yaml
Normal file
|
@ -0,0 +1,32 @@
|
|||
url: "http://localhost:3000"
|
||||
log_level: 2
|
||||
language: "it"
|
||||
profiling: true
|
||||
|
||||
keys:
|
||||
cookie_store_key: "something-very-secret"
|
||||
jwt_signing_key: "secret"
|
||||
|
||||
handlers:
|
||||
allow_session_url_query: true
|
||||
|
||||
orm:
|
||||
connection: "oef:oef@tcp(localhost:3307)/oef_test"
|
||||
options: "charset=utf8&parseTime=True&loc=Local"
|
||||
automigrate: true
|
||||
regenerate: false
|
||||
|
||||
admin:
|
||||
username: "admin"
|
||||
password: "admin"
|
||||
|
||||
subscriber:
|
||||
password: "subscribe"
|
||||
|
||||
smtp:
|
||||
host: "localhost"
|
||||
port: 1025
|
||||
username: ""
|
||||
password: ""
|
||||
from: "no-reply@olimpiadi-economiaefinanza.it"
|
||||
bcc: "bcc@fake.org"
|
10
docker/oef_test/db.env
Normal file
10
docker/oef_test/db.env
Normal file
|
@ -0,0 +1,10 @@
|
|||
MYSQL_ROOT_PASSWORD=oef
|
||||
MYSQL_PASSWORD=oef
|
||||
MYSQL_DATABASE=oef_test
|
||||
MYSQL_USER=oef
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
37
docker/oef_test/docker-compose.yaml
Normal file
37
docker/oef_test/docker-compose.yaml
Normal file
|
@ -0,0 +1,37 @@
|
|||
version: "3.3"
|
||||
|
||||
services:
|
||||
|
||||
app:
|
||||
build: ../../
|
||||
ports:
|
||||
- 3000:3000
|
||||
environment:
|
||||
- DB_HOST=db
|
||||
- DB_PORT=3306
|
||||
volumes:
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- ./config/config.yaml:/src/oef/config/config.yaml
|
||||
|
||||
db:
|
||||
image: mariadb
|
||||
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
|
||||
restart: always
|
||||
volumes:
|
||||
- db:/var/lib/mysql
|
||||
- ./sql:/docker-entrypoint-initdb.d
|
||||
env_file:
|
||||
- db.env
|
||||
ports:
|
||||
- 3307:3306
|
||||
|
||||
smtp:
|
||||
image: digiplant/fake-smtp
|
||||
ports:
|
||||
- "1025:25"
|
||||
|
||||
volumes:
|
||||
db:
|
||||
|
||||
|
||||
|
355
docker/oef_test/sql/oef_test.sql
Normal file
355
docker/oef_test/sql/oef_test.sql
Normal file
File diff suppressed because one or more lines are too long
21
go.mod
21
go.mod
|
@ -6,21 +6,42 @@ require (
|
|||
github.com/BurntSushi/toml v0.3.1
|
||||
github.com/PuerkitoBio/goquery v1.5.0
|
||||
github.com/auth0/go-jwt-middleware v0.0.0-20190805220309-36081240882b
|
||||
github.com/bmizerany/perks v0.0.0-20141205001514-d9a9656a3a4b // indirect
|
||||
github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee // indirect
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
github.com/dgryski/go-gk v0.0.0-20140819190930-201884a44051 // indirect
|
||||
github.com/dustin/go-humanize v1.0.0 // indirect
|
||||
github.com/elgs/gojq v0.0.0-20160421194050-81fa9a608a13 // indirect
|
||||
github.com/elgs/gosplitargs v0.0.0-20161028071935-a491c5eeb3c8 // indirect
|
||||
github.com/gobwas/glob v0.2.3
|
||||
github.com/gocarina/gocsv v0.0.0-20190927101021-3ecffd272576
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
github.com/gorilla/handlers v1.4.2
|
||||
github.com/gorilla/mux v1.7.3
|
||||
github.com/gorilla/schema v1.1.0
|
||||
github.com/gorilla/sessions v1.2.0
|
||||
github.com/influxdata/tdigest v0.0.1 // indirect
|
||||
github.com/jinzhu/gorm v1.9.11
|
||||
github.com/jinzhu/inflection v1.0.0
|
||||
github.com/kr/pretty v0.1.0 // indirect
|
||||
github.com/mailru/easyjson v0.7.0 // indirect
|
||||
github.com/monochromegane/terminal v0.0.0-20161222050454-9bc47e2707d9 // indirect
|
||||
github.com/pkg/profile v1.4.0
|
||||
github.com/remogatto/prettytest v0.0.0-20191105125618-8fe70ed7a3e1
|
||||
github.com/robfig/cron v1.2.0
|
||||
github.com/rs/jplot v0.0.0-20180624024257-9b69b4534805 // indirect
|
||||
github.com/sethvargo/go-password v0.1.3
|
||||
github.com/smartystreets/goconvey v1.6.4 // indirect
|
||||
github.com/streadway/quantile v0.0.0-20150917103942-b0c588724d25 // indirect
|
||||
github.com/tsenart/go-tsz v0.0.0-20180814235614-0bd30b3df1c3 // indirect
|
||||
github.com/tsenart/vegeta v12.7.0+incompatible
|
||||
github.com/urfave/negroni v1.0.0 // indirect
|
||||
github.com/wcharczuk/go-chart v2.0.1+incompatible // indirect
|
||||
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d // indirect
|
||||
golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa // indirect
|
||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 // indirect
|
||||
golang.org/x/text v0.3.2 // indirect
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||
gopkg.in/yaml.v2 v2.2.4
|
||||
)
|
||||
|
|
51
go.sum
51
go.sum
|
@ -16,15 +16,27 @@ github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb
|
|||
github.com/auth0/go-jwt-middleware v0.0.0-20190805220309-36081240882b h1:CvoEHGmxWl5kONC5icxwqV899dkf4VjOScbxLpllEnw=
|
||||
github.com/auth0/go-jwt-middleware v0.0.0-20190805220309-36081240882b/go.mod h1:LWMyo4iOLWXHGdBki7NIht1kHru/0wM179h+d3g8ATM=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/bmizerany/perks v0.0.0-20141205001514-d9a9656a3a4b h1:AP/Y7sqYicnjGDfD5VcY4CIfh1hRXBUavxrvELjTiOE=
|
||||
github.com/bmizerany/perks v0.0.0-20141205001514-d9a9656a3a4b/go.mod h1:ac9efd0D1fsDb3EJvhqgXRbFx7bs2wqZ10HQPeU8U/Q=
|
||||
github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee h1:BnPxIde0gjtTnc9Er7cxvBk8DHLWhEux0SxayC8dP6I=
|
||||
github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3 h1:tkum0XDgfR0jcVVXuTsYv/erY2NnEDqwRojbxR1rBYA=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-gk v0.0.0-20140819190930-201884a44051 h1:ByJUvQYyTtNNCVfYNM48q6uYUT4fAlN0wNmd3th4BSo=
|
||||
github.com/dgryski/go-gk v0.0.0-20140819190930-201884a44051/go.mod h1:qm+vckxRlDt0aOla0RYJJVeqHZlWfOm2UIxHaqPB46E=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/elgs/gojq v0.0.0-20160421194050-81fa9a608a13 h1:/voSflvo4UvPT0XZy+YQMuUk04topJ2swxyOOyXefMM=
|
||||
github.com/elgs/gojq v0.0.0-20160421194050-81fa9a608a13/go.mod h1:rQELVIqRXpraeUryHOBadz99ePvEVQmTVpGr8M9QQ4Q=
|
||||
github.com/elgs/gosplitargs v0.0.0-20161028071935-a491c5eeb3c8 h1:bD2/rCXwgXJm2vgoSSSCM9IPjVFfEoQFFblzg7HHABI=
|
||||
github.com/elgs/gosplitargs v0.0.0-20161028071935-a491c5eeb3c8/go.mod h1:o4DgpccPNAQAlPSxo7I4L/LWNh2oyr/BBGSynrLTmZM=
|
||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
|
||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
|
@ -39,6 +51,8 @@ github.com/gocarina/gocsv v0.0.0-20190927101021-3ecffd272576 h1:nDMaZgjBNKhsVJEW
|
|||
github.com/gocarina/gocsv v0.0.0-20190927101021-3ecffd272576/go.mod h1:/oj50ZdPq/cUjA02lMZhijk5kR31SEydKyqah1OgBuo=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
|
@ -64,6 +78,8 @@ github.com/gorilla/sessions v1.2.0 h1:S7P+1Hm5V/AT9cjEcUD5uDaQSX0OE577aCXgoaKpYb
|
|||
github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/influxdata/tdigest v0.0.1 h1:XpFptwYmnEKUqmkcDjrzffswZ3nvNeevbUSLPP/ZzIY=
|
||||
github.com/influxdata/tdigest v0.0.1/go.mod h1:Z0kXnxzbTC2qrx4NaIzYkE1k66+6oEDQTvL95hQFh5Y=
|
||||
github.com/jinzhu/gorm v1.9.11 h1:gaHGvE+UnWGlbWG4Y3FUwY1EcZ5n6S9WtqBA/uySMLE=
|
||||
github.com/jinzhu/gorm v1.9.11/go.mod h1:bu/pK8szGZ2puuErfU0RwyeNdsf3e6nCX/noXaVxkfw=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
|
@ -84,9 +100,13 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
|||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4=
|
||||
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
|
||||
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||
github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=
|
||||
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/monochromegane/terminal v0.0.0-20161222050454-9bc47e2707d9 h1:YhsMshmD0JlqM4ss3JBY6Ul4QLigGvBtShFYHkb3JGg=
|
||||
github.com/monochromegane/terminal v0.0.0-20161222050454-9bc47e2707d9/go.mod h1:9N3QHEQ4Ov/dAnHmOIJ8ffm8O1iQfCPfso+PpakXPsY=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
|
@ -94,6 +114,8 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa
|
|||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/profile v1.4.0 h1:uCmaf4vVbWAOZz36k1hrQD7ijGRzLwaME8Am/7a4jZI=
|
||||
github.com/pkg/profile v1.4.0/go.mod h1:NWz/XGvpEW1FyYQ7fCx4dqYBLlfTcE+A9FLAkNKqjFE=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
|
@ -109,6 +131,8 @@ github.com/remogatto/prettytest v0.0.0-20191105125618-8fe70ed7a3e1 h1:qU1a7/zsCi
|
|||
github.com/remogatto/prettytest v0.0.0-20191105125618-8fe70ed7a3e1/go.mod h1:jOEnp79oIHy5cvQSHeLcgVJk1GHOOHJHQWps/d1N5Yo=
|
||||
github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=
|
||||
github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
|
||||
github.com/rs/jplot v0.0.0-20180624024257-9b69b4534805 h1:Y9XRz+J6fBX74oHZX9KwMzVRnq7AJNxfJSilUpZBrvU=
|
||||
github.com/rs/jplot v0.0.0-20180624024257-9b69b4534805/go.mod h1:1GjGIxIXi6t9QbWYLwl8E7knyiIbtoGShze7zXmj2Nw=
|
||||
github.com/sethvargo/go-password v0.1.3 h1:18KkbGDkw8SuzeohAbWqBLNSfRQblVwEHOLbPa0PvWM=
|
||||
github.com/sethvargo/go-password v0.1.3/go.mod h1:2tyaaoHK/AlXwh5WWQDYjqQbHcq4cjPj5qb/ciYvu/Q=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
|
@ -116,16 +140,29 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykE
|
|||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/streadway/quantile v0.0.0-20150917103942-b0c588724d25 h1:7z3LSn867ex6VSaahyKadf4WtSsJIgne6A1WLOAGM8A=
|
||||
github.com/streadway/quantile v0.0.0-20150917103942-b0c588724d25/go.mod h1:lbP8tGiBjZ5YWIc2fzuRpTaz0b/53vT6PEs3QuAWzuU=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/tsenart/go-tsz v0.0.0-20180814235614-0bd30b3df1c3 h1:pcQGQzTwCg//7FgVywqge1sW9Yf8VMsMdG58MI5kd8s=
|
||||
github.com/tsenart/go-tsz v0.0.0-20180814235614-0bd30b3df1c3/go.mod h1:SWZznP1z5Ki7hDT2ioqiFKEse8K9tU2OUvaRI0NeGQo=
|
||||
github.com/tsenart/vegeta v12.7.0+incompatible h1:sGlrv11EMxQoKOlDuMWR23UdL90LE5VlhKw/6PWkZmU=
|
||||
github.com/tsenart/vegeta v12.7.0+incompatible/go.mod h1:Smz/ZWfhKRcyDDChZkG3CyTHdj87lHzio/HOCkbndXM=
|
||||
github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc=
|
||||
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
|
||||
github.com/wcharczuk/go-chart v2.0.1+incompatible h1:0pz39ZAycJFF7ju/1mepnk26RLVLBCWz1STcD3doU0A=
|
||||
github.com/wcharczuk/go-chart v2.0.1+incompatible/go.mod h1:PF5tmL4EIx/7Wf+hEkpCqYi5He4u90sw+0+6FhrryuE=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d h1:9FCpayM9Egr1baVnV1SX0H87m+XB0B8S0hAMi99X/3U=
|
||||
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/image v0.0.0-20200119044424-58c23975cae1 h1:5h3ngYt7+vXCDZCup/HkCQgW5XwmSvR/nA2JmJ0RErg=
|
||||
golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
|
@ -139,6 +176,9 @@ golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73r
|
|||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa h1:F+8P+gmewFQYRk6JoLQLwjBCTu3mcIURZfNkVweuRKA=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -150,15 +190,26 @@ golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 h1:1/DFK4b7JH8DmkqhUk48onnSfrPzImPoVxuomtbT2nk=
|
||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
|
||||
gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
|
|
|
@ -374,6 +374,9 @@ func respondWithError(h *Handlers, w http.ResponseWriter, r *http.Request, err e
|
|||
if format == "" {
|
||||
format = renderer.GetContentFormat(r)
|
||||
}
|
||||
if h.Config.LogLevel > config.LOG_LEVEL_OFF {
|
||||
log.Println(err)
|
||||
}
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
h.Renderer[format].Render(w, r, h.CookieStore, err)
|
||||
}
|
||||
|
|
6
main.go
6
main.go
|
@ -8,6 +8,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/gorilla/handlers"
|
||||
"github.com/pkg/profile"
|
||||
|
||||
"git.andreafazzi.eu/andrea/oef/config"
|
||||
oef_handlers "git.andreafazzi.eu/andrea/oef/handlers"
|
||||
|
@ -65,6 +66,11 @@ func main() {
|
|||
log.Println("Eventually write regions on DB...")
|
||||
orm.CreateRegions(db)
|
||||
|
||||
if conf.Profiling {
|
||||
log.Println("Start profiling...")
|
||||
defer profile.Start().Stop()
|
||||
}
|
||||
|
||||
log.Println("OEF is listening to port 3000...")
|
||||
|
||||
htmlRenderer, err := renderer.NewHTMLRenderer("templates")
|
||||
|
|
|
@ -132,7 +132,12 @@ func (model *Response) Read(db *Database, args map[string]string, w http.Respons
|
|||
|
||||
id := args["id"]
|
||||
|
||||
if err := db._db.Preload("Contest").Preload("Participant").First(&response, id).Error; err != nil {
|
||||
if err := db._db.
|
||||
Preload("Contest").
|
||||
Preload("Participant").
|
||||
Preload("Creator").
|
||||
Preload("Updater").
|
||||
First(&response, id).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -232,7 +237,6 @@ func (model *Response) Update(db *Database, args map[string]string, w http.Respo
|
|||
if !response.(*Response).IsActive() {
|
||||
return nil, errors.OutOfTime
|
||||
}
|
||||
|
||||
err = renderer.Decode(response, r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -33,7 +33,7 @@ var (
|
|||
"prettyTime": prettyTime,
|
||||
"prettyDateTime": prettyDateTime,
|
||||
"zeroTime": zeroTime,
|
||||
"minutes": minutes,
|
||||
"seconds": seconds,
|
||||
"modelPath": modelPath,
|
||||
"dict": dict,
|
||||
"yaml": yaml,
|
||||
|
@ -50,7 +50,7 @@ var (
|
|||
"mod2": mod2,
|
||||
"toLower": toLower,
|
||||
"anchor": anchor,
|
||||
"alertLink": alertLink,
|
||||
"alertLink": alertLink,
|
||||
"html": html,
|
||||
"field": field,
|
||||
"modelName": modelName,
|
||||
|
@ -329,8 +329,8 @@ func zeroTime(t *time.Time) bool {
|
|||
return *t == time.Time{}
|
||||
}
|
||||
|
||||
func minutes(d time.Duration) int {
|
||||
return int(d.Minutes())
|
||||
func seconds(d time.Duration) int {
|
||||
return int(d.Seconds())
|
||||
}
|
||||
|
||||
func modelPath(model string, action string, id uint) string {
|
||||
|
|
|
@ -4,9 +4,13 @@ $(function () {
|
|||
|
||||
setInterval(function() {
|
||||
var timeleft = parseInt($("#timeleft").html());
|
||||
timeleft--;
|
||||
if (timeleft > 0) {
|
||||
timeleft--;
|
||||
} else {
|
||||
timeleft = 0;
|
||||
}
|
||||
$("#timeleft").html(timeleft)
|
||||
}, 1000*60);
|
||||
}, 1000);
|
||||
|
||||
$("#myInput").on("keyup", function(eventObject) {
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ html {
|
|||
|
||||
body {
|
||||
padding-top: 60px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
div.login {
|
||||
|
@ -103,7 +104,7 @@ ul.karmen-related-elements {
|
|||
}
|
||||
|
||||
.sticky-offset {
|
||||
top: 56px;
|
||||
top: 60px;
|
||||
}
|
||||
|
||||
.oef-anchor-selection:target {
|
||||
|
@ -121,6 +122,6 @@ ul.karmen-related-elements {
|
|||
div.oef-anchor {
|
||||
display: block;
|
||||
position: relative;
|
||||
top: -56px;
|
||||
top: -60px;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<link rel="stylesheet" href="/styles.css" />
|
||||
<title>Olimpiadi di Economia e Finanza - Piattaforma di gara</title>
|
||||
</head>
|
||||
<body>
|
||||
<body data-spy="scroll">
|
||||
<nav class="navbar navbar-expand-lg fixed-top navbar-dark bg-primary">
|
||||
{{- $homeURL := "" -}}
|
||||
{{- if $isAdmin}}{{$homeURL = all "Contest"}}{{end}}
|
||||
|
@ -94,8 +94,8 @@
|
|||
</div>
|
||||
</div>
|
||||
<script
|
||||
src="https://code.jquery.com/jquery-3.4.1.slim.min.js"
|
||||
integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n"
|
||||
src="https://code.jquery.com/jquery-3.4.1.min.js"
|
||||
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
|
||||
crossorigin="anonymous">
|
||||
</script>
|
||||
<script
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
|
||||
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
|
||||
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<a href="{{.id|show .options.model}}" class="btn btn-default">Annulla</a>
|
||||
{{else}}
|
||||
{{if .options.cancelTitle}}
|
||||
<a href="{{all .options.model}}" class="btn btn-default">Annulla</a>
|
||||
<a href="{{if .referer}}{{.referer|html}}{{else}}{{all .options.model}}{{end}}" class="btn btn-default">Annulla</a>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</div>
|
||||
|
|
|
@ -97,7 +97,7 @@
|
|||
icon: "fa fa-hourglass-start"
|
||||
`}}
|
||||
|
||||
{{$noElements := "Al partecipante non è associata alcuna risposta."}}
|
||||
{{$noElements := "Al partecipante non è associata alcuna prova."}}
|
||||
{{template "relation_list" dict "options" ($options|yaml) "data" .Data.Responses "noElements" $noElements}}
|
||||
|
||||
</div>
|
||||
|
|
|
@ -12,21 +12,19 @@
|
|||
{{- end -}}
|
||||
{{- if $isAdmin -}}
|
||||
{{template "add_update_header" dict "update" $update "addTitle" "Rispondi al questionario" "updateTitle" (printf "Aggiorna %s" (.Data|string))}}
|
||||
{{- else -}}
|
||||
{{template "add_update_header" dict "update" $update "addTitle" "Rispondi al questionario" "updateTitle" (.Data|string)}}
|
||||
{{- end -}}
|
||||
{{- $form := "form_add_update" -}}
|
||||
<div class="row">
|
||||
<div class="col-2 border-right">
|
||||
<div class="col-2">
|
||||
<div class="sticky-top sticky-offset">
|
||||
<nav class="nav flex-column">
|
||||
{{- if and $isParticipant .Data.TimeLeft}}
|
||||
<h5 class="mt-1 badge badge-info sticky-top sticky-offset">Tempo rimanente <span id="timeleft">{{.Data.TimeLeft.Minutes|toInt}}</span> min</h5>
|
||||
{{- end -}}
|
||||
{{range $n, $question := .Data.Questions -}}
|
||||
<a class="nav-link" href="#question_{{$n}}">Domanda {{$n|incr}}</a>
|
||||
{{end -}}
|
||||
</nav>
|
||||
<div class="card">
|
||||
<div class="card-header">Explorer delle domande</div>
|
||||
<div id="navbar_questions" class="list-group">
|
||||
{{range $n, $question := .Data.Questions -}}
|
||||
<a class="list-group-item list-group-item-action" href="#question_{{$n}}">Domanda {{$n|incr}}</a>
|
||||
{{end -}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
|
@ -36,6 +34,7 @@
|
|||
method="POST"
|
||||
role="form"
|
||||
id={{$form}}>
|
||||
<div data-spy="scroll" data-target="#navbar_questions" data-offset="0">
|
||||
{{range $id,$question := .Data.Questions -}}
|
||||
<div class="oef-anchor" id="question_{{$id}}"></div>
|
||||
<div class="oef-anchor-selection">
|
||||
|
@ -57,15 +56,30 @@
|
|||
</div>
|
||||
<hr>
|
||||
{{end}}
|
||||
{{- if $isAdmin -}}
|
||||
{{- $options := ` { cancelTitle: "Annulla", saveTitle: "Salva", model: "Response" } ` -}}
|
||||
{{- template "submit_cancel_buttons" dict "options" ($options|yaml) "id" (.Data|field "ID") "update" $update -}}
|
||||
{{- else -}}
|
||||
{{- $options := ` { saveTitle: "Invia le risposte", model: "Response" } ` -}}
|
||||
{{template "submit_cancel_buttons" dict "options" ($options|yaml) "id" (.Data|field "ID") "update" $update}}
|
||||
{{end -}}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="col-2">
|
||||
<div class="sticky-top sticky-offset">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Informazioni sulla prova
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<dl>
|
||||
<dt>Gara</dt><dd>{{.Data.Contest}}</dd>
|
||||
<dt>Partecipante</dt><dd>{{.Data.Participant}}</dd>
|
||||
{{- if $isParticipant -}}
|
||||
<dt>Tempo rimanente</dt>{{if .Data.TimeLeft}}<dd><span id="timeleft">{{.Data.TimeLeft.Seconds|toInt}}</span> secondi rimanenti</dd>{{else}}<dd>La gara è sempre attiva</dd>{{end}}
|
||||
{{- end -}}
|
||||
</dl>
|
||||
<button type="submit" class="btn btn-primary" form="{{$form}}">Salva</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{{ end -}}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<dd class="col-sm-9">
|
||||
{{if not (.Data.Contest.Date|zeroTime)}}
|
||||
Giorno {{.Data.Contest.Date|prettyDate}} dalle ore {{.Data.Contest.StartTime|convertTime}} alle ore {{.Data.Contest.EndTime|convertTime}}
|
||||
{{- if not .Data.IsActive -}}<strong> [Scaduta]</strong>{{- end -}}
|
||||
{{- if not .Data.IsActive -}}<strong> [Scaduta o non ancora attiva]</strong>{{- end -}}
|
||||
{{else}}
|
||||
La gara è sempre attiva.
|
||||
{{end}}
|
||||
|
|
|
@ -106,7 +106,11 @@
|
|||
{{template "submit_cancel_buttons" dict "options" ($options|yaml) "id" (.Data|field "ID") "update" $update}}
|
||||
{{else}}
|
||||
{{$options := ` { cancelTitle: "Annulla", saveTitle: "Salva", model: "School" } `}}
|
||||
{{if $isAdmin}}
|
||||
{{template "submit_cancel_buttons" dict "options" ($options|yaml) "id" (.Data|field "ID") "update" $update}}
|
||||
{{else}}
|
||||
{{template "submit_cancel_buttons" dict "options" ($options|yaml) "id" (.Data|field "ID") "update" $update "referer" (.Data.ID|show "School")}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
</form>
|
||||
|
|
|
@ -56,6 +56,9 @@
|
|||
<dt class="col-sm-3">Password</dt>
|
||||
<dd class="col-sm-9"><span class="text-monospace">{{.Data.User.Password}}</span></dd>
|
||||
|
||||
<dt class="col-sm-3">Referente di sede</dt><dd class="col-sm-9">{{.Data.SchoolContactPersonLastname}} {{.Data.SchoolContactPersonFirstname}}</dd>
|
||||
<dt class="col-sm-3">Responsabile di gara</dt><dd class="col-sm-9">{{.Data.ContestDirectorLastname}} {{.Data.ContestDirectorFirstname}}</dd>
|
||||
|
||||
{{if $isAdmin}}
|
||||
{{if $creatorUser:=.Data.CreatedBy}}
|
||||
<dt class="col-sm-3">Creato da</dt>
|
||||
|
|
1
watch.sh
1
watch.sh
|
@ -1,6 +1,5 @@
|
|||
#!/bin/bash
|
||||
|
||||
|
||||
echo "Executing Makefile... $1"
|
||||
|
||||
make -k $1
|
||||
|
|
Loading…
Reference in a new issue