Compare commits
	
		
			No commits in common. "bf0b400708e4fcb045ed834d92484869648a900e" and "c94aafe981c335ff53c192d353b5cbf059159bcc" have entirely different histories.
		
	
	
		
			bf0b400708
			...
			c94aafe981
		
	
		
							
								
								
									
										174
									
								
								otime/iof_xml.py
									
									
									
									
									
								
							
							
						
						
									
										174
									
								
								otime/iof_xml.py
									
									
									
									
									
								
							| @ -1,174 +0,0 @@ | |||||||
| 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) |  | ||||||
|                 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 |  | ||||||
							
								
								
									
										299
									
								
								otime/otime.py
									
									
									
									
									
								
							
							
						
						
									
										299
									
								
								otime/otime.py
									
									
									
									
									
								
							| @ -20,7 +20,6 @@ class Runner: | |||||||
|         self.start_time = start_time |         self.start_time = start_time | ||||||
|         self.fee_id = fee_id |         self.fee_id = fee_id | ||||||
|         self.status_override = '' |         self.status_override = '' | ||||||
| 
 |  | ||||||
|     def __repr__(self): |     def __repr__(self): | ||||||
|         return(f'name({self.fullname()})') |         return(f'name({self.fullname()})') | ||||||
|          |          | ||||||
| @ -63,6 +62,71 @@ class Runner: | |||||||
|     def fullname(self): |     def fullname(self): | ||||||
|         return '{} {}'.format(self.first, self.last) |         return '{} {}'.format(self.first, self.last) | ||||||
| 
 | 
 | ||||||
|  |     # TODO: må forbedres | ||||||
|  |     def rank(self, allrunners): | ||||||
|  |         c_ranked = rank_runners(allrunners, self.o_class) | ||||||
|  |         try: | ||||||
|  |             return c_ranked.index(self) + 1 | ||||||
|  |         except ValueError: | ||||||
|  |             return None | ||||||
|  | 
 | ||||||
|  |     def get_codes(self): | ||||||
|  |         if self.o_class.course.forked is False: | ||||||
|  |             return self.o_class.course.codes | ||||||
|  |         else: | ||||||
|  |             return self.o_class.course.variations[self.fork] | ||||||
|  | 
 | ||||||
|  |     # TODO: Mange bugs med løyper som har samme post flere ganger | ||||||
|  |     # Used for making result files and tables | ||||||
|  |     def get_splits(self): | ||||||
|  |         if self.status() == 'OK': | ||||||
|  |             splits_cpy = self.card_r.splits.copy() | ||||||
|  |             for control in self.card_r.controls: | ||||||
|  |                 if control not in self.res_codes(): | ||||||
|  |                     index = self.card_r.controls.index(control) | ||||||
|  |                     split = self.card_r.splits[index] | ||||||
|  |                     splits_cpy.remove(split) | ||||||
|  |             return splits_cpy | ||||||
|  | 
 | ||||||
|  |         else: | ||||||
|  |             splits_cpy = self.card_r.splits.copy() | ||||||
|  |             for control in self.card_r.controls: | ||||||
|  |                 if control not in self.res_codes(): | ||||||
|  |                     index = self.card_r.controls.index(control) | ||||||
|  |                     split = self.card_r.splits[index] | ||||||
|  |                     try: | ||||||
|  |                         splits_cpy.remove(split) | ||||||
|  |                     except Exception: | ||||||
|  |                         print('aaaaaa') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |             punches = self.card_r.controls.copy() | ||||||
|  |             splits = [] | ||||||
|  |             for code in self.res_codes(): | ||||||
|  |                 if punches[0] == code: | ||||||
|  |                     splits.append(splits_cpy[0]) | ||||||
|  |                     splits_cpy.pop(0) | ||||||
|  |                     punches.pop(0) | ||||||
|  |                     continue | ||||||
|  |                 else: | ||||||
|  |                     splits.append(None) | ||||||
|  |             return splits | ||||||
|  | 
 | ||||||
|  |     def asdict(self): | ||||||
|  |         return { | ||||||
|  |             'id': self.id, | ||||||
|  |             'first': self.first, | ||||||
|  |             'last': self.last, | ||||||
|  |             'club_id': self.club_id, | ||||||
|  |             'club': self.club, | ||||||
|  |             'country': self.country, | ||||||
|  |             'card': self.card, | ||||||
|  |             'o_class_str': self.o_class_str, | ||||||
|  |             'fork' : self.fork, | ||||||
|  |             'start_time': self.start_time, | ||||||
|  |             'fee_id': self.fee_id | ||||||
|  |         } | ||||||
|  | 
 | ||||||
