Create basic environment for flask-based output

This commit is contained in:
Christian Wolf 2023-09-29 16:34:44 +02:00
parent 488bfae25e
commit a8be846f36
10 changed files with 164 additions and 13 deletions

View File

@ -1,16 +1,20 @@
attrs==22.1.0
beautifulsoup4==4.11.1
blinker==1.6.2
certifi==2023.7.22
charset-normalizer==3.2.0
click==8.1.7
colorama==0.4.6
coloredlogs==15.0.1
coverage==6.5.0
debugpy==1.6.7
distlib==0.3.7
exceptiongroup==1.0.1
Flask==2.3.3
humanfriendly==10.0
idna==3.4
iniconfig==1.1.1
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.3
packaging==21.3
@ -26,4 +30,5 @@ soupsieve==2.3.2.post1
tabulate==0.9.0
tomli==2.0.1
urllib3==2.0.5
Werkzeug==2.3.7
yarg==0.1.9

View File

@ -15,11 +15,17 @@ def main():
l = __initLogging()
cli = solo_turnier.cli.Cli(l)
batchWorker = solo_turnier.batch.BatchWorker(cli)
if cli.showGUI():
raise Exception('Not yet implemented')
elif cli.startFlaskServer():
solo_turnier.flask.startFlask(batchWorker, cli.getLogLevel() > 0)
else:
batchWorker = solo_turnier.batch.BatchWorker(cli)
batchWorker.run()
combinedData = batchWorker.run()
consoleOutputtter = solo_turnier.output.ConsoleOutputter()
consoleOutputtter.output(combinedData)
if __name__ == '__main__':
main()

View File

@ -13,3 +13,4 @@ from . import worker
from . import output
from . import batch
from . import flask

View File

@ -14,7 +14,7 @@ class BatchWorker:
self.l = logging.getLogger('solo_turnier.batch')
self.config = config
def run(self):
def run(self, removeFilteredParicipants=True):
self.l.debug(self.config.__dict__)
locator = solo_turnier.html_locator.HtmlLocator()
@ -30,7 +30,6 @@ class BatchWorker:
combinedData = worker.combineData(importedData)
if not self.config.showAllParticipants():
worker.filterOutFinalists(combinedData)
worker.filterOutFinalists(combinedData, removeFilteredParicipants)
consoleOutputtter = solo_turnier.output.ConsoleOutputter()
consoleOutputtter.output(combinedData)
return combinedData

View File

@ -6,7 +6,8 @@ import debugpy
class Cli:
def __init__(self, l: logging.Logger):
parser = argparse.ArgumentParser()
parser.add_argument('--gui', help='Show the GUI', action='store_true')
# parser.add_argument('--gui', help='Show the GUI', action='store_true')
parser.add_argument('--no-flask', action='store_false', dest='flask', help='Disable the internal flask web server')
parser.add_argument('html', help='The path from where to look for HTML export files', nargs=1, default=['.'])
parser.add_argument('-o', '--output', help='Set the output path of the script', nargs=1, default=[None])
@ -31,8 +32,12 @@ class Cli:
l.setLevel(logLevel)
def showGUI(self):
return self.__args.gui
# return self.__args.gui
return False
def startFlaskServer(self):
return self.__args.flask
def importHtmlPath(self):
return self.__args.html[0]

13
src/solo_turnier/flask.py Normal file
View File

@ -0,0 +1,13 @@
import flask
import solo_turnier
def startFlask(batchWorker: solo_turnier.batch.BatchWorker, debug: bool = False):
app = flask.Flask(__name__)
@app.route('/')
def index():
combinedData = batchWorker.run(False)
return flask.render_template('index.html', data=combinedData)
app.run(host='0.0.0.0', port=8082, debug=debug)

View File

@ -0,0 +1,47 @@
.tab-summary {
width: 100%;
border-collapse: collapse;
}
.tab-summary tr:nth-of-type(even) {
background-color: cyan;
}
.tab-summary td {
text-align: center;
}
.tab-summary td .competition-place {
font-size: smaller;
font-weight: 300;
font-style: italic;
}
.tab-summary .no-finalist {
color: gray;
}
@media print {
@page {
size: landscape;
}
@page portrait {
size: portrait;
}
/* body {
size: landscape;
page-orientation: rotate-right;
} */
.section,
.section table tr,
.section table td
{
page-break-inside: avoid;
}
.tab-summary .no-finalist {
color: gray;
}
}

