forked from Trygve/otime
La til import og eksport av json .otime filer
Alle import metoder og funksjoner tar nå filobjekter istedet for paths. Runner objektet bruker nå kwargs.
This commit is contained in:
parent
63f9e40fc6
commit
e11e25ea81
223
otime.py
223
otime.py
@ -1,20 +1,36 @@
|
||||
import copy
|
||||
import datetime
|
||||
import csv
|
||||
import re
|
||||
import json
|
||||
import xml.etree.ElementTree as ET
|
||||
from fpdf import FPDF
|
||||
|
||||
|
||||
# The event object stores all the event data.
|
||||
# A .otime file is just a pickle dump of an event object.
|
||||
# A .otime file is more or less just a json dump of the Event object.
|
||||
class Event:
|
||||
def __init__(self, eventid, name, **kwargs):
|
||||
self.id = eventid
|
||||
self.name = name
|
||||
|
||||
try:
|
||||
self.courses = kwargs['courses']
|
||||
except KeyError:
|
||||
self.courses = []
|
||||
|
||||
try:
|
||||
self.o_classes = kwargs['o_classes']
|
||||
except KeyError:
|
||||
self.o_classes = []
|
||||
|
||||
try:
|
||||
self.runners = kwargs['runners']
|
||||
except KeyError:
|
||||
self.runners = []
|
||||
|
||||
try:
|
||||
self.card_dumps = kwargs['card_dumps']
|
||||
except KeyError:
|
||||
self.card_dumps = []
|
||||
|
||||
def add_course(self, *args):
|
||||
@ -29,12 +45,16 @@ class Event:
|
||||
for n in args:
|
||||
self.runners.append(n)
|
||||
|
||||
def import_xml_entries(self, xml_file):
|
||||
self.add_runners(*runners_from_xml_entries(xml_file, self.o_classes))
|
||||
|
||||
def import_ttime_cnf(self, ttime_file):
|
||||
self.add_course(*courses_from_ttime_conf(ttime_file))
|
||||
ttime_file.seek(0)
|
||||
self.add_o_class(*classes_from_ttime_conf(ttime_file, self.courses))
|
||||
|
||||
def import_ttime_db(self, ttime_file):
|
||||
csvreader = csv.reader(open(ttime_file, 'r', encoding='latin_1'), delimiter=';',)
|
||||
csvreader = csv.reader(ttime_file, delimiter=';',)
|
||||
runnerarray = []
|
||||
for row in csvreader:
|
||||
if len(row) == 0 or row[1] == '':
|
||||
@ -46,10 +66,25 @@ class Event:
|
||||
self.card_dumps = CardDump.list_from_mtr_f(mtr_file)
|
||||
|
||||
def match_runners_cards(self):
|
||||
for n in self.runners:
|
||||
for i in self.card_dumps:
|
||||
if n.card == i.card:
|
||||
n.card_r = i
|
||||
for r in self.runners:
|
||||
for d in self.card_dumps:
|
||||
if r.card == d.card:
|
||||
r.card_r = d
|
||||
def match_runners_o_classes(self):
|
||||
for r in self.runners:
|
||||
for c in self.o_classes:
|
||||
if r.o_class_str == c.name:
|
||||
r.o_class = c
|
||||
|
||||
def match_o_classes_courses(self):
|
||||
for oc in self.o_classes:
|
||||
for c in self.courses:
|
||||
if oc.course_str == c.name:
|
||||
oc.course = c
|
||||
def match_all(self):
|
||||
self.match_runners_cards()
|
||||
self.match_runners_o_classes()
|
||||
self.match_o_classes_courses()
|
||||
|
||||
def get_xml_res(self):
|
||||
root = ET.Element('ResultList')
|
||||
@ -135,6 +170,54 @@ class Event:
|
||||
ET.indent(root, space=' ', level=0)
|
||||
return tree
|
||||
|
||||
def create_json_file(self):
|
||||
rdicts = []
|
||||
for runner in self.runners:
|
||||
rdicts.append(runner.asdict())
|
||||
|
||||
cdicts = []
|
||||
for course in self.courses:
|
||||
cdicts.append(course.asdict())
|
||||
|
||||
ocdicts = []
|
||||
for o_class in self.o_classes:
|
||||
ocdicts.append(o_class.asdict())
|
||||
|
||||
ddicts = []
|
||||
for dump in self.card_dumps:
|
||||
ddicts.append(dump.asdict())
|
||||
|
||||
json_data = {
|
||||
'id': self.id,
|
||||
'name': self.name,
|
||||
'runners': rdicts,
|
||||
'courses': cdicts,
|
||||
'o_classes': ocdicts,
|
||||
'card_dumps': ddicts
|
||||
}
|
||||
return json.dumps(json_data, sort_keys=True, indent=4)
|
||||
|
||||
# Get event object from .otime json file
|
||||
def from_json(f):
|
||||
data = json.load(f)
|
||||
runners = []
|
||||
for r in data['runners']:
|
||||
runners.append(Runner(r['id'], r['first'], r['last'], club_id=r['club_id'], club=r['club'], country=r['country'], card=r['card'], o_class_str=r['o_class_str'], fork=r['fork'],start_time=r['start_time']))
|
||||
|
||||
courses = []
|
||||
for c in data['courses']:
|
||||
courses.append(Course(c['name'], c['codes']))
|
||||
|
||||
o_classes = []
|
||||
for c in data['o_classes']:
|
||||
o_classes.append(OClass(c['name'], c['course_str'], None))
|
||||
|
||||
card_dumps = []
|
||||
for d in data['card_dumps']:
|
||||
card_dumps.append(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'])))
|
||||
|
||||
return Event(data['id'], data['name'], runners=runners, courses=courses, o_classes=o_classes, card_dumps=card_dumps)
|
||||
|
||||
def create_start_list_pdf(self, file_name):
|
||||
pdf = FPDF()
|
||||
pdf.add_page()
|
||||
@ -155,16 +238,52 @@ class Event:
|
||||
|
||||
# The runner object stores all the data specific to a runner.
|
||||
class Runner:
|
||||
def __init__(self, runner_id, first, last, club, club_id, country, card, o_class, start_time):
|
||||
def __init__(self, runner_id, first, last, **kwargs):
|
||||
self.id = runner_id
|
||||
self.first = first
|
||||
self.last = last
|
||||
self.club = club
|
||||
self.club_id = club_id
|
||||
self.country = country
|
||||
self.card = card
|
||||
self.o_class = o_class
|
||||
self.start_time = start_time
|
||||
try:
|
||||
self.club = kwargs['club']
|
||||
except KeyError:
|
||||
self.club = None
|
||||
|
||||
try:
|
||||
self.club_id = kwargs['club_id']
|
||||
except KeyError:
|
||||
self.club_id = None
|
||||
|
||||
try:
|
||||
self.country = kwargs['country']
|
||||
except KeyError:
|
||||
self.country = None
|
||||
|
||||
try:
|
||||
self.card = kwargs['card']
|
||||
except KeyError:
|
||||
self.card = 0
|
||||
|
||||
try:
|
||||
self.o_class_str = kwargs['o_class_str']
|
||||
except KeyError:
|
||||
self.o_class = None
|
||||
|
||||
try:
|
||||
self.o_class = kwargs['o_class']
|
||||
except KeyError:
|
||||
self.o_class = None
|
||||
|
||||
try:
|
||||
self.fork = kwargs['fork']
|
||||
except KeyError:
|
||||
self.fork = 0
|
||||
|
||||
try:
|
||||
self.start_time = kwargs['start_time']
|
||||
except KeyError:
|
||||
self.start_time = None
|
||||
|
||||
#self.o_class = o_class
|
||||
#self.start_time = start_time
|
||||
|
||||
def from_string(tt_line, o_classes):
|
||||
#https://web.archive.org/web/20191229124046/http://wiki.ttime.no/index.php/Developer
|
||||
@ -208,7 +327,9 @@ class Runner:
|
||||
start_time = options[options.index('U')+1]
|
||||
except:
|
||||
start_time = None
|
||||
return Runner(eventorid, first, last, club, club_id, country, card, runner_o_class, start_time)
|
||||
return Runner(eventorid, first, last, club=club, club_id=club_id,
|
||||
country=country, card=card, o_class_str=raw_class_str,
|
||||
o_class=runner_o_class, start_time=start_time)
|
||||
|
||||
def fullname(self):
|
||||
return '{} {}'.format(self.first, self.last)
|
||||
@ -244,7 +365,21 @@ class Runner:
|
||||
index = self.card_r.controls.index(control)
|
||||
split = self.card_r.splits[index]
|
||||
splits_cpy.remove(split)
|
||||
return splits_cpy
|
||||
return splits_cpy # list
|
||||
|
||||
def asdict(self):
|
||||
return {
|
||||
'id': self.id,
|
||||
'first': self.first,
|
||||
'last': self.last,
|
||||
'club_id': self.club_id,
|
||||
'club': self.club_id,
|
||||
'country': self.country,
|
||||
'card': self.card,
|
||||
'o_class_str': self.o_class_str,
|
||||
'fork' : self.fork,
|
||||
'start_time': self.start_time
|
||||
}
|
||||
|
||||
class CardDump:
|
||||
def __init__(self, card, controls, splits, read_time, s_time, f_time):
|
||||
@ -297,7 +432,7 @@ class CardDump:
|
||||
return(CardDump(card, controls, splits, read_time, s_time, f_time))
|
||||
|
||||
def list_from_mtr_f(mtr_f):
|
||||
csvreader = csv.reader(open(mtr_f))
|
||||
csvreader = csv.reader(mtr_f)
|
||||
|
||||
rows = []
|
||||
cards = []
|
||||
@ -333,7 +468,7 @@ class CardDump:
|
||||
tl[1][2] = float(tl[1][2])
|
||||
tl[1] = list(map(int, tl[1]))
|
||||
read_time = datetime.datetime(tl[0][2], tl[0][1], tl[0][0], tl[1][0], tl[1][1], tl[1][2])
|
||||
if len(controls) > 2:
|
||||
if len(controls) > 2 and len(splits) > 2:
|
||||
s_time = read_time - datetime.timedelta(seconds = splits[-1])
|
||||
f_time = read_time - (datetime.timedelta(seconds = splits[-1]) + datetime.timedelta(seconds = splits[-2]))
|
||||
else:
|
||||
@ -342,26 +477,61 @@ class CardDump:
|
||||
cards.append(CardDump(int(row[6]), controls, splits, read_time, s_time, f_time))
|
||||
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
|
||||
class Course:
|
||||
def __init__(self, name, codes):
|
||||
def __init__(self, name, codes, **kwargs):
|
||||
self.name = name
|
||||
self.codes = codes
|
||||
|
||||
try:
|
||||
forked = kwargs['forked']
|
||||
except KeyError:
|
||||
forked = False
|
||||
|
||||
try:
|
||||
variations = kwargs['variations']
|
||||
except KeyError:
|
||||
variations = None
|
||||
|
||||
def __repr__(self):
|
||||
return f'name({self.name})'
|
||||
|
||||
def asdict(self):
|
||||
return {
|
||||
'name': self.name,
|
||||
'codes': self.codes
|
||||
}
|
||||
|
||||
# Stored in Event.o_classes
|
||||
class OClass:
|
||||
def __init__(self, name, course):
|
||||
def __init__(self, name, course_str, course):
|
||||
self.name = name
|
||||
self.course_str = course_str
|
||||
self.course = course
|
||||
|
||||
def __repr__(self):
|
||||
return f'name({self.name})'
|
||||
|
||||
def asdict(self):
|
||||
return {
|
||||
'name': self.name,
|
||||
'course_str': self.course_str
|
||||
}
|
||||
|
||||
# TODO: Take string instead of file.
|
||||
def courses_from_ttime_conf(ttime_file):
|
||||
courses = []
|
||||
conf = open(ttime_file, 'r', encoding='latin_1').readlines()
|
||||
conf = ttime_file.readlines()
|
||||
for line in conf:
|
||||
if '-codes' in line:
|
||||
code_list = re.search(r'(?<=\")(.*?)(?=\")', line).group().split(';')
|
||||
@ -375,7 +545,7 @@ def courses_from_ttime_conf(ttime_file):
|
||||
|
||||
def classes_from_ttime_conf(ttime_file, courses):
|
||||
o_classes = []
|
||||
conf = open(ttime_file, 'r', encoding='latin_1').readlines()
|
||||
conf = ttime_file.readlines()
|
||||
for line in conf:
|
||||
if '-courses' in line:
|
||||
raw_courselist = re.search(r'(?<=\")(.*?)(?=\")', line).group().split(';')
|
||||
@ -383,7 +553,7 @@ def classes_from_ttime_conf(ttime_file, courses):
|
||||
for n in raw_courselist:
|
||||
split = n.split(',')
|
||||
for i in split:
|
||||
o_classes.append(OClass(i,courses[loops]))
|
||||
o_classes.append(OClass(i, courses[loops].name, courses[loops]))
|
||||
loops += 1
|
||||
return o_classes
|
||||
|
||||
@ -406,6 +576,7 @@ def runners_from_xml_entries(xml_file, o_classes=[]):
|
||||
card = int(person_root[3].text)
|
||||
except:
|
||||
card = 0
|
||||
runner_o_class = None
|
||||
try:
|
||||
xml_class_str = person_root[4][1].text
|
||||
except:
|
||||
@ -419,8 +590,10 @@ def runners_from_xml_entries(xml_file, o_classes=[]):
|
||||
# Gjør sånn at den lager nye o klasser om den ikke finnes fra før
|
||||
|
||||
start_time = None
|
||||
runnerarray.append(Runner(rid, first, last, club, club_id, country, card, runner_o_class, start_time))
|
||||
print(rid, first, last, club_id, club, card, xml_class_str)
|
||||
runnerarray.append(Runner(rid, first, last, club=club, club_id=club_id,
|
||||
country=country,card=card, o_class_str=xml_class_str,
|
||||
o_class=runner_o_class, start_time=start_time))
|
||||
#print(rid, first, last, club_id, club, card, xml_class_str)
|
||||
|
||||
return runnerarray
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user