| class CardDump: | class CardDump: | ||||||
|     def __init__(self, card, controls, splits, read_time, s_time, f_time): |     def __init__(self, card, controls, splits, read_time, s_time, f_time): | ||||||
|         self.card = card |         self.card = card | ||||||
| @ -152,14 +216,19 @@ class CardDump: | |||||||
|             else: |             else: | ||||||
|                 s_time = read_time |                 s_time = read_time | ||||||
|                 f_time = read_time |                 f_time = read_time | ||||||
| 
 |  | ||||||
|             # Remove mtr from splits: |  | ||||||
|             if controls[-1] == 250: |  | ||||||
|                 controls.pop(-1) |  | ||||||
|                 splits.pop(-1) |  | ||||||
|             cards.append(CardDump(int(row[6]), controls, splits, read_time, s_time, f_time)) |             cards.append(CardDump(int(row[6]), controls, splits, read_time, s_time, f_time)) | ||||||
|         return cards |         return cards | ||||||
| 
 | 
 | ||||||
|  |     def asdict(self): | ||||||
|  |         return { | ||||||
|  |             'card': self.card, | ||||||
|  |             'controls': self.controls, | ||||||
|  |             'splits': self.splits, | ||||||
|  |             'read_time': self.read_time.isoformat(), | ||||||
|  |             's_time': self.s_time.isoformat(), | ||||||
|  |             'f_time': self.f_time.isoformat() | ||||||
|  |         } | ||||||
|  | 
 | ||||||
| # Stored in Event.courses | # Stored in Event.courses | ||||||
| class Course: | class Course: | ||||||
|     def __init__(self, name, codes, forked=False, variations=None): |     def __init__(self, name, codes, forked=False, variations=None): | ||||||
| @ -172,6 +241,14 @@ class Course: | |||||||
|     def __repr__(self): |     def __repr__(self): | ||||||
|         return f'name({self.name})' |         return f'name({self.name})' | ||||||
| 
 | 
 | ||||||
|  |     def asdict(self): | ||||||
|  |         return { | ||||||
|  |             'name': self.name, | ||||||
|  |             'codes': self.codes, | ||||||
|  |             'forked': self.forked, | ||||||
|  |             'variations': self.variations | ||||||
|  |         } | ||||||
|  | 
 | ||||||
| # Stored in Event.o_classes | # Stored in Event.o_classes | ||||||
| class OClass: | class OClass: | ||||||
|     def __init__(self, name, course): |     def __init__(self, name, course): | ||||||
| @ -188,7 +265,6 @@ class RunnerResult: | |||||||
|         self.first = first |         self.first = first | ||||||
|         self.last = last |         self.last = last | ||||||
|         self.club = club |         self.club = club | ||||||
|         self.club_id = club_id |  | ||||||
|         self.country = country |         self.country = country | ||||||
|         self.card_id = card_id |         self.card_id = card_id | ||||||
|         self.o_class = o_class |         self.o_class = o_class | ||||||
| @ -213,7 +289,7 @@ class ClassResult: | |||||||
|         self.runner_results = runner_results |         self.runner_results = runner_results | ||||||
| 
 | 
 | ||||||
| class Event: | class Event: | ||||||
|     def __init__(self, eventid=0, name=None, start_time=None, end_time=None, |     def __init__(self, eventid, name, start_time=None, end_time=None, | ||||||
|                  organiser=None, courses=[], o_classes=[], runners=[], |                  organiser=None, courses=[], o_classes=[], runners=[], | ||||||
|                  card_dumps=[], fees=[]): |                  card_dumps=[], fees=[]): | ||||||
|         self.id = eventid |         self.id = eventid | ||||||
| @ -384,6 +460,92 @@ class Event: | |||||||
|     def create_result_pdf(self, file_path): |     def create_result_pdf(self, file_path): | ||||||
|         pdf.create_result_list(copy.deepcopy(self), file_path) |         pdf.create_result_list(copy.deepcopy(self), file_path) | ||||||
| 
 | 
 | ||||||
|  |     def create_result_xml(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: | ||||||
|  |             print('Hmmmmmm') | ||||||
|  |             # <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 | ||||||
|  |             runners_sorted = [i for i in runners_same_c if i not in runners_ranked] | ||||||
|  |             runners_ranked.extend(runners_sorted) | ||||||
|  | 
 | ||||||
|  |             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', 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') | ||||||
|  | 
 | ||||||
