From 725198e4c981292fb938f74b359214eee007d666 Mon Sep 17 00:00:00 2001 From: User <> Date: Wed, 13 Mar 2019 19:42:40 +0100 Subject: [PATCH] rename files, generate SVG page without XML --- generate-html.py | 62 +++++++++++++++++++++++++++++++++ generate-svg.py | 82 -------------------------------------------- index.html | 11 ------ parse.py | 73 --------------------------------------- style.css => svg.css | 0 template.html | 31 +++++++++++++++++ 6 files changed, 93 insertions(+), 166 deletions(-) create mode 100644 generate-html.py delete mode 100644 generate-svg.py delete mode 100644 index.html delete mode 100644 parse.py rename style.css => svg.css (100%) create mode 100644 template.html diff --git a/generate-html.py b/generate-html.py new file mode 100644 index 0000000..92724c4 --- /dev/null +++ b/generate-html.py @@ -0,0 +1,62 @@ +from json import loads +from datetime import datetime +from re import compile + +# scale down coordinates to dx=1 per day to prevent SVG coordinate overflows +scale = 1/60/60/24 + +def get_date(dtime): + return datetime.fromtimestamp(dtime).strftime('%Y-%m-%d %H:%M') + +def make_line(event): + evstart = event['period'][0] + evstop = event['period'][1] + return '{text} ({start_date} — {stop_date})'.format( + type = '' if event['status'] == 'online' else ' class="error"', + start = scale*evstart, + stop = scale*evstop, + start_date = get_date(evstart), + stop_date = get_date(evstop), + height = len(event['players']) if 'players' in event else 0, + text = ('no one' if len(event['players']) == 0 else ', '.join(event['players'])) if event['status'] == 'online' else event['status'] + ) + +def get_lines(start,stop): + lines = [] + find_start = compile(r'x1="([0-9.]+)"') + find_stop = compile(r'x2="([0-9.]+)"') + with open('events.log', 'r') as fin: + for l in fin: + evstart = float(find_start.search(l).group(1)) + evstop = float(find_stop.search(l).group(1)) + + if evstop > start and evstart < stop: + lines.append(l) + with open('current-state.json', 'r') as fin: + lines.append(make_line(loads(fin.read()))) + + return lines + +def make_html(name,period): + stop = scale*datetime.now().timestamp() + start = stop-period + lines = get_lines(start, stop) + display_scale = 24*60/10 # 1 pixel per 10 minutes + with open('template.html', 'r') as fin: + with open(name+'.html', 'w') as fout: + fout.write(fin.read().format( + outer_width = display_scale*period+10, + inner_width = display_scale*period, + start = start, + period = period, + day_start = scale*datetime.fromtimestamp(start/scale).replace(hour=0,minute=0,second=0,microsecond=0).timestamp(), + day_stop = stop, + events = ''.join(lines) + )) + +def make_htmls(): + make_html('day', 1) + make_html('month', 31) + make_html('4months', 120) + +make_htmls() diff --git a/generate-svg.py b/generate-svg.py deleted file mode 100644 index 2aaea9b..0000000 --- a/generate-svg.py +++ /dev/null @@ -1,82 +0,0 @@ -from json import loads -from xml.etree.ElementTree import Element, tostring -from datetime import datetime - -def readEvents(): - events = [] - with open('events.json', 'r') as f: - for line in f: - events.append(loads(line)) - - with open('current-state.json', 'r') as f: - events.append(loads(f.read())) - - return events - -def getSVG(events): - scale = 1/60/60/24 - period = 3*30 *60*60*24 - end = datetime.now().timestamp() - start = end-period -# start = events[0]['period'][0] -# end = events[-1]['period'][1] - root = Element('svg', { - 'version': '1.1', - 'xmlns': 'http://www.w3.org/2000/svg', - 'viewBox': '0 0 {} 200'.format(scale*period*200), - 'width': str(scale*period*200), - 'height': '200', - }) - group = Element('svg', { - 'viewBox': '{} 0 {} 10'.format(scale*start,scale*period), - 'width': '100%', - 'height': '100%', - 'preserveAspectRatio': 'none' - }) - - for i in range(0,10+1): - num = Element('text', { - 'x': str(scale*period*200-20), - 'y': str((1-i/10)*200) - }) - num.text = str(i) - root.append(num) - root.append(group) - - for event in events: - evstart = event['period'][0] - evend = event['period'][1] - - if evend < start or evstart > end: - continue - - props = { 'x1': str(scale*evstart), 'x2': str(scale*evend), 'y1': '0', 'y2': '0' } - titletext = 'unknown' - - if 'players' in event: - y = str(len(event['players'])) - props['y1'] = y - props['y2'] = y - if len(event['players']) == 0: - titletext = '(no one)' - else: - titletext = ', '.join(event['players']) - - if event['type'] == 'error': - props['class'] = 'error' - titletext = 'error' - - ev = Element('line', props) - title = Element('title') - title.text = '{} ({} — {})'.format(titletext, datetime.fromtimestamp(evstart).strftime('%Y-%m-%d %H:%M'), datetime.fromtimestamp(evend).strftime('%Y-%m-%d %H:%M')) - ev.append(title) - group.append(ev) - - return root - -def dumpHTML(arg): - with open('index.html', 'r') as f: - html = f.read() - print( html.format(arg) ) - -dumpHTML(tostring(getSVG(readEvents()), encoding='unicode')) diff --git a/index.html b/index.html deleted file mode 100644 index 6ad6dd5..0000000 --- a/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - {} - - - diff --git a/parse.py b/parse.py deleted file mode 100644 index 34b67a0..0000000 --- a/parse.py +++ /dev/null @@ -1,73 +0,0 @@ -from json import loads, dumps - -events = [] - -def doOffline(state, cur_t, cur_ps): - (last_t, last_ev, last_evt, last_ps) = state - working = (cur_t - last_t < 70) - - if not working and last_ev == 'online': - events.append({'period': [last_evt, last_t], 'type': 'players', 'players': last_ps}) - return (cur_t, 'error', last_t, cur_ps) - else: - return state - - -def doBackOnline(state, cur_t, cur_ps): - (last_t, last_ev, last_evt, last_ps) = state - working = (cur_t - last_t < 70) - - if working and last_ev != 'online': - events.append({'period': [last_evt, cur_t], 'type': 'error'}) - return (cur_t, 'online', last_t, last_ps) - else: - return state - - -def doPlayerChange(state, cur_t, cur_ps): - (last_t, last_ev, last_evt, last_ps) = state - working = (cur_t - last_t < 70) - - if working and last_ps != cur_ps: - events.append({'period': [last_evt, cur_t], 'type': 'players', 'players': last_ps}) - return (cur_t, 'online', cur_t, cur_ps) - else: - return state - - -def doUpdateTime(state, cur_t, cur_ps): - (last_t, last_ev, last_evt, last_ps) = state - return (cur_t, last_ev, last_evt, last_ps) - - -def doCurrent(state): - (last_t, last_ev, last_evt, last_ps) = state - events.append({'period': [last_evt, last_t], 'type': 'current', 'players': last_ps}) - - -with open('all-time.txt') as f: - state = () - cur_t = 0 - cur_ps = [] - - for line in f: - current = loads(line) - cur_t = current['time'] - cur_ps = current['players'] - - if state == (): - state = (cur_t, 'online', cur_t, cur_ps) - else: - state = doOffline(state, cur_t, cur_ps) - state = doBackOnline(state, cur_t, cur_ps) - state = doPlayerChange(state, cur_t, cur_ps) - state = doUpdateTime(state, cur_t, cur_ps) - - doCurrent(state) - - -def dumpJSON(events): - for event in events: - print(dumps(event)) - -dumpJSON(events) diff --git a/style.css b/svg.css similarity index 100% rename from style.css rename to svg.css diff --git a/template.html b/template.html new file mode 100644 index 0000000..f2d0368 --- /dev/null +++ b/template.html @@ -0,0 +1,31 @@ + + + + + + + + + + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + + +{events} + + + +