#!/usr/bin/python
import sys, os, stat, glob
import config
all_teams = config.all_teams
team_names = config.team_names
template = """
Results for map %(mapname)s
Results for %(mapname)s
%(map_download)s
Initial score: %(init_score).2f
%(log_download)s
%(table)s
"""
class TeamEntry(object):
def __init__(self, team, mapdata):
self.id = team
self.name = team_names[team]
self.map = mapdata
self.dir = os.path.join(self.map.path, team)
self.running = True
self.init_score = None
self.final_score = 0.0
self.last_score = 0.0
self.scores = None
self.max_time = 0
self.rank = -1
self.jlog= None
self.full_log=None
if self.valid():
for line in open(os.path.join(self.dir, "init-score.txt")):
self.init_score = float(line.strip())
for line in open(os.path.join(self.dir, "scores.txt")):
self.scores = [float(s) for s in line.split()]
self.last_score = self.scores[-1]
try:
for line in open(os.path.join(self.dir, "final-score.txt")):
self.final_score = float(line.strip())
self.running = False
except:
pass
self.max_time = len(self.scores) - 1
try:
self.full_log=self.get_logfile(self.map.mapname)[1]
self.jlog=self.get_jlogfile(self.map.mapname)[1]
except:
pass
def valid(self):
if not os.path.exists(self.dir):
return False
return True
def get_logfile(self, mapdir):
# files = glob.glob(os.path.join(mapdir, "*-%s*.gz" % self.name))
files = glob.glob(os.path.join(mapdir, "*-%s*.7z" % self.name))
if len(files) != 1:
#Can't identify team logfile
raise KeyError
size = os.stat(files[0])[stat.ST_SIZE]
return (size, files[0])
def get_jlogfile(self, mapdir):
files = glob.glob(os.path.join(mapdir, "*-%s*.jlog.zip" % self.name))
if len(files) != 1:
#Can't identify team logfile
raise KeyError
size = os.stat(files[0])[stat.ST_SIZE]
return (size, files[0])
def get_screenshots(self):
times = list(self.map.get_screenshot_timepoints())
for t in times[:-1]:
path = os.path.join(self.dir, "snapshot-%d.png" % t)
tn_path = os.path.join(self.dir, "snapshot-%d-tn.jpg" % t)
if os.path.exists(path) and t <= self.max_time:
yield(t, path, tn_path, self.scores[t])
else:
yield(t, None, None, None)
if self.max_time != self.map.turns:
#final snapshot would not correspond to others - don't use it
yield(self.max_time, None, None, None)
else:
path = os.path.join(self.dir, "snapshot-final.png")
tn_path = os.path.join(self.dir, "snapshot-final-tn.jpg")
yield(self.max_time, path, tn_path, self.scores[self.max_time])
class MapData(object):
def __init__(self, mapname, teams=None):
self.mapname = mapname
self.teamdict = None
self.entries = []
self.init_score = -1
self.turns = -1
self.path = None
self.started = False
if os.path.exists("%s-eval" % mapname):
self.path = "%s-eval" % mapname
elif os.path.exists(os.path.join(mapname, "plot-%s.svg" % mapname)):
self.path = mapname
elif os.path.exists("plot-%s.svg" % mapname):
self.path = "."
else:
print >> sys.stderr, "Couldn't find eval directory for map %s." % mapname
return
used_teams = teams if teams else all_teams
for t in used_teams:
try:
entry = TeamEntry(t, self)
if entry.valid():
self.entries.append(entry)
self.init_score = entry.init_score
self.turns = max(self.turns, entry.max_time)
elif teams is not None:
self.entries.append(entry)
except:
print >> sys.stderr, "Couldn't find eval directory for map %s team %s." % (mapname,t)
return
for t in self.entries:
if t.max_time != self.turns:
t.final_score = 0.0
sorted_by_score = sorted(self.entries, key=lambda t: -t.final_score)
if sorted_by_score[0].last_score != 0.0:
self.started = True
i = 1
prev_score = -1
prev_teams = []
for t in sorted_by_score:
# print >> sys.stderr, t.final_score, prev_score, i
if t.final_score != prev_score:
prev_teams = []
for prev in prev_teams:
prev.rank = i
t.rank = i
prev_teams.append(t)
prev_score = t.final_score
i += 1
self.step_ranking(self.entries)
# for i, t in enumerate(sorted_by_score):
# t.rank = i+1
def step_ranking(self, entries):
sorted_by_score = sorted(entries, key=lambda t: -t.final_score)
best = sorted_by_score[0].final_score
n = len(entries)
delta = best/(2.0*n)
def get_upper_bound(t):
score = best
upper = 2*n
while score > t.final_score:
score -= delta
upper -= 1
return upper + 1
prev_rank = 2*n
prev_score = sorted_by_score[0].final_score
sorted_by_score[0].rank = 2*n
for t in sorted_by_score[1:]:
upper = get_upper_bound(t)
if prev_score == t.final_score:
t.rank = prev_rank
elif upper >= prev_rank:
t.rank = prev_rank - 1
else:
t.rank = upper
if t.rank < 1:
t.rank = 1
prev_rank = t.rank
prev_score = t.final_score
def get_team(self, id):
if self.teamdict is None:
self.teamdict = dict((t.id, t) for t in self.entries)
return self.teamdict[id]
def get_screenshot_timepoints(self):
t = 50
while t < self.turns:
yield t
t += 50
yield self.turns
def get_mapfile(self):
names = ["%s.7z" % self.mapname, "%s-map.tar.gz" % self.mapname, "%s-map.tgz" % self.mapname, "%s.tgz" % self.mapname, "%s.tar.gz" % self.mapname]
for fname in names:
if os.path.exists(fname):
size = os.stat(fname)[stat.ST_SIZE]
return size, fname
return 0, None
def get_logpackage(self):
path = "%s-logs.7z" % self.mapname
descent = 3
while not os.path.exists(path) and descent > 0:
path = os.path.join("..", path)
descent -= 1
if not os.path.exists(path):
return 0, None
size = os.stat(path)[stat.ST_SIZE]
return size, path
def sizeof_fmt(num):
for x in ['bytes','KB','MB','GB','TB']:
if num < 1024.0:
return "%3.1f%s" % (num, x)
num /= 1024.0
def list_to_row(l, elem='td'):
elems, classes = l
if classes:
cl_string = 'class="%s"' % ", ".join(classes)
else:
cl_string = ""
delim = "%s><%s>" % (elem, elem)
return "<%s>" % (cl_string, elem) + delim.join(elems) + "%s>
" % elem
if __name__ == '__main__':
mapname = sys.argv[1]
data = MapData(mapname)
init_score = data.init_score
pack_size, pack_path = data.get_logpackage()
log_download = ""
if pack_path:
archive_url = "http://sourceforge.net/projects/roborescue/files/logs/2011/%s/%s-all.tar" % (mapname, mapname)
log_download = 'Download all logs (Size: %s)' % (archive_url, sizeof_fmt(pack_size))
map_size, map_path = data.get_mapfile()
map_download = ""
if map_path:
map_download = 'Download map (Size: %s)' % (map_path, sizeof_fmt(map_size))
sorted_by_rank = sorted(data.entries, key=lambda t: -t.rank)
def make_table_row(team, count):
classes = []
if team == sorted_by_rank[0]:
classes.append("first")
elif team == sorted_by_rank[1]:
classes.append("second")
elif team == sorted_by_rank[2]:
classes.append("third")
if team.final_score == team.last_score:
result = [team.name, "%.6f" % team.final_score, "%d" % team.rank]
else:
result = [team.name, "%.6f" % team.last_score, "%d" % team.rank]
for t, path, tn_path, score in team.get_screenshots():
if path:
html = '
%.4f' % (path, tn_path, t, score)
else:
html = ''
result.append(html)
if config.add_downloads and team.valid():
try:
size, log = team.get_logfile(data.path)
jsize, jlog = team.get_jlogfile(data.path)
# log_url = log
# log_url = "http://sourceforge.net/projects/roborescue/files/%s/%s/%s/download" % (config.log_location, data.mapname, log)
log_url = "%s" % (log)
jlog_url= "../viewer/?jlog=../%s/%s&full_log=../%s/%s"%(mapname,jlog,mapname,log_url)
# log_url = "http://sourceforge.net/projects/roborescue/files/logs/2011/%s" % log
result += ['View Simulation (%s)
Download Simulation (%s)' % (jlog_url,sizeof_fmt(jsize), log_url, sizeof_fmt(size))]
except KeyError:
pass
else:
result.append("")
#result += [""] * (count - len(result))
return result, classes
headers = ["Team", "Score", "Points"]
headers += ["%d" % t for t in data.get_screenshot_timepoints()]
headers.append("Logfile")
table = ''
table += list_to_row((headers, None), "th")
for t in data.entries:
table += list_to_row(make_table_row(t, len(headers))) + "\n"
table += "