La til toml konfigurasjon og iof xml løype lasting
This commit is contained in:
		
							parent
							
								
									74ee5cad56
								
							
						
					
					
						commit
						bc611e91e9
					
				
							
								
								
									
										163
									
								
								event_mgr.py
									
									
									
									
									
								
							
							
						
						
									
										163
									
								
								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() | ||||
|  | ||||
							
								
								
									
										89
									
								
								otime.py
									
									
									
									
									
								
							
							
						
						
									
										89
									
								
								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> | ||||
|                 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) | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user