La til toml konfigurasjon og iof xml løype lasting

This commit is contained in:
Trygve 2023-09-08 08:50:30 +02:00
parent 74ee5cad56
commit bc611e91e9
2 changed files with 108 additions and 144 deletions

View File

@ -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()

View File

@ -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)