Compare commits
47 Commits
rails
..
bc4cb181c3
| Author | SHA1 | Date | |
|---|---|---|---|
| bc4cb181c3 | |||
| 822f49bcc2 | |||
| aec77628f7 | |||
| ecb696372d | |||
| 31b8404be1 | |||
| 8cd47d7e70 | |||
| d17b66920a | |||
| 47cb580393 | |||
| 883019b181 | |||
| 2cc80e239b | |||
| ed085e4b40 | |||
| cf9235cb18 | |||
| 28b6cc66bb | |||
| e3a334546f | |||
| d899ffe58a | |||
| e6853a52d7 | |||
| 6d26eea419 | |||
| 778bd25ef2 | |||
| 6aca95d832 | |||
| 357bb69257 | |||
| 1e0cd49cf8 | |||
| 5628c69d66 | |||
| e6333b855f | |||
| f7979cd005 | |||
| ef2e0a12a5 | |||
| c83d517437 | |||
| 8dee8b1f40 | |||
| 175ce24b27 | |||
| 516f125ea7 | |||
| 34741691ed | |||
| fa9245d7ec | |||
| 1a363a5862 | |||
| b819f4f1cd | |||
| 394a8ef91f | |||
| c940a248d7 | |||
| 269587e6c9 | |||
| 3c9e6eab6b | |||
| a1a00d9fe5 | |||
| 7e38154bc1 | |||
| f0115847b8 | |||
| b8bec03357 | |||
| 7655b75410 | |||
| 691e2e9b1e | |||
| 291db231d5 | |||
| 6c1c8bca0a | |||
| 6f680e72e5 | |||
| b376bf3a79 |
@@ -0,0 +1,2 @@
|
|||||||
|
---
|
||||||
|
BUNDLE_PATH: "vendor/bundle"
|
||||||
@@ -56,3 +56,12 @@ build-iPhoneSimulator/
|
|||||||
# Used by RuboCop. Remote config files pulled in from inherit_from directive.
|
# Used by RuboCop. Remote config files pulled in from inherit_from directive.
|
||||||
# .rubocop-https?--*
|
# .rubocop-https?--*
|
||||||
|
|
||||||
|
# Ignore local data
|
||||||
|
data/
|
||||||
|
|
||||||
|
# Node modules
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Compiled assets
|
||||||
|
public/css/
|
||||||
|
public/js/
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
require: rubocop-sequel
|
||||||
|
|
||||||
|
AllCops:
|
||||||
|
NewCops: enable
|
||||||
|
|
||||||
|
Layout/EmptyLinesAroundClassBody:
|
||||||
|
EnforcedStyle: 'empty_lines_except_namespace'
|
||||||
|
Layout/EmptyLinesAroundModuleBody:
|
||||||
|
EnforcedStyle: 'empty_lines_except_namespace'
|
||||||
|
Layout/FirstHashElementIndentation:
|
||||||
|
EnforcedStyle: 'consistent'
|
||||||
|
Metrics/ClassLength:
|
||||||
|
Max: 150
|
||||||
|
Style/ClassVars:
|
||||||
|
Enabled: false
|
||||||
|
Style/GlobalVars:
|
||||||
|
Enabled: false
|
||||||
|
Style/MethodCallWithoutArgsParentheses:
|
||||||
|
Enabled: false
|
||||||
|
Style/MethodCallWithArgsParentheses:
|
||||||
|
Enabled: true
|
||||||
|
Style/RedundantReturn:
|
||||||
|
Enabled: false
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
pipeline:
|
||||||
|
style:
|
||||||
|
image: ruby:3.0
|
||||||
|
commands:
|
||||||
|
- 'gem install rake'
|
||||||
|
- 'bundle config set --local path "vendor/bundle"'
|
||||||
|
- 'bundle install'
|
||||||
|
- 'rake test:rubocop'
|
||||||
|
|
||||||
|
gitea_release:
|
||||||
|
image: plugins/gitea-release
|
||||||
|
settings:
|
||||||
|
api_key:
|
||||||
|
from_secret: gitea_api_key
|
||||||
|
base_url: https://git.metaunix.net
|
||||||
|
title: "${CI_COMMIT_TAG}"
|
||||||
|
when:
|
||||||
|
event: tag
|
||||||
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
FROM ruby:3.4
|
||||||
|
|
||||||
|
RUN gem install bundler
|
||||||
|
|
||||||
|
WORKDIR /usr/src/game-data
|
||||||
|
|
||||||
|
COPY Gemfile Gemfile.l*ck ./
|
||||||
|
|
||||||
|
RUN bundle check || bundle install
|
||||||
|
|
||||||
|
RUN gem install rake
|
||||||
|
|
||||||
|
COPY . ./
|
||||||
|
|
||||||
|
ENTRYPOINT ["bash", "entrypoints/dev.sh"]
|
||||||
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# Node.js runtime
|
||||||
|
FROM node:24
|
||||||
|
|
||||||
|
WORKDIR /usr/src/game-data/
|
||||||
|
|
||||||
|
COPY package.* /usr/src/game-data/
|
||||||
|
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
VOLUME /usr/src/game-data/node_modules/
|
||||||
|
|
||||||
|
# Run the app
|
||||||
|
CMD [ "npm", "run", "gulp" ]
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
|
gem 'sinatra', '~> 3.2'
|
||||||
|
gem 'sinatra-contrib', '~> 3.2'
|
||||||
|
gem 'puma', '~> 6.6'
|
||||||
|
|
||||||
|
gem 'sequel', '~> 5.92'
|
||||||
|
gem 'sqlite3', '~> 2.6'
|
||||||
|
|
||||||
|
gem 'logger'
|
||||||
|
|
||||||
|
group :development, :test do
|
||||||
|
gem 'rerun'
|
||||||
|
gem 'wdm', '>= 0.1.0' if Gem.win_platform?
|
||||||
|
|
||||||
|
# rubocop and extensions for code style
|
||||||
|
gem 'rubocop'
|
||||||
|
gem 'rubocop-sequel'
|
||||||
|
end
|
||||||
+118
@@ -0,0 +1,118 @@
|
|||||||
|
GEM
|
||||||
|
remote: https://rubygems.org/
|
||||||
|
specs:
|
||||||
|
ast (2.4.3)
|
||||||
|
base64 (0.3.0)
|
||||||
|
bigdecimal (3.2.2)
|
||||||
|
ffi (1.17.2-aarch64-linux-gnu)
|
||||||
|
ffi (1.17.2-aarch64-linux-musl)
|
||||||
|
ffi (1.17.2-arm-linux-gnu)
|
||||||
|
ffi (1.17.2-arm-linux-musl)
|
||||||
|
ffi (1.17.2-arm64-darwin)
|
||||||
|
ffi (1.17.2-x86-linux-gnu)
|
||||||
|
ffi (1.17.2-x86-linux-musl)
|
||||||
|
ffi (1.17.2-x86_64-darwin)
|
||||||
|
ffi (1.17.2-x86_64-linux-gnu)
|
||||||
|
ffi (1.17.2-x86_64-linux-musl)
|
||||||
|
json (2.12.2)
|
||||||
|
language_server-protocol (3.17.0.5)
|
||||||
|
lint_roller (1.1.0)
|
||||||
|
listen (3.9.0)
|
||||||
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||||
|
rb-inotify (~> 0.9, >= 0.9.10)
|
||||||
|
logger (1.7.0)
|
||||||
|
multi_json (1.15.0)
|
||||||
|
mustermann (3.0.3)
|
||||||
|
ruby2_keywords (~> 0.0.1)
|
||||||
|
nio4r (2.7.4)
|
||||||
|
parallel (1.27.0)
|
||||||
|
parser (3.3.8.0)
|
||||||
|
ast (~> 2.4.1)
|
||||||
|
racc
|
||||||
|
prism (1.4.0)
|
||||||
|
puma (6.6.0)
|
||||||
|
nio4r (~> 2.0)
|
||||||
|
racc (1.8.1)
|
||||||
|
rack (2.2.17)
|
||||||
|
rack-protection (3.2.0)
|
||||||
|
base64 (>= 0.1.0)
|
||||||
|
rack (~> 2.2, >= 2.2.4)
|
||||||
|
rainbow (3.1.1)
|
||||||
|
rb-fsevent (0.11.2)
|
||||||
|
rb-inotify (0.11.1)
|
||||||
|
ffi (~> 1.0)
|
||||||
|
regexp_parser (2.10.0)
|
||||||
|
rerun (0.14.0)
|
||||||
|
listen (~> 3.0)
|
||||||
|
rubocop (1.76.1)
|
||||||
|
json (~> 2.3)
|
||||||
|
language_server-protocol (~> 3.17.0.2)
|
||||||
|
lint_roller (~> 1.1.0)
|
||||||
|
parallel (~> 1.10)
|
||||||
|
parser (>= 3.3.0.2)
|
||||||
|
rainbow (>= 2.2.2, < 4.0)
|
||||||
|
regexp_parser (>= 2.9.3, < 3.0)
|
||||||
|
rubocop-ast (>= 1.45.0, < 2.0)
|
||||||
|
ruby-progressbar (~> 1.7)
|
||||||
|
unicode-display_width (>= 2.4.0, < 4.0)
|
||||||
|
rubocop-ast (1.45.1)
|
||||||
|
parser (>= 3.3.7.2)
|
||||||
|
prism (~> 1.4)
|
||||||
|
rubocop-sequel (0.4.1)
|
||||||
|
lint_roller (~> 1.1)
|
||||||
|
rubocop (>= 1.72.1, < 2)
|
||||||
|
ruby-progressbar (1.13.0)
|
||||||
|
ruby2_keywords (0.0.5)
|
||||||
|
sequel (5.93.0)
|
||||||
|
bigdecimal
|
||||||
|
sinatra (3.2.0)
|
||||||
|
mustermann (~> 3.0)
|
||||||
|
rack (~> 2.2, >= 2.2.4)
|
||||||
|
rack-protection (= 3.2.0)
|
||||||
|
tilt (~> 2.0)
|
||||||
|
sinatra-contrib (3.2.0)
|
||||||
|
multi_json (>= 0.0.2)
|
||||||
|
mustermann (~> 3.0)
|
||||||
|
rack-protection (= 3.2.0)
|
||||||
|
sinatra (= 3.2.0)
|
||||||
|
tilt (~> 2.0)
|
||||||
|
sqlite3 (2.7.0-aarch64-linux-gnu)
|
||||||
|
sqlite3 (2.7.0-aarch64-linux-musl)
|
||||||
|
sqlite3 (2.7.0-arm-linux-gnu)
|
||||||
|
sqlite3 (2.7.0-arm-linux-musl)
|
||||||
|
sqlite3 (2.7.0-arm64-darwin)
|
||||||
|
sqlite3 (2.7.0-x86-linux-gnu)
|
||||||
|
sqlite3 (2.7.0-x86-linux-musl)
|
||||||
|
sqlite3 (2.7.0-x86_64-darwin)
|
||||||
|
sqlite3 (2.7.0-x86_64-linux-gnu)
|
||||||
|
sqlite3 (2.7.0-x86_64-linux-musl)
|
||||||
|
tilt (2.6.0)
|
||||||
|
unicode-display_width (3.1.4)
|
||||||
|
unicode-emoji (~> 4.0, >= 4.0.4)
|
||||||
|
unicode-emoji (4.0.4)
|
||||||
|
|
||||||
|
PLATFORMS
|
||||||
|
aarch64-linux-gnu
|
||||||
|
aarch64-linux-musl
|
||||||
|
arm-linux-gnu
|
||||||
|
arm-linux-musl
|
||||||
|
arm64-darwin
|
||||||
|
x86-linux-gnu
|
||||||
|
x86-linux-musl
|
||||||
|
x86_64-darwin
|
||||||
|
x86_64-linux-gnu
|
||||||
|
x86_64-linux-musl
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
logger
|
||||||
|
puma (~> 6.6)
|
||||||
|
rerun
|
||||||
|
rubocop
|
||||||
|
rubocop-sequel
|
||||||
|
sequel (~> 5.92)
|
||||||
|
sinatra (~> 3.2)
|
||||||
|
sinatra-contrib (~> 3.2)
|
||||||
|
sqlite3 (~> 2.6)
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
2.6.9
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
Copyright (c) <year> <owner>
|
Copyright (c) 2023 Bit Goblin
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,34 @@
|
|||||||
# game-data
|
# Game Data
|
||||||
|
|
||||||
Web-based tool to store and organize PC hardware gaming benchmarks
|
Web-based tool to store and organize PC hardware gaming benchmarks.
|
||||||
|
|
||||||
|
## Project Goals
|
||||||
|
|
||||||
|
The goals of this project are to:
|
||||||
|
|
||||||
|
* Record benchmarking results from multiple devices - e.g. log from a laptop or a phone.
|
||||||
|
* Group results into tests - it's good practice to run a benchmark multiple times for accuracy.
|
||||||
|
* Create comparisons of hardware tests to compare performance.
|
||||||
|
* Generate graphs of hardware comparisons for usage in videos and articles.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
Game Data runs on Ruby, and takes advantage of Bundler to manage code dependencies and Rake to run various tasks for maintaining the app. You can install them globally like so:
|
||||||
|
|
||||||
|
Debian/Ubuntu: `apt install -y ruby ruby-bundler rake`
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
Install dependencies via bundler:
|
||||||
|
|
||||||
|
`bundle install`
|
||||||
|
|
||||||
|
Perform database migrations:
|
||||||
|
|
||||||
|
`rake db:migrate`
|
||||||
|
|
||||||
|
Run the server in development with auto-reloading:
|
||||||
|
|
||||||
|
`rake server:dev`
|
||||||
|
|
||||||
|
If everything is running successfully you can open your browser and go to https://localhost:9292.
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
require 'bundler/setup'
|
||||||
|
|
||||||
|
namespace :db do
|
||||||
|
desc 'Run migrations'
|
||||||
|
task :migrate, [:version] do |t, args|
|
||||||
|
require "sequel/core"
|
||||||
|
Sequel.extension :migration
|
||||||
|
version = args[:version].to_i if args[:version]
|
||||||
|
Sequel.connect('sqlite://data/gamedata.db') do |db|
|
||||||
|
Sequel::Migrator.run(db, "db/migrations", target: version)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
namespace :server do
|
||||||
|
task :start do
|
||||||
|
ENV['APP_ENV'] = 'production'
|
||||||
|
system("puma")
|
||||||
|
end
|
||||||
|
|
||||||
|
task :dev do
|
||||||
|
system('rerun --no-notify --dir="src/" puma')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
namespace :test do
|
||||||
|
task :rubocop do
|
||||||
|
system("rubocop src/")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
$ ->
|
||||||
|
# run foundation scripts
|
||||||
|
$(document).foundation()
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
$(document).ready ->
|
||||||
|
$('#generate_button').on 'click', (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
$.ajax(
|
||||||
|
method: 'POST'
|
||||||
|
url: '/reports'
|
||||||
|
data:
|
||||||
|
type: $('#report_type').val()
|
||||||
|
choice: $('#report_choice').val()
|
||||||
|
compare: $('#report_compare').val()
|
||||||
|
).done (data) ->
|
||||||
|
benchChart.options.title.text = data.choice
|
||||||
|
benchChart.data.labels = data.names
|
||||||
|
benchChart.data.datasets[0].data = data.avg_results
|
||||||
|
benchChart.data.datasets[1].data = data.min_results
|
||||||
|
benchChart.update()
|
||||||
|
return
|
||||||
|
return
|
||||||
|
return
|
||||||
|
|
||||||
|
benchChart = new Chart(document.getElementById('chart_canvas').getContext('2d'),
|
||||||
|
type: 'horizontalBar'
|
||||||
|
data:
|
||||||
|
labels: []
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: 'Average FPS'
|
||||||
|
data: []
|
||||||
|
backgroundColor: 'hotpink'
|
||||||
|
borderColor: '#212121'
|
||||||
|
borderWidth: 1
|
||||||
|
}
|
||||||
|
{
|
||||||
|
label: 'Minimum FPS'
|
||||||
|
data: []
|
||||||
|
backgroundColor: 'cornflowerblue'
|
||||||
|
borderColor: '#212121'
|
||||||
|
borderWidth: 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
options:
|
||||||
|
title:
|
||||||
|
display: true
|
||||||
|
text: 'N/a'
|
||||||
|
scales: xAxes: [ {
|
||||||
|
display: true
|
||||||
|
ticks: beginAtZero: true
|
||||||
|
} ]
|
||||||
|
animation: onComplete: ->
|
||||||
|
dwnbtn = $('#download_button')
|
||||||
|
dwnbtn.attr 'href', benchChart.toBase64Image()
|
||||||
|
dwnbtn.attr 'download', 'benchmark_chart.png'
|
||||||
|
dwnbtn.attr 'disabled', false
|
||||||
|
return
|
||||||
|
)
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
testId = $('#results-table').data('test-id')
|
||||||
|
|
||||||
|
fetchTestBenchmarkResults = (testId, benchmarkId) ->
|
||||||
|
try
|
||||||
|
benchmarkSearchParams = new URLSearchParams
|
||||||
|
benchmark_id: benchmarkId
|
||||||
|
benchmarkRes = await fetch("/api/v1/benchmark/details?#{benchmarkSearchParams}")
|
||||||
|
benchmarkData = await benchmarkRes.json()
|
||||||
|
|
||||||
|
resultSearchParams = new URLSearchParams
|
||||||
|
test_id: testId
|
||||||
|
benchmark_id: benchmarkId
|
||||||
|
resultRes = await fetch("/api/v1/results?#{resultSearchParams}")
|
||||||
|
resultData = await resultRes.json()
|
||||||
|
|
||||||
|
avg_total = 0
|
||||||
|
min_total = 0
|
||||||
|
max_total = 0
|
||||||
|
|
||||||
|
for result in resultData
|
||||||
|
avg_total += result.avg_score
|
||||||
|
min_total += result.min_score
|
||||||
|
max_total += result.max_score
|
||||||
|
|
||||||
|
tableRow = $("#results-table tr[data-benchmark-id=#{benchmarkId}]")
|
||||||
|
|
||||||
|
tableRow.append('<td>' + benchmarkData.name + '</td>')
|
||||||
|
tableRow.append('<td>' + benchmarkData.scoring + '</td>')
|
||||||
|
tableRow.append('<td>' + resultData.length + '</td>')
|
||||||
|
|
||||||
|
if resultData.length != 0
|
||||||
|
tableRow.append('<td>' + (avg_total / resultData.length) + '</td>')
|
||||||
|
else
|
||||||
|
tableRow.append('<td>N/a</td>')
|
||||||
|
|
||||||
|
if min_total != 0
|
||||||
|
tableRow.append('<td>' + (min_total / resultData.length) + '</td>')
|
||||||
|
tableRow.append('<td>' + (max_total / resultData.length) + '</td>')
|
||||||
|
else
|
||||||
|
tableRow.append('<td>N/a</td>')
|
||||||
|
tableRow.append('<td>N/a</td>')
|
||||||
|
catch error
|
||||||
|
console.error 'An error occurred while fetching benchmark results.', error
|
||||||
|
|
||||||
|
$('#results-table tbody tr').each((index, tr) ->
|
||||||
|
benchmarkId = $(tr).data('benchmark-id')
|
||||||
|
console.log("Fetching results for benchmark id: " + benchmarkId)
|
||||||
|
fetchTestBenchmarkResults(testId, benchmarkId)
|
||||||
|
)
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
@use "sass:color"
|
||||||
|
|
||||||
|
//$primary-color: #3399ff
|
||||||
|
$primary-color: cornflowerblue
|
||||||
|
$primary-color-highlight: color.adjust($primary-color, $lightness: -10%)
|
||||||
|
|
||||||
|
body
|
||||||
|
background: #eee
|
||||||
|
|
||||||
|
a
|
||||||
|
color: $primary-color
|
||||||
|
transition: color 225ms ease-in-out
|
||||||
|
&:hover
|
||||||
|
color: $primary-color-highlight
|
||||||
|
|
||||||
|
input[type=submit],
|
||||||
|
button
|
||||||
|
background: $primary-color
|
||||||
|
color: #eee
|
||||||
|
border-radius: 8px
|
||||||
|
transition: all 225ms ease-in-out
|
||||||
|
&:hover
|
||||||
|
background: $primary-color-highlight
|
||||||
|
color: white
|
||||||
|
|
||||||
|
#wrapper
|
||||||
|
background: white
|
||||||
|
padding: 1rem 2rem
|
||||||
|
border-radius: 8px
|
||||||
|
|
||||||
|
#main-nav
|
||||||
|
margin-bottom: 15px
|
||||||
|
background: $primary-color
|
||||||
|
border-bottom: 1px solid #eee
|
||||||
|
|
||||||
|
ul
|
||||||
|
background: none
|
||||||
|
|
||||||
|
a
|
||||||
|
color: #eee
|
||||||
|
font-weight: bold
|
||||||
|
&:hover
|
||||||
|
color: white
|
||||||
|
|
||||||
|
h1.invalid
|
||||||
|
color: red
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
docker build -t game-data -f Dockerfile.dev .
|
||||||
|
docker build -t game-data-gulp -f Dockerfile.gulp .
|
||||||
Executable
+5
@@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
docker build -t game-data -f Dockerfile.dev .
|
||||||
|
docker build -t game-data-gulp -f Dockerfile.gulp .
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
docker exec game-data rake %*
|
||||||
Executable
+3
@@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
docker exec game-data rake "$@"
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
docker run --rm -d -t -v "%cd%:/usr/src/game-data" -p 9292:9292 --name game-data game-data
|
||||||
|
docker run --rm -d -t -v "%cd%:/usr/src/game-data" --name game-data-gulp game-data-gulp npm run gulp watch
|
||||||
Executable
+5
@@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
docker run --rm -d -t -v "$(pwd):/usr/src/game-data" -p 9292:9292 --name game-data game-data
|
||||||
|
docker run --rm -d -t -v "$(pwd):/usr/src/game-data" --name game-data-gulp game-data-gulp npm run gulp watch
|
||||||
|
|
||||||
Executable
+6
@@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Configure bundler to use local vendor path
|
||||||
|
bundle config set --local path 'vendor/bundle'
|
||||||
|
# Install gems
|
||||||
|
bundle install
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# Load application config
|
||||||
|
require_relative 'src/config.rb'
|
||||||
|
$conf = Config.new(File.join(__dir__, 'config/defaults.yaml'))
|
||||||
|
|
||||||
|
root = ::File.dirname(__FILE__)
|
||||||
|
require ::File.join( root, 'src', 'server' )
|
||||||
|
run GameData.new
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
database:
|
||||||
|
adapter: 'sqlite'
|
||||||
|
database: 'data/gamedata.db'
|
||||||
|
|
||||||
|
testing:
|
||||||
|
minimum_results_required: 3
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
Sequel.migration do
|
||||||
|
|
||||||
|
up do
|
||||||
|
create_table(:hardware) do
|
||||||
|
primary_key :id
|
||||||
|
String :name, null: false
|
||||||
|
String :type, null: false
|
||||||
|
String :description, text: true
|
||||||
|
DateTime :created_at, default: Sequel::CURRENT_TIMESTAMP
|
||||||
|
DateTime :updated_at, default: Sequel::CURRENT_TIMESTAMP
|
||||||
|
end
|
||||||
|
|
||||||
|
create_table(:benchmarks) do
|
||||||
|
primary_key :id
|
||||||
|
String :name, null: false
|
||||||
|
String :description, text: true
|
||||||
|
String :scoring, null: false
|
||||||
|
DateTime :created_at, default: Sequel::CURRENT_TIMESTAMP
|
||||||
|
DateTime :updated_at, default: Sequel::CURRENT_TIMESTAMP
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
down do
|
||||||
|
drop_table(:hardware)
|
||||||
|
drop_table(:benchmarks)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
Sequel.migration do
|
||||||
|
|
||||||
|
up do
|
||||||
|
# create tests table
|
||||||
|
create_table(:results) do
|
||||||
|
primary_key :id
|
||||||
|
foreign_key :hardware_id, :hardware
|
||||||
|
foreign_key :benchmark_id, :benchmarks
|
||||||
|
Float :avg_score, null: false
|
||||||
|
Float :min_score
|
||||||
|
Float :max_score
|
||||||
|
DateTime :created_at, default: Sequel::CURRENT_TIMESTAMP
|
||||||
|
DateTime :updated_at, default: Sequel::CURRENT_TIMESTAMP
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
down do
|
||||||
|
drop_table(:results)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
Sequel.migration do
|
||||||
|
|
||||||
|
up do
|
||||||
|
# create tests table
|
||||||
|
create_table(:tests) do
|
||||||
|
primary_key :id
|
||||||
|
foreign_key :hardware_id, :hardware
|
||||||
|
String :name, null: false
|
||||||
|
String :description
|
||||||
|
DateTime :created_at, default: Sequel::CURRENT_TIMESTAMP
|
||||||
|
DateTime :updated_at, default: Sequel::CURRENT_TIMESTAMP
|
||||||
|
end
|
||||||
|
|
||||||
|
# create many-to-many table between tests and benchmarks
|
||||||
|
create_table(:benchmarks_tests) do
|
||||||
|
primary_key :id
|
||||||
|
foreign_key :benchmark_id, :benchmarks
|
||||||
|
foreign_key :test_id, :tests
|
||||||
|
DateTime :created_at, default: Sequel::CURRENT_TIMESTAMP
|
||||||
|
DateTime :updated_at, default: Sequel::CURRENT_TIMESTAMP
|
||||||
|
end
|
||||||
|
|
||||||
|
# modify results table to integrate with the new tests table
|
||||||
|
alter_table(:results) do
|
||||||
|
drop_foreign_key :hardware_id
|
||||||
|
add_foreign_key :test_id, :tests
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
down do
|
||||||
|
alter_table(:results) do
|
||||||
|
drop_foreign_key :test_id
|
||||||
|
add_foreign_key :hardware_id, :hardware
|
||||||
|
end
|
||||||
|
drop_table(:benchmarks_tests)
|
||||||
|
drop_table(:tests)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ ! -f ./data/gamedata.db ]; then
|
||||||
|
rake db:migrate
|
||||||
|
fi
|
||||||
|
|
||||||
|
rake server:dev
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
const gulp = require('gulp');
|
||||||
|
const sass = require('gulp-sass')(require('sass'));
|
||||||
|
const coffee = require('gulp-coffee');
|
||||||
|
const sourcemaps = require('gulp-sourcemaps');
|
||||||
|
const plumber = require('gulp-plumber');
|
||||||
|
|
||||||
|
// Compile .sass files to compressed CSS
|
||||||
|
function compileSass() {
|
||||||
|
return gulp.src('assets/styles/**/*.sass')
|
||||||
|
.pipe(plumber())
|
||||||
|
.pipe(sass({ outputStyle: 'compressed' }).on('error', sass.logError))
|
||||||
|
.pipe(gulp.dest('public/css'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compile .coffee files to JavaScript with source maps
|
||||||
|
function compileCoffee() {
|
||||||
|
return gulp.src('assets/scripts/*.coffee', { sourcemaps: true })
|
||||||
|
.pipe(plumber())
|
||||||
|
.pipe(coffee({ bare: true }))
|
||||||
|
.pipe(gulp.dest('public/js', { sourcemaps: '.' }));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Watch files for changes
|
||||||
|
function watchFiles() {
|
||||||
|
gulp.watch('assets/styles/**/*.sass', compileSass);
|
||||||
|
gulp.watch('assets/scripts/**/*.coffee', compileCoffee);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define default task
|
||||||
|
exports.default = gulp.series(
|
||||||
|
gulp.parallel(compileSass, compileCoffee),
|
||||||
|
watchFiles
|
||||||
|
);
|
||||||
|
|
||||||
|
// one-time build
|
||||||
|
exports.build = gulp.parallel(compileSass, compileCoffee);
|
||||||
|
|
||||||
|
// start builds with file watching
|
||||||
|
exports.watch = watchFiles;
|
||||||
Generated
+3159
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"name": "game-data",
|
||||||
|
"description": "PC hardware benchmarking data logger",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"main": "src/server.rb",
|
||||||
|
"scripts": {
|
||||||
|
"gulp": "gulp"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.metaunix.net/BitGoblin/game-data"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"pc",
|
||||||
|
"hardware",
|
||||||
|
"benchmarking"
|
||||||
|
],
|
||||||
|
"author": "Gregory Ballantine <gballantine@bitgoblin.tech>",
|
||||||
|
"license": "BSD-2-Clause",
|
||||||
|
"devDependencies": {
|
||||||
|
"gulp": "^5.0.1",
|
||||||
|
"gulp-coffee": "^3.0.3",
|
||||||
|
"gulp-plumber": "^1.2.1",
|
||||||
|
"gulp-sass": "^6.0.1",
|
||||||
|
"gulp-sourcemaps": "^3.0.0",
|
||||||
|
"sass": "^1.89.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'yaml'
|
||||||
|
|
||||||
|
# Config - loads and manages the app's configuration
|
||||||
|
class Config
|
||||||
|
|
||||||
|
DEFAULT_CONFIG = 'config/defaults.yaml'
|
||||||
|
|
||||||
|
def initialize(config_path)
|
||||||
|
@data = YAML.load_file(DEFAULT_CONFIG)
|
||||||
|
|
||||||
|
# merge in user-defined configuration if it exists
|
||||||
|
@data.merge!(YAML.load_file(config_path)) if File.exist?(config_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(key)
|
||||||
|
bits = key.split('.')
|
||||||
|
value = @data
|
||||||
|
|
||||||
|
bits.each do |bit|
|
||||||
|
value = value[bit]
|
||||||
|
end
|
||||||
|
|
||||||
|
return value
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# Helpers - view helper functions
|
||||||
|
module Helpers
|
||||||
|
|
||||||
|
def date_format(date)
|
||||||
|
dt = date.to_datetime
|
||||||
|
return dt.strftime('%B %d, %Y @ %I:%M:%S %p %Z')
|
||||||
|
end
|
||||||
|
|
||||||
|
def average_array(arr, decimals = 1)
|
||||||
|
sum = 0
|
||||||
|
|
||||||
|
arr.each do |i|
|
||||||
|
sum += i
|
||||||
|
end
|
||||||
|
|
||||||
|
return (sum / arr.length).round(decimals)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# Benchmark - database model for PC benchmarks
|
||||||
|
class Benchmark < Sequel::Model
|
||||||
|
|
||||||
|
one_to_many :results
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# Hardware - database model for PC hardware
|
||||||
|
class Hardware < Sequel::Model(:hardware)
|
||||||
|
|
||||||
|
one_to_many :tests
|
||||||
|
|
||||||
|
def bench_results
|
||||||
|
br = {}
|
||||||
|
|
||||||
|
results.each do |r|
|
||||||
|
br[r.benchmark.name.to_s] = [] unless br.key?(r.benchmark.name)
|
||||||
|
|
||||||
|
br[r.benchmark.name.to_s].push(r.avg_score)
|
||||||
|
end
|
||||||
|
|
||||||
|
return br
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require_relative 'hardware'
|
||||||
|
require_relative 'benchmark'
|
||||||
|
require_relative 'result'
|
||||||
|
require_relative 'test'
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# Result - database model for benchmark results
|
||||||
|
class Result < Sequel::Model
|
||||||
|
|
||||||
|
many_to_one :test
|
||||||
|
many_to_one :benchmark
|
||||||
|
|
||||||
|
def formatted_score
|
||||||
|
return @avg_score
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# Test - database model for hardware tests
|
||||||
|
class Test < Sequel::Model
|
||||||
|
|
||||||
|
one_to_many :result
|
||||||
|
many_to_one :hardware
|
||||||
|
many_to_many :benchmark
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# /api/v1 routes
|
||||||
|
class GameData < Sinatra::Base
|
||||||
|
|
||||||
|
get '/api/v1/benchmark/details' do
|
||||||
|
benchmark_id = params[:benchmark_id]
|
||||||
|
|
||||||
|
benchmark = Benchmark.where(id: benchmark_id).first()
|
||||||
|
|
||||||
|
json benchmark.values()
|
||||||
|
end
|
||||||
|
|
||||||
|
get '/api/v1/results' do
|
||||||
|
test_id = params[:test_id]
|
||||||
|
benchmark_id = params[:benchmark_id]
|
||||||
|
|
||||||
|
results = Result.where(test_id: test_id, benchmark_id: benchmark_id).all()
|
||||||
|
|
||||||
|
json results.map(&:values)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# /benchmark routes
|
||||||
|
class GameData < Sinatra::Base
|
||||||
|
|
||||||
|
get '/benchmark' do
|
||||||
|
benchmarks = Benchmark.reverse(:updated_at).limit(10).all()
|
||||||
|
|
||||||
|
erb :'benchmark/index', locals: {
|
||||||
|
title: 'List of Benchmarks',
|
||||||
|
benchmarks: benchmarks
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
get '/benchmark/add' do
|
||||||
|
erb :'benchmark/add', locals: {
|
||||||
|
title: 'Add Benchmark'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
post '/benchmark/add' do
|
||||||
|
benchmark = Benchmark.create(
|
||||||
|
name: params[:benchmark_name],
|
||||||
|
scoring: params[:benchmark_scoring],
|
||||||
|
description: params[:benchmark_description]
|
||||||
|
)
|
||||||
|
|
||||||
|
redirect "/benchmark/#{benchmark.id}"
|
||||||
|
end
|
||||||
|
|
||||||
|
get '/benchmark/:benchmark_id' do
|
||||||
|
benchmark = Benchmark.where(id: params[:benchmark_id]).first()
|
||||||
|
erb :'benchmark/view', locals: {
|
||||||
|
title: benchmark.name,
|
||||||
|
benchmark: benchmark
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
get '/benchmark/:benchmark_id/edit' do
|
||||||
|
benchmark = Benchmark.where(id: params[:benchmark_id]).first()
|
||||||
|
erb :'benchmark/edit', locals: {
|
||||||
|
title: "Editing: #{benchmark.name}",
|
||||||
|
benchmark: benchmark
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
post '/benchmark/:benchmark_id/edit' do
|
||||||
|
benchmark = Benchmark.where(id: params[:benchmark_id]).first()
|
||||||
|
|
||||||
|
benchmark.update(
|
||||||
|
name: params[:benchmark_name],
|
||||||
|
scoring: params[:benchmark_scoring],
|
||||||
|
description: params[:benchmark_description]
|
||||||
|
)
|
||||||
|
|
||||||
|
redirect "/benchmark/#{benchmark.id}"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# /hardware routes
|
||||||
|
class GameData < Sinatra::Base
|
||||||
|
|
||||||
|
get '/hardware' do
|
||||||
|
hardware = Hardware.reverse(:updated_at).limit(10).all()
|
||||||
|
|
||||||
|
erb :'hardware/index', locals: {
|
||||||
|
title: 'List of Hardware',
|
||||||
|
hardware: hardware
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
get '/hardware/add' do
|
||||||
|
erb :'hardware/add', locals: {
|
||||||
|
title: 'Add Hardware'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
post '/hardware/add' do
|
||||||
|
hardware = Hardware.create(
|
||||||
|
name: params[:hardware_name],
|
||||||
|
type: params[:hardware_type]
|
||||||
|
)
|
||||||
|
|
||||||
|
redirect "/hardware/#{hardware.id}"
|
||||||
|
end
|
||||||
|
|
||||||
|
get '/hardware/:hardware_id' do
|
||||||
|
benchmarks = Benchmark.order(:name).all()
|
||||||
|
hardware = Hardware.where(id: params[:hardware_id]).first()
|
||||||
|
erb :'hardware/view', locals: {
|
||||||
|
title: hardware.name,
|
||||||
|
hardware: hardware,
|
||||||
|
benchmarks: benchmarks
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
get '/hardware/:hardware_id/edit' do
|
||||||
|
hardware = Hardware.where(id: params[:hardware_id]).first()
|
||||||
|
erb :'hardware/edit', locals: {
|
||||||
|
title: "Editing: #{hardware.name}",
|
||||||
|
hardware: hardware
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
post '/hardware/:hardware_id/edit' do
|
||||||
|
hardware = Hardware.where(id: params[:hardware_id]).first()
|
||||||
|
|
||||||
|
hardware.update(
|
||||||
|
name: params[:hardware_name],
|
||||||
|
type: params[:hardware_type]
|
||||||
|
)
|
||||||
|
|
||||||
|
redirect "/hardware/#{hardware.id}"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# / (top-level) routes
|
||||||
|
class GameData < Sinatra::Base
|
||||||
|
|
||||||
|
get '/' do
|
||||||
|
tests = Test.reverse(:updated_at).limit(10).all()
|
||||||
|
|
||||||
|
erb :'index/index', locals: {
|
||||||
|
title: 'Dashboard',
|
||||||
|
tests: tests
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require_relative 'index'
|
||||||
|
require_relative 'hardware'
|
||||||
|
require_relative 'benchmark'
|
||||||
|
require_relative 'result'
|
||||||
|
require_relative 'reports'
|
||||||
|
require_relative 'test'
|
||||||
|
|
||||||
|
require_relative 'api1'
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# /reports routes
|
||||||
|
class GameData < Sinatra::Base
|
||||||
|
|
||||||
|
get '/reports' do
|
||||||
|
benchmarks = Benchmark.order(:name).all()
|
||||||
|
tests = Test.order(:name).all()
|
||||||
|
|
||||||
|
erb :'reports/index', locals: {
|
||||||
|
title: 'Generate Reports',
|
||||||
|
tests: tests,
|
||||||
|
benchmarks: benchmarks
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
post '/reports' do
|
||||||
|
report_type = params[:type]
|
||||||
|
report_choice = params[:choice]
|
||||||
|
report_compare = params[:compare]
|
||||||
|
|
||||||
|
if report_type == 'benchmark'
|
||||||
|
choice = Benchmark.where(id: report_choice).first().name
|
||||||
|
names = []
|
||||||
|
avg_results = []
|
||||||
|
min_results = []
|
||||||
|
|
||||||
|
report_compare.each do |c|
|
||||||
|
tst = Test.where(id: c).first()
|
||||||
|
names.push(tst.name)
|
||||||
|
|
||||||
|
res = Result.where(benchmark_id: report_choice, test_id: c).first()
|
||||||
|
avg_results.push(res.avg_score)
|
||||||
|
min_results.push(res.min_score)
|
||||||
|
end
|
||||||
|
|
||||||
|
json({
|
||||||
|
choice: choice,
|
||||||
|
names: names,
|
||||||
|
avg_results: avg_results,
|
||||||
|
min_results: min_results
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# /result routes
|
||||||
|
class GameData < Sinatra::Base
|
||||||
|
|
||||||
|
get '/result' do
|
||||||
|
results = Result.reverse(:updated_at).limit(10).all()
|
||||||
|
|
||||||
|
erb :'result/index', locals: {
|
||||||
|
title: 'List of Results',
|
||||||
|
results: results
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
get '/result/add' do
|
||||||
|
hardware = Hardware.all()
|
||||||
|
benchmarks = Benchmark.all()
|
||||||
|
|
||||||
|
erb :'result/add', locals: {
|
||||||
|
title: 'Add Result',
|
||||||
|
hardware: hardware,
|
||||||
|
benchmarks: benchmarks
|
||||||
|
}
|
||||||
|
end
|
||||||
|
post '/result/add' do
|
||||||
|
result_minimum = params[:result_minimum] if params.key?(:result_minimum)
|
||||||
|
result_maximum = params[:result_maximum] if params.key?(:result_maximum)
|
||||||
|
|
||||||
|
Result.create(
|
||||||
|
test_id: params[:result_test],
|
||||||
|
benchmark_id: params[:result_benchmark],
|
||||||
|
avg_score: params[:result_average],
|
||||||
|
min_score: result_minimum,
|
||||||
|
max_score: result_maximum
|
||||||
|
)
|
||||||
|
|
||||||
|
if params.key?(:result_referrer)
|
||||||
|
if params[:result_referrer] == 'test'
|
||||||
|
redirect "/test/#{params[:result_test]}"
|
||||||
|
elsif params[:result_referrer] == 'benchmark'
|
||||||
|
redirect "/benchmark/#{params[:result_benchmark]}"
|
||||||
|
end
|
||||||
|
else
|
||||||
|
redirect '/result'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# /test routes
|
||||||
|
class GameData < Sinatra::Base
|
||||||
|
|
||||||
|
get '/test' do
|
||||||
|
tests = Test.reverse(:updated_at).limit(10).all()
|
||||||
|
|
||||||
|
erb :'test/index', locals: {
|
||||||
|
title: 'List of Tests',
|
||||||
|
tests: tests
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
get '/test/add' do
|
||||||
|
hardware = Hardware.order(:name).all()
|
||||||
|
benchmarks = Benchmark.order(:name).all()
|
||||||
|
erb :'test/add', locals: {
|
||||||
|
title: 'Add Test',
|
||||||
|
hardware: hardware,
|
||||||
|
benchmarks: benchmarks
|
||||||
|
}
|
||||||
|
end
|
||||||
|
post '/test/add' do
|
||||||
|
tst = Test.create(
|
||||||
|
name: params[:test_name],
|
||||||
|
hardware_id: params[:test_hardware],
|
||||||
|
description: params[:test_description]
|
||||||
|
)
|
||||||
|
|
||||||
|
# create an array of the selected benchmarks
|
||||||
|
benchmarks = Array(params[:test_benchmarks])
|
||||||
|
# associate the benchmarks to the test
|
||||||
|
benchmarks.each do |b|
|
||||||
|
tst.add_benchmark(b)
|
||||||
|
end
|
||||||
|
|
||||||
|
redirect "/test/#{tst.id}"
|
||||||
|
end
|
||||||
|
|
||||||
|
get '/test/:test_id' do
|
||||||
|
tst = Test.where(id: params[:test_id]).first()
|
||||||
|
erb :'test/view', locals: {
|
||||||
|
title: tst.name,
|
||||||
|
test: tst
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
get '/test/:hardware_id/edit' do
|
||||||
|
hardware = Hardware.where(id: params[:hardware_id]).first()
|
||||||
|
erb :'test/edit', locals: {
|
||||||
|
title: "Editing: #{hardware.name}",
|
||||||
|
hardware: hardware
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
post '/test/:hardware_id/edit' do
|
||||||
|
hardware = Hardware.where(id: params[:hardware_id]).first()
|
||||||
|
|
||||||
|
hardware.update(
|
||||||
|
name: params[:hardware_name],
|
||||||
|
type: params[:hardware_type]
|
||||||
|
)
|
||||||
|
|
||||||
|
redirect "/hardware/#{hardware.id}"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
Executable
+34
@@ -0,0 +1,34 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'sinatra/base'
|
||||||
|
require 'sinatra/json'
|
||||||
|
require 'sequel'
|
||||||
|
require 'sqlite3'
|
||||||
|
|
||||||
|
# Load the Sequel timestamps plugin
|
||||||
|
Sequel::Model.plugin(:timestamps)
|
||||||
|
# Initialize Sequel gem for database actions
|
||||||
|
DB = Sequel.connect(adapter: $conf.get('database.adapter'), database: $conf.get('database.database'))
|
||||||
|
|
||||||
|
# Base app
|
||||||
|
class GameData < Sinatra::Base
|
||||||
|
|
||||||
|
enable :sessions
|
||||||
|
|
||||||
|
# Set up static file serving
|
||||||
|
enable :static
|
||||||
|
set :public_folder, File.join(__dir__, '/../public')
|
||||||
|
|
||||||
|
# Register view helpers
|
||||||
|
require_relative 'helpers'
|
||||||
|
helpers Helpers
|
||||||
|
|
||||||
|
# Set up our view engine
|
||||||
|
set :views, File.join(settings.root, '/../views')
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
# Load routes
|
||||||
|
require_relative 'routes/init'
|
||||||
|
# Load models
|
||||||
|
require_relative 'models/init'
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
<div class="cell small-12">
|
||||||
|
<h1>Add new benchmark</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
|
||||||
|
<form class="cell small-12" action="/benchmark/add" method="post">
|
||||||
|
<div class="grid-x grid-padding-x">
|
||||||
|
<div class="cell medium-9">
|
||||||
|
<label>
|
||||||
|
Benchmark name
|
||||||
|
<input type="text" name="benchmark_name" placeholder="Example benchmark">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell medium-3">
|
||||||
|
<label>
|
||||||
|
Scoring type
|
||||||
|
<select name="benchmark_scoring">
|
||||||
|
<option value="fps">Frames per Second (fps)</option>
|
||||||
|
<option value="ms">Frame Time (ms)</option>
|
||||||
|
<option value="pts">Total Points</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid-x grid-padding-x">
|
||||||
|
<div class="cell small-12">
|
||||||
|
<textarea name="benchmark_description" class="cell small-12">Enter a description/notes here.</textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid-x grid-padding-x">
|
||||||
|
<div class="cell small-12">
|
||||||
|
<input type="submit" class="button" value="Submit">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
<div class="cell small-12">
|
||||||
|
<h1>Editing: <%= benchmark.name %></h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
|
||||||
|
<form class="cell small-12" action="/benchmark/<%= benchmark.id %>/edit" method="post">
|
||||||
|
<div class="grid-x grid-padding-x">
|
||||||
|
<div class="cell medium-9">
|
||||||
|
<label>
|
||||||
|
Benchmark name
|
||||||
|
<input type="text" name="benchmark_name" placeholder="Example benchmark" value="<%= benchmark.name %>">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell medium-3">
|
||||||
|
<label>
|
||||||
|
Scoring type
|
||||||
|
<select name="benchmark_scoring">
|
||||||
|
<option value="fps" <% if benchmark.scoring == 'fps' %>selected<% end %>>Frames per Second (fps)</option>
|
||||||
|
<option value="ms" <% if benchmark.scoring == 'ms' %>selected<% end %>>Frame Time (ms)</option>
|
||||||
|
<option value="pts" <% if benchmark.scoring == 'pts' %>selected<% end %>>Total Points</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid-x grid-padding-x">
|
||||||
|
<div class="cell small-12">
|
||||||
|
<textarea name="benchmark_description" class="cell small-12"><%= benchmark.description %></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid-x grid-padding-x">
|
||||||
|
<div class="cell small-12">
|
||||||
|
<input type="submit" class="button" value="Submit">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
<div class="cell small-12">
|
||||||
|
<h1>List of benchmarks</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell small-12">
|
||||||
|
<p>
|
||||||
|
<a href="/benchmark/add">Add new benchmark</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
<% if benchmarks.length > 0 %>
|
||||||
|
<div class="cell small-12">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Benchmark name</th>
|
||||||
|
<th>Scoring type</th>
|
||||||
|
<th>Notes</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% benchmarks.each do |b| %>
|
||||||
|
<tr>
|
||||||
|
<td><a href="/benchmark/<%= b.id %>"><%= b.name %></a</td>
|
||||||
|
<td><%= b.scoring %></td>
|
||||||
|
<td><%= b.description %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<% else %>
|
||||||
|
<div class="cell small-12">
|
||||||
|
<p>I'm sorry, there doesn't appear to be any benchmarks added yet. Check again later!</p>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
<div class="cell small-12">
|
||||||
|
<h1><%= benchmark.name %></h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell small-12">
|
||||||
|
<p><a href="/benchmark/<%= benchmark.id %>/edit">Edit</a></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell small-12">
|
||||||
|
Benchmark scoring type: <%= benchmark.scoring %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell small-12">
|
||||||
|
Description:
|
||||||
|
<p><%= benchmark.description %></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
<div class="cell small-12">
|
||||||
|
<h1>Add new hardware</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
|
||||||
|
<form class="cell small-12" action="/hardware/add" method="post">
|
||||||
|
<div class="grid-x grid-padding-x">
|
||||||
|
<div class="cell medium-9">
|
||||||
|
<label>
|
||||||
|
Hardware name
|
||||||
|
<input type="text" name="hardware_name" placeholder="Example hardware">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell medium-3">
|
||||||
|
<label>
|
||||||
|
Type
|
||||||
|
<select name="hardware_type">
|
||||||
|
<option value="gpu">Graphics card</option>
|
||||||
|
<option value="cpu">Processor</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="submit" class="button" value="Submit">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
<div class="cell small-12">
|
||||||
|
<h1>Editing: <%= hardware.name %></h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
|
||||||
|
<form class="cell small-12" action="/hardware/<%= hardware.id %>/edit" method="post">
|
||||||
|
<div class="grid-x grid-padding-x">
|
||||||
|
<div class="cell medium-9">
|
||||||
|
<label>
|
||||||
|
Hardware name
|
||||||
|
<input type="text" name="hardware_name" placeholder="Example hardware" value="<%= hardware.name %>">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell medium-3">
|
||||||
|
<label>
|
||||||
|
Type
|
||||||
|
<select name="hardware_type">
|
||||||
|
<option value="gpu" <% if hardware.type == 'gpu' %>selected<% end %>>Graphics card</option>
|
||||||
|
<option value="cpu" <% if hardware.type == 'cpu' %>selected<% end %>>Processor</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="submit" class="button" value="Submit">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
<div class="cell small-12">
|
||||||
|
<h1>List of hardware</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell small-12">
|
||||||
|
<p>
|
||||||
|
<a href="/hardware/add">Add new hardware</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
<% if hardware.length > 0 %>
|
||||||
|
<div class="cell small-12">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Hardware name</th>
|
||||||
|
<th>Type</th>
|
||||||
|
<th>Date added</th>
|
||||||
|
<th>Date modified</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% hardware.each do |h| %>
|
||||||
|
<tr>
|
||||||
|
<td><a href="/hardware/<%= h.id %>"><%= h.name %></a></td>
|
||||||
|
<td><%= h.type %></td>
|
||||||
|
<td><%= date_format(h.created_at) %></td>
|
||||||
|
<td><%= date_format(h.updated_at) %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<% else %>
|
||||||
|
<div class="cell small-12">
|
||||||
|
<p>I'm sorry, there doesn't appear to be any hardware added yet. Check again later!</p>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
<div class="cell small-12">
|
||||||
|
<h1><%= hardware.name %></h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell small-12">
|
||||||
|
<p><a href="/hardware/<%= hardware.id %>/edit">Edit</a></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell small-12">
|
||||||
|
Hardware type: <%= hardware.type %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
<% if tests.length > 0 %>
|
||||||
|
<div class="cell small-12">
|
||||||
|
<h2>Latest benchmark results:</h2>
|
||||||
|
</div>
|
||||||
|
<div class="cell small-12">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Test name</th>
|
||||||
|
<th># Benchmarks</th>
|
||||||
|
<th>Last Updated</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% tests.each do |t| %>
|
||||||
|
<tr>
|
||||||
|
<td><a href="/test/<%= t.id %>"><%= t.name %></a></td>
|
||||||
|
<td><%= t.benchmark.length %></td>
|
||||||
|
<td><%= t.updated_at %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<% else %>
|
||||||
|
<div class="cell small-12">
|
||||||
|
<p>I'm sorry, there don't appear to be any benchmark results logged yet. Check again later!</p>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
<!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 %> | Game Data</title>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.7.5/css/foundation.min.css">
|
||||||
|
<link rel="stylesheet" href="/css/rimmington.css">
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min.js" charset="utf-8"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.7.5/js/foundation.min.js" charset="utf-8"></script>
|
||||||
|
<script src="/js/edgeville.js" charset="utf-8"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js" charset="utf-8"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- main navigation -->
|
||||||
|
<%= erb :'partials/navbar', :locals => locals %>
|
||||||
|
|
||||||
|
<!-- main content -->
|
||||||
|
<div id="wrapper" class="grid-container">
|
||||||
|
<%= yield %>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<div id="main-nav" class="top-bar">
|
||||||
|
<div class="top-bar-left">
|
||||||
|
<ul class="menu">
|
||||||
|
<li><a href="/">Dashboard</a></li>
|
||||||
|
<li><a href="/hardware">Hardware</a></li>
|
||||||
|
<li><a href="/benchmark">Benchmarks</a></li>
|
||||||
|
<li><a href="/test">Tests</a></li>
|
||||||
|
<li><a href="/reports">Reports</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
<form class="cell small-12" action="/reports" method="post">
|
||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
<select class="cell medium-6" id="report_type" name="report_type" disabled>
|
||||||
|
<option value="benchmark">Benchmark</option>
|
||||||
|
<option value="test">Test</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select class="cell medium-6" id="report_choice" name="report_choice">
|
||||||
|
<% benchmarks.each do |b| %>
|
||||||
|
<option value="<%= b.id %>"><%= b.name %></option>
|
||||||
|
<% end %>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
<select class="cell small-12" id="report_compare" name="report_compare[]" multiple>
|
||||||
|
<% tests.each do |t| %>
|
||||||
|
<option value="<%= t.id %>"><%= t.name %></option>
|
||||||
|
<% end %>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="submit" class="button" id="generate_button" value="Generate">
|
||||||
|
<a href="#" class="button" id="download_button" disabled>Download</a>
|
||||||
|
|
||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
<canvas id="chart_canvas" width="100%" height="25"></canvas>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- load the chart.js library -->
|
||||||
|
<!-- load chart functionality -->
|
||||||
|
<script src="/js/reports.js" charset="utf-8"></script>
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
<div class="cell small-12">
|
||||||
|
<h1>Add new result</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
|
||||||
|
<form class="cell small-12" action="/result/add" method="post">
|
||||||
|
<div class="grid-x grid-padding-x">
|
||||||
|
<div class="cell medium-6">
|
||||||
|
<label>
|
||||||
|
Hardware:
|
||||||
|
<select name="result_hardware">
|
||||||
|
<% hardware.each do |h| %>
|
||||||
|
<option value="<%= h.id %>"><%= h.name %></option>
|
||||||
|
<% end %>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell medium-6">
|
||||||
|
<label>
|
||||||
|
Benchmark:
|
||||||
|
<select name="result_benchmark">
|
||||||
|
<% benchmarks.each do |b| %>
|
||||||
|
<option value="<%= b.id %>"><%= b.name %></option>
|
||||||
|
<% end %>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid-x grid-padding-x">
|
||||||
|
<div class="cell medium-4">
|
||||||
|
<label>
|
||||||
|
Average score:
|
||||||
|
<input type="number" name="result_average" value="0.0" step="0.01" required>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell medium-4">
|
||||||
|
<label>
|
||||||
|
Minimum score:
|
||||||
|
<input type="number" name="result_minimum" value="0.0" step="0.01">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell medium-4">
|
||||||
|
<label>
|
||||||
|
Maximum score:
|
||||||
|
<input type="number" name="result_maximum" value="0.0" step="0.01">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="submit" class="button" value="Submit">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
<div class="cell small-12">
|
||||||
|
<h1>List of results</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell small-12">
|
||||||
|
<p>
|
||||||
|
<a href="/result/add">Add new result</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
<% if results.length > 0 %>
|
||||||
|
<div class="cell small-12">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Hardware</th>
|
||||||
|
<th>Benchmark</th>
|
||||||
|
<th>Score (type)</th>
|
||||||
|
<th>Date added</th>
|
||||||
|
<th>Date modified</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% results.each do |r| %>
|
||||||
|
<tr>
|
||||||
|
<td><%= r.hardware.name %></td>
|
||||||
|
<td><%= r.benchmark.name %></td>
|
||||||
|
<td><%= r.score %> (<%= r.benchmark.scoring %>)</td>
|
||||||
|
<td><%= date_format(r.created_at) %></td>
|
||||||
|
<td><%= date_format(r.updated_at) %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<% else %>
|
||||||
|
<div class="cell small-12">
|
||||||
|
<p>I'm sorry, there don't appear to be any results added yet. Check again later!</p>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
<div class="cell small-12">
|
||||||
|
<h1>Add new test</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
|
||||||
|
<form class="cell small-12" action="/test/add" method="post">
|
||||||
|
<div class="grid-x grid-padding-x">
|
||||||
|
<div class="cell medium-6">
|
||||||
|
<label>
|
||||||
|
Test name
|
||||||
|
<input type="text" name="test_name" placeholder="My hardware test (01/99)">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell medium-6">
|
||||||
|
<label>
|
||||||
|
Type
|
||||||
|
<select name="test_hardware">
|
||||||
|
<% for h in hardware %>
|
||||||
|
<option value="<%= h.id %>"><%= h.name %></option>
|
||||||
|
<% end %>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell medium-4">
|
||||||
|
<label>
|
||||||
|
Benchmarks
|
||||||
|
<select name="test_benchmarks[]" multiple>
|
||||||
|
<% for b in benchmarks %>
|
||||||
|
<option value="<%= b.id %>"><%= b.name %></option>
|
||||||
|
<% end %>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell medium-8">
|
||||||
|
<label>
|
||||||
|
Test description
|
||||||
|
<textarea name="test_description" placeholder="This is my test for a hardware..."></textarea>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="submit" class="button" value="Submit">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
<div class="cell small-12">
|
||||||
|
<h1>Editing: <%= hardware.name %></h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
|
||||||
|
<form class="cell small-12" action="/hardware/<%= hardware.id %>/edit" method="post">
|
||||||
|
<div class="grid-x grid-padding-x">
|
||||||
|
<div class="cell medium-9">
|
||||||
|
<label>
|
||||||
|
Hardware name
|
||||||
|
<input type="text" name="hardware_name" placeholder="Example hardware" value="<%= hardware.name %>">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell medium-3">
|
||||||
|
<label>
|
||||||
|
Type
|
||||||
|
<select name="hardware_type">
|
||||||
|
<option value="gpu" <% if hardware.type == 'gpu' %>selected<% end %>>Graphics card</option>
|
||||||
|
<option value="cpu" <% if hardware.type == 'cpu' %>selected<% end %>>Processor</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="submit" class="button" value="Submit">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
<div class="cell small-12">
|
||||||
|
<h1>List of tests</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell small-12">
|
||||||
|
<p>
|
||||||
|
<a href="/test/add">Add new test</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
<% if tests.length > 0 %>
|
||||||
|
<div class="cell small-12">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Test name</th>
|
||||||
|
<th># of benchmarks</th>
|
||||||
|
<th>Date added</th>
|
||||||
|
<th>Date modified</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% tests.each do |t| %>
|
||||||
|
<tr>
|
||||||
|
<td><a href="/test/<%= t.id %>"><%= t.name %></a></td>
|
||||||
|
<td><%= t.benchmark.length %></td>
|
||||||
|
<td><%= date_format(t.created_at) %></td>
|
||||||
|
<td><%= date_format(t.updated_at) %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<% else %>
|
||||||
|
<div class="cell small-12">
|
||||||
|
<p>I'm sorry, there doesn't appear to be any tests added yet. Check again later!</p>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
<div class="cell small-12">
|
||||||
|
<h1><%= test.name %></h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell small-12">
|
||||||
|
<p><a href="/test/<%= test.id %>/edit">Edit</a></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell small-12">
|
||||||
|
Hardware tested: <%= test.hardware.name %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell small-12">
|
||||||
|
<p><%= test.description %></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div class="grix-x grix-margin-x">
|
||||||
|
<div class="cell small-12">
|
||||||
|
<form class="u-full-width" action="/result/add" method="post">
|
||||||
|
<input type="hidden" name="result_test" value="<%= test.id %>">
|
||||||
|
<input type="hidden" name="result_referrer" value="test">
|
||||||
|
|
||||||
|
<div class="grid-x grid-margin-x">
|
||||||
|
<div class="cell medium-5">
|
||||||
|
<label for="result_benchmark">
|
||||||
|
Add benchmark result:
|
||||||
|
<select class="u-full-width" id="result_benchmark" name="result_benchmark">
|
||||||
|
<% test.benchmark.each do |b| %>
|
||||||
|
<option value="<%= b.id %>"><%= b.name %></option>
|
||||||
|
<% end %>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell medium-2">
|
||||||
|
<label for="result_average">
|
||||||
|
Average score:
|
||||||
|
<input type="text" id="result_average" name="result_average" value="">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell medium-2">
|
||||||
|
<label for="result_minimum">
|
||||||
|
Minimum score:
|
||||||
|
<input type="text" id="result_minimum" name="result_minimum" value="">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell medium-2">
|
||||||
|
<label for="result_maximum">
|
||||||
|
Maximum score:
|
||||||
|
<input type="text" id="result_maximum" name="result_maximum" value="">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell medium-1">
|
||||||
|
<input type="submit" class="u-full-width button" value="Submit">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h4>Benchmark results for this test:</h4>
|
||||||
|
|
||||||
|
<table id="results-table" data-test-id="<%= test.id %>">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Benchmark name</th>
|
||||||
|
<th>Scoring type</th>
|
||||||
|
<th># results</th>
|
||||||
|
<th>Average</th>
|
||||||
|
<th>Minimum</th>
|
||||||
|
<th>Maximum</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% test.benchmark.each do |benchmark| %>
|
||||||
|
<tr data-benchmark-id="<%= benchmark.id %>"></tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- load test data fetching functionality -->
|
||||||
|
<script src="/js/test.js" charset="utf-8"></script>
|
||||||
Reference in New Issue
Block a user