View File

@ -0,0 +1,56 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Solo Turnier Auswertung</title>
{# <meta name="description" content="Webpage for xxxx"> #}
<!-- http://meyerweb.com/eric/tools/css/reset/ -->
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
{# <h1>Finalauswertung Solo-Turniere</h1> #}
{% for group in data.groups %}
{% block groupBlk scoped %}
<div class="section">
<h1>Auswertung Gruppe {{ group.name }}</h1>
<table class="tab-summary">
<tr>
<th>Teilnehmer</th>
{% for dance in data.results[group].dances %}
<th>{{ dance }}</th>
{% endfor %}
</tr>
{% set activeGroup = data.results[group].results %}
{% for participant, results in activeGroup|dictsort() %}
{% block participantGrp scoped %}
{% set rowCls = "" %}
{% if not participant.finalist %}
{% set rowCls = "no-finalist" %}
{% endif %}
<tr class="{{ rowCls }}">
<td>{{ participant.name }} ({{ participant.id }})</td>
{% for dance in data.results[group].dances %}
{% block danceResult scoped %}
{% set res = activeGroup[participant][loop.index0] %}
<td>
{% if res is not none %}
{% if not participant.finalist %}
Kein/e Finalist/in
{% endif %}
{{ res.getNativePlace() }} ({{ res.nativeClass }}) <br />
<span class="competition-place">
{{ res.getPlace() }} in {{ res.competitionClass }}
</span>
{% endif %}
</td>
{% endblock %}
{% endfor %}
</tr>
{% endblock %}
{% endfor %}
</table>
</div>
{% endblock %}
{% endfor %}
</body>
</html>

View File

@ -26,6 +26,7 @@ class HtmlPreviewParticipant:
self.id = id
groupParser = group.GroupParser()
self.group = groupParser.parseClass(group_)
self.finalist = None
def __eq__(self, o):
if type(o) != HtmlPreviewParticipant:
@ -39,6 +40,9 @@ class HtmlPreviewParticipant:
def __hash__(self):
return hash((self.id, self.name, self.group))
def __gt__(self, other):
return self.id >= other.id
class HtmlParticipant:
def __init__(self, name, id):
self.name = name
@ -201,6 +205,18 @@ class SingleParticipantResult:
return f'SR[{self.place} in {self.dance} {self.competitionClass} ({self.placeNative}-{self.placeNativeTo}, {self.nativeClass}){asFinalist}]'
return f'SR[{self.place}-{self.placeTo} in {self.dance} {self.competitionClass} ({self.placeNative}-{self.placeNativeTo}, {self.nativeClass}){asFinalist}]'
def getPlace(self):
if self.placeTo is None:
return f'{self.place}.'
else:
return f'{self.place}.-{self.placeTo}.'
def getNativePlace(self):
if self.placeNativeTo is None:
return f'{self.placeNative}.'
else:
return f'{self.placeNative}.-{self.placeNativeTo}.'
class TotalGroupResult:
def __init__(self, dances: list[str], results: dict[HtmlPreviewParticipant, list[SingleParticipantResult]]):

View File

@ -651,7 +651,7 @@ class Worker:
# self.l.log(5, '(Partially) fixed places: %s', (data))
def filterOutFinalists(self, data: types.State4):
def filterOutFinalists(self, data: types.State4, filterOut: bool):
for group in data.results:
self.l.debug('Cleaning up group %s', group.name)
participants = data.results[group].results.keys()
@ -668,10 +668,13 @@ class Worker:
finalist = True in mapped
self.l.log(5,'Check for finalist (in dances %s): %s', mapped, finalist)
if not finalist:
if finalist:
participant.finalist = True
else:
participant.finalist = False
self.l.warning('Dropping %s from the output as no finalist', participant)
droppedParticipants.append(participant)
for droppedParticipant in droppedParticipants:
data.results[group].results.pop(droppedParticipant)
pass
if filterOut:
for droppedParticipant in droppedParticipants:
data.results[group].results.pop(droppedParticipant)