First push
This commit is contained in:
0
ACC/results/__init__.py
Normal file
0
ACC/results/__init__.py
Normal file
5
ACC/results/apps.py
Normal file
5
ACC/results/apps.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class ResultsConfig(AppConfig):
|
||||
name = 'results'
|
30
ACC/results/templates/results/results.html
Normal file
30
ACC/results/templates/results/results.html
Normal file
@@ -0,0 +1,30 @@
|
||||
{% extends "main.html" %}
|
||||
{% block content %}
|
||||
|
||||
<style>
|
||||
.container {
|
||||
padding: 20px 16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
{% load django_bootstrap_breadcrumbs %}
|
||||
{% block breadcrumbs %}
|
||||
{% clear_breadcrumbs %}
|
||||
{% for b, u in path %}
|
||||
{% breadcrumb_raw_safe b u %}
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
{% load django_bootstrap5 %}
|
||||
{% bootstrap_css %}
|
||||
{% bootstrap_javascript %}
|
||||
|
||||
<div class="container">
|
||||
<div class="card">
|
||||
{% render_breadcrumbs %}
|
||||
{% load django_tables2 %}
|
||||
{% render_table table %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
@@ -0,0 +1 @@
|
||||
<a class="btn btn-success" href="{{record.name}}.json">Download</a>
|
@@ -0,0 +1 @@
|
||||
<a class="btn btn-dark" target="_blank" href="https://simresults.net/remote?result={{ request.build_absolute_uri }}{{record.name}}.json">Simresults</a>
|
@@ -0,0 +1 @@
|
||||
<a class="btn btn-primary" href="{{record.name}}">View</a>
|
9
ACC/results/urls.py
Normal file
9
ACC/results/urls.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from django.urls import re_path, path
|
||||
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
path('', views.resultSelect, name='instances'),
|
||||
re_path(r'^([^/]+)/?(.*).json', views.download, name='download'),
|
||||
re_path(r'^([^/]+)/?(.*)', views.results, name='results'),
|
||||
]
|
137
ACC/results/views.py
Normal file
137
ACC/results/views.py
Normal file
@@ -0,0 +1,137 @@
|
||||
import glob
|
||||
import itertools
|
||||
import ntpath
|
||||
|
||||
from django.http import HttpResponse, Http404
|
||||
from django.shortcuts import render
|
||||
|
||||
import os, json
|
||||
|
||||
from django.utils.html import format_html
|
||||
from django_tables2 import tables, Column, TemplateColumn, RequestConfig
|
||||
|
||||
from accservermanager.settings import CAR_MODEL_TYPES, DATA_DIR
|
||||
|
||||
|
||||
class LeaderBoard(tables.Table):
|
||||
position = Column(empty_values=())
|
||||
raceNumber = Column(accessor='car.raceNumber')
|
||||
carModel = Column(accessor='car.carModel')
|
||||
teamName = Column(accessor='car.teamName')
|
||||
drivers = Column(accessor='car.drivers')
|
||||
bestLap = Column(accessor='timing')
|
||||
laps = Column(accessor='timing.lapCount')
|
||||
totaltime = Column(accessor='timing.totalTime')
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(LeaderBoard, self).__init__(*args, **kwargs)
|
||||
self.counter = itertools.count(start=1)
|
||||
|
||||
def render_position(self):
|
||||
return '%d' % next(self.counter)
|
||||
|
||||
def render_carModel(self, value):
|
||||
for model in CAR_MODEL_TYPES:
|
||||
if model[0]==value: return model[1]
|
||||
return 'Unknown model %i'%value
|
||||
|
||||
def render_drivers(self, value):
|
||||
short = ' / '.join([d['shortName'] for d in value])
|
||||
long = ' / '.join(['%s %s'%(d['firstName'],d['lastName']) for d in value])
|
||||
return format_html('<p title="{}">{}</p>', long, short)
|
||||
|
||||
def render_time(self, value):
|
||||
if(value == 2147483647):
|
||||
return '---'
|
||||
s = value//1000
|
||||
m = s//60
|
||||
s %=60
|
||||
if m==0: return '%02i.%03i'%(s, value%1000)
|
||||
return '%i:%02i.%03i'%(m, s, value%1000)
|
||||
|
||||
def render_bestLap(self, value):
|
||||
return format_html('<p title="{}">{}</p>',
|
||||
' | '.join(list(map(self.render_time, value['bestSplits']))),
|
||||
self.render_time(value['bestLap']))
|
||||
|
||||
def render_totaltime(self, value):
|
||||
return self.render_time(value)
|
||||
|
||||
|
||||
class Results(tables.Table):
|
||||
name = Column()
|
||||
type = Column()
|
||||
track = Column()
|
||||
entries = Column()
|
||||
wetSession = Column()
|
||||
view = TemplateColumn(template_name='results/table/results_view_column.html')
|
||||
download = TemplateColumn(template_name='results/table/results_download_column.html')
|
||||
simresults = TemplateColumn(template_name='results/table/results_simresults_column.html')
|
||||
# delete = TemplateColumn(template_name='results/table/results_delete_column.html')
|
||||
|
||||
|
||||
def parse_url(args, kwargs):
|
||||
""" Read the select results file and display the selected portion of the json object """
|
||||
instance = kwargs['instance']
|
||||
result = args[0]
|
||||
results_path = os.path.join(DATA_DIR, 'instances', instance, 'results')
|
||||
return os.path.join(results_path, result+'.json')
|
||||
|
||||
|
||||
def results(request, *args, **kwargs):
|
||||
""" Read the select results file and display the selected portion of the json object """
|
||||
results = json.load(open(parse_url(args, kwargs), 'rb'))
|
||||
path = request.path
|
||||
if path[0] == '/': path = path[1:]
|
||||
if path[-1] == '/': path = path[:-1]
|
||||
path = path.split('/')
|
||||
|
||||
context = {
|
||||
'path': [(j, '/'+'/'.join(path[:i+1])) for i,j in enumerate(path)],
|
||||
'table': LeaderBoard(results['sessionResult']['leaderBoardLines'])
|
||||
}
|
||||
return render(request, 'results/results.html', context)
|
||||
|
||||
|
||||
def download(request, *args, **kwargs):
|
||||
_f = parse_url(args, kwargs)
|
||||
print(_f, os.path.basename(_f))
|
||||
if _f is not None and os.path.isfile(_f):
|
||||
with open(_f, 'r') as fh:
|
||||
response = HttpResponse(fh.read(), content_type="text/plain")
|
||||
response['Content-Disposition'] = 'inline; filename=' + os.path.basename(_f)
|
||||
return response
|
||||
raise Http404
|
||||
|
||||
|
||||
def resultSelect(request, instance):
|
||||
""" Show available results """
|
||||
results_path = os.path.join(DATA_DIR, 'instances', instance, 'results')
|
||||
files = sorted(glob.glob('%s/*.json'%(results_path)), reverse=True)
|
||||
files = filter(lambda x: not x.endswith('entrylist.json') , files)
|
||||
|
||||
results = []
|
||||
for f in files:
|
||||
r = json.load(open(f, 'rb'))
|
||||
|
||||
results.append(dict(
|
||||
name=os.path.splitext(ntpath.basename(f))[0],
|
||||
type=r['sessionType'], # TODO: decode session type, seems to be borked atm
|
||||
entries=len(r['sessionResult']['leaderBoardLines']),
|
||||
wetSession=r['sessionResult']['isWetSession'],
|
||||
track=r['trackName'],
|
||||
))
|
||||
|
||||
path = request.path
|
||||
if path[0] == '/': path = path[1:]
|
||||
if path[-1] == '/':path = path[:-1]
|
||||
path = path.split('/')
|
||||
|
||||
table = Results(results)
|
||||
RequestConfig(request).configure(table)
|
||||
|
||||
context = {
|
||||
'path' : [(j, '/'+'/'.join(path[:i+1])) for i,j in enumerate(path)],
|
||||
'table' : table,
|
||||
}
|
||||
return render(request, 'results/results.html', context)
|
Reference in New Issue
Block a user