diff --git a/ctf.css b/ctf.css index d3c033a..433b9c6 100644 --- a/ctf.css +++ b/ctf.css @@ -30,6 +30,49 @@ h1:first-child:before { content: "Capture The Flag: "; } +/*** left side bar ***/ + +#navigation { + position: fixed; + background: #222; + opacity: 0.9; + top: 80px; + left: 0px; + padding: 0; +} + +#navigation ul { + list-style: none; + padding: 0; + margin: 0; +} + +#navigation li a { + display: block; + height: 25px; + width: 90px; + padding: 5px; + margin: 5px; + background: inherit; + border-right: 4px solid #444; + color: #999; + text-transform: lowercase; + font-size: 0.9em; +} + +#navigation li a:hover { + color: #f4f4f4; + background: #333; + border-right: 4px solid #2a2; +} + +#navigation li .active { + color: #999; + background: #333; + border-right: 4px solid #444; +} + + /**** body ****/ a img { @@ -64,6 +107,18 @@ th, td { vertical-align: top; } +p { + line-height: 1.4em; + margin-bottom: 20px; + color: #f4f4f4; +} + +/**** special cases ****/ + +.wide { + max-width: inherit; +} + .scoreboard { background: #222; } @@ -72,24 +127,20 @@ th, td { height: 400px; } -p { - line-height: 1.4em; - margin-bottom: 20px; - color: #f4f4f4; -} - .solved { text-decoration: line-through; } table.pollster { - margin-left: 5em; + margin-left: 5em; } table.pollster td { - padding: 2px 1em 2px 5px; + padding: 2px 1em 2px 5px; } table.pollster thead { - font-weight: bold; + font-weight: bold; } + + diff --git a/ctf/config.py b/ctf/config.py index 65f9ae2..600aa7a 100755 --- a/ctf/config.py +++ b/ctf/config.py @@ -28,27 +28,33 @@ if 'home' in os.environ.get('SCRIPT_FILENAME', ''): } else: # An actual installation - config = {'global': - {'data_dir': '/var/lib/ctf', - 'base_url': '/', - 'css_url': '/ctf.css', - 'disabled_dir': '/var/lib/ctf/disabled', - 'flags_dir': '/var/lib/ctf/flags', - 'house_team': 'dirtbags', - 'passwd': '/var/lib/ctf/passwd', - 'team_colors': team_colors, - 'poll_interval': 60, - 'poll_timeout': 0.5, - 'heartbeat_dir': '/var/lib/pollster', - 'poll_dir': '/var/lib/www', - }, - 'puzzler': - {'dir': '/usr/lib/www/puzzler', - 'cgi_url': '/puzzler.cgi', - 'base_url': '/puzzler', - 'keys_file': '/usr/lib/ctf/puzzler.keys', - }, - } + config = { + 'global': + { + 'data_dir': '/var/lib/ctf', + 'base_url': '/', + 'css_url': '/ctf.css', + 'disabled_dir': '/var/lib/ctf/disabled', + 'flags_dir': '/var/lib/ctf/flags', + 'house_team': 'dirtbags', + 'passwd': '/var/lib/ctf/passwd', + 'team_colors': team_colors, + }, + 'pollster': + { + 'poll_interval': 60, + 'poll_timeout': 0.5, + 'heartbeat_dir': '/var/lib/pollster', + 'results': '/var/lib/pollster/status.html', + }, + 'puzzler': + { + 'dir': '/usr/lib/www/puzzler', + 'cgi_url': '/puzzler.cgi', + 'base_url': '/puzzler', + 'keys_file': '/usr/lib/ctf/puzzler.keys', + }, + } def get(section, key): return config[section][key] @@ -71,22 +77,37 @@ def datafile(filename): def url(path): return base_url + path -def start_html(title): +def start_html(title, hdr='', cls=''): + ret = [] if os.environ.get('GATEWAY_INTERFACE'): - print('Content-type: text/html') - print() - print(''' + ret.append('Content-type: text/html') + ret.append('') + ret.append('''
-