Compare commits
No commits in common. "95f10000bb991ec2bb600d13f9c2802e82e6ef27" and "7fab832321b2e897c9cf51d116eef11c297dea93" have entirely different histories.
95f10000bb
...
7fab832321
@ -1,2 +0,0 @@
|
|||||||
from cli import main
|
|
||||||
main()
|
|
@ -16,7 +16,7 @@ def create_result_file(event, file_path, o_classes=[]):
|
|||||||
root.set('iofVersion', '3.0')
|
root.set('iofVersion', '3.0')
|
||||||
root.set('createTime', datetime.datetime.now().isoformat(timespec='seconds'))
|
root.set('createTime', datetime.datetime.now().isoformat(timespec='seconds'))
|
||||||
root.set('creator', 'oTime')
|
root.set('creator', 'oTime')
|
||||||
#root.set('status', 'Complete')
|
root.set('status', 'Complete')
|
||||||
tree = ET.ElementTree(root)
|
tree = ET.ElementTree(root)
|
||||||
xml_event = ET.SubElement(root, 'Event')
|
xml_event = ET.SubElement(root, 'Event')
|
||||||
xml_child(xml_event, 'Id', event.id)
|
xml_child(xml_event, 'Id', event.id)
|
||||||
|
@ -2,19 +2,13 @@ import argparse
|
|||||||
import file_io
|
import file_io
|
||||||
import iof_xml
|
import iof_xml
|
||||||
import serial
|
import serial
|
||||||
import subprocess
|
|
||||||
import os
|
|
||||||
import otime
|
import otime
|
||||||
import iof_xml
|
|
||||||
import pdf
|
|
||||||
from pdf import format_m_s
|
|
||||||
from rich import print
|
|
||||||
|
|
||||||
# Main entrypoint for now. Cli with two options; init will make the files needed and run will start the program from the specified directory
|
# Main entrypoint for now. Cli with two options; init will make the files needed and run will start the program from the specified directory
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(description='Otime very alpha version 😁')
|
parser = argparse.ArgumentParser(description='Otime very alpha version 😁')
|
||||||
subparsers = parser.add_subparsers(dest='command')
|
subparsers = parser.add_subparsers(dest='command')
|
||||||
parser_init = subparsers.add_parser('init', help='Create project files')
|
parser_init = subparsers.add_parser('init', help='INIT')
|
||||||
parser_init.add_argument('--entries', required=True, dest='entries_file', action='store', default='./',
|
parser_init.add_argument('--entries', required=True, dest='entries_file', action='store', default='./',
|
||||||
help='The xml file with entries')
|
help='The xml file with entries')
|
||||||
parser_init.add_argument('--courses', required=True, dest='courses_file', action='store', default='./',
|
parser_init.add_argument('--courses', required=True, dest='courses_file', action='store', default='./',
|
||||||
@ -25,18 +19,14 @@ def main():
|
|||||||
parser_init = subparsers.add_parser('run', help='run otime')
|
parser_init = subparsers.add_parser('run', help='run otime')
|
||||||
parser_init.add_argument('--dir', required=False, dest='dir', action='store', default='./', help='specify a directory')
|
parser_init.add_argument('--dir', required=False, dest='dir', action='store', default='./', help='specify a directory')
|
||||||
parser_init.add_argument('--port', required=False, dest='port', action='store', help='specify a serial port')
|
parser_init.add_argument('--port', required=False, dest='port', action='store', help='specify a serial port')
|
||||||
parser_init.add_argument('--xml', required=False, dest='xml_path', action='store', default=None, help='Where the xml result file should be saved')
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if not args.xml_path:
|
|
||||||
args.xml_path = args.dir + '/output'
|
|
||||||
|
|
||||||
match args.command:
|
match args.command:
|
||||||
case 'init':
|
case 'init':
|
||||||
init_dir(args.dir, args.entries_file, args.courses_file)
|
init_dir(args.dir, args.entries_file, args.courses_file)
|
||||||
case 'run':
|
case 'run':
|
||||||
run(args.port, args.dir, args.xml_path)
|
run(args.port, args.dir)
|
||||||
|
|
||||||
def init_dir(project_dir, entries_xml_file, courses_xml_file):
|
def init_dir(project_dir, entries_xml_file, courses_xml_file):
|
||||||
# Lager mappe med en config fil, en csv fil med løpere og en fil med mtr data
|
# Lager mappe med en config fil, en csv fil med løpere og en fil med mtr data
|
||||||
@ -47,23 +37,15 @@ def init_dir(project_dir, entries_xml_file, courses_xml_file):
|
|||||||
event = iof_xml.event_from_xml_entries(entries_xml_file)
|
event = iof_xml.event_from_xml_entries(entries_xml_file)
|
||||||
event.courses = iof_xml.courses_from_xml(courses_xml_file)
|
event.courses = iof_xml.courses_from_xml(courses_xml_file)
|
||||||
|
|
||||||
print(f'Read {len(event.runners)} runners, {len(event.card_dumps)} ecards, {len(event.courses)} courses and {len(event.o_classes)} classes')
|
|
||||||
print('Remember to manually link the courses and classes in the config file')
|
|
||||||
|
|
||||||
file_io.write_runners_csv(event, csv_db_path)
|
file_io.write_runners_csv(event, csv_db_path)
|
||||||
file_io.write_config(event, config_path)
|
file_io.write_config(event, config_path)
|
||||||
file_io.write_card_dumps(event, mtr_path)
|
file_io.write_card_dumps(event, mtr_path)
|
||||||
os.makedirs(project_dir+'/output')
|
|
||||||
|
|
||||||
subprocess.run(['git', 'init', project_dir])
|
def run(port='/dev/ttyUSB0', dir='./'):
|
||||||
subprocess.run(['git', 'add', './*'], cwd=project_dir)
|
|
||||||
subprocess.run(['git', 'commit', '-m', f'Project initiated by otime'], cwd=project_dir)
|
|
||||||
|
|
||||||
def run(port='/dev/ttyUSB0', project_dir='./', xml_path='./output/'):
|
|
||||||
mtr = serial.Serial(port=port, baudrate=9600, timeout=40)
|
mtr = serial.Serial(port=port, baudrate=9600, timeout=40)
|
||||||
config_path = project_dir + '/config.yaml'
|
config_path = dir + '/config.yaml'
|
||||||
mtr_path = project_dir + '/mtr.yaml'
|
mtr_path = dir + '/mtr.yaml'
|
||||||
csv_path = project_dir + '/runners.csv'
|
csv_path = dir + '/runners.csv'
|
||||||
while True:
|
while True:
|
||||||
if mtr.in_waiting > 0:
|
if mtr.in_waiting > 0:
|
||||||
mtr.read_until(expected=b'\xFF\xFF\xFF\xFF')
|
mtr.read_until(expected=b'\xFF\xFF\xFF\xFF')
|
||||||
@ -76,30 +58,16 @@ def run(port='/dev/ttyUSB0', project_dir='./', xml_path='./output/'):
|
|||||||
event.card_dumps.append(card_dump)
|
event.card_dumps.append(card_dump)
|
||||||
file_io.write_card_dumps(event, mtr_path)
|
file_io.write_card_dumps(event, mtr_path)
|
||||||
print(runner_info(event, card_dump))
|
print(runner_info(event, card_dump))
|
||||||
subprocess.run(['git', 'add', './*'], cwd=project_dir, stdout=subprocess.DEVNULL)
|
|
||||||
subprocess.run(['git', 'commit', '-m', f'Added {card_dump.card}'], cwd=project_dir, stdout=subprocess.DEVNULL)
|
|
||||||
|
|
||||||
iof_xml.create_result_file(event, xml_path + '/results.xml')
|
|
||||||
pdf.create_result_list(event, project_dir + '/output/results.pdf')
|
|
||||||
|
|
||||||
elif size == b'\x37':
|
elif size == b'\x37':
|
||||||
meat = mtr.read(55)
|
meat = mtr.read(55)
|
||||||
inspect(status)
|
inspect(status)
|
||||||
|
|
||||||
def runner_info(event, card_dump):
|
def runner_info(event, card_dump):
|
||||||
runner = next((i for i in event.runners if str(i.card_id) == str(card_dump.card)), None)
|
runner = next((i for i in event.runners if str(i.card_id) == str(card_dump.card)), None)
|
||||||
if runner is None:
|
if runner:
|
||||||
return card_dump
|
return f'{runner.fullname()}, {runner.o_class}, {runner.club}, {event.get_runner_status(runner.id)}, {event.get_runner_time(runner.id)}'
|
||||||
result = event.get_runner_result(runner.id)
|
|
||||||
if result is None:
|
|
||||||
return '🧐 Dette skal ikke skje...'
|
|
||||||
if result.status == 'OK':
|
|
||||||
result_text = f'[green]Place: {result.place}. Time: [bold][yellow]{format_m_s(result.total_time)}[/yellow][/bold][/green]'
|
|
||||||
elif result.status == 'MissingPunch':
|
|
||||||
result_text = f'[red]Missed Control! Time: [bold][yellow]{format_m_s(result.total_time)}[/yellow][/bold][/red]'
|
|
||||||
else:
|
else:
|
||||||
result_text = f'[blue]{result.status}, Time: [bold][yellow]{result.total_time}[/yellow][/bold][/blue]'
|
return card_dump
|
||||||
return result_text + f' [blue]{result.fullname()}[/blue], {result.o_class}, {result.club}, [italic]Card: {result.card_id}[/italic]'
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
@ -94,7 +94,7 @@ class CardDump:
|
|||||||
splits.append(time)
|
splits.append(time)
|
||||||
|
|
||||||
# Extract start time:
|
# Extract start time:
|
||||||
year = 2000 + int.from_bytes(datamsg[8:9], 'little')
|
year = int.from_bytes(datamsg[8:9], 'little')
|
||||||
month = int.from_bytes(datamsg[9:10], 'little')
|
month = int.from_bytes(datamsg[9:10], 'little')
|
||||||
day = int.from_bytes(datamsg[10:11], 'little')
|
day = int.from_bytes(datamsg[10:11], 'little')
|
||||||
hours = int.from_bytes(datamsg[11:12], 'little')
|
hours = int.from_bytes(datamsg[11:12], 'little')
|
||||||
@ -182,7 +182,7 @@ class OClass:
|
|||||||
|
|
||||||
class RunnerResult:
|
class RunnerResult:
|
||||||
def __init__(self, runner_id: int, first: str, last: str, status: str, place: int, total_time: int, splits: list[int], end_time,
|
def __init__(self, runner_id: int, first: str, last: str, status: str, place: int, total_time: int, splits: list[int], end_time,
|
||||||
club=None, club_id=None, country=None, card_id=None, o_class=None, controls=None, fork=0, start_time=datetime.datetime(1973, 1, 1), fee_id=None):
|
club=None, club_id=None, country=None, card_id=None, o_class=None, controls=None, fork=0, start_time=None, fee_id=None):
|
||||||
self.id = runner_id
|
self.id = runner_id
|
||||||
self.first = first
|
self.first = first
|
||||||
self.last = last
|
self.last = last
|
||||||
@ -268,17 +268,13 @@ class Event:
|
|||||||
if not o_class:
|
if not o_class:
|
||||||
return 'Inactive'
|
return 'Inactive'
|
||||||
course = self.get_course(o_class.course)
|
course = self.get_course(o_class.course)
|
||||||
if not self.get_card_dump(runner.card_id):
|
if self.get_card_dump(runner.card_id) == None:
|
||||||
return 'Active'
|
return 'Active'
|
||||||
if contains(course.codes, self.get_card_dump(runner.card_id).controls):
|
if contains(course.codes, self.get_card_dump(runner.card_id).controls):
|
||||||
return 'OK'
|
return 'OK'
|
||||||
else:
|
else:
|
||||||
return 'MissingPunch'
|
return 'MissingPunch'
|
||||||
|
|
||||||
def get_runner_result(self, runner_id):
|
|
||||||
runner = self.get_runner(runner_id)
|
|
||||||
return next((i for i in produce_class_result(self, runner.o_class).runner_results if i.id == runner_id), None)
|
|
||||||
|
|
||||||
def get_runner_time(self, id):
|
def get_runner_time(self, id):
|
||||||
runner = self.get_runner(id)
|
runner = self.get_runner(id)
|
||||||
card_dump = self.get_card_dump(runner.card_id)
|
card_dump = self.get_card_dump(runner.card_id)
|
||||||
@ -335,7 +331,7 @@ class Event:
|
|||||||
def get_result(self, o_classes: list[str] = []) -> list[ClassResult]:
|
def get_result(self, o_classes: list[str] = []) -> list[ClassResult]:
|
||||||
if not o_classes:
|
if not o_classes:
|
||||||
o_classes = [i.name for i in self.o_classes]
|
o_classes = [i.name for i in self.o_classes]
|
||||||
return [produce_class_result(self, i) for i in o_classes]
|
return [produce_class_result(copy.deepcopy(self), i) for i in o_classes]
|
||||||
|
|
||||||
def read_xml_entries(self, xml_file):
|
def read_xml_entries(self, xml_file):
|
||||||
self.add_runners(*runners_from_xml_entries(xml_file))
|
self.add_runners(*runners_from_xml_entries(xml_file))
|
||||||
@ -383,11 +379,11 @@ def produce_class_result(event, o_class_name) -> ClassResult:
|
|||||||
other_runners = [i for i in runners if i not in ok_runners and i not in dsq_runners]
|
other_runners = [i for i in runners if i not in ok_runners and i not in dsq_runners]
|
||||||
|
|
||||||
results = [RunnerResult(i.id, i.first, i.last, event.get_runner_status(i.id), ok_runners.index(i)+1, event.get_runner_time(i.id), event.get_runner_splits(i.id),
|
results = [RunnerResult(i.id, i.first, i.last, event.get_runner_status(i.id), ok_runners.index(i)+1, event.get_runner_time(i.id), event.get_runner_splits(i.id),
|
||||||
event.get_runner_end_clock(i.id), i.club, 0, i.country, i.card_id, i.o_class, event.get_runner_controls(i.id), start_time=event.get_card_dump(i.card_id).s_time) for i in ok_runners]
|
event.get_runner_end_clock(i.id), i.club, i.country, i.card_id, i.o_class, event.get_runner_controls(i.id), start_time=event.get_card_dump(i.card_id).s_time) for i in ok_runners]
|
||||||
results += [RunnerResult(i.id, i.first, i.last, event.get_runner_status(i.id), 0, event.get_runner_time(i.id), event.get_runner_splits(i.id),
|
results += [RunnerResult(i.id, i.first, i.last, event.get_runner_status(i.id), 0, event.get_runner_time(i.id), event.get_runner_splits(i.id),
|
||||||
event.get_runner_end_clock(i.id), i.club, 0, i.country, i.card_id, i.o_class, event.get_runner_controls(i.id), start_time=event.get_card_dump(i.card_id).s_time) for i in dsq_runners]
|
event.get_runner_end_clock(i.id), i.club, i.country, i.card_id, i.o_class, event.get_runner_controls(i.id), start_time=event.get_card_dump(i.card_id).s_time) for i in dsq_runners]
|
||||||
results += [RunnerResult(i.id, i.first, i.last, event.get_runner_status(i.id), 0, event.get_runner_time(i.id), event.get_runner_splits(i.id),
|
results += [RunnerResult(i.id, i.first, i.last, event.get_runner_status(i.id), 0, event.get_runner_time(i.id), event.get_runner_splits(i.id),
|
||||||
event.get_runner_end_clock(i.id), i.club, 0, i.country, i.card_id, i.o_class, event.get_runner_controls(i.id)) for i in other_runners]
|
event.get_runner_end_clock(i.id), i.club, i.country, i.card_id, i.o_class, event.get_runner_controls(i.id)) for i in other_runners]
|
||||||
|
|
||||||
return ClassResult(o_class.name, event.get_course(o_class.course), results)
|
return ClassResult(o_class.name, event.get_course(o_class.course), results)
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ def create_result_list(event, file_path, o_classes=[]):
|
|||||||
|
|
||||||
pdf = FPDF()
|
pdf = FPDF()
|
||||||
pdf.add_page()
|
pdf.add_page()
|
||||||
pdf.add_font("LiberationSans", fname="otime/data/fonts/LiberationSans-Regular.ttf")
|
pdf.add_font("LiberationSans", fname="../../otime/data/fonts/LiberationSans-Regular.ttf")
|
||||||
pdf.set_font("LiberationSans", size=10)
|
pdf.set_font("LiberationSans", size=10)
|
||||||
line_height = pdf.font_size * 1.5
|
line_height = pdf.font_size * 1.5
|
||||||
col_width = pdf.epw / 4 # distribute content evenly
|
col_width = pdf.epw / 4 # distribute content evenly
|
||||||
@ -38,7 +38,7 @@ def create_split_result_list(event, file_path, o_classes=[]):
|
|||||||
|
|
||||||
pdf = FPDF()
|
pdf = FPDF()
|
||||||
pdf.add_page(orientation='L')
|
pdf.add_page(orientation='L')
|
||||||
pdf.add_font("LiberationSans", fname="otime/data/fonts/LiberationSans-Regular.ttf")
|
pdf.add_font("LiberationSans", fname="../../otime/data/fonts/LiberationSans-Regular.ttf")
|
||||||
pdf.set_font("LiberationSans", size=8)
|
pdf.set_font("LiberationSans", size=8)
|
||||||
line_height = pdf.font_size * 1.5
|
line_height = pdf.font_size * 1.5
|
||||||
col_width = pdf.epw / 4 # distribute content evenly
|
col_width = pdf.epw / 4 # distribute content evenly
|
||||||
|
@ -1,3 +1 @@
|
|||||||
fpdf2
|
fpdf2
|
||||||
pyserial
|
|
||||||
rich
|
|
Loading…
Reference in New Issue
Block a user