Compare commits

..

2 Commits

3 changed files with 232 additions and 76 deletions

27
dev.py Normal file
View File

@ -0,0 +1,27 @@
import otime
from rich import print
from rich import inspect
from rich.console import Console
from rich.columns import Columns
from rich.table import Table
if __name__ == "__main__":
#courses = otime.courses_from_ttime_conf('sc_2021_ttime/ttime.cnf.txt')
#o_classes = otime.classes_from_ttime_conf('sc_2021_ttime/ttime.cnf.txt', courses)
#runner_list = otime.ttime_db_to_class('sc_2021_ttime/db_eventor.csv', o_classes)
#runner_list = otime.xml_to_class('entries_KOK_Sommercup,_løp_2.xml', o_classes)
#otime.ttime_mtr_to_class('sc_2021_ttime/mtr.csv', runner_list)
#print_runners(runner_list)
#print_time(runner_list)
#print_o_classes(o_classes)
#print_class_splits(runner_list, o_classes[0])
#print(otime.check_codes(runner_list[1]))
#otime.gen_xml_result(runner_list, o_classes)
event = otime.event(0, 'supercup')
event.import_ttime_cnf('sc_2021_ttime/ttime.cnf.txt')
event.import_ttime_db('sc_2021_ttime/db_eventor.csv')
#event.import_mtr_file('sc_2021_ttime/mtr.csv')
card_punches = otime.card_punch.list_from_mtr_f('sc_2021_ttime/mtr.csv')
event.append_punch_list(card_punches)
event.get_xml_res().write('Resultater.xml')

247
otime.py
View File

