Compare commits
63 Commits
190ae9f302
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
4b98322022 | ||
60d8554cf1 | |||
c19bb2108c | |||
27cff3e79b | |||
03ef5cc905 | |||
f81879302d | |||
9ecff3a25d | |||
bef17b5a59 | |||
82f42ecbed | |||
673e2e9634 | |||
178894a360 | |||
5fc381c4b9 | |||
c9d2f7114a | |||
bce063c5f4 | |||
b54d31213b | |||
ae4198f3cc | |||
9fdf6e2b99 | |||
8f0cce7550 | |||
d97fee0911 | |||
de107761eb | |||
26ad420436 | |||
47f3dcdbd1 | |||
6bb06205b0 | |||
b508efd5a8 | |||
e5a18f77f2 | |||
db41f0d6bd | |||
b93c8a5319 | |||
346b9e3911 | |||
446590acb1 | |||
a38ede5187 | |||
2b3f24ee5c | |||
9104125de7 | |||
5ad0810d81 | |||
e27fd8d214 | |||
3910c4dc9c | |||
3b8a30c7f8 | |||
293098e173 | |||
10298cbf7c | |||
743a108add | |||
c8a47b270a | |||
fde8d1dee4 | |||
bee64576bc | |||
3c1d48a9ed | |||
633fc4ac02 | |||
79924cd978 | |||
e5443fb644 | |||
81a87e2761 | |||
65550c983c | |||
f3a2376c19 | |||
99f45b3b3a | |||
4718aeaccd | |||
62654b9a3e | |||
93778274c2 | |||
7c13b1f209 | |||
e09d399c98 | |||
c9ad5df2ed | |||
0f89087134 | |||
819baeb0c3 | |||
fe303cb778 | |||
98bd1f7eca | |||
09a2667fc5 | |||
4020812549 | |||
8bc9849776 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,6 +3,7 @@ blt
|
||||
|
||||
# Local data files
|
||||
data/
|
||||
tmp/
|
||||
|
||||
# Compiled assets
|
||||
public/css/
|
||||
|
32
.woodpecker.yml
Normal file
32
.woodpecker.yml
Normal file
@@ -0,0 +1,32 @@
|
||||
pipeline:
|
||||
build:
|
||||
image: golang:1.22
|
||||
commands:
|
||||
- go mod vendor
|
||||
- GOOS=linux GOARCH=amd64 go build -o "dist/blt-linux-amd64-${CI_COMMIT_TAG}.bin"
|
||||
- GOOS=windows GOARCH=amd64 go build -o "dist/blt-windows-amd64-${CI_COMMIT_TAG}.exe"
|
||||
|
||||
assets:
|
||||
image: node:24
|
||||
commands:
|
||||
- npm install
|
||||
- npm run grunt build
|
||||
|
||||
package:
|
||||
image: alpine
|
||||
commands:
|
||||
- tar -cvzf "dist/blt-assets-${CI_COMMIT_TAG}.tar.gz" public/
|
||||
when:
|
||||
event: tag
|
||||
|
||||
gitea_release:
|
||||
image: plugins/gitea-release
|
||||
settings:
|
||||
api_key:
|
||||
from_secret: gitea_api_key
|
||||
base_url: https://git.metaunix.net
|
||||
title: "${CI_COMMIT_TAG}"
|
||||
files:
|
||||
- dist/blt-*
|
||||
when:
|
||||
event: tag
|
@@ -60,6 +60,8 @@ module.exports = function(grunt) {
|
||||
grunt.loadNpmTasks('grunt-contrib-coffee');
|
||||
|
||||
// CLI tasks.
|
||||
grunt.registerTask('default', ['sass', 'coffee']);
|
||||
grunt.registerTask('build', ['sass', 'coffee']);
|
||||
grunt.registerTask('dev', ['watch']);
|
||||
grunt.registerTask('default', ['build']);
|
||||
|
||||
};
|
||||
|
12
main.go
12
main.go
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
gotemplate "html/template"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
@@ -25,7 +26,16 @@ func main() {
|
||||
f.Use(flamego.Renderer())
|
||||
|
||||
// initialize templating engine
|
||||
f.Use(template.Templater())
|
||||
f.Use(template.Templater(template.Options{
|
||||
FuncMaps: []gotemplate.FuncMap{
|
||||
{
|
||||
"contains": web.Contains,
|
||||
},
|
||||
},
|
||||
Directory: "templates",
|
||||
Extensions: []string{".tmpl", ".html"},
|
||||
},
|
||||
))
|
||||
|
||||
// inject custom middleware
|
||||
f.Use(middleware.CustomVars)
|
||||
|
@@ -1,6 +1,8 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
@@ -16,3 +18,7 @@ type Benchmark struct {
|
||||
// has many results
|
||||
Results []Result
|
||||
}
|
||||
|
||||
func (b *Benchmark) StringID() string {
|
||||
return strconv.Itoa(int(b.ID))
|
||||
}
|
||||
|
@@ -1,6 +1,9 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
@@ -19,3 +22,29 @@ type Test struct {
|
||||
// has many results
|
||||
Results []Result
|
||||
}
|
||||
|
||||
func (t *Test) SelectedBenchmarks() []string {
|
||||
benchmarks := t.Benchmarks
|
||||
ids := make([]string, len(benchmarks))
|
||||
for i, b := range benchmarks {
|
||||
ids[i] = strconv.Itoa(int(b.ID))
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
func (t *Test) IsBenchmarkSelected(benchmarkID string) bool {
|
||||
benchmarkConv, err := strconv.ParseUint(benchmarkID, 10, 0)
|
||||
if err != nil {
|
||||
fmt.Println("Error parsing Uint: ", err)
|
||||
}
|
||||
|
||||
benchmarkUint := uint(benchmarkConv)
|
||||
|
||||
for _, b := range t.Benchmarks {
|
||||
if b.ID == benchmarkUint {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
@@ -4,7 +4,8 @@
|
||||
"description": "Self-hosted PC hardware benchmark logging tool",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"grunt": "grunt"
|
||||
"grunt": "grunt",
|
||||
"nodemon": "nodemon"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -27,8 +28,8 @@
|
||||
"devDependencies": {
|
||||
"grunt": "^1.5.3",
|
||||
"grunt-cli": "^1.4.3",
|
||||
"grunt-contrib-sass": "^2.0.0",
|
||||
"grunt-contrib-coffee": "^2.1.0",
|
||||
"grunt-contrib-sass": "^2.0.0",
|
||||
"grunt-contrib-watch": "^1.1.0",
|
||||
"sass": "^1.55.0"
|
||||
}
|
||||
|
53
templates/test/edit.tmpl
Normal file
53
templates/test/edit.tmpl
Normal file
@@ -0,0 +1,53 @@
|
||||
{{ template "header" . }}
|
||||
|
||||
<div class="row">
|
||||
<h2>{{ .title }}</h2>
|
||||
|
||||
<form class="twelve columns" action="/test/{{ .test.ID }}/edit" 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">
|
||||
{{ $testHardwareID := .test.Hardware.ID }}
|
||||
{{ range $hw := .hardware }}
|
||||
<option value="{{ $hw.ID }}" {{ if eq $testHardwareID $hw.ID }}selected{{ end }}>{{ $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" value="{{ .test.Name }}">
|
||||
</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>
|
||||
{{ $selectedBenchmarks := .selectedBenchmarks }}
|
||||
{{ range $bm := .benchmarks }}
|
||||
<option value="{{ $bm.ID }}" {{ if contains $selectedBenchmarks $bm.StringID }}selected{{ end }}>{{ $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" . }}
|
10
web/helpers.go
Normal file
10
web/helpers.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package web
|
||||
|
||||
func Contains(slice []string, val string) bool {
|
||||
for _, v := range slice {
|
||||
if v == val {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
@@ -51,7 +51,10 @@ func RegisterRoutes(f *flamego.Flame) {
|
||||
f.Get("/create", routes.TestGetCreate)
|
||||
f.Post("/create", binding.Form(forms.TestForm{}), routes.TestPostCreate)
|
||||
|
||||
f.Get("/{test_id}", routes.TestGetView)
|
||||
f.Group("/{test_id}", func() {
|
||||
f.Get("", routes.TestGetView)
|
||||
f.Get("/edit", routes.TestGetEdit)
|
||||
})
|
||||
})
|
||||
|
||||
// result routes
|
||||
|
@@ -81,3 +81,68 @@ func TestPostCreate(c flamego.Context, form forms.TestForm, errs binding.Errors)
|
||||
|
||||
c.Redirect(fmt.Sprintf("/test/%d", test.ID))
|
||||
}
|
||||
|
||||
func TestGetEdit(c flamego.Context, t template.Template, data template.Data) {
|
||||
// find test in DB
|
||||
testID := c.Param("test_id")
|
||||
var test models.Test
|
||||
models.DB.Preload("Hardware").Preload("Benchmarks").First(&test, testID)
|
||||
data["test"] = test
|
||||
|
||||
// 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
|
||||
|
||||
// determine which benchmarks are selected in a test
|
||||
selectedBenchmarks := test.SelectedBenchmarks()
|
||||
data["selectedBenchmarks"] = selectedBenchmarks
|
||||
|
||||
data["title"] = fmt.Sprintf("Editing Test: %s", test.Name)
|
||||
t.HTML(http.StatusOK, "test/edit")
|
||||
}
|
||||
|
||||
func TestPostEdit(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)
|
||||
}
|
||||
|
||||
// find test ID from request
|
||||
testID := c.Param("test_id")
|
||||
|
||||
// find hardware from DB
|
||||
var test models.Test
|
||||
models.DB.Preload("Hardware").Preload("Benchmarks").First(&test, testID)
|
||||
|
||||
test.Name = form.Name
|
||||
test.Description = form.Description
|
||||
test.HardwareID = form.Hardware
|
||||
|
||||
// bind benchmarks to test that aren't already associated
|
||||
for _, b := range form.Benchmarks {
|
||||
if ! test.IsBenchmarkSelected(b) {
|
||||
var benchmark models.Benchmark
|
||||
models.DB.First(&benchmark, b) // find benchmark
|
||||
models.DB.Model(&test).Association("Benchmarks").Append(&benchmark)
|
||||
}
|
||||
}
|
||||
|
||||
// removed associated benchmarks that weren't in the form
|
||||
for _, b := range test.Benchmarks {
|
||||
|
||||
}
|
||||
|
||||
c.Redirect(fmt.Sprintf("/test/%d", test.ID))
|
||||
}
|
||||
|
Reference in New Issue
Block a user