mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-02 02:13:55 +00:00
First working version with new data in backend; Configurable columns; Leaderboard live still not working
This commit is contained in:
1 parent
2100945078
commit
995a2cd647
12 files changed
+119
-107
No files matched your search
@@ -58,6 +58,8 @@ class LiveDataReceiver(threading.Thread):
|
||||
try:
|
||||
# need to lock because other threads could overwrite information
|
||||
with lock:
|
||||
print >>sys.stderr, '*',
|
||||
sys.stderr.flush()
|
||||
updatecount = liveRaceInformation(conf)
|
||||
print >>sys.stderr, '.',
|
||||
sys.stderr.flush()
|
||||
@@ -76,7 +78,7 @@ class LiveDataReceiver(threading.Thread):
|
||||
continue
|
||||
|
||||
# avoid filling console with errors
|
||||
time.sleep(2)
|
||||
time.sleep(5)
|
||||
|
||||
# avoid hammering java server - can occur if call does not block correctly
|
||||
time.sleep(1)
|
||||
@@ -93,6 +95,7 @@ def eventConfiguration(configurator):
|
||||
events = jsonByUrl(configurator)
|
||||
|
||||
for event in events:
|
||||
# erroneous data
|
||||
if not event.has_key('boatclass'):
|
||||
continue
|
||||
|
||||
@@ -142,12 +145,11 @@ def eventConfiguration(configurator):
|
||||
|
||||
rcnames.sort(lambda x,y: cmp(x[1], y[1]))
|
||||
|
||||
# fill competitors with empty data
|
||||
# fill competitor ranks and leg values with empty data
|
||||
for cp in cobjects:
|
||||
races = [0.0 for r in range(raceindex)]
|
||||
|
||||
marks = cp.marks; values = cp.values;
|
||||
upordown = cp.upordownwind; additional = cp.additional
|
||||
marknames = cp.marknames
|
||||
|
||||
# update races and marks - support add operation
|
||||
@@ -162,15 +164,9 @@ def eventConfiguration(configurator):
|
||||
if len(marknames) < r+1:
|
||||
marknames.append([])
|
||||
|
||||
if len(upordown) < r+1:
|
||||
upordown.append([])
|
||||
|
||||
if len(values) < r+1:
|
||||
values.append([])
|
||||
|
||||
if len(additional) < r+1:
|
||||
additional.append([])
|
||||
|
||||
for m in range(len(rcmarks[r])):
|
||||
if len(marks[r]) < m+1:
|
||||
marks[r].append(0.0)
|
||||
@@ -178,14 +174,8 @@ def eventConfiguration(configurator):
|
||||
if len(marknames[r]) < m+1:
|
||||
marknames[r].append('')
|
||||
|
||||
if len(upordown[r]) < m+1:
|
||||
upordown[r].append(False)
|
||||
|
||||
if len(values[r]) < m+1:
|
||||
values[r].append([])
|
||||
|
||||
if len(additional[r]) < m+1:
|
||||
additional[r].append([])
|
||||
values[r].append({})
|
||||
|
||||
# recognize if races and/or marks changed
|
||||
if cp.races and len(cp.races) != len(races):
|
||||
@@ -194,7 +184,7 @@ def eventConfiguration(configurator):
|
||||
if cp.marks and len(cp.marks) != len(marks):
|
||||
log.error('Difference between marks for competitor %s found. Old: %s New: %s' % (cp.name, cp.marks, marks))
|
||||
|
||||
cp.update(dict(races=races, marks=marks, upordownwind=upordown, additional=additional, marknames=marknames))
|
||||
cp.update(dict(races=races, marks=marks, marknames=marknames))
|
||||
|
||||
# finally update event
|
||||
dbevent.update(dict(name=event['name'],
|
||||
@@ -252,12 +242,21 @@ def liveRaceInformation(configurator):
|
||||
# strange things can happen - make such errors visible
|
||||
raise Exception, 'Could not find competitor %s for event %s' % (competitor['name'], eventname)
|
||||
|
||||
# compute total rank for competitor
|
||||
c_current_rank = competitor.get('rank', 0)
|
||||
|
||||
# search thru ranks provided and use the
|
||||
# rank there as the current one
|
||||
if data.has_key('ranks'):
|
||||
for c in data['ranks']:
|
||||
if c['competitor'] == competitor['name']:
|
||||
c_current_rank = c['rank']
|
||||
break
|
||||
|
||||
c_races = comp.races
|
||||
c_marks = comp.marks
|
||||
c_values = comp.values
|
||||
c_total_rank = comp.total
|
||||
c_additional = comp.additional
|
||||
c_upordown = comp.upordownwind
|
||||
c_marknames = comp.marknames
|
||||
|
||||
# if competitor hasn't started yet we just ignore this leg
|
||||
@@ -305,55 +304,48 @@ def liveRaceInformation(configurator):
|
||||
current_legs[lcount] = 1
|
||||
|
||||
# now update values for the current position
|
||||
for key in config.SORTED_LEG_VALUE_NAMES:
|
||||
|
||||
# dynamically extend this one
|
||||
attr = config.LEG_VALUE_DATA[key]
|
||||
if len(c_values[raceindex][lcount]) < attr[0]+1:
|
||||
c_values[raceindex][lcount].append(0.0)
|
||||
|
||||
k = competitor.get(key, None)
|
||||
dc_leg_values = {}
|
||||
for key in competitor.keys():
|
||||
kvalue = competitor.get(key, None)
|
||||
|
||||
# treat nulled numbers as unset
|
||||
if k in [None, 'null', 'Null', 'nUlL', '']:
|
||||
k = 0.0
|
||||
if kvalue in [None, 'null', 'Null', 'nUlL', '']:
|
||||
kvalue = None
|
||||
|
||||
# check for cases where calculations from backend yield
|
||||
# strange numbers - this happens in cases where the competitor
|
||||
# has no speed during mark passing
|
||||
if k in ['Infinity', 'Infinite'] or float(k) > 150000.0:
|
||||
if isinstance(kvalue, (float, int)) and (kvalue in ['Infinity', 'Infinite'] or float(kvalue) > 150000.0):
|
||||
|
||||
# use a magic number (that is very unlikely to occur)
|
||||
# to indicate that competitor has no speed
|
||||
# hint: it is not the question it is the answer
|
||||
k = 42.260426041982
|
||||
kvalue = 42.260426041982
|
||||
|
||||
c_values[raceindex][lcount][attr[0]] = k
|
||||
dc_leg_values[key] = kvalue
|
||||
|
||||
if len(c_additional[raceindex][lcount]) == 0:
|
||||
c_additional[raceindex][lcount] = [0, 0]
|
||||
dc_leg_values['upOrDownWindLeg'] = leg['upordownwindleg']
|
||||
|
||||
c_additional[raceindex][lcount][0] = competitor['started']
|
||||
c_additional[raceindex][lcount][1] = competitor['finished']
|
||||
# compute gains and losses (places, )
|
||||
if legcount == 0:
|
||||
# for the first leg just put 0 into data
|
||||
dc_leg_values['gainsAndLossesInPlaces'] = 0
|
||||
else:
|
||||
# search for the last place
|
||||
last_rank_computed = c_marks[raceindex][lcount-1]
|
||||
if last_rank_computed > c_current_rank:
|
||||
dc_leg_values['gainsAndLossesInPlaces'] = c_current_rank - last_rank_computed
|
||||
else: dc_leg_values['gainsAndLossesInPlaces'] = last_rank_computed - c_current_rank
|
||||
|
||||
c_upordown[raceindex][lcount] = leg['upordownwindleg']
|
||||
c_values[raceindex][lcount] = dc_leg_values
|
||||
|
||||
# save marknames for the given leg
|
||||
c_marknames[raceindex][lcount] = (leg['from'], leg['to'])
|
||||
|
||||
# compute total rank for competitor
|
||||
rank = competitor.get('rank', 0)
|
||||
|
||||
# search thru ranks provided and use the
|
||||
# rank as the current one
|
||||
if data.has_key('ranks'):
|
||||
for c in data['ranks']:
|
||||
if c['competitor'] == competitor['name']:
|
||||
rank = c['rank']
|
||||
break
|
||||
|
||||
comp.update(dict(current_rank=rank,races=c_races, marks=c_marks, values=c_values,
|
||||
additional=c_additional, upordownwind=c_upordown,
|
||||
comp.update(dict(current_rank=c_current_rank,
|
||||
races=c_races,
|
||||
marks=c_marks,
|
||||
values=c_values,
|
||||
total=c_total_rank))
|
||||
|
||||
# next leg
|
||||
@@ -369,7 +361,7 @@ def liveRaceInformation(configurator):
|
||||
if data.get('wind'):
|
||||
mdup['wind_source'] = data['wind']['source']
|
||||
mdup['wind_bearing'] = data['wind']['truebearingdeg']
|
||||
mdup['wind_speed'] = data['wind']['knowspeed']
|
||||
mdup['wind_speed'] = data['wind']['knotspeed']
|
||||
|
||||
mdup['current_legs'] = current_legs.keys()
|
||||
dbrace.update(mdup)
|
||||
|
||||
@@ -26,7 +26,7 @@ class CompetitorImpl(ModelBase):
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def sortedBy(cls, eventname, raceindex=None, markindex=None, valueindex=None):
|
||||
def sortedBy(cls, eventname, raceindex=None, markindex=None, valueindex=None, columns=None):
|
||||
""" Returns competitors sorted by given index. If index
|
||||
is None no sorting is performed on this index. If all index
|
||||
params are None sorting is performed by total. """
|
||||
@@ -36,12 +36,9 @@ class CompetitorImpl(ModelBase):
|
||||
yval = y.total
|
||||
|
||||
if valueindex is not None:
|
||||
try:
|
||||
xval = x.values[raceindex][markindex][valueindex]
|
||||
yval = y.values[raceindex][markindex][valueindex]
|
||||
except IndexError:
|
||||
xval = 0.0
|
||||
yval = 0.0
|
||||
valuekey = columns[valueindex][-1]
|
||||
xval = x.values[raceindex][markindex].get(valuekey, 0.0)
|
||||
yval = y.values[raceindex][markindex].get(valuekey, 0.0)
|
||||
|
||||
elif markindex is not None:
|
||||
xval = x.marks[raceindex][markindex]
|
||||
|
||||
@@ -72,9 +72,7 @@ class Competitor(BaseDocument):
|
||||
'races' : [float, ],
|
||||
'marks' : [[float, ], ], # ranks for marks
|
||||
'marknames' : [[[unicode,] ]], # marknames for legs
|
||||
'upordownwind' : [[bool], ], # indicates wheter the leg is up or downwind
|
||||
'additional' : [[[float]]], # additional information regarding one leg (finished, started)
|
||||
'values' : [[[float, ]]]
|
||||
'values' : [[{}]] # values is a hashset that for each leg contains values
|
||||
}
|
||||
|
||||
indexes = [
|
||||
|
||||
@@ -141,7 +141,7 @@ class BaseView(object):
|
||||
def allCompetitorsFor(self, event):
|
||||
return model.CompetitorImpl.queryBy(event=event)
|
||||
|
||||
def competitorsSortedBy(self, eventname, sortparam):
|
||||
def competitorsSortedBy(self, eventname, sortparam, columnmode):
|
||||
param = sortparam
|
||||
if param == 'name':
|
||||
competitors = model.CompetitorImpl.sortedBy(eventname=eventname)
|
||||
@@ -156,7 +156,8 @@ class BaseView(object):
|
||||
if len(params) == 2:
|
||||
competitors = model.CompetitorImpl.sortedBy(eventname=eventname, raceindex=int(params[0])-1, markindex=int(params[1])-1)
|
||||
elif len(params) == 3:
|
||||
competitors = model.CompetitorImpl.sortedBy(eventname=eventname, raceindex=int(params[0])-1, markindex=int(params[1])-1, valueindex=int(params[2])-1)
|
||||
columns = self.configuredColumns(columnmode)
|
||||
competitors = model.CompetitorImpl.sortedBy(eventname=eventname, raceindex=int(params[0])-1, markindex=int(params[1])-1, valueindex=int(params[2])-1, columns=columns)
|
||||
|
||||
else:
|
||||
param = int(param.strip())
|
||||
@@ -164,6 +165,24 @@ class BaseView(object):
|
||||
|
||||
return competitors
|
||||
|
||||
def configuredColumns(self, modename):
|
||||
return config.COLUMN_MODE_NAMES.get(modename)
|
||||
|
||||
def displayLegValue(self, name, value):
|
||||
if isinstance(value, float) \
|
||||
and value == 42.260426041982:
|
||||
val = 'ANCH'
|
||||
else:
|
||||
if value in [None, 'None']:
|
||||
return ''
|
||||
|
||||
val = name[2] % value
|
||||
|
||||
if name[0] == 'ETASEC':
|
||||
val = '%.f:%.f' % (int(value) / 60, int(value)-( (int(value)/60)*60 ))
|
||||
|
||||
return val
|
||||
|
||||
def callFunction(context, request):
|
||||
""" Calls a function dynamically """
|
||||
|
||||
|
||||
@@ -497,36 +497,26 @@ def adminLiveData(context, request):
|
||||
t_up = threaded_listener.values()[0].last_update.strftime('%H:%M:%S')
|
||||
t_upcount = threaded_listener.values()[0].updatecount
|
||||
|
||||
columns = view.configuredColumns('TOP')
|
||||
|
||||
results = ''
|
||||
for pos in range(len(currentlegs)):
|
||||
legpos = currentlegs[pos]
|
||||
|
||||
results += '\nLAST SHOWRACE CALL: %s (UPCOUNT PARAM: %s)\nLEG: %s (FROM: %s TO: %s)\nRACE-START: %s NEWEST EVENT: %s WIND: (%s %s %s)\n' % (t_up, t_upcount, legpos+1, competitors[0].marknames[racepos][legpos][0], competitors[0].marknames[racepos][legpos][1], view.millisToDatetime(race.start), view.millisToDatetime(race.timeofnewestevent), race.wind_source, race.wind_bearing, race.wind_speed)
|
||||
results += 'NAME'.ljust(16) + 'TOTAL'.ljust(7) + 'CRANK'.ljust(7) + 'RRANK'.ljust(7)
|
||||
results += 'MRANK'.ljust(7) + 'LRANK'.ljust(9) + 'SPD'.ljust(9) + 'DSTTRV'.ljust(9) + 'VMG'.ljust(9) + 'AVMG'.ljust(9) + 'SGAP'.ljust(9) + 'ETA'.ljust(9) + 'DSTGO'.ljust(9) + 'STARTD'.ljust(9) + 'FINISHD'.ljust(9) + 'UPDOWNWIND'.ljust(12)
|
||||
results += 'MRANK'.ljust(7) + ''.join([title[0].ljust(9) for title in columns])
|
||||
results += '\n'
|
||||
|
||||
# sort competitors by rank in current leg
|
||||
competitors.sort(lambda x,y:cmp(x.values[racepos][legpos] and x.values[racepos][legpos][0] or 6000, y.values[racepos][legpos] and y.values[racepos][legpos][0] or 6000))
|
||||
competitors.sort(lambda x,y:cmp(x.values[racepos][legpos] and x.values[racepos][legpos].get('rank') or 6000, y.values[racepos][legpos] and y.values[racepos][legpos].get('rank') or 6000))
|
||||
|
||||
for c in competitors:
|
||||
results += '%s %s %s' % (c.name.ljust(15), str(c.total).ljust(6), str(c.current_rank).ljust(6))
|
||||
results += '%s %s' % (str(c.races[racepos]).ljust(7), str(c.marks[racepos][legpos]).ljust(7))
|
||||
|
||||
for v in c.values[racepos][legpos]:
|
||||
if v == 42.260426041982:
|
||||
results += 'ANCHOR'.ljust(9)
|
||||
else:
|
||||
results += str('%.2f' % v).ljust(9)
|
||||
|
||||
try:
|
||||
results += str(c.additional[racepos][legpos][0]).ljust(9)
|
||||
results += str(c.additional[racepos][legpos][1]).ljust(9)
|
||||
except:
|
||||
results += "N/A".ljust(9)
|
||||
results += "N/A".ljust(9)
|
||||
|
||||
results += str(c.upordownwind[racepos][legpos]).ljust(12)
|
||||
for v in columns:
|
||||
results += view.displayLegValue(v, c.values[racepos][legpos].get(v[-1])).ljust(9)
|
||||
|
||||
results += '\n'
|
||||
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
${event.races[repeat['race'].index]}<br/><b style="color: red;">${race}</b> »
|
||||
<tal:for repeat="mark cp.marks[repeat['race'].index]">
|
||||
<b>${mark}</b> »
|
||||
<tal:for repeat="value cp.values[repeat['race'].index][repeat['mark'].index]">
|
||||
<b style="color: green" tal:on-error="value">${'%.2f' % value}</b>|
|
||||
<tal:for repeat="value cp.values[repeat['race'].index][repeat['mark'].index].items()">
|
||||
<b style="color: green">${value[0]}:${value[1]}</b>|
|
||||
</tal:for>
|
||||
</tal:for>
|
||||
<br/>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<td valign="top">${cr.wind_source and cr.wind_source[:3] or 'EXP'}</td>
|
||||
<td valign="top">${cr.wind_bearing or ''}</td>
|
||||
<td valign="top">
|
||||
Current Leg(s): ${','.join(cr.current_legs)}<br/>
|
||||
Current Leg(s): ${cr.current_legs}<br/><br/>
|
||||
<tal:for repeat="markname event.marks[racepos]">
|
||||
${markname}<br/>
|
||||
</tal:for>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
<div class="info">
|
||||
<div class="info" tal:define="columns view.configuredColumns('LEADERBOARD-STATIC')">
|
||||
<div tal:repeat="event view.allEvents()">
|
||||
<table width="100%">
|
||||
<tr>
|
||||
@@ -10,8 +10,8 @@
|
||||
<td style="color:white;font-size: 18px;font-weight: bold;background-color: #DE8A2E;">R${repeat['race'].number} (${race})</td>
|
||||
<tal:for repeat="mark event.marks[repeat['race'].index]">
|
||||
<td style="color:white;font-size: 14px;font-weight: bold;background-color: #95AA31;">R${repeat['race'].number}M${repeat['mark'].number}</td>
|
||||
<tal:for repeat="value ['Rank', 'AvgSpeed', 'DstTrav', 'Vel', 'AvgVel', 'Gap', 'EstNxt', 'DstToGo']">
|
||||
<td style="color: white;background-color: #FEC631">${value}</td>
|
||||
<tal:for repeat="value columns">
|
||||
<td style="color: white;background-color: #FEC631">${value[0]}</td>
|
||||
</tal:for>
|
||||
</tal:for>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
</tal:for>
|
||||
</tr>
|
||||
|
||||
<tal:for repeat="cp view.competitorsSortedBy(eventname=request.params.get('eventname'), sortparam=request.params.get('sortname'))">
|
||||
<tal:for repeat="cp view.competitorsSortedBy(eventname=request.params.get('eventname'), sortparam=request.params.get('sortname'), columnmode='LEADERBOARD-STATIC')">
|
||||
<tr>
|
||||
<td valign="top">${cp.total or 0}</td>
|
||||
<td valign="top">${cp.name}</td>
|
||||
@@ -31,8 +31,8 @@
|
||||
<td style="color:white;font-size: 18px;font-weight: bold;background-color: #DE8A2E;">${cp.races[repeat['race'].index]}</td>
|
||||
<tal:for repeat="mark event.marks[repeat['race'].index]">
|
||||
<td style="color:white;font-size: 14px;font-weight: bold;background-color: #95AA31;">${cp.marks[repeat['race'].index][repeat['mark'].index]}</td>
|
||||
<tal:for repeat="value ['Rank', 'AvgSpeed', 'DstTrav', 'Vel', 'AvgVel', 'Gap', 'EstNxt', 'DstToGo']">
|
||||
<td style="color:white;background-color: #FEC631"><b tal:on-error="string:">${'%.2f' % cp.values[repeat['race'].index][repeat['mark'].index][repeat['value'].index]}</b></td>
|
||||
<tal:for repeat="name columns">
|
||||
<td style="color:white;background-color: #FEC631"><b tal:on-error="string:">${view.displayLegValue(name, cp.values[repeat['race'].index][repeat['mark'].index].get(name[-1]))}</b></td>
|
||||
</tal:for>
|
||||
</tal:for>
|
||||
|
||||
|
||||
@@ -4,10 +4,6 @@
|
||||
<div>
|
||||
<input type="button" value="Pause" onclick="$(this).attr('value', togglePauseLive())"/>
|
||||
|
||||
<div id="live-data-bar" style="height: 30px;">
|
||||
|
||||
</div>
|
||||
|
||||
<pre id="live-data-receiver" style="font-size:11px;height:1630px; width: 1024px;">
|
||||
|
||||
</pre>
|
||||
@@ -30,12 +26,10 @@
|
||||
|
||||
function refreshLive() {
|
||||
if (paused_live == false) {
|
||||
displayLoader('#live-data-bar');
|
||||
GET('adminLiveData', {}, function(data) {
|
||||
$('#live-data-receiver').fadeTo('normal', 0.1, function() {
|
||||
$('#live-data-receiver').html(data);
|
||||
$('#live-data-receiver').fadeTo('fast', 1.0);
|
||||
$('#live-data-bar').html(' ');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -27,18 +27,32 @@ LIST_WIND_TRACKERS = 'listwindtrackers'
|
||||
STOP_EXP_WIND = 'stopreceivingexpeditionwind'
|
||||
START_EXP_WIND = 'receiveexpeditionwind'
|
||||
|
||||
# keys for competitor board leg values
|
||||
LEG_VALUE_DATA = {
|
||||
'rank': [0, ],
|
||||
'averageSpeedOverGroundInKnots': [1, ],
|
||||
'distanceTraveledOverGroundInMeters': [2, ],
|
||||
'velocityMadeGoodInKnots': [3, ],
|
||||
'averageVelocityMadeGoodInKnots': [4, ],
|
||||
'gapToLeaderInSeconds': [5, ],
|
||||
'estimatedTimeToNextMarkInSeconds': [6, ],
|
||||
'windwardDistanceToGoInMeters' : [7, ],
|
||||
VN = {
|
||||
'CSPDKNOT': ('CSPEEDKN', 'Current Speed (kn)', '%.1f', 'currentSpeedOverGroundInKnots'),
|
||||
'CSPDMS' : ('CSPDMS', 'Current Speed (m/s)', '%.1f', 'currentSpeedOverGroundInMetersPerSecond'),
|
||||
'ASPDKNOT': ('ASPDKN', 'Avg Speed (kn)', '%.1f', 'averageSpeedOverGroundInKnots'),
|
||||
'ASPDMS' : ('ASPDMS', 'Avg Speed (m/s)', '%.1f', 'averageSpeedOverGroundInMetersPerSecond'),
|
||||
'DSTTRV' : ('DSTTRV', 'Distance Travelled (m)', '%.f', 'distanceTraveledOverGroundInMeters'),
|
||||
'VMGKNOT': ('VMGKN', 'VMG (kn)', '%.1f', 'velocityMadeGoodInKnots'),
|
||||
'VMGMS' : ('VMGMS', 'VMG (m/s)', '%.1f', 'velocityMadeGoodInMetersPerSecond'),
|
||||
'AVMGKNOT': ('AVMGKN', 'Avg VMG (kn)', '%.1f', 'averageVelocityMadeGoodInKnots'),
|
||||
'AVMGMS' : ('AVMGMS', 'Avg VMG (m/s)', '%.1f', 'averageVelocityMadeGoodInMetersPerSecond'),
|
||||
'ETA' : ('ETASEC', 'ETA (sec.)', '%.f', 'estimatedTimeToNextMarkInSeconds'),
|
||||
'DSTGO' : ('DSTGO', 'Distance To Go (m)', '%.f', 'windwardDistanceToGoInMeters'),
|
||||
'GAPSEC' : ('SGAP', 'Gap To Leader (sec)', '%.1f','gapToLeaderInSeconds'),
|
||||
'UPDOWNWIND' : ('UPDOWN', 'Up or Downwind?', '%s', 'upOrDownWindLeg'),
|
||||
'GLP' : ('GLP', 'Gains and Losses (Places)', '%s', 'gainsAndLossesInPlaces'),
|
||||
'RANK' : ('LRANK', 'Rank', '%s', 'rank'),
|
||||
'STARTED' : ('STARTD', 'Started?', '%s','started'),
|
||||
'FINISHED' : ('FINISHD', 'Finished?', '%s','finished')
|
||||
}
|
||||
|
||||
SORTED_LEG_VALUE_NAMES = LEG_VALUE_DATA.keys()
|
||||
SORTED_LEG_VALUE_NAMES.sort(lambda x,y: cmp(LEG_VALUE_DATA[x][0], LEG_VALUE_DATA[y][0]))
|
||||
COLUMN_MODE_NAMES = {
|
||||
'TOP':
|
||||
[VN['RANK'], VN['CSPDKNOT'], VN['ASPDKNOT'], VN['DSTTRV'], VN['VMGKNOT'], VN['DSTGO'], VN['ETA'], VN['STARTED'], VN['FINISHED'], VN['UPDOWNWIND']],
|
||||
'LEADERBOARD-STATIC':
|
||||
[VN['RANK'], VN['CSPDMS'], VN['DSTTRV'], VN['VMGMS'], VN['GLP']],
|
||||
'LEADERBOARD-F1':
|
||||
[VN['RANK'], VN['GAPSEC'], VN['ASPDMS'], VN['DSTTRV'], VN['GLP']]
|
||||
}
|
||||
|
||||
@@ -18,6 +18,14 @@ username =
|
||||
password =
|
||||
collections = events races competitors
|
||||
|
||||
[winddb]
|
||||
host = localhost
|
||||
port = 10200
|
||||
dbname = winddb
|
||||
username =
|
||||
password =
|
||||
collections = WIND_TRACKS
|
||||
|
||||
[biography]
|
||||
host = ${conf:mongodb_host}
|
||||
port = ${conf:mongodb_port}
|
||||
|
||||
Reference in new issue
Block a user