Create basic environment for flask-based output
This commit is contained in:
parent
488bfae25e
commit
a8be846f36
@ -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
|
||||
|
10
src/main.py
10
src/main.py
@ -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()
|
||||
|
@ -13,3 +13,4 @@ from . import worker
|
||||
from . import output
|
||||
|
||||
from . import batch
|
||||
from . import flask
|
||||
|
@ -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
|
||||
|
@ -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,7 +32,11 @@ 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
13
src/solo_turnier/flask.py
Normal 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)
|
47
src/solo_turnier/static/style.css
Normal file
47
src/solo_turnier/static/style.css
Normal 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;
|
||||
}
|
||||
}
|
56
src/solo_turnier/templates/index.html
Normal file
56
src/solo_turnier/templates/index.html
Normal 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>
|
@ -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
|
||||
@ -202,6 +206,18 @@ class SingleParticipantResult:
|
||||
|
||||
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]]):
|
||||
self.dances = dances
|
||||
|
@ -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)
|
||||
|
||||
if filterOut:
|
||||
for droppedParticipant in droppedParticipants:
|
||||
data.results[group].results.pop(droppedParticipant)
|
||||
pass
|
||||
|
Loading…
Reference in New Issue
Block a user