@ -1,7 +1,130 @@
import copy
import datetime import datetime
import csv import csv
import re import re
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
class event:
def __init__(self, eventid, name, **kwargs):
self.id = eventid
self.name = name
self.courses = []
self.o_classes = []
self.runners = []
self.card_punches= []
def add_course(self, *args):
for n in args:
self.courses.append(n)
def add_o_class(self, *args):
for n in args:
self.o_classes.append(n)
def add_runners(self, *args):
for n in args:
self.runners.append(n)
def import_ttime_cnf(self, ttime_file):
self.add_course(*courses_from_ttime_conf(ttime_file))
self.add_o_class(*classes_from_ttime_conf(ttime_file, self.courses))
def import_ttime_db(self, ttime_file):
self.add_runners(*ttime_db_to_class(ttime_file, self.o_classes))
def import_mtr_file(self, mtr_file):
ttime_mtr_to_class(mtr_file, self.runners)
# MIDLERTIDIG
def append_punch_list(self, punches):
for n in self.runners:
for i in punches:
if n.card == i.card:
n.controls = list(i.punches.keys())
n.splits = list(i.punches.values())
def get_xml_res(self):
root = ET.Element('ResultList')
root.set('xmlns', 'http://www.orienteering.org/datastandard/3.0')
root.set('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance')
root.set('iofVersion', '3.0')
root.set('createTime', datetime.datetime.now().isoformat(timespec='seconds'))
root.set('creator', 'oTime')
root.set('status', 'Complete')
tree = ET.ElementTree(root)
event = ET.SubElement(root, 'Event')
xml_child(event, 'Id', self.id)
xml_child(event, 'Name', self.name)
for i in self.o_classes:
#<ClassResult>
class_result = ET.SubElement(root, 'ClassResult')
#<Class>
t = ET.SubElement(class_result, 'Class')
xml_child(t, 'Name', i.name)
#<PersonResult>
runners_same_c = get_runners_in_class(self.runners, i)
runners_ranked = rank_runners(runners_same_c, i)
# Put the OK runners first and Active last
print(len(runners_same_c), len(runners_ranked))
runners_sorted = [i for i in runners_same_c if i not in runners_ranked]
print(len(runners_same_c), len(runners_ranked))
runners_ranked.extend(runners_sorted)
print(len(runners_same_c), len(runners_ranked))
for n in runners_ranked:
person_result = ET.SubElement(class_result, 'PersonResult')
#<Person>
person = ET.SubElement(person_result, 'Person')
xml_child(person, 'Id', n.id)
#<Name>
name = ET.SubElement(person, 'Name')
xml_child(name, 'Family', n.last)
xml_child(name, 'Given', n.first)
#</Name>
#</Person>
#<Organisation>
org = ET.SubElement(person_result, 'Organisation')
xml_child(org, 'Id', '0')
xml_child(org, 'Name', n.club)
country = ET.SubElement(org, 'Country')
# TODO: hent land fra løperobjektet
country.text = 'Norway'
country.set('code', 'NOR')
#</Organisation>
#<Result>
result = ET.SubElement(person_result, 'Result')
if len(n.splits) > 2:
xml_child(result, 'StartTime', n.s_time.isoformat())
xml_child(result, 'FinishTime', n.f_time.isoformat())
xml_child(result, 'Time', n.totaltime())
if n.status() == 'OK':
#<TimeBehind>
xml_child(result, 'TimeBehind', n.totaltime() - runners_ranked[0].totaltime())
#</TimeBehind>
xml_child(result, 'Position', n.rank(self.runners))
xml_child(result, 'Status', n.status())
#<SplitTime>
for code,split in zip(n.o_class.course.codes, n.res_splits(), strict=True):
st = ET.SubElement(result, 'SplitTime')
xml_child(st, 'ControlCode', code)
xml_child(st, 'Time', split)
#</SplitTime>
elif n.status() == 'Disqualified':
xml_child(result, 'Status', n.status())
for code in n.o_class.course.codes:
st = ET.SubElement(result, 'SplitTime')
xml_child(st, 'ControlCode', code)
for control,split in zip(n.controls, n.splits):
if code == control:
xml_child(st, 'Time', split)
else:
xml_child(result, 'Status', n.status())
else:
xml_child(result, 'Status', n.status())
#</Result>
#</PersonResult>
#</Class>
ET.indent(root, space=' ', level=0)
return tree
class runner: class runner:
def __init__(self, eventorid, first, last, club, country, card, o_class, controls, splits): def __init__(self, eventorid, first, last, club, country, card, o_class, controls, splits):
self.id = eventorid self.id = eventorid
@ -40,6 +163,53 @@ class runner:
for n in control_map: for n in control_map:
splits.append(self.splits[n]) splits.append(self.splits[n])
return splits return splits
class card_punch:
def __init__(self, card, punches, s_time, f_time):
self.card = card
self.punches = punches
self.s_time = s_time
self.f_time = f_time
def __repr__(self):
return f'card({self.card}) punches({self.punches})'
def list_from_mtr_f(mtr_f):
csvreader = csv.reader(open(mtr_f))
fields = next(csvreader)
fields = []
rows = []
cards = []
# hver rad er brikkenummer med tilhørende info
for row in csvreader:
rows.append(row)
controls = []
splits = []
# postkodene kommer på oddetall fra og med den 11. De blir hevet inn i controls
for item in row[11::2]:
if item != '000' and item != '0000' and item != '00000':
controls.append(int(item))
# strekktidene kommer på partall fra og med den 12. De blir hevet i splits.
for item in row[12::2]:
if item != '000' and item != '0000' and item != '00000':
splits.append(int(item))
# looper gjonnom løperobjektene og legger til poster og strekktider + start og sluttid
# usikker på om dette er riktig klokeslett
tl = row[5].split(' ')
tl[0] = tl[0].split('.')
tl[0][2] = '20' + tl[0][2]
tl[0] = list(map(int, tl[0]))
tl[1] = tl[1].split(':')
tl[1][2] = float(tl[1][2])
tl[1] = list(map(int, tl[1]))
f_time = datetime.datetime(tl[0][2], tl[0][1], tl[0][0], tl[1][0], tl[1][1], tl[1][2])
if controls[-1] == 250:
s_time = f_time - datetime.timedelta(seconds = splits[-2])
else:
pass
#s_time = f_time
cards.append(card_punch(int(row[6]), dict(zip(controls, splits)), s_time, f_time))
return cards
class course: class course:
def __init__(self, name, codes): def __init__(self, name, codes):
self.name = name self.name = name
@ -144,6 +314,7 @@ def ttime_db_to_class(ttime_file, o_class_list=[]):
runnerarray.append(runner(eventorid, first, last, club, country, card, runner_o_class, [], [])) runnerarray.append(runner(eventorid, first, last, club, country, card, runner_o_class, [], []))
return runnerarray return runnerarray
# Denne fjernes når card_punch klasses er ferdig
def ttime_mtr_to_class(csv_file, runnerarray): def ttime_mtr_to_class(csv_file, runnerarray):
csvreader = csv.reader(open(csv_file)) csvreader = csv.reader(open(csv_file))
fields = next(csvreader) fields = next(csvreader)
@ -216,83 +387,9 @@ def rank_runners(allrunners, o_class):
for i in runners: for i in runners:
if i.status() == 'OK': if i.status() == 'OK':
runners_ranked.append(i) runners_ranked.append(i)
runners_ranked.sort(key=lambda x: x.totaltime())
return runners_ranked return runners_ranked
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)
def gen_xml_result(runners, o_classes):
root = ET.Element('ResultList')
root.set('iofVersion', '3.0')
root.set('createTime', datetime.datetime.now().isoformat())
root.set('creator', 'oTime')
root.set('status', 'Complete')
tree = ET.ElementTree(root)
event = ET.SubElement(root, 'Event')
xml_child(event, 'Name', 'PLACEHOLDER')
for i in o_classes:
#<ClassResult>
class_result = ET.SubElement(root, 'ClassResult')
#<Class>
t = ET.SubElement(class_result, 'Class')
xml_child(t, 'Name', i.name)
#<PersonResult>
runners_same_c = get_runners_in_class(runners, i)
runners_ranked = rank_runners(runners_same_c, i)
for n in runners_same_c:
person_result = ET.SubElement(class_result, 'PersonResult')
#<Person>
person = ET.SubElement(person_result, 'Person')
xml_child(person, 'Id', n.id)
#<Name>
name = ET.SubElement(person, 'Name')
xml_child(name, 'Family', n.last)
xml_child(name, 'Given', n.first)
#</Name>
#</Person>
#<Organisation>
org = ET.SubElement(person_result, 'Organisation')
xml_child(org, 'Id', '0')
xml_child(org, 'Name', n.club)
country = ET.SubElement(org, 'Country')
# TODO: hent land fra løperobjektet
country.text = 'Norway'
country.set('code', 'NOR')
#</Organisation>
#<Result>
result = ET.SubElement(person_result, 'Result')
if len(n.splits) > 2:
xml_child(result, 'StartTime', n.s_time.isoformat())
xml_child(result, 'FinishTime', n.f_time.isoformat())
xml_child(result, 'Time', n.totaltime())
if n.status() == 'OK':
#<TimeBehind>
xml_child(result, 'TimeBehind', n.totaltime() - runners_ranked[0].totaltime())
#</TimeBehind>
xml_child(result, 'Position', n.rank(runners))
xml_child(result, 'Status', n.status())
#<SplitTime>
for code,split in zip(n.o_class.course.codes, n.res_splits(), strict=True):
st = ET.SubElement(result, 'SplitTime')
xml_child(st, 'ControlCode', code)
xml_child(st, 'Time', split)
#</SplitTime>
elif n.status() == 'Disqualified':
xml_child(result, 'Status', n.status())
for code in n.o_class.course.codes:
st = ET.SubElement(result, 'SplitTime')
xml_child(st, 'ControlCode', code)
for control,split in zip(n.controls, n.splits):
if code == control:
xml_child(st, 'Time', split)
else:
xml_child(result, 'Status', n.status())
else:
xml_child(result, 'Status', n.status())
#</Result>
#</PersonResult>
#</Class>
ET.indent(root, space=' ', level=0)
tree.write('Resultater.xml')
return tree

