#!/usr/bin/env python import otime import datetime import serial import binascii import pickle import asyncio import argparse from difflib import Differ from watchfiles import awatch from config import config from rich import print from rich import inspect from rich.console import Console from rich.columns import Columns 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) 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') 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)) 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 async def main(): async def mtr_listener(): mtr = serial.Serial(port=config['port'], baudrate=9600, timeout=40) while True: mtr.read_until(expected=b'\xFF\xFF\xFF\xFF') size = mtr.read(size=1) 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) assign_card_r_to_runner(event.runners, card_r) 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()) asyncio.create_task(mtr_listener()) async for changes in awatch(config['db_file']): print('😵') global event global db_file global db_file_u 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] == '+': #print(line) clean = str(line).replace('+ ', '').split(';') runner = otime.runner.from_string(clean, event.o_classes) inspect(runner) if runner.first != None: added_raw.append(runner) elif line[:1] == '-': #print(line) 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]') 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}') event.match_runners_cards() event.get_xml_res().write(config['xml_res_file']) db_file_u = None if __name__ == "__main__": start_parse() asyncio.run(main())