Create basic environment for flask-based output
This commit is contained in:
parent
488bfae25e
commit
a8be846f36
@ -1,16 +1,20 @@
|
|||||||
attrs==22.1.0
|
attrs==22.1.0
|
||||||
beautifulsoup4==4.11.1
|
beautifulsoup4==4.11.1
|
||||||
|
blinker==1.6.2
|
||||||
certifi==2023.7.22
|
certifi==2023.7.22
|
||||||
charset-normalizer==3.2.0
|
charset-normalizer==3.2.0
|
||||||
|
click==8.1.7
|
||||||
colorama==0.4.6
|
colorama==0.4.6
|
||||||
coloredlogs==15.0.1
|
coloredlogs==15.0.1
|
||||||
coverage==6.5.0
|
coverage==6.5.0
|
||||||
debugpy==1.6.7
|
debugpy==1.6.7
|
||||||
distlib==0.3.7
|
distlib==0.3.7
|
||||||
exceptiongroup==1.0.1
|
exceptiongroup==1.0.1
|
||||||
|
Flask==2.3.3
|
||||||
humanfriendly==10.0
|
humanfriendly==10.0
|
||||||
idna==3.4
|
idna==3.4
|
||||||
iniconfig==1.1.1
|
iniconfig==1.1.1
|
||||||
|
itsdangerous==2.1.2
|
||||||
Jinja2==3.1.2
|
Jinja2==3.1.2
|
||||||
MarkupSafe==2.1.3
|
MarkupSafe==2.1.3
|
||||||
packaging==21.3
|
packaging==21.3
|
||||||
@ -26,4 +30,5 @@ soupsieve==2.3.2.post1
|
|||||||
tabulate==0.9.0
|
tabulate==0.9.0
|
||||||
tomli==2.0.1
|
tomli==2.0.1
|
||||||
urllib3==2.0.5
|
urllib3==2.0.5
|
||||||
|
Werkzeug==2.3.7
|
||||||
yarg==0.1.9
|
yarg==0.1.9
|
||||||
|
10
src/main.py
10
src/main.py
@ -15,11 +15,17 @@ def main():
|
|||||||
l = __initLogging()
|
l = __initLogging()
|
||||||
cli = solo_turnier.cli.Cli(l)
|
cli = solo_turnier.cli.Cli(l)
|
||||||
|
|
||||||
|
batchWorker = solo_turnier.batch.BatchWorker(cli)
|
||||||
|
|
||||||
if cli.showGUI():
|
if cli.showGUI():
|
||||||
raise Exception('Not yet implemented')
|
raise Exception('Not yet implemented')
|
||||||
|
elif cli.startFlaskServer():
|
||||||
|
solo_turnier.flask.startFlask(batchWorker, cli.getLogLevel() > 0)
|
||||||
else:
|
else:
|
||||||
batchWorker = solo_turnier.batch.BatchWorker(cli)
|
combinedData = batchWorker.run()
|
||||||
batchWorker.run()
|
|
||||||
|
consoleOutputtter = solo_turnier.output.ConsoleOutputter()
|
||||||
|
consoleOutputtter.output(combinedData)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
@ -13,3 +13,4 @@ from . import worker
|
|||||||
from . import output
|
from . import output
|
||||||
|
|
||||||
from . import batch
|
from . import batch
|
||||||
|
from . import flask
|
||||||
|
@ -14,7 +14,7 @@ class BatchWorker:
|
|||||||
self.l = logging.getLogger('solo_turnier.batch')
|
self.l = logging.getLogger('solo_turnier.batch')
|
||||||
self.config = config
|
self.config = config
|
||||||
|
|
||||||
def run(self):
|
def run(self, removeFilteredParicipants=True):
|
||||||
self.l.debug(self.config.__dict__)
|
self.l.debug(self.config.__dict__)
|
||||||
|
|
||||||
locator = solo_turnier.html_locator.HtmlLocator()
|
locator = solo_turnier.html_locator.HtmlLocator()
|
||||||
@ -30,7 +30,6 @@ class BatchWorker:
|
|||||||
combinedData = worker.combineData(importedData)
|
combinedData = worker.combineData(importedData)
|
||||||
|
|
||||||
if not self.config.showAllParticipants():
|
if not self.config.showAllParticipants():
|
||||||
worker.filterOutFinalists(combinedData)
|
worker.filterOutFinalists(combinedData, removeFilteredParicipants)
|
||||||
|
|
||||||
consoleOutputtter = solo_turnier.output.ConsoleOutputter()
|
return combinedData
|
||||||
consoleOutputtter.output(combinedData)
|
|
||||||
|
@ -6,7 +6,8 @@ import debugpy
|
|||||||
class Cli:
|
class Cli:
|
||||||
def __init__(self, l: logging.Logger):
|
def __init__(self, l: logging.Logger):
|
||||||
parser = argparse.ArgumentParser()
|
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('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])
|
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)
|
l.setLevel(logLevel)
|
||||||
|
|
||||||
def showGUI(self):
|
def showGUI(self):
|
||||||
return self.__args.gui
|
# return self.__args.gui
|
||||||
|
return False
|
||||||
|
|
||||||
|
def startFlaskServer(self):
|
||||||
|
return self.__args.flask
|
||||||
|
|
||||||
def importHtmlPath(self):
|
def importHtmlPath(self):
|
||||||
return self.__args.html[0]
|
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
|
self.id = id
|
||||||
groupParser = group.GroupParser()
|
groupParser = group.GroupParser()
|
||||||
self.group = groupParser.parseClass(group_)
|
self.group = groupParser.parseClass(group_)
|
||||||
|
self.finalist = None
|
||||||
|
|
||||||
def __eq__(self, o):
|
def __eq__(self, o):
|
||||||
if type(o) != HtmlPreviewParticipant:
|
if type(o) != HtmlPreviewParticipant:
|
||||||
@ -39,6 +40,9 @@ class HtmlPreviewParticipant:
|
|||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return hash((self.id, self.name, self.group))
|
return hash((self.id, self.name, self.group))
|
||||||
|
|
||||||
|
def __gt__(self, other):
|
||||||
|
return self.id >= other.id
|
||||||
|
|
||||||
class HtmlParticipant:
|
class HtmlParticipant:
|
||||||
def __init__(self, name, id):
|
def __init__(self, name, id):
|
||||||
self.name = name
|
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}]'
|
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:
|
class TotalGroupResult:
|
||||||
def __init__(self, dances: list[str], results: dict[HtmlPreviewParticipant, list[SingleParticipantResult]]):
|
def __init__(self, dances: list[str], results: dict[HtmlPreviewParticipant, list[SingleParticipantResult]]):
|
||||||
self.dances = dances
|
self.dances = dances
|
||||||
|
@ -651,7 +651,7 @@ class Worker:
|
|||||||
|
|
||||||
# self.l.log(5, '(Partially) fixed places: %s', (data))
|
# 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:
|
for group in data.results:
|
||||||
self.l.debug('Cleaning up group %s', group.name)
|
self.l.debug('Cleaning up group %s', group.name)
|
||||||
participants = data.results[group].results.keys()
|
participants = data.results[group].results.keys()
|
||||||
@ -668,10 +668,13 @@ class Worker:
|
|||||||
finalist = True in mapped
|
finalist = True in mapped
|
||||||
self.l.log(5,'Check for finalist (in dances %s): %s', mapped, finalist)
|
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)
|
self.l.warning('Dropping %s from the output as no finalist', participant)
|
||||||
droppedParticipants.append(participant)
|
droppedParticipants.append(participant)
|
||||||
|
|
||||||
|
if filterOut:
|
||||||
for droppedParticipant in droppedParticipants:
|
for droppedParticipant in droppedParticipants:
|
||||||
data.results[group].results.pop(droppedParticipant)
|
data.results[group].results.pop(droppedParticipant)
|
||||||
pass
|
|
||||||
|
Loading…
Reference in New Issue
Block a user