diff --git a/event_mgr.py b/event_mgr.py index 87bcbe5..707af9e 100644 --- a/event_mgr.py +++ b/event_mgr.py @@ -1,13 +1,12 @@ #!/usr/bin/env python import otime -from config import config import datetime import os from time import sleep import serial -import pickle import argparse -from difflib import Differ +import json +import cli from rich import print from rich import inspect from rich.console import Console @@ -17,130 +16,25 @@ from rich.panel import Panel from rich.console import Group -def save(obj): - f = open(config['otime_file'], "wb") - pickle.dump(obj,f) - f.close() -def start_parse(): - parser = argparse.ArgumentParser(description='Event manager') - subparsers = parser.add_subparsers(dest='command') - open_event = subparsers.add_parser('continue', help='Open pickle') - open_event.add_argument('--file', help='.otime file') +def run_otime(): + event = otime.Event.from_toml(open("/home/trygve/Prosjekter/otime-testing/sc3/sc3.toml", "rb")) + event.import_ttime_db(open("/home/trygve/Prosjekter/otime-testing/sc3/db.csv")) - args = parser.parse_args() - - if args.command == 'continue': - print('Later ' + args.file) - else: - print('Starter fra scratch') - start_event() - -def start_event(): - global event - 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") - event = pickle.load(f) - f.close() - global db_file - global db_file_u - db_file = open(config['db_file'], 'r', encoding='latin_1').read().splitlines() - -def assign_card_r_to_runner(runners, card_r): - for n in runners: - if n.card == card_r.card: - n.card_r = card_r - print(runner_info(n)) - break - else: - cont = f'Brikke ikke registrert på noen løper\nId: {card_r.card}\nPoster: {card_r.controls}' - 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': - dsqp = Panel.fit(f'Løype: {runner.o_class.course.codes}\nRegistrert: {runner.card_r.controls}', border_style='red') - cont = Group(f'Status: {runner.status()}',dsqp) - panel = Panel.fit(cont, title=runner.fullname(), border_style='red') - elif runner.status() == 'OK': - cont = f'Status: {runner.status()}\nTid: {time}' - panel = Panel.fit(cont, title=runner.fullname(), border_style='green') - elif runner.status() == 'Active': - cont = '' - panel = Panel.fit(cont, title=runner.fullname()) - return panel - -def read_db_changes(): - global event - global db_file - global db_file_u - print('DB file changed') - db_file_u = open(config['db_file'], 'r', encoding='latin_1').read().splitlines() - d = Differ() - result = list(d.compare(db_file, db_file_u)) - db_file = db_file_u - - added_raw = [] - removed_raw = [] - added = [] - removed = [] - changed = [] - for line in result: - if line[:1] == '+': - clean = str(line).replace('+ ', '').split(';') - 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) - if runner.first != None: - removed_raw.append(runner) - - for plus in added_raw: - for index, minus in enumerate(removed_raw): - if plus.id == minus.id: - changed.append(plus) - removed_raw[index] = plus - break - - added = [x for x in added_raw if x not in changed] - removed = [x for x in removed_raw if x not in changed] - #print(len(added_raw),len(removed_raw)) - #print(len(added),len(removed),len(changed)) - - event.runners.extend(added) - for n in added: - print(f'[green]Added: {n.fullname()}, {n.o_class.name}, {n.card}[green]') - if n.status != 'Active': - print(runner_info(n)) - - for r in removed: - for n in event.runners: - if n.id == r.id: - print(f'[red]Removed: {n.fullname()}, {n.o_class.name}, {n.card}') - event.runners.remove(n) - - for change in changed: - for i, n in enumerate(event.runners): - if n.id == runner.id: - event.runners[i] = runner - print(f'[blue]Changed: {runner.fullname()}, {runner.o_class.name}, {runner.card}') - if n.status != 'Active': - print(runner_info(n)) - event.match_runners_cards() - event.get_xml_res().write(config['xml_res_file']) + data = (open("/home/trygve/Prosjekter/otime-testing/sc3/mtr.json")).readlines() + for l in data: + d = json.loads(l) + #print(l) + event.card_dumps.append(otime.CardDump(d['card'], d['controls'], d['splits'], + datetime.datetime.fromisoformat(d['read_time']), + datetime.datetime.fromisoformat(d['s_time']), + datetime.datetime.fromisoformat(d['f_time']))) + print('Ecards:'+str(len(event.card_dumps))) + print('Løpere:'+str(len(event.runners))) + event.match_all() + #cli.print_runners(event.runners) + for n in event.o_classes: + cli.print_class_result(event.runners, n) def read_mtr(mtr): global event @@ -151,29 +45,24 @@ def read_mtr(mtr): meat = mtr.read(229) full = b'\xFF\xFF\xFF\xFF' + size + meat card_r = otime.CardDump.from_mtr_bytes(full) - event.card_dumps.append(card_r) - assign_card_r_to_runner(event.runners, card_r) + print(json.dumps(card_r.asdict())) + with open("sc3/mtr.json", "a") as myfile: + myfile.write('\n' + json.dumps(card_r.asdict())) + run_otime() + elif size == b'\x37': meat = mtr.read(55) status = mtrreader.MtrStatusMessage(meat) 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 - global db_file_u - mtr = serial.Serial(port=config['port'], baudrate=9600, timeout=40) - db_file_date = os.path.getctime(config['db_file']) + mtr = serial.Serial(port="/dev/pts/2", baudrate=9600, timeout=40) + # mtr.write(b'/SA') while True: - if db_file_date != os.path.getctime(config['db_file']): - db_file_date = os.path.getctime(config['db_file']) - read_db_changes() read_mtr(mtr) sleep(0.1) db_file_u = None if __name__ == "__main__": - start_parse() main() diff --git a/otime.py b/otime.py index 120d78d..55eb183 100644 --- a/otime.py +++ b/otime.py @@ -3,6 +3,8 @@ import datetime import csv import re import json +import tomllib +import tomlkit import io import xml.etree.ElementTree as ET # from fpdf import FPDF @@ -25,6 +27,53 @@ class Event: self.card_dumps = card_dumps self.fees = fees + def from_toml(f): + cfg = tomllib.load(f) + courses = [] + for c in cfg['course']: + courses.append(Course(c['name'] , c['codes'], c['forked'], c['variations'])) + o_classes = [] + for c in cfg['classes']: + for n in courses: + if n.name == cfg['classes'][c]: + course = n + break + o_classes.append(OClass(c, cfg['classes'][c], course)) + + return Event(1, cfg['name'], cfg['start_time'], cfg['end_time'], cfg['organiser'], courses, o_classes, [], [], []) + + def create_toml(self, dir='./'): + doc = tomlkit.document() + cdicts = [] + for course in self.courses: + cdicts.append(course.asdict()) + #Fjern None fra dictene + for c in cdicts: + if c['forked'] == False: + c['variations'] = [] + + + ocdicts = [] + for o_class in self.o_classes: + ocdicts.append(o_class.asdict()) + + fdicts = [] + for fee in self.fees: + fdicts.append(fee.asdict()) + + data = { + 'id': self.id, + 'name': self.name, + 'organiser': self.organiser, + 'start_time': self.start_time.isoformat(), + 'end_time': self.end_time.isoformat(), + 'course': cdicts, + #'o_classes': ocdicts, + #'fees': fdicts + } + with open(dir + 'cfg.toml', "w") as f: + tomlkit.dump(data, f) + def add_course(self, *args): for n in args: self.courses.append(n) @@ -68,6 +117,8 @@ class Event: return Event(event_id, name, organiser=organiser, runners=runners, fees=fees, start_time=start_time, end_time=end_time) + def import_xml_courses(self, xml_file): + self.courses = courses_from_xml(xml_file) def import_ttime_cnf(self, ttime_file): self.add_course(*courses_from_ttime_conf(ttime_file)) @@ -79,7 +130,7 @@ class Event: if type(ttime_file) == str: f_list = ttime_file.splitlines() elif isinstance(ttime_file, io.TextIOBase): - csvreader = csv.reader(ttime_file, delimiter=';',) + f_list = csv.reader(ttime_file, delimiter=';',) runnerarray = [] for row in f_list: if len(row) == 0 or row[1] == '': @@ -111,8 +162,9 @@ class Event: def match_runners_fees(self): for r in self.runners: for f in self.fees: - if r.fee_id == f.id: - r.fee = f + if r.fee_id == f.id: tree = ET.parse(xml_file) + root = tree.getroot() + r.fee = f def match_all(self): self.match_runners_cards() @@ -147,8 +199,6 @@ class Event: runners_ranked.extend(runners_sorted) for n in runners_ranked: - if n.status() == 'Active': - continue person_result = ET.SubElement(class_result, 'PersonResult') # person = ET.SubElement(person_result, 'Person') @@ -593,7 +643,12 @@ class Runner: if control not in self.res_codes(): index = self.card_r.controls.index(control) split = self.card_r.splits[index] - splits_cpy.remove(split) + try: + splits_cpy.remove(split) + except Exception: + print('aaaaaa') + + punches = self.card_r.controls.copy() splits = [] for code in self.res_codes(): @@ -736,6 +791,7 @@ class Course: self.name = name self.codes = codes self.forked = forked + # Variations is a list self.variations = variations def __repr__(self): @@ -862,7 +918,6 @@ def runners_from_xml_entries(xml_file): start_time=start_time, fee_id=fee_id)) return runners - def fees_from_xml_entries(xml_file): tree = ET.parse(xml_file) root = tree.getroot() @@ -893,6 +948,24 @@ def fees_from_xml_entries(xml_file): from_birth_date=from_birth_date, to_birth_date=to_birth_date)) return fee_objs +def courses_from_xml(xml_file): + tree = ET.parse(xml_file) + root = tree.getroot() + + url = '{http://www.orienteering.org/datastandard/3.0}' + allcourses = root.findall(f'.//{url}Course') + courseobjs = [] + for c in allcourses: + name = c.find(f'./{url}Name').text + controls = [] + allcontrols = c.findall(f'./{url}CourseControl') + for n in allcontrols: + controls.append(n.find(f'./{url}Control').text) + controls.remove('STA1') + controls.remove('FIN1') + controls = [int(l) for l in controls] + courseobjs.append(Course(name, controls)) + return courseobjs # Checks if small list is in big list def contains(small, big): @@ -936,3 +1009,5 @@ def rank_runners(allrunners, o_class): def xml_child(parent, tag, content): e = ET.SubElement(parent, tag) e.text = str(content) + +