From ac2bdab1cf65fddf6d5bb0a710fa4ee7693108b0 Mon Sep 17 00:00:00 2001 From: Trygve Date: Wed, 11 May 2022 15:07:33 +0200 Subject: [PATCH] Opprydning og navnendringer --- cli.py | 20 +++--- config.py | 8 +++ dev.py | 2 +- event_mgr.py | 17 +++-- otime.py | 193 +++++++++++++++++++++++++++------------------------ 5 files changed, 133 insertions(+), 107 deletions(-) create mode 100644 config.py diff --git a/cli.py b/cli.py index ee3f48a..3dfff2d 100755 --- a/cli.py +++ b/cli.py @@ -17,11 +17,11 @@ def print_runners(Runners): table.add_column("Status", justify="right", style="blue") for i in Runners: - try: - o_class = i.o_class.name - except: - o_class = '' - table.add_row(i.fullname(), i.club ,str(i.card), o_class, i.status()) + try: + o_class = i.o_class.name + except: + o_class = '' + table.add_row(i.fullname(), i.club ,str(i.card), o_class, i.status()) console = Console() console.print(table) @@ -146,14 +146,14 @@ def main(): args = parser.parse_args() if args.command == 'show_runners': - event = otime.event(0, 'NoName') + event = otime.Event(0, 'NoName') event.import_ttime_cnf(args.ttcnf) event.import_ttime_db(args.ttdb) event.import_mtr_file(args.mtr) event.match_runners_cards() print_runners(event.runners) elif args.command == 'show_runner': - event = otime.event(0, 'NoName') + event = otime.Event(0, 'NoName') event.import_ttime_cnf(args.ttcnf) event.import_ttime_db(args.ttdb) event.import_mtr_file(args.mtr) @@ -167,7 +167,7 @@ def main(): elif args.command == 'show_result': - event = otime.event(0, 'NoName') + event = otime.Event(0, 'NoName') event.import_ttime_cnf(args.ttcnf) event.import_ttime_db(args.ttdb) event.import_mtr_file(args.mtr) @@ -184,12 +184,12 @@ def main(): else: print_class_result(event.runners, o_class) elif args.command == 'show_classes': - event = otime.event(0, 'NoName') + event = otime.Event(0, 'NoName') event.import_ttime_cnf(args.ttcnf) print_o_classes(event.o_classes) elif args.command == 'create_xml': - event = otime.event(0, 'NoName') + event = otime.Event(0, 'NoName') event.import_ttime_cnf(args.ttcnf) event.import_ttime_db(args.ttdb) event.import_mtr_file(args.mtr) diff --git a/config.py b/config.py new file mode 100644 index 0000000..d9c87f7 --- /dev/null +++ b/config.py @@ -0,0 +1,8 @@ +config = { + 'event_name': 'KOK 2-dagers testing', + 'port': '/dev/pts/2', + 'cnf_file': 'k2ds/tt.cnf', + 'db_file': 'k2ds/db.csv', + 'xml_res_file': 'Resultater.xml', + 'otime_file': 'test.otime' + } diff --git a/dev.py b/dev.py index 53d5aea..1988b07 100644 --- a/dev.py +++ b/dev.py @@ -6,7 +6,7 @@ from rich.columns import Columns from rich.table import Table if __name__ == "__main__": - event = otime.event(0, 'supercup') + event = otime.Event(0, 'supercup') event.import_ttime_cnf('k2ds/tt.cnf') event.import_ttime_db('k2ds/db.csv') event.import_mtr_file('k2ds/mtr.txt') diff --git a/event_mgr.py b/event_mgr.py index c71bd1a..87bcbe5 100644 --- a/event_mgr.py +++ b/event_mgr.py @@ -5,7 +5,6 @@ import datetime import os from time import sleep import serial -import binascii import pickle import argparse from difflib import Differ @@ -17,6 +16,7 @@ from rich.table import Table from rich.panel import Panel from rich.console import Group + def save(obj): f = open(config['otime_file'], "wb") pickle.dump(obj,f) @@ -35,15 +35,17 @@ def start_parse(): else: print('Starter fra scratch') start_event() + def start_event(): global event - event = otime.event(0, config['event_name']) + event = otime.Event(0, config['event_name']) event.import_ttime_cnf(config['cnf_file']) event.import_ttime_db(config['db_file']) save(event) global db_file global db_file_u db_file = open(config['db_file'], 'r', encoding='latin_1').read().splitlines() + def load_event(ot_file): global event f = open(ot_file, "r") @@ -64,7 +66,6 @@ def assign_card_r_to_runner(runners, card_r): panel = Panel.fit(cont, title=str(card_r.card), border_style='white') print(panel) - def runner_info(runner): time = str(datetime.timedelta(seconds=runner.totaltime())) if runner.status() == 'Disqualified': @@ -97,13 +98,13 @@ def read_db_changes(): for line in result: if line[:1] == '+': clean = str(line).replace('+ ', '').split(';') - runner = otime.runner.from_string(clean, event.o_classes) + runner = otime.Runner.from_string(clean, event.o_classes) if runner.first != None: added_raw.append(runner) elif line[:1] == '-': clean = str(line).replace('- ', '').split(';') - runner = otime.runner.from_string(clean, event.o_classes) + runner = otime.Runner.from_string(clean, event.o_classes) if runner.first != None: removed_raw.append(runner) @@ -140,6 +141,7 @@ def read_db_changes(): print(runner_info(n)) event.match_runners_cards() event.get_xml_res().write(config['xml_res_file']) + def read_mtr(mtr): global event if mtr.in_waiting > 0: @@ -148,8 +150,8 @@ def read_mtr(mtr): if size == b'\xe6': meat = mtr.read(229) full = b'\xFF\xFF\xFF\xFF' + size + meat - card_r = otime.card_punch.from_mtr_bytes(full) - event.card_punches.append(card_r) + card_r = otime.CardDump.from_mtr_bytes(full) + event.card_dumps.append(card_r) assign_card_r_to_runner(event.runners, card_r) elif size == b'\x37': meat = mtr.read(55) @@ -157,6 +159,7 @@ def read_mtr(mtr): inspect(status) print(status.year(),status.month(),status.day(),status.hours(),status.minutes()) event.get_xml_res().write(config['xml_res_file']) + def main(): global event global db_file diff --git a/otime.py b/otime.py index eb47e7f..79e2fb2 100644 --- a/otime.py +++ b/otime.py @@ -5,15 +5,18 @@ import re import xml.etree.ElementTree as ET from fpdf import FPDF -class event: + +# The event object stores all the event data. +# A .otime file is just a pickle dump of an event object. +class Event: def __init__(self, eventid, name, **kwargs): self.id = eventid self.name = name - self.courses = [] self.o_classes = [] self.runners = [] - self.card_punches= [] + self.card_dumps = [] + def add_course(self, *args): for n in args: self.courses.append(n) @@ -25,6 +28,7 @@ class event: def add_runners(self, *args): for n in args: self.runners.append(n) + def import_ttime_cnf(self, ttime_file): self.add_course(*courses_from_ttime_conf(ttime_file)) self.add_o_class(*classes_from_ttime_conf(ttime_file, self.courses)) @@ -35,13 +39,15 @@ class event: for row in csvreader: if len(row) == 0 or row[1] == '': continue - runnerarray.append(runner.from_string(row, self.o_classes)) + runnerarray.append(Runner.from_string(row, self.o_classes)) self.runners = runnerarray + def import_mtr_file(self, mtr_file): - self.card_punches = card_punch.list_from_mtr_f(mtr_file) + self.card_dumps = card_punch.list_from_mtr_f(mtr_file) + def match_runners_cards(self): for n in self.runners: - for i in self.card_punches: + for i in self.card_dumps: if n.card == i.card: n.card_r = i @@ -58,12 +64,12 @@ class event: xml_child(event, 'Id', self.id) xml_child(event, 'Name', self.name) for i in self.o_classes: - # + # class_result = ET.SubElement(root, 'ClassResult') - # + # t = ET.SubElement(class_result, 'Class') xml_child(t, 'Name', i.name) - # + # runners_same_c = get_runners_in_class(self.runners, i) runners_ranked = rank_runners(runners_same_c, i) # Put the OK runners first and Active last @@ -72,16 +78,16 @@ class event: for n in runners_ranked: person_result = ET.SubElement(class_result, 'PersonResult') - # + # person = ET.SubElement(person_result, 'Person') xml_child(person, 'Id', n.id) - # + # name = ET.SubElement(person, 'Name') xml_child(name, 'Family', n.last) xml_child(name, 'Given', n.first) - # - # - # + # + # + # org = ET.SubElement(person_result, 'Organisation') xml_child(org, 'Id', '0') xml_child(org, 'Name', n.club) @@ -89,43 +95,43 @@ class event: # TODO: hent land fra løperobjektet country.text = 'Norway' country.set('code', 'NOR') - # - # + # + # result = ET.SubElement(person_result, 'Result') - if hasattr(n,'card_r') and len(n.card_r.splits) > 2: + if hasattr(n, 'card_r') and len(n.card_r.splits) > 2: xml_child(result, 'StartTime', n.card_r.s_time.isoformat()) xml_child(result, 'FinishTime', n.card_r.f_time.isoformat()) xml_child(result, 'Time', n.totaltime()) if n.status() == 'OK': - # + # xml_child(result, 'TimeBehind', n.totaltime() - runners_ranked[0].totaltime()) - # + # xml_child(result, 'Position', n.rank(self.runners)) xml_child(result, 'Status', n.status()) - # - #TODO: ta utgangspunkt i løypa, ikke det brikka har stempla - for code,split in zip(n.card_r.controls,n.card_r.splits): + # + # TODO: ta utgangspunkt i løypa, ikke det brikka har stempla + for code, split in zip(n.card_r.controls, n.card_r.splits): st = ET.SubElement(result, 'SplitTime') xml_child(st, 'ControlCode', code) xml_child(st, 'Time', split) if code == n.o_class.course.codes[-1]: break - # + # elif n.status() == 'Disqualified': xml_child(result, 'Status', n.status()) for code in n.o_class.course.codes: st = ET.SubElement(result, 'SplitTime') xml_child(st, 'ControlCode', code) - for control,split in zip(n.card_r.controls,n.card_r.splits): - if code == control: - xml_child(st, 'Time', split) + for control, split in zip(n.card_r.controls, n.card_r.splits): + if code == control: + xml_child(st, 'Time', split) else: xml_child(result, 'Status', n.status()) else: xml_child(result, 'Status', n.status()) - # - # - # + # + # + # ET.indent(root, space=' ', level=0) return tree @@ -147,61 +153,66 @@ class event: pdf.ln(line_height) pdf.output(file_name) -class runner: + +# The runner object stores all the data specific to a runner. +class Runner: def __init__(self, runner_id, first, last, club, country, card, o_class, start_time): - self.id = runner_id - self.first = first - self.last = last - self.club = club - self.country = country - self.card = card - self.o_class = o_class - self.start_time = start_time + self.id = runner_id + self.first = first + self.last = last + self.club = club + self.country = country + self.card = card + self.o_class = o_class + self.start_time = start_time + def from_string(tt_line, o_classes): - #https://web.archive.org/web/20191229124046/http://wiki.ttime.no/index.php/Developer - eventorid = tt_line[0] - country = '' - name = tt_line[2].split(',') - try: - first = name[1].strip() - except: - first = '' - last = name[0] - try: - club = tt_line[4] - except: - club = "None" - try: - card = int(tt_line[6]) - except: - card = 0 + #https://web.archive.org/web/20191229124046/http://wiki.ttime.no/index.php/Developer + eventorid = tt_line[0] + country = '' + name = tt_line[2].split(',') + try: + first = name[1].strip() + except: + first = '' + last = name[0] + try: + club = tt_line[4] + except: + club = "None" + try: + card = int(tt_line[6]) + except: + card = 0 + runner_o_class = None + try: + raw_class_str = tt_line[3] + except: + # VELDIG MIDLERTIDIG runner_o_class = None - try: - raw_class_str = tt_line[3] - except: - # VELDIG MIDLERTIDIG - runner_o_class = None + else: + if raw_class_str != '': + for i in o_classes: + if i.name == raw_class_str: + runner_o_class = i + break else: - if raw_class_str != '': - for i in o_classes: - if i.name == raw_class_str: - runner_o_class = i - break - else: - runner_o_class = None - # TODO: Gjør sånn at den lager nye o klasser om den ikke finnes fra før - try: - options = tt_line[5].split(',') - start_time = options[options.index('U')+1] - except: - start_time = None - return runner(eventorid, first, last, club, country, card, runner_o_class, start_time) + runner_o_class = None + # TODO: Gjør sånn at den lager nye o klasser om den ikke finnes fra før + try: + options = tt_line[5].split(',') + start_time = options[options.index('U')+1] + except: + start_time = None + return Runner(eventorid, first, last, club, country, card, runner_o_class, start_time) def fullname(self): return '{} {}'.format(self.first, self.last) + def check_codes(self): # Returns False if not ok and touple if ok return contains(self.o_class.course.codes, list(self.card_r.controls)) + def totaltime(self): f_control = self.o_class.course.codes[-1] try: @@ -217,9 +228,11 @@ class runner: return 'OK' elif self.check_codes() == False: return 'Disqualified' + def rank(self, allrunners): c_ranked = rank_runners(allrunners, self.o_class) return c_ranked.index(self) + 1 + def res_splits(self): splits_cpy = self.card_r.splits.copy() for control in self.card_r.controls: @@ -229,7 +242,7 @@ class runner: splits_cpy.remove(split) return splits_cpy -class card_punch: +class CardDump: def __init__(self, card, controls, splits, read_time, s_time, f_time): self.card = card self.controls = controls @@ -237,6 +250,7 @@ class card_punch: self.read_time = read_time self.s_time = s_time self.f_time = f_time + def __repr__(self): return f'card({self.card}) controls({self.controls}) splits({self.splits})' @@ -271,12 +285,12 @@ class card_punch: read_time = datetime.datetime(year, month, day, hours, minutes, seconds, milliseconds) if len(controls) > 2: s_time = read_time - datetime.timedelta(seconds = splits[-1]) - f_time = read_time - (datetime.timedelta(seconds = splits[-1]) + datetime.timedelta(seconds = splits[-2])) + f_time = read_time - (datetime.timedelta(seconds=splits[-1]) + datetime.timedelta(seconds=splits[-2])) else: s_time = read_time f_time = read_time - return(card_punch(card, controls, splits, read_time, s_time, f_time)) + return(CardDump(card, controls, splits, read_time, s_time, f_time)) def list_from_mtr_f(mtr_f): csvreader = csv.reader(open(mtr_f)) @@ -321,23 +335,27 @@ class card_punch: else: s_time = read_time f_time = read_time - cards.append(card_punch(int(row[6]), controls, splits, read_time, s_time, f_time)) + cards.append(CardDump(int(row[6]), controls, splits, read_time, s_time, f_time)) return cards -class course: + +# Stored in Event.courses +class Course: def __init__(self, name, codes): self.name = name self.codes = codes def __repr__(self): return f'name({self.name})' -class o_class: +# Stored in Event.o_classes +class OClass: def __init__(self, name, course): self.name = name self.course = course def __repr__(self): return f'name({self.name})' -def courses_from_ttime_conf(ttime_file = 'sc_2021_ttime/ttime.cnf.txt'): +# TODO: Take string instead of file. +def courses_from_ttime_conf(ttime_file): courses = [] conf = open(ttime_file, 'r', encoding='latin_1').readlines() for line in conf: @@ -348,8 +366,9 @@ def courses_from_ttime_conf(ttime_file = 'sc_2021_ttime/ttime.cnf.txt'): n = n.split(',') loops += 1 n = list(map(int, n)) - courses.append(course('course_'+str(loops), n)) + courses.append(Course('course_'+str(loops), n)) return courses + def classes_from_ttime_conf(ttime_file, courses): o_classes = [] conf = open(ttime_file, 'r', encoding='latin_1').readlines() @@ -360,16 +379,12 @@ def classes_from_ttime_conf(ttime_file, courses): for n in raw_courselist: split = n.split(',') for i in split: - o_classes.append(o_class(i,courses[loops])) + o_classes.append(OClass(i,courses[loops])) loops += 1 - - return o_classes - - +# Checks if small list is in big list def contains(small, big): - # Checks if small list is in big list valid = True mark = 0 map_bl = [] @@ -404,7 +419,7 @@ def rank_runners(allrunners, o_class): runners_ranked.sort(key=lambda x: x.totaltime()) return runners_ranked +# Used to make creating xml files easier def xml_child(parent, tag, content): - # Used to make creating xml files easier e = ET.SubElement(parent, tag) e.text = str(content)