#!/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 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)) 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']) def read_mtr(mtr): global event if mtr.in_waiting > 0: 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.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) 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']) 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()