forked from Trygve/otime
176 lines
6.7 KiB
Python
176 lines
6.7 KiB
Python
import datetime
|
|
import xml.etree.ElementTree as ET
|
|
|
|
def xml_child(parent, tag, content):
|
|
# Used to make creating xml files easier
|
|
e = ET.SubElement(parent, tag)
|
|
e.text = str(content)
|
|
|
|
def create_result_file(event, file_path, o_classes=[]):
|
|
results = event.get_result(o_classes)
|
|
|
|
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)
|
|
xml_event = ET.SubElement(root, 'Event')
|
|
xml_child(xml_event, 'Id', event.id)
|
|
xml_child(xml_event, 'Name', event.name)
|
|
for i in results:
|
|
# <ClassResult>
|
|
class_result = ET.SubElement(root, 'ClassResult')
|
|
# <Class>
|
|
t = ET.SubElement(class_result, 'Class')
|
|
xml_child(t, 'Name', i.name)
|
|
# <PersonResult>
|
|
|
|
for n in i.runner_results:
|
|
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', n.club_id)
|
|
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 n.status == 'OK' or n.status == 'MissingPunch':
|
|
xml_child(result, 'StartTime', n.start_time.isoformat())
|
|
xml_child(result, 'FinishTime', n.end_time.isoformat())
|
|
xml_child(result, 'Time', n.total_time)
|
|
if n.status == 'OK':
|
|
# <TimeBehind>
|
|
xml_child(result, 'TimeBehind', n.total_time - i.runner_results[0].total_time)
|
|
# </TimeBehind>
|
|
xml_child(result, 'Position', n.place)
|
|
xml_child(result, 'Status', n.status)
|
|
# <SplitTime>
|
|
# TODO: ta utgangspunkt i løypa, ikke det brikka har stempla
|
|
for code, split in zip(i.course.codes, n.splits):
|
|
st = ET.SubElement(result, 'SplitTime')
|
|
xml_child(st, 'ControlCode', code)
|
|
xml_child(st, 'Time', split)
|
|
# </SplitTime>
|
|
elif n.status == 'MissingPunch':
|
|
xml_child(result, 'Status', n.status)
|
|
for code, split in zip(i.course.codes, n.splits):
|
|
st = ET.SubElement(result, 'SplitTime')
|
|
xml_child(st, 'ControlCode', code)
|
|
if split != 0: 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(file_path)
|
|
|
|
def runners_from_xml_entries(xml_file):
|
|
tree = ET.parse(xml_file)
|
|
root = tree.getroot()
|
|
|
|
url = '{http://www.orienteering.org/datastandard/3.0}'
|
|
runners = []
|
|
person_entries = root.findall(f'./{url}PersonEntry')
|
|
for p_entry in person_entries:
|
|
|
|
rid = p_entry[1][0].text
|
|
|
|
person = p_entry.find(f'./{url}Person')
|
|
name = person.find(f'./{url}Name')
|
|
first = name.find(f'./{url}Given').text
|
|
last = name.find(f'./{url}Family').text
|
|
|
|
organisation = p_entry.find(f'./{url}Organisation')
|
|
if organisation is not None:
|
|
club_id = organisation.find(f'./{url}Id').text
|
|
club_name = organisation.find(f'./{url}Name').text
|
|
club_name_short = organisation.find(f'./{url}ShortName').text
|
|
country = organisation.find(f'./{url}Country').attrib['code']
|
|
else:
|
|
club_id = club_name = club_name_short = country = None
|
|
|
|
class_el = p_entry.find(f'./{url}Class')
|
|
class_str = class_el.find(f'./{url}Name').text
|
|
|
|
fee_id = int(p_entry.find(f'./{url}AssignedFee/{url}Fee/{url}Id').text)
|
|
|
|
try:
|
|
card = int(p_entry.find(f'./{url}ControlCard').text)
|
|
except AttributeError:
|
|
card = None
|
|
|
|
start_time = None
|
|
runners.append(Runner(rid, first, last, club=club_name, club_id=club_id,
|
|
country=country,card=card, o_class_str=class_str,
|
|
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()
|
|
|
|
url = '{http://www.orienteering.org/datastandard/3.0}'
|
|
allfees = root.findall(f'.//{url}Fee')
|
|
added_ids = []
|
|
fee_objs = []
|
|
for fee in allfees:
|
|
f_id = int(fee.find(f'./{url}Id').text)
|
|
if f_id not in added_ids:
|
|
added_ids.append(f_id)
|
|
|
|
fee_id = f_id
|
|
name = fee.find(f'./{url}Name').text
|
|
currency = fee.find(f'./{url}Amount').attrib['currency']
|
|
amount = int(fee.find(f'./{url}Amount').text)
|
|
try:
|
|
from_birth_date = fee.find(f'./{url}FromDateOfBirth').text
|
|
except AttributeError:
|
|
from_birth_date = None
|
|
try:
|
|
to_birth_date = fee.find(f'./{url}ToDateOfBirth').text
|
|
except AttributeError:
|
|
to_birth_date = None
|
|
|
|
fee_objs.append(Fee(fee_id, name, currency, amount,
|
|
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
|