Compare commits
No commits in common. "go" and "main" have entirely different histories.
33
.gitignore
vendored
33
.gitignore
vendored
@ -1,26 +1,13 @@
|
|||||||
# ---> Go
|
|
||||||
# If you prefer the allow list template instead of the deny list, see community template:
|
|
||||||
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
|
||||||
#
|
|
||||||
# Binaries for programs and plugins
|
|
||||||
*.exe
|
|
||||||
*.exe~
|
|
||||||
*.dll
|
|
||||||
*.so
|
|
||||||
*.dylib
|
|
||||||
|
|
||||||
# Test binary, built with `go test -c`
|
|
||||||
*.test
|
|
||||||
|
|
||||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
|
||||||
*.out
|
|
||||||
|
|
||||||
# Dependency directories (remove the comment below to include it)
|
|
||||||
vendor/
|
|
||||||
|
|
||||||
# Go workspace file
|
|
||||||
go.work
|
|
||||||
|
|
||||||
# Compiled binary
|
# Compiled binary
|
||||||
blt
|
blt
|
||||||
|
|
||||||
|
# Local data files
|
||||||
|
data/
|
||||||
|
|
||||||
|
# Compiled assets
|
||||||
|
public/css/
|
||||||
|
public/js/
|
||||||
|
|
||||||
|
# Node modules
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
65
Gruntfile.js
Normal file
65
Gruntfile.js
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
module.exports = function(grunt) {
|
||||||
|
|
||||||
|
// Project configuration.
|
||||||
|
grunt.initConfig({
|
||||||
|
pkg: grunt.file.readJSON('package.json'),
|
||||||
|
|
||||||
|
sass: {
|
||||||
|
dist: {
|
||||||
|
options: {
|
||||||
|
style: 'compressed'
|
||||||
|
},
|
||||||
|
files: [{
|
||||||
|
expand: true,
|
||||||
|
cwd: 'assets/styles',
|
||||||
|
src: ['**/*.sass'],
|
||||||
|
dest: 'public/css',
|
||||||
|
ext: '.css'
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
coffee: {
|
||||||
|
options: {
|
||||||
|
sourceMap: true,
|
||||||
|
style: 'compressed'
|
||||||
|
},
|
||||||
|
files: {
|
||||||
|
expand: true,
|
||||||
|
flatten: true,
|
||||||
|
cwd: 'assets/scripts',
|
||||||
|
src: ['*.coffee'],
|
||||||
|
dest: 'public/js',
|
||||||
|
ext: '.js'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
css: {
|
||||||
|
files: ['assets/styles/**/*.sass'],
|
||||||
|
tasks: ['sass'],
|
||||||
|
options: {
|
||||||
|
atBegin: true,
|
||||||
|
spawn: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
js: {
|
||||||
|
files: ['assets/scripts/**/*.js'],
|
||||||
|
tasks: ['coffee'],
|
||||||
|
options: {
|
||||||
|
atBegin: true,
|
||||||
|
spawn: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Load plugins.
|
||||||
|
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||||
|
grunt.loadNpmTasks('grunt-contrib-sass');
|
||||||
|
grunt.loadNpmTasks('grunt-contrib-coffee');
|
||||||
|
|
||||||
|
// CLI tasks.
|
||||||
|
grunt.registerTask('default', ['sass', 'coffee']);
|
||||||
|
|
||||||
|
};
|
42
Makefile
Normal file
42
Makefile
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
NAME=blt
|
||||||
|
VERSION=`git describe --tags`
|
||||||
|
|
||||||
|
.PHONY: build
|
||||||
|
## build: Compile the packages.
|
||||||
|
build:
|
||||||
|
@go build -o $(NAME) -ldflags "-X git.metaunix.net/bitgoblin/blt/app.AppVersion=$(VERSION)"
|
||||||
|
|
||||||
|
.PHONY: run
|
||||||
|
## run: Build and Run in development mode.
|
||||||
|
run: build
|
||||||
|
@./$(NAME) -e development
|
||||||
|
|
||||||
|
.PHONY: run-prod
|
||||||
|
## run-prod: Build and Run in production mode.
|
||||||
|
run-prod: build
|
||||||
|
@./$(NAME) -e production
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
## clean: Clean project and previous builds.
|
||||||
|
clean:
|
||||||
|
@rm -f $(NAME)
|
||||||
|
|
||||||
|
.PHONY: deps
|
||||||
|
## deps: Download modules
|
||||||
|
deps:
|
||||||
|
@go mod download
|
||||||
|
|
||||||
|
.PHONY: test
|
||||||
|
## test: Run tests with verbose mode
|
||||||
|
test:
|
||||||
|
@go test -v ./tests/*
|
||||||
|
|
||||||
|
.PHONY: help
|
||||||
|
all: help
|
||||||
|
# help: show this help message
|
||||||
|
help: Makefile
|
||||||
|
@echo
|
||||||
|
@echo " Choose a command to run in "$(APP_NAME)":"
|
||||||
|
@echo
|
||||||
|
@sed -n 's/^##//p' $< | column -t -s ':' | sed -e 's/^/ /'
|
||||||
|
@echo
|
15
app/vars.go
Normal file
15
app/vars.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
AppVersion string = "N/a"
|
||||||
|
RuntimeVersion string = runtimeVersion()
|
||||||
|
)
|
||||||
|
|
||||||
|
func runtimeVersion() string {
|
||||||
|
raw_string := runtime.Version()
|
||||||
|
return raw_string[2:]
|
||||||
|
}
|
2
assets/scripts/kebos.coffee
Normal file
2
assets/scripts/kebos.coffee
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
$ ->
|
||||||
|
console.log('DOM is ready.')
|
133
assets/styles/kourend.sass
Normal file
133
assets/styles/kourend.sass
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
html,
|
||||||
|
body
|
||||||
|
width: 100%
|
||||||
|
height: 100%
|
||||||
|
margin: 0
|
||||||
|
padding: 0
|
||||||
|
|
||||||
|
body
|
||||||
|
height: auto
|
||||||
|
min-height: 100%
|
||||||
|
box-sizing: border-box
|
||||||
|
padding-top: 80px
|
||||||
|
padding-bottom: 100px
|
||||||
|
background: #eee
|
||||||
|
|
||||||
|
a
|
||||||
|
color: teal
|
||||||
|
transition: color 180ms ease-in-out
|
||||||
|
&:hover
|
||||||
|
color: darkcyan
|
||||||
|
|
||||||
|
button.button-primary
|
||||||
|
background: teal
|
||||||
|
transition: background 180ms ease-in-out
|
||||||
|
&:hover
|
||||||
|
background: darkcyan
|
||||||
|
|
||||||
|
textarea
|
||||||
|
max-width: 100%
|
||||||
|
min-width: 100%
|
||||||
|
height: 100px
|
||||||
|
|
||||||
|
|
||||||
|
form select[multiple]
|
||||||
|
min-height: 100px
|
||||||
|
|
||||||
|
table
|
||||||
|
border: 1px solid #ddd
|
||||||
|
border-radius: 8px
|
||||||
|
border-spacing: 0
|
||||||
|
overflow: hidden
|
||||||
|
|
||||||
|
table th,
|
||||||
|
table td,
|
||||||
|
table th:first-child,
|
||||||
|
table td:first-child
|
||||||
|
border: none
|
||||||
|
padding: 7px 12px
|
||||||
|
|
||||||
|
table thead tr
|
||||||
|
border-radius: 8px 8px 0 0
|
||||||
|
&:last-child
|
||||||
|
border-radius: 0 0 8px 8px
|
||||||
|
|
||||||
|
table thead tr,
|
||||||
|
table tr:nth-child(even)
|
||||||
|
background: #eee
|
||||||
|
|
||||||
|
table tbody tr
|
||||||
|
transition: background 180ms ease-in-out
|
||||||
|
&:hover
|
||||||
|
background: lightgrey
|
||||||
|
|
||||||
|
/* Material card styles */
|
||||||
|
.card-1
|
||||||
|
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24)
|
||||||
|
transition: all 0.3s cubic-bezier(.25,.8,.25,1)
|
||||||
|
&:hover
|
||||||
|
box-shadow: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22)
|
||||||
|
|
||||||
|
.card-2
|
||||||
|
box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23)
|
||||||
|
|
||||||
|
.card-3
|
||||||
|
box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23)
|
||||||
|
|
||||||
|
.card-4
|
||||||
|
box-shadow: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22)
|
||||||
|
|
||||||
|
.card-5
|
||||||
|
box-shadow: 0 19px 38px rgba(0,0,0,0.30), 0 15px 12px rgba(0,0,0,0.22)
|
||||||
|
|
||||||
|
.container
|
||||||
|
max-width: 1200px
|
||||||
|
|
||||||
|
#main-nav
|
||||||
|
position: fixed
|
||||||
|
top: 0
|
||||||
|
left: 0
|
||||||
|
width: 100%
|
||||||
|
height: 64px
|
||||||
|
background: teal
|
||||||
|
color: white
|
||||||
|
z-index: 20
|
||||||
|
|
||||||
|
ul
|
||||||
|
list-style: none
|
||||||
|
display: inline-block
|
||||||
|
|
||||||
|
li
|
||||||
|
display: inline-block
|
||||||
|
margin-left: 15px
|
||||||
|
|
||||||
|
h4
|
||||||
|
display: inline-block
|
||||||
|
margin-left: 25px
|
||||||
|
line-height: 64px
|
||||||
|
|
||||||
|
a
|
||||||
|
color: white
|
||||||
|
font-size: 2.25rem
|
||||||
|
line-height: 64px
|
||||||
|
transition: all 200ms ease-in-out
|
||||||
|
&:hover
|
||||||
|
color: #eee
|
||||||
|
font-size: 2.5rem
|
||||||
|
|
||||||
|
#main-content
|
||||||
|
padding: 15px 25px
|
||||||
|
background: white
|
||||||
|
border-radius: 8px
|
||||||
|
z-index: 10
|
||||||
|
|
||||||
|
#main-footer
|
||||||
|
position: fixed
|
||||||
|
bottom: 0
|
||||||
|
left: 0
|
||||||
|
width: 100%
|
||||||
|
height: 64px
|
||||||
|
|
||||||
|
p
|
||||||
|
margin-bottom: 5px
|
||||||
|
text-align: center
|
24
blt.go
24
blt.go
@ -1,24 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/flamego/flamego"
|
|
||||||
"github.com/flamego/template"
|
|
||||||
|
|
||||||
web "git.metaunix.net/bitgoblin/blt/src/web"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// initialize Flamego instance
|
|
||||||
f := flamego.Classic()
|
|
||||||
|
|
||||||
// enable templates
|
|
||||||
f.Use(template.Templater(template.Options{
|
|
||||||
Directory: "./views",
|
|
||||||
}))
|
|
||||||
|
|
||||||
// register routes
|
|
||||||
web.RegisterRoutes(f)
|
|
||||||
|
|
||||||
// start Flamego
|
|
||||||
f.Run()
|
|
||||||
}
|
|
0
data/.gitkeep
Normal file
0
data/.gitkeep
Normal file
18
go.mod
18
go.mod
@ -2,20 +2,34 @@ module git.metaunix.net/bitgoblin/blt
|
|||||||
|
|
||||||
go 1.18
|
go 1.18
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/flamego/flamego v1.9.4
|
||||||
|
github.com/flamego/template v1.2.2
|
||||||
|
gorm.io/driver/sqlite v1.5.4
|
||||||
|
gorm.io/gorm v1.25.5
|
||||||
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/alecthomas/participle/v2 v2.0.0 // indirect
|
github.com/alecthomas/participle/v2 v2.0.0 // indirect
|
||||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||||
github.com/charmbracelet/lipgloss v0.7.1 // indirect
|
github.com/charmbracelet/lipgloss v0.7.1 // indirect
|
||||||
github.com/charmbracelet/log v0.2.3 // indirect
|
github.com/charmbracelet/log v0.2.3 // indirect
|
||||||
github.com/flamego/flamego v1.9.4 // indirect
|
github.com/flamego/binding v1.3.0 // indirect
|
||||||
github.com/flamego/template v1.2.2 // indirect
|
github.com/flamego/validator v1.0.0 // indirect
|
||||||
github.com/go-logfmt/logfmt v0.6.0 // indirect
|
github.com/go-logfmt/logfmt v0.6.0 // indirect
|
||||||
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
|
github.com/jinzhu/now v1.1.5 // indirect
|
||||||
|
github.com/leodido/go-urn v1.2.1 // indirect
|
||||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.18 // indirect
|
github.com/mattn/go-isatty v0.0.18 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.14 // indirect
|
github.com/mattn/go-runewidth v0.0.14 // indirect
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.18 // indirect
|
||||||
github.com/muesli/reflow v0.3.0 // indirect
|
github.com/muesli/reflow v0.3.0 // indirect
|
||||||
github.com/muesli/termenv v0.15.2 // indirect
|
github.com/muesli/termenv v0.15.2 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/rivo/uniseg v0.2.0 // indirect
|
github.com/rivo/uniseg v0.2.0 // indirect
|
||||||
|
golang.org/x/crypto v0.0.0-20210920023735-84f357641f63 // indirect
|
||||||
golang.org/x/sys v0.7.0 // indirect
|
golang.org/x/sys v0.7.0 // indirect
|
||||||
|
golang.org/x/text v0.3.7 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
59
go.sum
59
go.sum
@ -1,33 +1,92 @@
|
|||||||
|
github.com/alecthomas/assert/v2 v2.2.2/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ=
|
||||||
github.com/alecthomas/participle/v2 v2.0.0 h1:Fgrq+MbuSsJwIkw3fEj9h75vDP0Er5JzepJ0/HNHv0g=
|
github.com/alecthomas/participle/v2 v2.0.0 h1:Fgrq+MbuSsJwIkw3fEj9h75vDP0Er5JzepJ0/HNHv0g=
|
||||||
github.com/alecthomas/participle/v2 v2.0.0/go.mod h1:rAKZdJldHu8084ojcWevWAL8KmEU+AT+Olodb+WoN2Y=
|
github.com/alecthomas/participle/v2 v2.0.0/go.mod h1:rAKZdJldHu8084ojcWevWAL8KmEU+AT+Olodb+WoN2Y=
|
||||||
|
github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
||||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
||||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
||||||
github.com/charmbracelet/lipgloss v0.7.1 h1:17WMwi7N1b1rVWOjMT+rCh7sQkvDU75B2hbZpc5Kc1E=
|
github.com/charmbracelet/lipgloss v0.7.1 h1:17WMwi7N1b1rVWOjMT+rCh7sQkvDU75B2hbZpc5Kc1E=
|
||||||
github.com/charmbracelet/lipgloss v0.7.1/go.mod h1:yG0k3giv8Qj8edTCbbg6AlQ5e8KNWpFujkNawKNhE2c=
|
github.com/charmbracelet/lipgloss v0.7.1/go.mod h1:yG0k3giv8Qj8edTCbbg6AlQ5e8KNWpFujkNawKNhE2c=
|
||||||
|
github.com/charmbracelet/log v0.2.1/go.mod h1:GwFfjewhcVDWLrpAbY5A0Hin9YOlEn40eWT4PNaxFT4=
|
||||||
|
github.com/charmbracelet/log v0.2.2/go.mod h1:Zs11hKpb8l+UyX4y1srwZIGW+MPCXJHIty3MB9l/sno=
|
||||||
github.com/charmbracelet/log v0.2.3 h1:YVmBhJtpGL7nW/nlf5u+SEloU8XYljxozGzZpgwIvhs=
|
github.com/charmbracelet/log v0.2.3 h1:YVmBhJtpGL7nW/nlf5u+SEloU8XYljxozGzZpgwIvhs=
|
||||||
github.com/charmbracelet/log v0.2.3/go.mod h1:ZApwwzDbbETVTIRTk7724yQRJAXIktt98yGVMMaa3y8=
|
github.com/charmbracelet/log v0.2.3/go.mod h1:ZApwwzDbbETVTIRTk7724yQRJAXIktt98yGVMMaa3y8=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/flamego/binding v1.3.0 h1:CPbnSuP0SxT50JR7lK2khTjcQi1oOECqRK7kbOYw91U=
|
||||||
|
github.com/flamego/binding v1.3.0/go.mod h1:xgm6FEpEKKkF8CQilK2X3MJ5kTjOTnYdz/ooFctDTdc=
|
||||||
|
github.com/flamego/flamego v1.9.1/go.mod h1:WjaZO8GM/EGvIIGXlOiwp3oPuyy1fAdjWqEgEJWovJo=
|
||||||
github.com/flamego/flamego v1.9.4 h1:SNsooIfNa6ljQM1rBmfg4cFcXPIhQdG/uvNHqXxPvD8=
|
github.com/flamego/flamego v1.9.4 h1:SNsooIfNa6ljQM1rBmfg4cFcXPIhQdG/uvNHqXxPvD8=
|
||||||
github.com/flamego/flamego v1.9.4/go.mod h1:2tAVbugA3fgX8xOBoqR2jmJSSvZDLBFGXTFCR5h5eAU=
|
github.com/flamego/flamego v1.9.4/go.mod h1:2tAVbugA3fgX8xOBoqR2jmJSSvZDLBFGXTFCR5h5eAU=
|
||||||
github.com/flamego/template v1.2.2 h1:aMpt8RzXBb2ZGuABf9p/q8oBBpXrurUV8rgBbz7mj2o=
|
github.com/flamego/template v1.2.2 h1:aMpt8RzXBb2ZGuABf9p/q8oBBpXrurUV8rgBbz7mj2o=
|
||||||
github.com/flamego/template v1.2.2/go.mod h1:xTAmwCCPaOuxN5t4CpzOP7WZN5WkLRiJfJCpsiB0aUg=
|
github.com/flamego/template v1.2.2/go.mod h1:xTAmwCCPaOuxN5t4CpzOP7WZN5WkLRiJfJCpsiB0aUg=
|
||||||
|
github.com/flamego/validator v1.0.0 h1:ixuWHVgiVGp4pVGtUn/0d6HBjZJbbXfJHDNkxW+rZoY=
|
||||||
|
github.com/flamego/validator v1.0.0/go.mod h1:POYn0/5iW4sdamdPAYPrzqN6DFC4YaczY0gYY+Pyx5E=
|
||||||
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
|
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
|
||||||
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||||
|
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
|
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
|
||||||
|
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||||
|
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||||
|
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||||
|
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||||
|
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||||
|
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||||
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
||||||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||||
|
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
|
github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
|
||||||
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||||
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
|
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
|
||||||
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.18 h1:JL0eqdCOq6DJVNPSvArO/bIV9/P7fbGrV00LZHc+5aI=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.18/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||||
github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
|
github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
|
||||||
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
|
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
|
||||||
|
github.com/muesli/termenv v0.15.1/go.mod h1:HeAQPTzpfs016yGtA4g00CsdYnVLJvxsS4ANqrZs2sQ=
|
||||||
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
|
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
|
||||||
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
|
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
|
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
golang.org/x/crypto v0.0.0-20210920023735-84f357641f63 h1:kETrAMYZq6WVGPa8IIixL0CaEcIUNi+1WX7grUoi3y8=
|
||||||
|
golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||||
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gorm.io/driver/sqlite v1.5.4 h1:IqXwXi8M/ZlPzH/947tn5uik3aYQslP9BVveoax0nV0=
|
||||||
|
gorm.io/driver/sqlite v1.5.4/go.mod h1:qxAuCol+2r6PannQDpOP1FP6ag3mKi4esLnB/jHed+4=
|
||||||
|
gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||||
|
gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls=
|
||||||
|
gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||||
|
36
main.go
Normal file
36
main.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/flamego/flamego"
|
||||||
|
"github.com/flamego/template"
|
||||||
|
|
||||||
|
"git.metaunix.net/bitgoblin/blt/models"
|
||||||
|
"git.metaunix.net/bitgoblin/blt/web"
|
||||||
|
"git.metaunix.net/bitgoblin/blt/web/middleware"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Version string = "N/a"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// initial Flamego server object
|
||||||
|
f := flamego.Classic()
|
||||||
|
|
||||||
|
// initialize database
|
||||||
|
models.Open()
|
||||||
|
|
||||||
|
// initialize templating engine
|
||||||
|
f.Use(template.Templater())
|
||||||
|
|
||||||
|
// inject custom middleware
|
||||||
|
f.Use(middleware.CustomVars)
|
||||||
|
|
||||||
|
// register routes to server (moved to separate file for cleanliness)
|
||||||
|
web.RegisterRoutes(f)
|
||||||
|
|
||||||
|
// alert the user and start the server
|
||||||
|
log.Println("Server is running...")
|
||||||
|
log.Println(http.ListenAndServe("0.0.0.0:2830", f))
|
||||||
|
}
|
18
models/benchmark.go
Normal file
18
models/benchmark.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Benchmark struct {
|
||||||
|
gorm.Model
|
||||||
|
Name string
|
||||||
|
ScoringType string
|
||||||
|
Description string
|
||||||
|
|
||||||
|
// many-to-many test
|
||||||
|
Tests []Test `gorm:"many2many:tests_benchmarks;"`
|
||||||
|
|
||||||
|
// has many results
|
||||||
|
Results []Result
|
||||||
|
}
|
17
models/hardware.go
Normal file
17
models/hardware.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Hardware struct {
|
||||||
|
gorm.Model
|
||||||
|
Name string
|
||||||
|
Type string
|
||||||
|
|
||||||
|
// has many tests
|
||||||
|
Tests []Test
|
||||||
|
|
||||||
|
// has many results
|
||||||
|
Results []Result
|
||||||
|
}
|
26
models/init.go
Normal file
26
models/init.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"gorm.io/driver/sqlite"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
DB *gorm.DB
|
||||||
|
)
|
||||||
|
|
||||||
|
// Initializes the Gorm database object
|
||||||
|
func Open() {
|
||||||
|
// Initialize database object
|
||||||
|
var err error
|
||||||
|
DB, err = gorm.Open(sqlite.Open("data/blt.db"), &gorm.Config{})
|
||||||
|
if err != nil {
|
||||||
|
panic("Failed to connect database")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Migrate the schema
|
||||||
|
DB.AutoMigrate(&Test{}, &Hardware{}, &Benchmark{}, &Result{})
|
||||||
|
log.Println("Database migrations complete.")
|
||||||
|
}
|
24
models/result.go
Normal file
24
models/result.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Result struct {
|
||||||
|
gorm.Model
|
||||||
|
AverageScore float32
|
||||||
|
MinimumScore float32
|
||||||
|
MaximumScore float32
|
||||||
|
|
||||||
|
// belongs to Hardware
|
||||||
|
HardwareID int
|
||||||
|
Hardware Hardware
|
||||||
|
|
||||||
|
// belongs to Benchmark
|
||||||
|
BenchmarkID int
|
||||||
|
Benchmark Benchmark
|
||||||
|
|
||||||
|
// belongs to Test
|
||||||
|
TestID int
|
||||||
|
Test Test
|
||||||
|
}
|
21
models/test.go
Normal file
21
models/test.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Test struct {
|
||||||
|
gorm.Model
|
||||||
|
Name string
|
||||||
|
Description string
|
||||||
|
|
||||||
|
// belongs to hardware
|
||||||
|
HardwareID int
|
||||||
|
Hardware Hardware
|
||||||
|
|
||||||
|
// many-to-many benchmarks
|
||||||
|
Benchmarks []Benchmark `gorm:"many2many:tests_benchmarks;"`
|
||||||
|
|
||||||
|
// has many results
|
||||||
|
Results []Result
|
||||||
|
}
|
1853
package-lock.json
generated
Normal file
1853
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
35
package.json
Normal file
35
package.json
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"name": "blt",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"description": "Self-hosted PC hardware benchmark logging tool",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"grunt": "grunt"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "gitea@git.metaunix.net:BitGoblin/blt.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"hardware",
|
||||||
|
"benchmark",
|
||||||
|
"testing",
|
||||||
|
"PC"
|
||||||
|
],
|
||||||
|
"author": "Gregory Ballanine <gballantine@bitgoblin.tech>",
|
||||||
|
"uploaders": [
|
||||||
|
{
|
||||||
|
"name": "Gregory Ballantine",
|
||||||
|
"email": "gballantine@bitgoblin.tech"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "BSD-2-Clause",
|
||||||
|
"devDependencies": {
|
||||||
|
"grunt": "^1.5.3",
|
||||||
|
"grunt-cli": "^1.4.3",
|
||||||
|
"grunt-contrib-sass": "^2.0.0",
|
||||||
|
"grunt-contrib-coffee": "^2.1.0",
|
||||||
|
"grunt-contrib-watch": "^1.1.0",
|
||||||
|
"sass": "^1.55.0"
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +0,0 @@
|
|||||||
package web
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/flamego/flamego"
|
|
||||||
|
|
||||||
"git.metaunix.net/bitgoblin/blt/src/web/routes"
|
|
||||||
)
|
|
||||||
|
|
||||||
func RegisterRoutes(f *flamego.Flame) {
|
|
||||||
// top-level routes
|
|
||||||
f.Get("/", routes.GetTopIndex)
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
package routes
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/flamego/template"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GetTopIndex(t template.Template, data template.Data) {
|
|
||||||
data["title"] = "Dashboard"
|
|
||||||
t.HTML(http.StatusOK, "index")
|
|
||||||
}
|
|
38
templates/benchmark/create.tmpl
Normal file
38
templates/benchmark/create.tmpl
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
{{ template "header" . }}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<h2>Add new benchmark</h2>
|
||||||
|
|
||||||
|
<form class="twelve columns" action="/benchmark/create" method="POST">
|
||||||
|
<div class="row">
|
||||||
|
<div class="nine columns">
|
||||||
|
<label for="benchmark_name">
|
||||||
|
Benchmark name:
|
||||||
|
<input id="benchmark_name" class="u-full-width" type="text" name="benchmark_name" placeholder="Unigine Heaven">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="three columns">
|
||||||
|
<label for="benchmark_scoring">
|
||||||
|
Benchmark type:
|
||||||
|
<select id="benchmark_scoring" class="u-full-width" name="benchmark_scoring">
|
||||||
|
<option value="fps">Frames per second</option>
|
||||||
|
<option value="ms">Frame time</option>
|
||||||
|
<option value="pts">Total points</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<label for="benchmark_description">
|
||||||
|
Benchmark description:
|
||||||
|
<textarea id="benchmark_description" class="twelve columns" cols="30" rows="10" name="benchmark_description"></textarea>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input class="button-primary u-full-width" type="submit" value="Submit">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ template "footer" . }}
|
27
templates/benchmark/list.tmpl
Normal file
27
templates/benchmark/list.tmpl
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{{ template "header" . }}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<h2>Benchmark</h2>
|
||||||
|
<a href="/benchmark/create">Add new benchmark</a>
|
||||||
|
|
||||||
|
<table class="twelve columns card-2">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td>Name</td>
|
||||||
|
<td>Created at</td>
|
||||||
|
<td>Last updated</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{ range $b := .benchmarks }}
|
||||||
|
<tr>
|
||||||
|
<td><a href="/benchmark/{{ $b.ID }}">{{ $b.Name }}</a></td>
|
||||||
|
<td>{{ $b.CreatedAt.Format "01/02/2006 15:04am" }}</td>
|
||||||
|
<td>{{ $b.UpdatedAt.Format "01/02/2006 15:04am" }}</td>
|
||||||
|
</tr>
|
||||||
|
{{ end }}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ template "footer" . }}
|
19
templates/benchmark/view.tmpl
Normal file
19
templates/benchmark/view.tmpl
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{{ template "header" . }}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<h2>{{ .benchmark.Name }}</h2>
|
||||||
|
|
||||||
|
<p>{{ .benchmark.ScoringType }}</p>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h4>Latest Benchmark Results:</h4>
|
||||||
|
|
||||||
|
<p>There are currently no results recorded using this benchmark.</p>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<p><a href="/benchmark">Back</a></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ template "footer" . }}
|
34
templates/hardware/create.tmpl
Normal file
34
templates/hardware/create.tmpl
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{{ template "header" . }}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<h2>Add new hardware</h2>
|
||||||
|
|
||||||
|
<form class="twelve columns" action="/hardware/create" method="POST">
|
||||||
|
<div class="row">
|
||||||
|
<div class="nine columns">
|
||||||
|
<label for="hardware_name">
|
||||||
|
Hardware name:
|
||||||
|
<input id="hardware_name" class="u-full-width" type="text" name="hardware_name" placeholder="EVGA RTX 3080 Ti">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="three columns">
|
||||||
|
<label for="hardware_type">
|
||||||
|
Hardware type:
|
||||||
|
<select id="hardware_type" class="u-full-width" name="hardware_type">
|
||||||
|
<option value="cpu">Processor</option>
|
||||||
|
<option value="mem">Memory</option>
|
||||||
|
<option value="gpu">Graphics Card</option>
|
||||||
|
<option value="ssd">Solid State Drive</option>
|
||||||
|
<option value="hdd">Hard Drive</option>
|
||||||
|
<option value="nic">Network Card</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input class="button-primary u-full-width" type="submit" value="Submit">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ template "footer" . }}
|
27
templates/hardware/list.tmpl
Normal file
27
templates/hardware/list.tmpl
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{{ template "header" . }}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<h2>Hardware</h2>
|
||||||
|
<a href="/hardware/create">Add new hardware</a>
|
||||||
|
|
||||||
|
<table class="twelve columns card-2">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td>Name</td>
|
||||||
|
<td>Created at</td>
|
||||||
|
<td>Last updated</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{ range $h := .hardware }}
|
||||||
|
<tr>
|
||||||
|
<td><a href="/hardware/{{ $h.ID }}">{{ $h.Name }}</a></td>
|
||||||
|
<td>{{ $h.CreatedAt.Format "01/02/2006 15:04am" }}</td>
|
||||||
|
<td>{{ $h.UpdatedAt.Format "01/02/2006 15:04am" }}</td>
|
||||||
|
</tr>
|
||||||
|
{{ end }}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ template "footer" . }}
|
40
templates/hardware/view.tmpl
Normal file
40
templates/hardware/view.tmpl
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
{{ template "header" . }}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<h2>{{ .hardware.Name }}</h2>
|
||||||
|
|
||||||
|
<p>{{ .hardware.Type }}</p>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h4>Tests Using This Component:</h4>
|
||||||
|
|
||||||
|
{{ $length := len .hardware.Tests }} {{ if eq $length 0 }}
|
||||||
|
<p>There are currently no tests using this hardware component.</p>
|
||||||
|
{{ else }}
|
||||||
|
<table class="u-full-width card-2">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Test</th>
|
||||||
|
<th># of Benchmarks</th>
|
||||||
|
<th>Last Updated</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{ range $test := .hardware.Tests }}
|
||||||
|
<tr>
|
||||||
|
<td><a href="/test/{{ $test.ID }}">{{ $test.Name }}</a></td>
|
||||||
|
<td>{{ len $test.Benchmarks }}</td>
|
||||||
|
<td>{{ $test.CreatedAt.Format "01/02/2006 15:04am" }}</td>
|
||||||
|
</tr>
|
||||||
|
{{ end }}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<p><a href="/hardware">Back</a></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ template "footer" . }}
|
@ -1,5 +1,5 @@
|
|||||||
{{ template "header" . }}
|
{{ template "header" . }}
|
||||||
|
|
||||||
<p>This is a test!</p>
|
<p>This is the BLT dashboard.</p>
|
||||||
|
|
||||||
{{ template "footer" . }}
|
{{ template "footer" . }}
|
11
templates/layout/footer.tmpl
Normal file
11
templates/layout/footer.tmpl
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{{ define "footer" }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- footer -->
|
||||||
|
<nav id="main-footer">
|
||||||
|
<p>BLT version {{ .app_version }} | Built with Go {{ .runtime_version }}</p>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
{{ end }}
|
21
templates/layout/header.tmpl
Normal file
21
templates/layout/header.tmpl
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{{ define "header" }}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
<title>{{ .title }} | BLT</title>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css">
|
||||||
|
<link rel="stylesheet" href="/css/kourend.css">
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js" charset="utf-8"></script>
|
||||||
|
<script src="/js/kebos.js" charset="utf-8"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<!-- navbar -->
|
||||||
|
{{ template "navbar" . }}
|
||||||
|
|
||||||
|
<!-- main content -->
|
||||||
|
<div id="main-content" class="container card-5">
|
||||||
|
{{ end }}
|
13
templates/layout/navbar.tmpl
Normal file
13
templates/layout/navbar.tmpl
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{{ define "navbar" }}
|
||||||
|
<nav id="main-nav" class="card-2">
|
||||||
|
<div class="nav-left">
|
||||||
|
<h4>BLT</h4>
|
||||||
|
<ul>
|
||||||
|
<li><a href="/">Dashboard</a></li>
|
||||||
|
<li><a href="/test">Tests</a></li>
|
||||||
|
<li><a href="/hardware">Hardware</a></li>
|
||||||
|
<li><a href="/benchmark">Benchmarks</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
{{ end }}
|
51
templates/test/create.tmpl
Normal file
51
templates/test/create.tmpl
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
{{ template "header" . }}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<h2>Create a test</h2>
|
||||||
|
|
||||||
|
<form class="twelve columns" action="/test/create" method="POST">
|
||||||
|
<div class="row">
|
||||||
|
<div class="columns four">
|
||||||
|
<label for="test_hardware">
|
||||||
|
Hardware Component:
|
||||||
|
<select id="test_hardware" class="u-full-width" name="test_hardware">
|
||||||
|
{{ range $hw := .hardware }}
|
||||||
|
<option value="{{ $hw.ID }}">{{ $hw.Name }}</option>
|
||||||
|
{{ end }}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="columns eight">
|
||||||
|
<label for="test_name">
|
||||||
|
Test name:
|
||||||
|
<input id="test_name" class="u-full-width" type="text" name="test_name" placeholder="My hardware benchmarking test">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="columns twelve">
|
||||||
|
<label for="test_benchmarks">
|
||||||
|
Benchmarks to Test:
|
||||||
|
<select id="test_benchmarks" class="u-full-width" name="test_benchmarks" multiple>
|
||||||
|
{{ range $bm := .benchmarks }}
|
||||||
|
<option value="{{ $bm.ID }}">{{ $bm.Name }}</option>
|
||||||
|
{{ end }}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<label for="test_description">
|
||||||
|
Test description:
|
||||||
|
<textarea id="test_description" class="twelve columns" cols="30" rows="10" name="test_description"></textarea>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input class="button-primary u-full-width" type="submit" value="Submit">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ template "footer" . }}
|
27
templates/test/list.tmpl
Normal file
27
templates/test/list.tmpl
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{{ template "header" . }}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<h2>Tests</h2>
|
||||||
|
<a href="/test/create">Create a new test</a>
|
||||||
|
|
||||||
|
<table class="twelve columns card-2">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td>Title</td>
|
||||||
|
<td>Created at</td>
|
||||||
|
<td>Last updated</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{ range $p := .tests }}
|
||||||
|
<tr>
|
||||||
|
<td><a href="/test/{{ $p.ID }}">{{ $p.Name }}</a></td>
|
||||||
|
<td>{{ $p.CreatedAt.Format "01/02/2006 15:04am" }}</td>
|
||||||
|
<td>{{ $p.UpdatedAt.Format "01/02/2006 15:04am" }}</td>
|
||||||
|
</tr>
|
||||||
|
{{ end }}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ template "footer" . }}
|
99
templates/test/view.tmpl
Normal file
99
templates/test/view.tmpl
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
{{ template "header" . }}
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<h2>{{ .test.Name }}</h2>
|
||||||
|
|
||||||
|
<p><a href="/hardware/{{ .test.Hardware.ID }}">link to hardware tested.</a></p>
|
||||||
|
|
||||||
|
<p>{{ .test.Description }}</p>
|
||||||
|
|
||||||
|
<h4>Benchmarks used:</h4>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
{{ range $bm := .test.Benchmarks }}
|
||||||
|
<li><a href="/benchmark/{{ $bm.ID }}">{{ $bm.Name }}</a></li>
|
||||||
|
{{ end }}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h4>Add new result:</h4>
|
||||||
|
|
||||||
|
<form class="u-full-width" action="/result/add" method="POST">
|
||||||
|
<div class="row">
|
||||||
|
<div class="columns four">
|
||||||
|
<label for="result_benchmark">
|
||||||
|
Benchmark:
|
||||||
|
<select id="result_benchmark" class="u-full-width" name="result_benchmark">
|
||||||
|
{{ range $bm := .test.Benchmarks }}
|
||||||
|
<option value="{{ $bm.ID }}">{{ $bm.Name }}</option>
|
||||||
|
{{ end }}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="columns two">
|
||||||
|
<label for="result_avg">
|
||||||
|
Average score:
|
||||||
|
<input id="result_avg" class="u-full-width" type="number" name="result_avg" value="0">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="columns two">
|
||||||
|
<label for="result_min">
|
||||||
|
Minimum score:
|
||||||
|
<input id="result_min" class="u-full-width" type="number" name="result_min" value="0">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="columns two">
|
||||||
|
<label for="result_max">
|
||||||
|
Maximum score:
|
||||||
|
<input id="result_max" class="u-full-width" type="number" name="result_max" value="0">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="columns two">
|
||||||
|
<button class="button-primary u-full-width" type="submit" name="button">Submit</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="hidden" name="result_test" value="{{ .test.ID }}">
|
||||||
|
<input type="hidden" name="result_hardware" value="{{ .test.Hardware.ID }}">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h4>Latest Benchmark Results:</h4>
|
||||||
|
|
||||||
|
{{ $length := len .test.Results }} {{ if eq $length 0 }}
|
||||||
|
<p>There are currently no benchmarks recorded in this test.</p>
|
||||||
|
{{ else }}
|
||||||
|
<table class="u-full-width card-2">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Benchmark</th>
|
||||||
|
<th>Average</th>
|
||||||
|
<th>Minimum</th>
|
||||||
|
<th>Maximum</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{ range $res := .test.Results }}
|
||||||
|
<tr>
|
||||||
|
<td>{{ $res.Benchmark.Name }}</td>
|
||||||
|
<td>{{ $res.AverageScore }}</td>
|
||||||
|
<td>{{ if eq $res.MinimumScore 0.0 }}N/a{{ else }}{{ $res.MinimumScore }}{{ end }}</td>
|
||||||
|
<td>{{ if eq $res.MaximumScore 0.0 }}N/a{{ else }}{{ $res.MaximumScore }}{{ end }}</td>
|
||||||
|
</tr>
|
||||||
|
{{ end }}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<p><a href="/test">Back</a></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ template "footer" . }}
|
@ -1,4 +0,0 @@
|
|||||||
{{ define "footer" }}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
{{ end }}
|
|
@ -1,11 +0,0 @@
|
|||||||
{{ define "header" }}
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
||||||
<title>{{ .title }} | BLT</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
{{ end }}
|
|
7
web/forms/benchmark.go
Normal file
7
web/forms/benchmark.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package forms
|
||||||
|
|
||||||
|
type BenchmarkForm struct {
|
||||||
|
Name string `form:"benchmark_name" validate:"required"`
|
||||||
|
ScoringType string `form:"benchmark_scoring" validate:"required"`
|
||||||
|
Description string `form:"benchmark_description"`
|
||||||
|
}
|
6
web/forms/hardware.go
Normal file
6
web/forms/hardware.go
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package forms
|
||||||
|
|
||||||
|
type HardwareForm struct {
|
||||||
|
Name string `form:"hardware_name" validate:"required"`
|
||||||
|
Type string `form:"hardware_type" validate:"required"`
|
||||||
|
}
|
10
web/forms/result.go
Normal file
10
web/forms/result.go
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package forms
|
||||||
|
|
||||||
|
type ResultForm struct {
|
||||||
|
Test int `form:"result_test" validate:"required"`
|
||||||
|
Hardware int `form:"result_hardware" validate:"required"`
|
||||||
|
Benchmark int `form:"result_benchmark" validate:"required"`
|
||||||
|
AverageScore float32 `form:"result_avg" validate:"required"`
|
||||||
|
MinimumScore float32 `form:"result_min"`
|
||||||
|
MaximumScore float32 `form:"result_max"`
|
||||||
|
}
|
8
web/forms/test.go
Normal file
8
web/forms/test.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package forms
|
||||||
|
|
||||||
|
type TestForm struct {
|
||||||
|
Name string `form:"test_name" validate:"required"`
|
||||||
|
Description string `form:"test_description"`
|
||||||
|
Hardware int `form:"test_hardware" validate:"required"`
|
||||||
|
Benchmarks []string `form:"test_benchmarks" validate:"required"`
|
||||||
|
}
|
12
web/middleware/vars.go
Normal file
12
web/middleware/vars.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package middleware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/flamego/template"
|
||||||
|
|
||||||
|
"git.metaunix.net/bitgoblin/blt/app"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CustomVars(data template.Data) {
|
||||||
|
data["app_version"] = app.AppVersion
|
||||||
|
data["runtime_version"] = app.RuntimeVersion
|
||||||
|
}
|
61
web/routes.go
Normal file
61
web/routes.go
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
package web
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/flamego/binding"
|
||||||
|
"github.com/flamego/flamego"
|
||||||
|
|
||||||
|
"git.metaunix.net/bitgoblin/blt/web/forms"
|
||||||
|
"git.metaunix.net/bitgoblin/blt/web/routes"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RegisterRoutes(f *flamego.Flame) {
|
||||||
|
// index routes
|
||||||
|
f.Get("/", routes.GetDashboard)
|
||||||
|
|
||||||
|
// hardware routes
|
||||||
|
f.Group("/hardware", func() {
|
||||||
|
f.Get("", func(c flamego.Context) {
|
||||||
|
c.Redirect("/hardware/list")
|
||||||
|
})
|
||||||
|
|
||||||
|
f.Get("/list", routes.HardwareGetList)
|
||||||
|
|
||||||
|
f.Get("/create", routes.HardwareGetCreate)
|
||||||
|
f.Post("/create", binding.Form(forms.HardwareForm{}), routes.HardwarePostCreate)
|
||||||
|
|
||||||
|
f.Get("/{hardware_id}", routes.HardwareGetView)
|
||||||
|
})
|
||||||
|
|
||||||
|
// benchmark routes
|
||||||
|
f.Group("/benchmark", func() {
|
||||||
|
f.Get("", func(c flamego.Context) {
|
||||||
|
c.Redirect("/benchmark/list")
|
||||||
|
})
|
||||||
|
|
||||||
|
f.Get("/list", routes.BenchmarkGetList)
|
||||||
|
|
||||||
|
f.Get("/create", routes.BenchmarkGetCreate)
|
||||||
|
f.Post("/create", binding.Form(forms.BenchmarkForm{}), routes.BenchmarkPostCreate)
|
||||||
|
|
||||||
|
f.Get("/{benchmark_id}", routes.BenchmarkGetView)
|
||||||
|
})
|
||||||
|
|
||||||
|
// test routes
|
||||||
|
f.Group("/test", func() {
|
||||||
|
f.Get("", func(c flamego.Context) {
|
||||||
|
c.Redirect("/test/list")
|
||||||
|
})
|
||||||
|
|
||||||
|
f.Get("/list", routes.TestGetList)
|
||||||
|
|
||||||
|
f.Get("/create", routes.TestGetCreate)
|
||||||
|
f.Post("/create", binding.Form(forms.TestForm{}), routes.TestPostCreate)
|
||||||
|
|
||||||
|
f.Get("/{test_id}", routes.TestGetView)
|
||||||
|
})
|
||||||
|
|
||||||
|
// result routes
|
||||||
|
f.Group("/result", func() {
|
||||||
|
f.Post("/add", binding.Form(forms.ResultForm{}), routes.ResultPostCreate)
|
||||||
|
})
|
||||||
|
}
|
66
web/routes/benchmark.go
Normal file
66
web/routes/benchmark.go
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/flamego/binding"
|
||||||
|
"github.com/flamego/flamego"
|
||||||
|
"github.com/flamego/template"
|
||||||
|
"github.com/flamego/validator"
|
||||||
|
|
||||||
|
"git.metaunix.net/bitgoblin/blt/models"
|
||||||
|
"git.metaunix.net/bitgoblin/blt/web/forms"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BenchmarkGetList(t template.Template, data template.Data) {
|
||||||
|
// add benchmarks to template
|
||||||
|
var benchmarks []models.Benchmark
|
||||||
|
models.DB.Find(&benchmarks)
|
||||||
|
data["benchmarks"] = benchmarks
|
||||||
|
|
||||||
|
data["title"] = "List of Benchmarks"
|
||||||
|
t.HTML(http.StatusOK, "benchmark/list")
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkGetView(c flamego.Context, t template.Template, data template.Data) {
|
||||||
|
// find benchmark ID from request
|
||||||
|
benchmarkID := c.Param("benchmark_id")
|
||||||
|
|
||||||
|
// find benchmark from DB
|
||||||
|
var benchmark models.Benchmark
|
||||||
|
models.DB.First(&benchmark, benchmarkID)
|
||||||
|
data["benchmark"] = benchmark
|
||||||
|
|
||||||
|
data["title"] = benchmark.Name
|
||||||
|
t.HTML(http.StatusOK, "benchmark/view")
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkGetCreate(t template.Template, data template.Data) {
|
||||||
|
data["title"] = "Add New Benchmark"
|
||||||
|
t.HTML(http.StatusOK, "benchmark/create")
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkPostCreate(c flamego.Context, form forms.BenchmarkForm, errs binding.Errors) {
|
||||||
|
if len(errs) > 0 {
|
||||||
|
var err error
|
||||||
|
switch errs[0].Category {
|
||||||
|
case binding.ErrorCategoryValidation:
|
||||||
|
err = errs[0].Err.(validator.ValidationErrors)[0]
|
||||||
|
default:
|
||||||
|
err = errs[0].Err
|
||||||
|
}
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
benchmark := models.Benchmark{
|
||||||
|
Name: form.Name,
|
||||||
|
ScoringType: form.ScoringType,
|
||||||
|
Description: form.Description,
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = models.DB.Create(&benchmark)
|
||||||
|
|
||||||
|
c.Redirect(fmt.Sprintf("/benchmark/%d", benchmark.ID))
|
||||||
|
}
|
65
web/routes/hardware.go
Normal file
65
web/routes/hardware.go
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/flamego/binding"
|
||||||
|
"github.com/flamego/flamego"
|
||||||
|
"github.com/flamego/template"
|
||||||
|
"github.com/flamego/validator"
|
||||||
|
|
||||||
|
"git.metaunix.net/bitgoblin/blt/models"
|
||||||
|
"git.metaunix.net/bitgoblin/blt/web/forms"
|
||||||
|
)
|
||||||
|
|
||||||
|
func HardwareGetList(t template.Template, data template.Data) {
|
||||||
|
// add hardwares to template
|
||||||
|
var hardware []models.Hardware
|
||||||
|
models.DB.Find(&hardware)
|
||||||
|
data["hardware"] = hardware
|
||||||
|
|
||||||
|
data["title"] = "List of Hardware"
|
||||||
|
t.HTML(http.StatusOK, "hardware/list")
|
||||||
|
}
|
||||||
|
|
||||||
|
func HardwareGetView(c flamego.Context, t template.Template, data template.Data) {
|
||||||
|
// find hardware ID from request
|
||||||
|
hardwareID := c.Param("hardware_id")
|
||||||
|
|
||||||
|
// find hardware from DB
|
||||||
|
var hardware models.Hardware
|
||||||
|
models.DB.Preload("Tests.Benchmarks").First(&hardware, hardwareID)
|
||||||
|
data["hardware"] = hardware
|
||||||
|
|
||||||
|
data["title"] = hardware.Name
|
||||||
|
t.HTML(http.StatusOK, "hardware/view")
|
||||||
|
}
|
||||||
|
|
||||||
|
func HardwareGetCreate(t template.Template, data template.Data) {
|
||||||
|
data["title"] = "Add New Hardware"
|
||||||
|
t.HTML(http.StatusOK, "hardware/create")
|
||||||
|
}
|
||||||
|
|
||||||
|
func HardwarePostCreate(c flamego.Context, form forms.HardwareForm, errs binding.Errors) {
|
||||||
|
if len(errs) > 0 {
|
||||||
|
var err error
|
||||||
|
switch errs[0].Category {
|
||||||
|
case binding.ErrorCategoryValidation:
|
||||||
|
err = errs[0].Err.(validator.ValidationErrors)[0]
|
||||||
|
default:
|
||||||
|
err = errs[0].Err
|
||||||
|
}
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
hardware := models.Hardware{
|
||||||
|
Name: form.Name,
|
||||||
|
Type: form.Type,
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = models.DB.Create(&hardware)
|
||||||
|
|
||||||
|
c.Redirect(fmt.Sprintf("/hardware/%d", hardware.ID))
|
||||||
|
}
|
12
web/routes/index.go
Normal file
12
web/routes/index.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/flamego/template"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetDashboard(t template.Template, data template.Data) {
|
||||||
|
data["title"] = "Dashboard"
|
||||||
|
t.HTML(http.StatusOK, "index/dashboard")
|
||||||
|
}
|
39
web/routes/result.go
Normal file
39
web/routes/result.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/flamego/binding"
|
||||||
|
"github.com/flamego/flamego"
|
||||||
|
"github.com/flamego/validator"
|
||||||
|
|
||||||
|
"git.metaunix.net/bitgoblin/blt/models"
|
||||||
|
"git.metaunix.net/bitgoblin/blt/web/forms"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ResultPostCreate(c flamego.Context, form forms.ResultForm, errs binding.Errors) {
|
||||||
|
if len(errs) > 0 {
|
||||||
|
var err error
|
||||||
|
switch errs[0].Category {
|
||||||
|
case binding.ErrorCategoryValidation:
|
||||||
|
err = errs[0].Err.(validator.ValidationErrors)[0]
|
||||||
|
default:
|
||||||
|
err = errs[0].Err
|
||||||
|
}
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
result := models.Result{
|
||||||
|
TestID: form.Test,
|
||||||
|
HardwareID: form.Hardware,
|
||||||
|
BenchmarkID: form.Benchmark,
|
||||||
|
AverageScore: form.AverageScore,
|
||||||
|
MinimumScore: form.MinimumScore,
|
||||||
|
MaximumScore: form.MaximumScore,
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = models.DB.Create(&result)
|
||||||
|
|
||||||
|
c.Redirect(fmt.Sprintf("/test/%d", result.TestID))
|
||||||
|
}
|
83
web/routes/test.go
Normal file
83
web/routes/test.go
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/flamego/binding"
|
||||||
|
"github.com/flamego/flamego"
|
||||||
|
"github.com/flamego/template"
|
||||||
|
"github.com/flamego/validator"
|
||||||
|
|
||||||
|
"git.metaunix.net/bitgoblin/blt/models"
|
||||||
|
"git.metaunix.net/bitgoblin/blt/web/forms"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetList(t template.Template, data template.Data) {
|
||||||
|
// add tests to template
|
||||||
|
var tests []models.Test
|
||||||
|
models.DB.Find(&tests)
|
||||||
|
data["tests"] = tests
|
||||||
|
|
||||||
|
data["title"] = "List of Tests"
|
||||||
|
t.HTML(http.StatusOK, "test/list")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetView(c flamego.Context, t template.Template, data template.Data) {
|
||||||
|
// find test ID from request
|
||||||
|
testID := c.Param("test_id")
|
||||||
|
|
||||||
|
// find hardware from DB
|
||||||
|
var test models.Test
|
||||||
|
models.DB.Preload("Hardware").Preload("Benchmarks").Preload("Results.Benchmark").First(&test, testID)
|
||||||
|
data["test"] = test
|
||||||
|
|
||||||
|
data["title"] = test.Name
|
||||||
|
t.HTML(http.StatusOK, "test/view")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetCreate(t template.Template, data template.Data) {
|
||||||
|
// add hardware components to template
|
||||||
|
var hardware []models.Hardware
|
||||||
|
models.DB.Find(&hardware)
|
||||||
|
data["hardware"] = hardware
|
||||||
|
|
||||||
|
// add benchmarks to template
|
||||||
|
var benchmarks []models.Benchmark
|
||||||
|
models.DB.Find(&benchmarks)
|
||||||
|
data["benchmarks"] = benchmarks
|
||||||
|
|
||||||
|
data["title"] = "Create a Test"
|
||||||
|
t.HTML(http.StatusOK, "test/create")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPostCreate(c flamego.Context, form forms.TestForm, errs binding.Errors) {
|
||||||
|
if len(errs) > 0 {
|
||||||
|
var err error
|
||||||
|
switch errs[0].Category {
|
||||||
|
case binding.ErrorCategoryValidation:
|
||||||
|
err = errs[0].Err.(validator.ValidationErrors)[0]
|
||||||
|
default:
|
||||||
|
err = errs[0].Err
|
||||||
|
}
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
test := models.Test{
|
||||||
|
Name: form.Name,
|
||||||
|
Description: form.Description,
|
||||||
|
HardwareID: form.Hardware,
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = models.DB.Create(&test)
|
||||||
|
|
||||||
|
// bind benchmarks to test
|
||||||
|
for _, v := range form.Benchmarks {
|
||||||
|
var benchmark models.Benchmark
|
||||||
|
models.DB.First(&benchmark, v) // find benchmark
|
||||||
|
models.DB.Model(&test).Association("Benchmarks").Append(&benchmark)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Redirect(fmt.Sprintf("/test/%d", test.ID))
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user