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
|
#!/usr/bin/env python
|
||||||
import otime
|
import otime
|
||||||
from config import config
|
|
||||||
import datetime
|
import datetime
|
||||||
import os
|
import os
|
||||||
from time import sleep
|
from time import sleep
|
||||||
import serial
|
import serial
|
||||||
import pickle
|
|
||||||
import argparse
|
import argparse
|
||||||
from difflib import Differ
|
import json
|
||||||
|
import cli
|
||||||
from rich import print
|
from rich import print
|
||||||
from rich import inspect
|
from rich import inspect
|
||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
@ -17,130 +16,25 @@ from rich.panel import Panel
|
|||||||
from rich.console import Group
|
from rich.console import Group
|
||||||
|
|
||||||
|
|
||||||
def save(obj):
|
|
||||||
f = open(config['otime_file'], "wb")
|
|
||||||
pickle.dump(obj,f)
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
def start_parse():
|
def run_otime():
|
||||||
parser = argparse.ArgumentParser(description='Event manager')
|
event = otime.Event.from_toml(open("/home/trygve/Prosjekter/otime-testing/sc3/sc3.toml", "rb"))
|
||||||
subparsers = parser.add_subparsers(dest='command')
|
event.import_ttime_db(open("/home/trygve/Prosjekter/otime-testing/sc3/db.csv"))
|
||||||
open_event = subparsers.add_parser('continue', help='Open pickle')
|
|
||||||
open_event.add_argument('--file', help='.otime file')
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
data = (open("/home/trygve/Prosjekter/otime-testing/sc3/mtr.json")).readlines()
|
||||||
|
for l in data:
|
||||||
if args.command == 'continue':
|
d = json.loads(l)
|
||||||
print('Later ' + args.file)
|
#print(l)
|
||||||
else:
|
event.card_dumps.append(otime.CardDump(d['card'], d['controls'], d['splits'],
|
||||||
print('Starter fra scratch')
|
datetime.datetime.fromisoformat(d['read_time']),
|
||||||
start_event()
|
datetime.datetime.fromisoformat(d['s_time']),
|
||||||
|
datetime.datetime.fromisoformat(d['f_time'])))
|
||||||
def start_event():
|
print('Ecards:'+str(len(event.card_dumps)))
|
||||||
global event
|
print('Løpere:'+str(len(event.runners)))
|
||||||
event = otime.Event(0, config['event_name'])
|
event.match_all()
|
||||||
event.import_ttime_cnf(config['cnf_file'])
|
#cli.print_runners(event.runners)
|
||||||
event.import_ttime_db(config['db_file'])
|
for n in event.o_classes:
|
||||||
save(event)
|
cli.print_class_result(event.runners, n)
|
||||||
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):
|
def read_mtr(mtr):
|
||||||
global event
|
global event
|
||||||
@ -151,29 +45,24 @@ def read_mtr(mtr):
|
|||||||
meat = mtr.read(229)
|
meat = mtr.read(229)
|
||||||
full = b'\xFF\xFF\xFF\xFF' + size + meat
|
full = b'\xFF\xFF\xFF\xFF' + size + meat
|
||||||
card_r = otime.CardDump.from_mtr_bytes(full)
|
card_r = otime.CardDump.from_mtr_bytes(full)
|
||||||
event.card_dumps.append(card_r)
|
print(json.dumps(card_r.asdict()))
|
||||||
assign_card_r_to_runner(event.runners, card_r)
|
with open("sc3/mtr.json", "a") as myfile:
|
||||||
|
myfile.write('\n' + json.dumps(card_r.asdict()))
|
||||||
|
run_otime()
|
||||||
|
|
||||||
elif size == b'\x37':
|
elif size == b'\x37':
|
||||||
meat = mtr.read(55)
|
meat = mtr.read(55)
|
||||||
status = mtrreader.MtrStatusMessage(meat)
|
status = mtrreader.MtrStatusMessage(meat)
|
||||||
inspect(status)
|
inspect(status)
|
||||||
print(status.year(),status.month(),status.day(),status.hours(),status.minutes())
|
print(status.year(),status.month(),status.day(),status.hours(),status.minutes())
|
||||||
event.get_xml_res().write(config['xml_res_file'])
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
global event
|
mtr = serial.Serial(port="/dev/pts/2", baudrate=9600, timeout=40)
|
||||||
global db_file
|
# mtr.write(b'/SA')
|
||||||
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:
|
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)
|
read_mtr(mtr)
|
||||||
sleep(0.1)
|
sleep(0.1)
|
||||||
|
|
||||||
db_file_u = None
|
db_file_u = None
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
start_parse()
|
|
||||||
main()
|
main()
|
||||||
|
89
otime.py
89
otime.py
@ -3,6 +3,8 @@ import datetime
|
|||||||
import csv
|
import csv
|
||||||
import re
|
import re
|
||||||
import json
|
import json
|
||||||
|
import tomllib
|
||||||
|
import tomlkit
|
||||||
import io
|
import io
|
||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
# from fpdf import FPDF
|
# from fpdf import FPDF
|
||||||
@ -25,6 +27,53 @@ class Event:
|
|||||||
self.card_dumps = card_dumps
|
self.card_dumps = card_dumps
|
||||||
self.fees = fees
|
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):
|
def add_course(self, *args):
|
||||||
for n in args:
|
for n in args:
|
||||||
self.courses.append(n)
|
self.courses.append(n)
|
||||||
@ -68,6 +117,8 @@ class Event:
|
|||||||
|
|
||||||
return Event(event_id, name, organiser=organiser, runners=runners,
|
return Event(event_id, name, organiser=organiser, runners=runners,
|
||||||
fees=fees, start_time=start_time, end_time=end_time)
|
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):
|
def import_ttime_cnf(self, ttime_file):
|
||||||
self.add_course(*courses_from_ttime_conf(ttime_file))
|
self.add_course(*courses_from_ttime_conf(ttime_file))
|
||||||
@ -79,7 +130,7 @@ class Event:
|
|||||||
if type(ttime_file) == str:
|
if type(ttime_file) == str:
|
||||||
f_list = ttime_file.splitlines()
|
f_list = ttime_file.splitlines()
|
||||||
elif isinstance(ttime_file, io.TextIOBase):
|
elif isinstance(ttime_file, io.TextIOBase):
|
||||||
csvreader = csv.reader(ttime_file, delimiter=';',)
|
f_list = csv.reader(ttime_file, delimiter=';',)
|
||||||
runnerarray = []
|
runnerarray = []
|
||||||
for row in f_list:
|
for row in f_list:
|
||||||
if len(row) == 0 or row[1] == '':
|
if len(row) == 0 or row[1] == '':
|
||||||
@ -111,8 +162,9 @@ class Event:
|
|||||||
def match_runners_fees(self):
|
def match_runners_fees(self):
|
||||||
for r in self.runners:
|
for r in self.runners:
|
||||||
for f in self.fees:
|
for f in self.fees:
|
||||||
if r.fee_id == f.id:
|
if r.fee_id == f.id: tree = ET.parse(xml_file)
|
||||||
r.fee = f
|
root = tree.getroot()
|
||||||
|
r.fee = f
|
||||||
|
|
||||||
def match_all(self):
|
def match_all(self):
|
||||||
self.match_runners_cards()
|
self.match_runners_cards()
|
||||||
@ -147,8 +199,6 @@ class Event:
|
|||||||
runners_ranked.extend(runners_sorted)
|
runners_ranked.extend(runners_sorted)
|
||||||
|
|
||||||
for n in runners_ranked:
|
for n in runners_ranked:
|
||||||
if n.status() == 'Active':
|
|
||||||
continue
|
|
||||||
person_result = ET.SubElement(class_result, 'PersonResult')
|
person_result = ET.SubElement(class_result, 'PersonResult')
|
||||||
# <Person>
|
# <Person>
|
||||||
person = ET.SubElement(person_result, 'Person')
|
person = ET.SubElement(person_result, 'Person')
|
||||||
@ -593,7 +643,12 @@ class Runner:
|
|||||||
if control not in self.res_codes():
|
if control not in self.res_codes():
|
||||||
index = self.card_r.controls.index(control)
|
index = self.card_r.controls.index(control)
|
||||||
split = self.card_r.splits[index]
|
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()
|
punches = self.card_r.controls.copy()
|
||||||
splits = []
|
splits = []
|
||||||
for code in self.res_codes():
|
for code in self.res_codes():
|
||||||
@ -736,6 +791,7 @@ class Course:
|
|||||||
self.name = name
|
self.name = name
|
||||||
self.codes = codes
|
self.codes = codes
|
||||||
self.forked = forked
|
self.forked = forked
|
||||||
|
# Variations is a list
|
||||||
self.variations = variations
|
self.variations = variations
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
@ -862,7 +918,6 @@ def runners_from_xml_entries(xml_file):
|
|||||||
start_time=start_time, fee_id=fee_id))
|
start_time=start_time, fee_id=fee_id))
|
||||||
return runners
|
return runners
|
||||||
|
|
||||||
|
|
||||||
def fees_from_xml_entries(xml_file):
|
def fees_from_xml_entries(xml_file):
|
||||||
tree = ET.parse(xml_file)
|
tree = ET.parse(xml_file)
|
||||||
root = tree.getroot()
|
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))
|
from_birth_date=from_birth_date, to_birth_date=to_birth_date))
|
||||||
return fee_objs
|
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
|
# Checks if small list is in big list
|
||||||
def contains(small, big):
|
def contains(small, big):
|
||||||
@ -936,3 +1009,5 @@ def rank_runners(allrunners, o_class):
|
|||||||
def xml_child(parent, tag, content):
|
def xml_child(parent, tag, content):
|
||||||
e = ET.SubElement(parent, tag)
|
e = ET.SubElement(parent, tag)
|
||||||
e.text = str(content)
|
e.text = str(content)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user