View File

@ -81,8 +81,25 @@ class MainWindow(Gtk.ApplicationWindow):
self.box2.append(self.save_btn) self.box2.append(self.save_btn)
self.save_dialog = Gtk.FileChooserNative.new(title="lagre xml resultat fil", self.save_dialog = Gtk.FileChooserNative.new(title="lagre xml resultat fil",
parent=self, action=Gtk.FileChooserAction.SAVE) parent=self, action=Gtk.FileChooserAction.SAVE)
self.text_buffer = Gtk.TextBuffer()
self.info_text = Gtk.TextView.new()
self.info_text.set_editable(False)
self.info_text.set_margin_top(8)
self.mainlist.get_style_context().add_class('card')
self.info_text.set_buffer(self.text_buffer)
self.box2.append(self.info_text)
self.viewstyle = self.info_text.get_style_context()
print(self.viewstyle.has_class('view'))
self.save_dialog.connect("response", self.save_xml) self.save_dialog.connect("response", self.save_xml)
self.save_btn.connect("clicked", self.show_save_dialog) self.save_btn.connect("clicked", self.show_save_dialog)
self.toast_overlay = Adw.ToastOverlay()
self.box2.append(self.toast_overlay)
self.save_toast = Adw.Toast.new('Fil lagra')
self.save_toast.set_timeout(8)
def show_cnf_dialog(self, button): def show_cnf_dialog(self, button):
@ -95,7 +112,6 @@ class MainWindow(Gtk.ApplicationWindow):
self.save_dialog.show() self.save_dialog.show()
def sel_cnf(self, dialog, response): def sel_cnf(self, dialog, response):
print('test')
if response == Gtk.ResponseType.ACCEPT: if response == Gtk.ResponseType.ACCEPT:
file = dialog.get_file() file = dialog.get_file()
filename = file.get_path() filename = file.get_path()
@ -128,6 +144,22 @@ class MainWindow(Gtk.ApplicationWindow):
otime.ttime_mtr_to_class(mtr_file, runners) otime.ttime_mtr_to_class(mtr_file, runners)
otime.gen_xml_result(runners, o_classes).write(filename) otime.gen_xml_result(runners, o_classes).write(filename)
runners_ok = []
for n in runners:
if n.status() == 'OK':
runners_ok.append(n)
runners_dsq = []
for n in runners:
if n.status() == 'Disqualified':
runners_dsq.append(n)
self.text_buffer.set_text(f'Antall påmeldte: {len(runners)} \nAntall godkjente: {len(runners_ok)} \nAntall dsq: {len(runners_dsq)}')
self.save_toast = Adw.Toast.new('Fil lagra i: '+filename)
self.save_toast.set_timeout(8)
self.toast_overlay.add_toast(self.save_toast)
class MyApp(Adw.Application): class MyApp(Adw.Application):
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)