diff --git a/src/solo_turnier/__init__.py b/src/solo_turnier/__init__.py index be1bde2..610279e 100644 --- a/src/solo_turnier/__init__.py +++ b/src/solo_turnier/__init__.py @@ -3,6 +3,9 @@ from . import cli from . import reader from . import participant +from . import html_locator +from . import html_parser from . import worker +from . import output from . import batch diff --git a/src/solo_turnier/batch.py b/src/solo_turnier/batch.py index 8b62f9c..460544d 100644 --- a/src/solo_turnier/batch.py +++ b/src/solo_turnier/batch.py @@ -174,6 +174,51 @@ class BatchWorker: return [__extractRow(r) for r in allResults['data'][0:2]] def run(self): + self.l.debug(self.config.__dict__) + + locator = solo_turnier.html_locator.HtmlLocator() + self.l.info('Checking for feasible HTML export files in "%s"', self.config.importHtmlPath()) + htmlCandidates = locator.findCandidates(self.config.importHtmlPath()) + self.l.debug('Found HTML file candidates: %s', htmlCandidates) + + htmlParser = solo_turnier.html_parser.HtmlParser() + htmlImports = [] + self.l.info('Importing the candidates') + for candidate in htmlCandidates: + self.l.debug('Processing file %s', candidate) + with open(candidate, 'r') as fp: + fileContent = fp.read() + htmlImports.append(htmlParser.parseString(fileContent)) + self.l.info('All HTML files have been parsed') + + csvReader = solo_turnier.reader.AllResultReader(self.config.importCSVPath()) + self.l.info('Importing the total result CSV file %s', self.config.importCSVPath()) + csvData = csvReader.readFile() + self.l.info('CSV file has been read') + + self.l.info('Processing the imported data') + + csvExtractor = solo_turnier.worker.CSVExtractor() + self.l.debug('Importing CSV data into internal structures') + csvRows = csvExtractor.mapCSVImport(csvData) + + worker = solo_turnier.worker.DataWorker() + self.l.debug('Combining results from CSV for individual users') + data = worker.combineRowsByPerson(csvRows) + self.l.debug('Fix the groups for combined competitions') + unambiguous, fixedGroups = worker.consolidateGroups(data) + if fixedGroups: + self.l.info('It was required to fix some group issues.') + if not unambiguous: + self.warning('There were couples whose group could not be extracted unambiguously.') + self.l.debug('Merging HTML and CSV data') + worker.mergeHtmlData(data, htmlImports) + self.l.info('Data is prepared') + + consoleOutputtter = solo_turnier.output.ConsoleOutputter() + consoleOutputtter.output(data) + + def run1(self): allResults, finals = self.__extractDataFromFiles() persons = self.__extractPersons(allResults) diff --git a/src/solo_turnier/cli.py b/src/solo_turnier/cli.py index 4aa7b87..b6fcc11 100644 --- a/src/solo_turnier/cli.py +++ b/src/solo_turnier/cli.py @@ -6,8 +6,9 @@ class Cli: parser = argparse.ArgumentParser() parser.add_argument('--gui', help='Show the GUI', action='store_true') - parser.add_argument('-i', '--import-from', help='Set the path to load the TopTurnier exports from', nargs=1, default=['.']) - parser.add_argument('-o', '--output', help='Set the output path of the script', nargs=1) + parser.add_argument('-i', '--import-from', help='Set the path to load the TopTurnier exports from', nargs=1, default=['allresults.csv']) + parser.add_argument('-p', '--html-path', 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('-v', '--verbose', help='Increase verbosity', action='count', default=0) self.__args = parser.parse_args() @@ -24,7 +25,10 @@ class Cli: def showGUI(self): return self.__args.gui - def importPath(self): + def importHtmlPath(self): + return self.__args.html_path[0] + + def importCSVPath(self): return self.__args.import_from[0] def output(self): diff --git a/src/solo_turnier/output.py b/src/solo_turnier/output.py new file mode 100644 index 0000000..a7d370b --- /dev/null +++ b/src/solo_turnier/output.py @@ -0,0 +1,69 @@ + +import logging +from tabulate import tabulate + +import solo_turnier + +sections = ('Kin.', 'Jun.', 'Jug.', 'Sonst') +sectionMap = { + 'Kin.': 'Kinder', + 'Jun.': 'Junioren', + 'Jug.': 'Jugend', + 'Sonst': 'Undefiniert' +} + +class AbstractOutputter: + def __init__(self): + self.worker = solo_turnier.worker.DataWorker() + self.groups = [] + self.dances = [] + self.showIds = False + + def getRowData(self, person: solo_turnier.worker.ResultPerson, results): + mappedResults = self.worker.mapPersonResultsToDanceList(results, self.dances) + if self.showIds: + name = f'{person.name} ({person.id})' + else: + name = person.name + + ret = [name] + for result in mappedResults: + if result is None: + ret.append('') + elif result.finalist == False: + ret.append('x') + elif result.place == result.placeTo: + ret.append(f'{result.place}. ({result.class_})') + else: + ret.append(f'{result.place}.-{result.placeTo}. ({result.class_})') + return ret + + def getTabularData(self, data, section): + sortedPersons, self.showIds = self.worker.sortPersonsInGroup(self.groups[section]) + + tableData = [] + for person in sortedPersons: + tableData.append(self.getRowData(person, data[person])) + + return tableData + +class ConsoleOutputter(AbstractOutputter): + def __init__(self): + super().__init__() + self.l = logging.getLogger('solo_turnier.output.console') + + def __outputSection(self, data, section): + tableData = self.getTabularData(data, section) + tableData = [['Name'] + self.dances] + tableData + + print(f"Einzeltanzwettbewerb der {sectionMap[section]}") + print(tabulate(tableData, headers='firstrow', tablefmt='fancy_grid')) + print() + + def output(self, data): + self.groups = self.worker.collectPersonsInGroups(data) + self.dances = self.worker.getAllDancesInCompetitions(data) + + for section in sections: + if len(self.groups[section]) > 0: + self.__outputSection(data, section)