#!/usr/bin/python
# Defcon 19 CTF quals scores graph script from html scoreboards
# Usage: python graph.py
import glob, re, time
from operator import itemgetter
from hashlib import sha1

teams, topteams = {}, []
processed = []
for filename in sorted(glob.glob("scoreboard_*")):
  h = sha1(open(filename,'r').read()).hexdigest()
  if h not in processed: # do not process duplicate scoreboards
    processed.append(h)
    m = re.match('scoreboard_([0-9_-]+)', filename)
    date = time.strftime('%Y %b %d %H:%M:%S', time.localtime(int(m.group(1))/1000))
    topteams = []
    for tp in re.findall(">([^<]+)<", open(filename,'r').read())[1:]:
        m = re.match('(.*?) \(([0-9]+)\)', tp)
        team, points = m.group(1), int(m.group(2))
        if team not in teams:
          teams[team] = []
        teams[team].append([date, points])
        topteams.append(team)

# prepare flot javascript data
i,o = 1,[]
for team in topteams:
  t  = '"%i": {\n' % i
  t += '  label: "%i. %s",\n' % (i, team)
  t += '  data: %s\n' % repr(teams[team])
  t += '}'
  o.append(t)
  i += 1

maxpoints = max(max(points for date, points in teams[team]) for team in teams)

print """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Defcon 19 CTF quals - Top 15 Graph</title>
    <!--[if IE]><script language="javascript" type="text/javascript" src="flot/excanvas.min.js"></script><![endif]-->
    <script language="javascript" type="text/javascript" src="flot/jquery.js"></script>
    <script language="javascript" type="text/javascript" src="flot/jquery.flot.js"></script>
 </head>
    <body>
    <h1><a href="http://quals.ddtek.biz">Defcon 19 CTF quals</a> - Top 15 Graph</h1>

    <div id="placeholder" style="width:1024px;height:500px;"></div>
    <div id="legendholder" style="width:200px;"></div>
    <p id="choices">Show:</p>

<script id="source" language="javascript" type="text/javascript">
$(function () {
    var datasets = {
""" + ','.join(o) + """
    };

    // hard-code color indices to prevent them from shifting as
    // countries are turned on/off
    var i = 0;
    $.each(datasets, function(key, val) {
        val.color = i;
        ++i;
        // fix up dates since i didn't preprocess enough
        $.each(val.data, function(the_time,the_score) {
                val.data[the_time][0] = new Date(val.data[the_time][0]).getTime();
            });
    });

    // insert checkboxes
    var choiceContainer = $("#choices");
    var legendContainer = $("#legendholder");
    $.each(datasets, function(key, val) {
        choiceContainer.append('<br/><input type="checkbox" name="' + key +
                               '" checked="checked" id="id' + key + '">' +
                               '<label for="id' + key + '">'
                                + val.label + '</label>');
    });
    choiceContainer.find("input").click(plotAccordingToChoices);


    function plotAccordingToChoices() {
        var data = [];

        choiceContainer.find("input:checked").each(function () {
            var key = $(this).attr("name");
            if (key && datasets[key])
                data.push(datasets[key]);
        });

        if (data.length > 0)
            $.plot($("#placeholder"), data, {
                xaxis: { mode:"time",timeformat:"%dth %H\\n"},
                yaxis: { min:0, max: """ + str(maxpoints*1.1) + """ },
                legend: { position:"ne", container:legendContainer}
            });
    }

    plotAccordingToChoices();
});
</script>

<p style='font-size: small; text-align: center;'>

Made using a <a href="http://stalkr.net/files/defcon/2011/quals/board/java_client_scoreboard.tar.bz2">java client</a> based on the
<a href="http://stalkr.net/files/defcon/2011/quals/board/quals.jar">board applet</a> to regularily
<br />save top 15 (see <a href="http://stalkr.net/files/defcon/2011/quals/board/scoreboards.tar.bz2">archived html scoreboards</a>),
and a <a href="http://stalkr.net/files/defcon/2011/quals/board/graph.py">python script</a> to create a 
<a href="http://code.google.com/p/flot/">flot</a> graph.
<br />
Unfortunately no data for the last 1h40 except at the end because ddtek's DNS were changed to playboy's.
<br />
Also see last year's quals <a href="http://stalkr.net/files/defcon/2010/quals/board/graph.htm">graph</a>
<br />
Inspired from <a href="http://shallweplayaga.me">shallweplayaga.me</a>'s <a href="http://shallweplayaga.me/graph.html">Defcon graphs</a>
</p> 

</p>

 </body>
</html>"""
