15 Commits

8 changed files with 72 additions and 21 deletions

View File

@@ -1,6 +1,6 @@
[Application]
name=Solo Auswertung
version=0.9.2
version=0.9.7
# How to launch the app - this calls the 'main' function from the 'myapp' package:
entry_point=main:main
# icon=myapp.ico

View File

@@ -23,7 +23,9 @@ def main():
solo_turnier.flask.startFlask(
batchWorker,
debug=cli.getLogLevel() > 0,
port=cli.getPort()
port=cli.getPort(),
showOnlyFinalists=not cli.showAllParticipants(),
externalDebugger=cli.externalDebugger
)
else:
combinedData = batchWorker.run(

View File

@@ -22,6 +22,8 @@ class Cli:
debugpy.listen(5678)
debugpy.wait_for_client()
self.externalDebugger = self.__args.debug
map = {
0: logging.ERROR,
1: logging.WARN,

View File

@@ -44,6 +44,11 @@ class CompetitionClassParser:
self.namesPreview = [
'Sichtung'
]
self.mapShortNames = {
'N': self.NEWC,
'B': self.BEG,
'A': self.ADV,
}
def parseClass(self, cls: str, allowPreview: bool = False) -> Class_t:
if allowPreview and cls in self.namesPreview:
@@ -57,6 +62,9 @@ class CompetitionClassParser:
else:
return self.mapNames[cls]
def parseAbbreviatedClass(self, cls: str) -> Class_t:
return self.mapShortNames[cls]
def isPureClass(self, cls: str, allowPreview: bool = False) -> bool:
parsedClass = self.parseClass(cls, allowPreview)
return isinstance(parsedClass, CompetitionClass)

View File

@@ -1,19 +1,24 @@
import flask
import solo_turnier
import logging
_l = logging.getLogger(__name__)
def startFlask(
batchWorker: solo_turnier.batch.BatchWorker,
debug: bool = False,
port: int = 8082,
showOnlyFinalists: bool = True
showOnlyFinalists: bool = True,
externalDebugger: bool = False,
):
app = flask.Flask(__name__)
@app.route('/')
def index():
combinedData = batchWorker.run(False)
_l.debug('Show only finalists %s', showOnlyFinalists)
return flask.render_template('index.html', data=combinedData)
return flask.render_template('index.html', data=combinedData, onlyFinalists=showOnlyFinalists)
@app.get('/custom.css')
def css():
@@ -23,4 +28,5 @@ def startFlask(
)
return flask.Response(ret, mimetype='text/css')
app.run(host='0.0.0.0', port=port, debug=debug)
useReloader = debug and not externalDebugger
app.run(host='0.0.0.0', port=port, debug=debug, use_reloader=useReloader)

View File

@@ -8,6 +8,10 @@ from .types import HtmlPreviewImport as HtmlImport, HtmlResultImport
from .group import GroupParser
from .competition_class import CompetitionClassParser
class IncompleteRoundException(Exception):
def __init__(self, *args):
super(IncompleteRoundException, self).__init__(*args)
class HtmlParser:
def __init__(self, text: str, fileName: str = None):
@@ -53,12 +57,17 @@ class HtmlParser:
if len(tds) != 2:
return
if tds[1].contents[0].startswith('Alle Starter weiter genommen.'):
self.l.info('No excluded starters found.')
return
regex = re.compile('(.*) \\(([0-9]+)\\)')
place = tds[0].contents[0]
match = regex.fullmatch(tds[1].contents[0])
if match is None:
self.l.error('Could not match %s to regex search pattern', str(tds))
raise Exception(f'Could not match {tds} to regex search pattern')
name = match.group(1)
number = match.group(2)
@@ -73,7 +82,8 @@ class HtmlParser:
def __parseFirstTable(table):
roundName = table.tr.td.contents[0]
if roundName != 'Endrunde':
raise Exception('Could not parse HTML file')
self.l.warning('Found table with round name %s.', roundName)
raise IncompleteRoundException('Could not parse HTML file')
__parseRows(table.find_all('tr')[2:], True)
@@ -82,10 +92,14 @@ class HtmlParser:
__parseRows(table.find_all('tr'), False)
tables = self.soup.find('div', class_='extract').find_all('table')
if len(tables) > 0:
__parseFirstTable(tables[0])
try:
if len(tables) > 0:
__parseFirstTable(tables[0])
__parseRemainingTables(tables[1:])
__parseRemainingTables(tables[1:])
except IncompleteRoundException:
pass
# title = self.soup.find('div', class_='eventhead').table.tr.td.contents[0]

View File

@@ -28,6 +28,7 @@
{% if not participant.finalist %}
{% set rowCls = "no-finalist" %}
{% endif %}
{% if participant.finalist or not onlyFinalists %}
<tr class="{{ rowCls }}">
<td>{{ participant.name }} ({{ participant.id }})</td>
{% for dance in data.results[group].dances %}
@@ -47,6 +48,7 @@
{% endblock %}
{% endfor %}
</tr>
{% endif %}
{% endblock %}
{% endfor %}
</table>

View File

@@ -159,7 +159,10 @@ class PreviewWorker:
for file in parsers:
parser = parsers[file]
self.__extractPersonsFromSinglePreview(parser)
try:
self.__extractPersonsFromSinglePreview(parser)
except:
self.l.error('Failed to parse preview round in file %s. Skipping this file\'s content.', parser.fileName)
return types.HtmlPreviewImport(self.participants, self.previewResults)
@@ -177,10 +180,14 @@ class ResultExtractor:
for filePair in files:
with open(filePair[0], 'r') as fp:
text = fp.read()
with open(filePair[1], 'r') as fp:
textTab = fp.read()
parser = html_parser.HtmlParser(text, filePair[0])
parserTab = html_parser.HtmlParser(textTab, filePair[1])
if filePair[1] is None:
parserTab = None
else:
with open(filePair[1], 'r') as fp:
textTab = fp.read()
parserTab = html_parser.HtmlParser(textTab, filePair[1])
try:
data = parser.guessDataFromHtmlTitle()
@@ -247,8 +254,11 @@ class ResultExtractor:
self.l.debug('Extracting data from file %s', fileName)
self._analyzeSingleParser(parsers[fileNameTuple][0], ret)
self.l.debug('Fetching individual result of combined competitions in %s', fileName)
self._analyzeIndividualResults(parsers[fileNameTuple][1], ret)
if parsers[fileNameTuple][1] is None:
self.l.info('Skipping extraction of individual result as class is not yet finished.')
else:
self.l.debug('Fetching individual result of combined competitions in %s', fileName)
self._analyzeIndividualResults(parsers[fileNameTuple][1], ret)
return ret
@@ -460,11 +470,11 @@ class Worker:
self.l.log(5, 'Obtained result %s', resultsOfParticipant)
results[participant] = resultsOfParticipant
self.l.log(5, 'Result before native fixing: %s', (results))
self.l.log(5, 'Result before native fixing: %s', pformat(results))
# self._fixNativePlaces(dances, results)
self._fixNativePlacesFromTable(dances, results, importedData.htmlResults)
# self.l.log(5, 'Result after native fixing: %s', pformat(results))
self.l.log(5,'Data %s', results)
self._fixNativeDataFromTable(dances, results, importedData.htmlResults)
self.l.log(5, 'Result after native fixing: %s', pformat(results))
# self.l.log(5,'Fixed data %s', results)
totalResult[group] = types.TotalGroupResult(dances, results)
@@ -540,7 +550,9 @@ class Worker:
raise Exception('Multiple results found with same key')
rawResult = rawResult[0]
nativeClass = previewResults.results[participant][dance]
nativeClass = key[2]
# nativeClass = previewResults.results[participant][dance]
# nativeClass = key[2]
# self.l.log(5, 'Result %s => %s', key, rawResult)
ret = types.SingleParticipantResult(
@@ -555,13 +567,15 @@ class Worker:
return results
def _fixNativePlacesFromTable(
def _fixNativeDataFromTable(
self,
dances: list[str],
data: dict[types.HtmlPreviewParticipant, list[types.SingleParticipantResult]],
importedData: types.HtmlCompetitionTotalResults
):
rePlace = re.compile('([0-9]+)(?:-([0-9]+))?')
classParser = competition_class.CompetitionClassParser()
for participant in data.keys():
self.l.log(5, 'fixing participant %s', participant)
results = data[participant]
@@ -588,6 +602,9 @@ class Worker:
result.placeNative = matcher.group(1)
result.placeNativeTo = matcher.group(2)
if raw[1] is not None:
result.nativeClass = classParser.parseAbbreviatedClass(raw[1])
pass
def _fixNativePlaces(