|  |                 # TODO: Dette bør skrives om til å bruke Runner metoder så mye som mulig. | ||||||
|  |                 if hasattr(n, 'card_r') and len(n.card_r.splits) > 2: | ||||||
|  |                     xml_child(result, 'StartTime', n.card_r.s_time.isoformat()) | ||||||
|  |                     xml_child(result, 'FinishTime', n.card_r.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> | ||||||
|  |                         # TODO: ta utgangspunkt i løypa, ikke det brikka har stempla | ||||||
|  |                         for code, split in zip(n.card_r.controls, n.card_r.splits): | ||||||
|  |                             st = ET.SubElement(result, 'SplitTime') | ||||||
|  |                             xml_child(st, 'ControlCode', code) | ||||||
|  |                             xml_child(st, 'Time', split) | ||||||
|  |                             if code == n.res_codes()[-1]: | ||||||
|  |                                 break | ||||||
|  |                         # </SplitTime> | ||||||
|  |                     elif n.status() == 'Disqualified': | ||||||
|  |                         xml_child(result, 'Status', n.status()) | ||||||
|  |                         for code, split in zip(n.res_codes(), n.res_splits()): | ||||||
|  |                             st = ET.SubElement(result, 'SplitTime') | ||||||
|  |                             xml_child(st, 'ControlCode', code) | ||||||
|  |                             if split is not None: | ||||||
|  |                                 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 Fee: | class Fee: | ||||||
|     def __init__(self, fee_id, name, currency, amount, from_birth_date=None, |     def __init__(self, fee_id, name, currency, amount, from_birth_date=None, | ||||||
|                  to_birth_date=None): |                  to_birth_date=None): | ||||||
| @ -394,6 +556,16 @@ class Fee: | |||||||
|         self.from_birth_date = from_birth_date |         self.from_birth_date = from_birth_date | ||||||
|         self.to_birth_date = to_birth_date |         self.to_birth_date = to_birth_date | ||||||
| 
 | 
 | ||||||
|  |     def asdict(self): | ||||||
|  |         return { | ||||||
|  |             'id': self.id, | ||||||
|  |             'name': self.name, | ||||||
|  |             'currency': self.currency, | ||||||
|  |             'amount': self.amount, | ||||||
|  |             'from_birth_date': self.from_birth_date, | ||||||
|  |             'to_birth_date': self.to_birth_date | ||||||
|  |         } | ||||||
|  | 
 | ||||||
| def produce_class_result(event, o_class_name) -> ClassResult: | def produce_class_result(event, o_class_name) -> ClassResult: | ||||||
|     o_class = event.get_o_class(o_class_name) |     o_class = event.get_o_class(o_class_name) | ||||||
|     runners = event.get_runners_in_o_class(o_class_name) |     runners = event.get_runners_in_o_class(o_class_name) | ||||||
| @ -403,13 +575,13 @@ def produce_class_result(event, o_class_name) -> ClassResult: | |||||||
|     other_runners = [i for i in runners if i not in ok_runners and i not in dsq_runners] |     other_runners = [i for i in runners if i not in ok_runners and i not in dsq_runners] | ||||||
|      |      | ||||||
|     results = [RunnerResult(i.id, i.first, i.last, event.get_runner_status(i.id), ok_runners.index(i)+1, event.get_runner_time(i.id), event.get_runner_splits(i.id), |     results = [RunnerResult(i.id, i.first, i.last, event.get_runner_status(i.id), ok_runners.index(i)+1, event.get_runner_time(i.id), event.get_runner_splits(i.id), | ||||||
|                 event.get_runner_end_clock(i.id), i.club, i.country, i.card_id, i.o_class, event.get_runner_controls(i.id), start_time=event.get_card_dump(i.card_id).s_time) for i in ok_runners] |                 event.get_runner_end_clock(i.id), i.club, i.country, i.card_id, i.o_class, event.get_runner_controls(i.id)) for i in ok_runners] | ||||||
|     results += [RunnerResult(i.id, i.first, i.last, event.get_runner_status(i.id), 0, event.get_runner_time(i.id), event.get_runner_splits(i.id), |     results += [RunnerResult(i.id, i.first, i.last, event.get_runner_status(i.id), 0, event.get_runner_time(i.id), event.get_runner_splits(i.id), | ||||||
|                 event.get_runner_end_clock(i.id), i.club, i.country, i.card_id, i.o_class, event.get_runner_controls(i.id), start_time=event.get_card_dump(i.card_id).s_time) for i in dsq_runners] |                 event.get_runner_end_clock(i.id), i.club, i.country, i.card_id, i.o_class, event.get_runner_controls(i.id)) for i in dsq_runners] | ||||||
|     results += [RunnerResult(i.id, i.first, i.last, event.get_runner_status(i.id), 0, event.get_runner_time(i.id), event.get_runner_splits(i.id), |     results += [RunnerResult(i.id, i.first, i.last, event.get_runner_status(i.id), 0, event.get_runner_time(i.id), event.get_runner_splits(i.id), | ||||||
|                 event.get_runner_end_clock(i.id), i.club, i.country, i.card_id, i.o_class, event.get_runner_controls(i.id)) for i in other_runners] |                 event.get_runner_end_clock(i.id), i.club, i.country, i.card_id, i.o_class, event.get_runner_controls(i.id)) for i in other_runners] | ||||||
|      |      | ||||||
|     return ClassResult(o_class.name, event.get_course(o_class.course), results) |     return ClassResult(o_class.name, o_class.course, results) | ||||||
| 
 | 
 | ||||||
| # TODO: Take string instead of file. | # TODO: Take string instead of file. | ||||||
| def courses_from_ttime_conf(ttime_file): | def courses_from_ttime_conf(ttime_file): | ||||||
| @ -442,6 +614,96 @@ def classes_from_ttime_conf(ttime_file, courses): | |||||||
|                 loops += 1 |                 loops += 1 | ||||||
|     return o_classes |     return o_classes | ||||||
| 
 | 
 | ||||||
|  | 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 | ||||||
|  | 
 | ||||||
| # Checks if small list is in big list | # Checks if small list is in big list | ||||||
| def contains(small, big): | def contains(small, big): | ||||||
|     valid = True |     valid = True | ||||||
| @ -459,3 +721,18 @@ def contains(small, big): | |||||||
|         return map_bl |         return map_bl | ||||||
|     else: |     else: | ||||||
|         return False |         return False | ||||||
|  | 
 | ||||||
|  | def rank_runners(allrunners, o_class): | ||||||
|  |     runners = get_runners_in_class(allrunners, o_class) | ||||||
|  |     runners_ranked = [] | ||||||
|  |     for i in runners: | ||||||
|  |         if i.status() == 'OK': | ||||||
|  |             runners_ranked.append(i) | ||||||
|  |     runners_ranked.sort(key=lambda x: x.totaltime()) | ||||||
|  |     return runners_ranked | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # Used to make creating xml files easier | ||||||
|  | def xml_child(parent, tag, content): | ||||||
|  |     e = ET.SubElement(parent, tag) | ||||||
|  |     e.text = str(content) | ||||||
| @ -44,7 +44,7 @@ def create_split_result_list(event, file_path, o_classes=[]): | |||||||
|         col_width = pdf.epw / 4  # distribute content evenly |         col_width = pdf.epw / 4  # distribute content evenly | ||||||
| 
 | 
 | ||||||
|         for class_result in results: |         for class_result in results: | ||||||
|             col_width = pdf.epw / (21+len(class_result.course.codes)) |             col_width = pdf.epw / (21+len(class_result.course)) | ||||||
|             pdf.write(txt=class_result.name) |             pdf.write(txt=class_result.name) | ||||||
|             pdf.ln(line_height) |             pdf.ln(line_height) | ||||||
|             for runner in class_result.runner_results: |             for runner in class_result.runner_results: | ||||||
|  | |||||||
| @ -2,7 +2,6 @@ import sys | |||||||
| sys.path.insert(0, '../../otime') | sys.path.insert(0, '../../otime') | ||||||
| import otime | import otime | ||||||
| import pdf | import pdf | ||||||
| import iof_xml |  | ||||||
| 
 | 
 | ||||||
| def main(): | def main(): | ||||||
|     event = otime.Event(0, 'TEEEST', start_time=None, end_time=None,organiser='Tygbe') |     event = otime.Event(0, 'TEEEST', start_time=None, end_time=None,organiser='Tygbe') | ||||||
| @ -10,7 +9,6 @@ def main(): | |||||||
|     event.read_ttime_db('db.csv') |     event.read_ttime_db('db.csv') | ||||||
|     event.read_mtr_file('mtr.csv') |     event.read_mtr_file('mtr.csv') | ||||||
|     pdf.create_split_result_list(event, 'output/result.pdf') |     pdf.create_split_result_list(event, 'output/result.pdf') | ||||||
|     iof_xml.create_result_file(event, 'output/result.xml') |  | ||||||
|     print(event.get_runner_status('1400')) |     print(event.get_runner_status('1400')) | ||||||
|     results = event.get_result() |     results = event.get_result() | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user