clean code -> rewrite
This commit is contained in:
parent
b4456d9080
commit
90bfa04696
|
@ -14,11 +14,6 @@ Run `tsstats.py` and point your web-server to the generated .html-file, now you
|
||||||
- outputfile `Path to the location, where the generator will put the generated .html-file`
|
- outputfile `Path to the location, where the generator will put the generated .html-file`
|
||||||
`[HTML]`
|
`[HTML]`
|
||||||
- title `HTML-Title`
|
- title `HTML-Title`
|
||||||
- onlinetime `Show the onlinetime-section (default=True)`
|
|
||||||
- kicks `Show the kicks-section (default=True)`
|
|
||||||
- pkicks `Show the passive-kicks-section (default=True)`
|
|
||||||
- bans `Show the bans-section (default=True)`
|
|
||||||
- pbans `Show the passive-bans-section (default=True)`
|
|
||||||
|
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
@ -26,9 +21,6 @@ Run `tsstats.py` and point your web-server to the generated .html-file, now you
|
||||||
[General]
|
[General]
|
||||||
logfile = /usr/local/bin/teamspeak-server/logs/ts3server_2015-03-02__14_01_43.110983_1.log
|
logfile = /usr/local/bin/teamspeak-server/logs/ts3server_2015-03-02__14_01_43.110983_1.log
|
||||||
outputfile = /var/www/html/stats.html
|
outputfile = /var/www/html/stats.html
|
||||||
[HTML]
|
|
||||||
title = TeamspeakStats
|
|
||||||
bans = False
|
|
||||||
```
|
```
|
||||||
|
|
||||||
# ID-Mapping
|
# ID-Mapping
|
||||||
|
|
|
@ -1,73 +1,27 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
<title>{{ title }}</title>
|
||||||
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
|
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
|
||||||
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css">
|
{# <link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css"> #}
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
h1, p {
|
h1, p {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<title>{{ title }}</title>
|
</head>
|
||||||
</head>
|
<body>
|
||||||
<body>
|
<div id="container">
|
||||||
{# Onlinetime #}
|
{% for headline, list in objs %}
|
||||||
{% if show_onlinetime is sameas true %}
|
{% if list|length > 0 %}
|
||||||
<h1>Onlinetime</h1>
|
<h1>{{ headline }}</h2>
|
||||||
<ul class="list-group">
|
<ul class="list-group">
|
||||||
{% for clid, nick, onlinetime_, connected in onlinetime %}
|
{% for client, value in list %}
|
||||||
<li class="list-group-item{{ ' list-group-item-success' if connected else loop.cycle('" style="background-color: #eee;', '') }}">{{ nick }}<span class="badge">{{ onlinetime_ }}</span></li>
|
<li class="list-group-item{{ ' list-group-item-success' if client.connected else loop.cycle('" style="background-color: #eee;', '') }}">{{ client.nick }}<span class="badge">{{ value }}</span></li>
|
||||||
{% else %}
|
|
||||||
<li class="list-group-item">No data</li>
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
{# Kicks #}
|
<p>generated in {{ generation_time }} seconds at {{ time }}</p>
|
||||||
{% if show_kicks is sameas true %}
|
</div>
|
||||||
<h1>Kicks</h1>
|
</body>
|
||||||
<ul class="list-group">
|
|
||||||
{% for _, nick, kicks_ in kicks %}
|
|
||||||
<li class="list-group-item">{{ nick }}<span class="badge">{{ kicks_ }}</span></li>
|
|
||||||
{% else %}
|
|
||||||
<li class="list-group-item">No data</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{# passive Kicks #}
|
|
||||||
{% if show_pkicks is sameas true %}
|
|
||||||
<h1>passive Kicks</h1>
|
|
||||||
<ul class="list-group">
|
|
||||||
{% for _, nick, pkicks_ in pkicks %}
|
|
||||||
<li class="list-group-item">{{ nick }}<span class="badge">{{ pkicks_ }}</span></li>
|
|
||||||
{% else %}
|
|
||||||
<li class="list-group-item">No data</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{# Bans #}
|
|
||||||
{% if show_bans is sameas true %}
|
|
||||||
<h1>Bans</h1>
|
|
||||||
<ul class="list-group">
|
|
||||||
{% for _, nick, bans_ in bans %}
|
|
||||||
<li class="list-group-item">{{ nick }}<span class="badge">{{ bans_ }}</span></li>
|
|
||||||
{% else %}
|
|
||||||
<li class="list-group-item">No data</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
{% endif %}
|
|
||||||
{# passive Bans #}
|
|
||||||
{% if show_pbans is sameas true %}
|
|
||||||
<h1>passive Bans</h1>
|
|
||||||
<ul class="list-group">
|
|
||||||
{% for _, nick, pbans_ in pbans %}
|
|
||||||
<li class="list-group-item">{{ nick }}<span class="badge">{{ pbans_ }}</span></li>
|
|
||||||
{% else %}
|
|
||||||
<li class="list-group-item">No data</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
{% endif %}
|
|
||||||
<p>generated in {{ seconds }} at {{ date }}</p>
|
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
|
|
369
tsstats.py
369
tsstats.py
|
@ -1,56 +1,128 @@
|
||||||
import re
|
import re
|
||||||
import sys
|
|
||||||
import glob
|
import glob
|
||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
|
import datetime
|
||||||
import configparser
|
import configparser
|
||||||
from os.path import exists
|
from sys import argv
|
||||||
from telnetlib import Telnet
|
from time import mktime
|
||||||
from time import mktime, sleep
|
from os.path import exists, abspath
|
||||||
from datetime import datetime, timedelta
|
|
||||||
from jinja2 import Environment, FileSystemLoader
|
from jinja2 import Environment, FileSystemLoader
|
||||||
|
|
||||||
|
# logging
|
||||||
|
log = logging.getLogger()
|
||||||
|
log.setLevel(logging.DEBUG)
|
||||||
|
# create handler
|
||||||
|
file_handler = logging.FileHandler('debug.txt', 'w', 'UTF-8')
|
||||||
|
file_handler.setFormatter(logging.Formatter('[%(asctime)s] %(message)s', '%d.%m.%Y %H:%M:%S'))
|
||||||
|
file_handler.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
def exit(error):
|
stream_handler = logging.StreamHandler()
|
||||||
print('FATAL ERROR:', error)
|
stream_handler.setLevel(logging.INFO)
|
||||||
import sys
|
# add handler
|
||||||
sys.exit(1)
|
log.addHandler(file_handler)
|
||||||
|
log.addHandler(stream_handler)
|
||||||
|
|
||||||
# get path
|
|
||||||
arg = sys.argv[0]
|
|
||||||
arg_find = arg.rfind('/')
|
|
||||||
if arg_find == -1:
|
|
||||||
path = '.'
|
|
||||||
else:
|
|
||||||
path = arg[:arg_find]
|
|
||||||
path += '/'
|
|
||||||
|
|
||||||
config_path = path + 'config.ini'
|
class Clients:
|
||||||
id_map_path = path + 'id_map.json'
|
|
||||||
|
def __init__(self):
|
||||||
|
self.clients_by_id = {}
|
||||||
|
self.clients_by_uid = {}
|
||||||
|
|
||||||
|
def is_id(self, id_or_uid):
|
||||||
|
try:
|
||||||
|
int(id_or_uid)
|
||||||
|
return True
|
||||||
|
except ValueError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def __add__(self, id_or_uid):
|
||||||
|
if self.is_id(id_or_uid):
|
||||||
|
if id_or_uid not in self.clients_by_id:
|
||||||
|
self.clients_by_id[id_or_uid] = Client(id_or_uid)
|
||||||
|
else:
|
||||||
|
if id_or_uid not in self.clients_by_uid:
|
||||||
|
self.clients_by_uid[id_or_uid] = Client(id_or_uid)
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __getitem__(self, id_or_uid):
|
||||||
|
if self.is_id(id_or_uid):
|
||||||
|
if id_or_uid not in self.clients_by_id:
|
||||||
|
self += id_or_uid
|
||||||
|
return self.clients_by_id[id_or_uid]
|
||||||
|
else:
|
||||||
|
if id_or_uid not in self.clients_by_uid:
|
||||||
|
self += id_or_uid
|
||||||
|
return self.clients_by_uid[id_or_uid]
|
||||||
|
|
||||||
|
clients = Clients()
|
||||||
|
|
||||||
|
|
||||||
|
class Client:
|
||||||
|
|
||||||
|
def __init__(self, identifier):
|
||||||
|
# public
|
||||||
|
self.identifier = identifier
|
||||||
|
self.nick = None
|
||||||
|
self.connected = False
|
||||||
|
self.onlinetime = datetime.timedelta()
|
||||||
|
self.kicks = 0
|
||||||
|
self.pkicks = 0
|
||||||
|
self.bans = 0
|
||||||
|
self.pbans = 0
|
||||||
|
# private
|
||||||
|
self._last_connect = 0
|
||||||
|
|
||||||
|
def connect(self, timestamp):
|
||||||
|
'''
|
||||||
|
client connects at "timestamp"
|
||||||
|
'''
|
||||||
|
logging.debug('CONNECT {}'.format(str(self)))
|
||||||
|
self.connected = True
|
||||||
|
self._last_connect = timestamp
|
||||||
|
|
||||||
|
def disconnect(self, timestamp):
|
||||||
|
'''
|
||||||
|
client disconnects at "timestamp"
|
||||||
|
'''
|
||||||
|
logging.debug('DISCONNECT {}'.format(str(self)))
|
||||||
|
if not self.connected:
|
||||||
|
raise Exception('WTF did just happen?! A client disconnected before connecting!')
|
||||||
|
self.connected = False
|
||||||
|
session_time = timestamp - self._last_connect
|
||||||
|
self.onlinetime += session_time
|
||||||
|
|
||||||
|
def kick(self, target):
|
||||||
|
'''
|
||||||
|
client kicks "target" (Client-obj)
|
||||||
|
'''
|
||||||
|
logging.debug('KICK {} -> {}'.format(str(self), str(target)))
|
||||||
|
target.pkicks += 1
|
||||||
|
self.kicks += 1
|
||||||
|
|
||||||
|
def ban(self, target):
|
||||||
|
'''
|
||||||
|
client bans "target" (Client-obj)
|
||||||
|
'''
|
||||||
|
logging.debug('BAN {} -> {}'.format(str(self), str(target)))
|
||||||
|
target.pbans += 1
|
||||||
|
self.bans += 1
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return '<{},{}>'.format(self.identifier, self.nick)
|
||||||
|
|
||||||
|
def __format__(self):
|
||||||
|
return self.__str__()
|
||||||
|
|
||||||
|
# check cmdline-args
|
||||||
|
config_path = argv[1] if len(argv) >= 2 else 'config.ini'
|
||||||
|
config_path = abspath(config_path)
|
||||||
|
id_map_path = argv[2] if len(argv) >= 3 else 'id_map.json'
|
||||||
|
id_map_path = abspath(id_map_path)
|
||||||
|
|
||||||
# exists config-file
|
|
||||||
if not exists(config_path):
|
if not exists(config_path):
|
||||||
exit('Couldn\'t find config-file at {}'.format(config_path))
|
raise Exception('Couldn\'t find config-file at {}'.format(config_path))
|
||||||
|
|
||||||
# parse config
|
|
||||||
config = configparser.ConfigParser()
|
|
||||||
config.read(config_path)
|
|
||||||
# check keys
|
|
||||||
if 'General' not in config or 'HTML' not in config:
|
|
||||||
exit('Invalid config!')
|
|
||||||
general = config['General']
|
|
||||||
html = config['HTML']
|
|
||||||
if ('logfile' not in general or 'outputfile' not in general) or ('title' not in html):
|
|
||||||
exit('Invalid config!')
|
|
||||||
log_path = general['logfile']
|
|
||||||
if not exists(log_path):
|
|
||||||
exit('Couldn\'t access log-file!')
|
|
||||||
output_path = general['outputfile']
|
|
||||||
title = html['title']
|
|
||||||
show_onlinetime = html.get('onlinetime', True)
|
|
||||||
show_kicks = html.get('kicks', True)
|
|
||||||
show_pkicks = html.get('pkicks', True)
|
|
||||||
show_bans = html.get('bans', True)
|
|
||||||
show_pbans = html.get('pbans', True)
|
|
||||||
|
|
||||||
if exists(id_map_path):
|
if exists(id_map_path):
|
||||||
# read id_map
|
# read id_map
|
||||||
|
@ -58,176 +130,83 @@ if exists(id_map_path):
|
||||||
else:
|
else:
|
||||||
id_map = {}
|
id_map = {}
|
||||||
|
|
||||||
generation_start = datetime.now()
|
# parse config
|
||||||
clients = {} # clid: {'nick': ..., 'onlinetime': ..., 'kicks': ..., 'pkicks': ..., 'bans': ..., 'last_connect': ..., 'connected': ...}
|
config = configparser.ConfigParser()
|
||||||
kicks = {}
|
config.read(config_path)
|
||||||
|
# check keys
|
||||||
|
if 'General' not in config:
|
||||||
|
raise Exception('Invalid config! Section "General" missing!')
|
||||||
|
general = config['General']
|
||||||
|
html = config['HTML'] if 'HTML' in config.sections() else {}
|
||||||
|
if not ('logfile' in general or 'outputfile' in general):
|
||||||
|
raise Exception('Invalid config! "logfile" and/or "outputfile" missing!')
|
||||||
|
log_path = general['logfile']
|
||||||
|
if not exists(log_path):
|
||||||
|
raise Exception('Couldn\'t access log-file!')
|
||||||
|
output_path = general['outputfile']
|
||||||
|
title = html.get('title', 'TeamspeakStats')
|
||||||
|
|
||||||
cldata = re.compile(r"'(.*)'\(id:(\d*)\)")
|
generation_start = datetime.datetime.now()
|
||||||
cldata_ban = re.compile(r"by\ client\ '(.*)'\(id:(\d*)\)")
|
|
||||||
cldata_invoker = re.compile(r"invokerid=\d*\ invokername=(.*)\ invokeruid=(.*)\ reasonmsg")
|
|
||||||
|
|
||||||
|
re_dis_connect = re.compile(r"'(.*)'\(id:(\d*)\)")
|
||||||
|
re_disconnect_invoker = re.compile(r"invokername=(.*)\ invokeruid=(.*)\ reasonmsg")
|
||||||
|
|
||||||
def add_connect(clid, nick, logdatetime):
|
# find all log-files and collect lines
|
||||||
check_client(clid, nick)
|
|
||||||
clients[clid]['last_connect'] = mktime(logdatetime.timetuple())
|
|
||||||
clients[clid]['connected'] = True
|
|
||||||
|
|
||||||
|
|
||||||
def add_disconnect(clid, nick, logdatetime, set_connected=True):
|
|
||||||
check_client(clid, nick)
|
|
||||||
connect = datetime.fromtimestamp(clients[clid]['last_connect'])
|
|
||||||
delta = logdatetime - connect
|
|
||||||
minutes = delta.seconds // 60
|
|
||||||
increase_onlinetime(clid, minutes)
|
|
||||||
if set_connected:
|
|
||||||
clients[clid]['connected'] = False
|
|
||||||
|
|
||||||
|
|
||||||
def add_ban(clid, nick):
|
|
||||||
check_client(clid, nick)
|
|
||||||
if 'bans' in clients[clid]:
|
|
||||||
clients[clid]['bans'] += 1
|
|
||||||
else:
|
|
||||||
clients[clid]['bans'] = 1
|
|
||||||
|
|
||||||
|
|
||||||
def add_pban(clid, nick):
|
|
||||||
check_client(clid, nick)
|
|
||||||
if 'pbans' in clients[clid]:
|
|
||||||
clients[clid]['pbans'] += 1
|
|
||||||
else:
|
|
||||||
clients[clid]['pbans'] = 1
|
|
||||||
|
|
||||||
|
|
||||||
####
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# TODO
|
|
||||||
#
|
|
||||||
#
|
|
||||||
###
|
|
||||||
def add_kick(cluid, nick):
|
|
||||||
if cluid not in kicks:
|
|
||||||
kicks[cluid] = {}
|
|
||||||
if 'kicks' in kicks[cluid]:
|
|
||||||
kicks[cluid]['kicks'] += 1
|
|
||||||
else:
|
|
||||||
kicks[cluid]['kicks'] = 1
|
|
||||||
kicks[cluid]['nick'] = nick
|
|
||||||
|
|
||||||
|
|
||||||
def add_pkick(clid, nick):
|
|
||||||
check_client(clid, nick)
|
|
||||||
if 'pkicks' in clients[clid]:
|
|
||||||
clients[clid]['pkicks'] += 1
|
|
||||||
else:
|
|
||||||
clients[clid]['pkicks'] = 1
|
|
||||||
|
|
||||||
|
|
||||||
def increase_onlinetime(clid, onlinetime):
|
|
||||||
if 'onlinetime' in clients[clid]:
|
|
||||||
clients[clid]['onlinetime'] += onlinetime
|
|
||||||
else:
|
|
||||||
clients[clid]['onlinetime'] = onlinetime
|
|
||||||
|
|
||||||
|
|
||||||
def check_client(clid, nick):
|
|
||||||
if clid not in clients:
|
|
||||||
clients[clid] = {}
|
|
||||||
clients[clid]['nick'] = nick
|
|
||||||
|
|
||||||
log_files = [file_name for file_name in glob.glob(log_path)]
|
log_files = [file_name for file_name in glob.glob(log_path)]
|
||||||
log_lines = []
|
log_lines = []
|
||||||
for log_file in log_files:
|
for log_file in log_files:
|
||||||
for line in open(log_file, 'r'):
|
for line in open(log_file, 'r'):
|
||||||
log_lines.append(line)
|
log_lines.append(line)
|
||||||
today = datetime.utcnow()
|
|
||||||
|
# process lines
|
||||||
for line in log_lines:
|
for line in log_lines:
|
||||||
parts = line.split('|')
|
parts = line.split('|')
|
||||||
logdatetime = datetime.strptime(parts[0], '%Y-%m-%d %H:%M:%S.%f')
|
logdatetime = datetime.datetime.strptime(parts[0], '%Y-%m-%d %H:%M:%S.%f')
|
||||||
sid = int(parts[3].strip())
|
data = parts[4].strip()
|
||||||
data = '|'.join(parts[4:]).strip()
|
|
||||||
if data.startswith('client'):
|
if data.startswith('client'):
|
||||||
r = cldata.findall(data)[0]
|
nick, clid = re_dis_connect.findall(data)[0]
|
||||||
nick = r[0]
|
|
||||||
clid = r[1]
|
|
||||||
if clid in id_map:
|
if clid in id_map:
|
||||||
clid = id_map[clid]
|
clid = id_map[clid]
|
||||||
|
client = clients[clid]
|
||||||
|
client.nick = nick
|
||||||
if data.startswith('client connected'):
|
if data.startswith('client connected'):
|
||||||
add_connect(clid, nick, logdatetime)
|
client.connect(logdatetime)
|
||||||
elif data.startswith('client disconnected'):
|
elif data.startswith('client disconnected'):
|
||||||
add_disconnect(clid, nick, logdatetime)
|
client.disconnect(logdatetime)
|
||||||
|
if 'invokeruid' in data:
|
||||||
|
re_disconnect_data = re_disconnect_invoker.findall(data)
|
||||||
|
invokernick, invokeruid = re_disconnect_data[0]
|
||||||
|
invoker = clients[invokeruid]
|
||||||
|
invoker.nick = invokernick
|
||||||
if 'bantime' in data:
|
if 'bantime' in data:
|
||||||
add_pban(clid, nick)
|
invoker.ban(client)
|
||||||
elif 'invokerid' in data:
|
else:
|
||||||
add_pkick(clid, nick)
|
invoker.kick(client)
|
||||||
r = cldata_invoker.findall(data)[0]
|
|
||||||
nick = r[0]
|
|
||||||
cluid = r[1]
|
|
||||||
add_kick(cluid, nick)
|
|
||||||
elif data.startswith('ban added') and 'cluid' in data:
|
|
||||||
r = cldata_ban.findall(data)[0]
|
|
||||||
nick = r[0]
|
|
||||||
clid = r[1]
|
|
||||||
add_ban(clid, nick)
|
|
||||||
|
|
||||||
for clid in clients:
|
generation_end = datetime.datetime.now()
|
||||||
if 'connected' not in clients[clid]:
|
|
||||||
clients[clid]['connected'] = False
|
|
||||||
if clients[clid]['connected']:
|
|
||||||
add_disconnect(clid, clients[clid]['nick'], today, set_connected=False)
|
|
||||||
|
|
||||||
|
|
||||||
generation_end = datetime.now()
|
|
||||||
generation_delta = generation_end - generation_start
|
generation_delta = generation_end - generation_start
|
||||||
|
|
||||||
|
# render template
|
||||||
|
template = Environment(loader=FileSystemLoader(abspath('.'))).get_template('template.html')
|
||||||
|
# sort all values desc
|
||||||
|
cl_by_id = clients.clients_by_id
|
||||||
|
cl_by_uid = clients.clients_by_uid
|
||||||
|
clients_onlinetime_ = sorted([(client, client.onlinetime) for client in cl_by_id.values()], key=lambda data: data[1], reverse=True)
|
||||||
|
clients_onlinetime = []
|
||||||
|
for client, onlinetime in clients_onlinetime_:
|
||||||
|
minutes, seconds = divmod(client.onlinetime.seconds, 60)
|
||||||
|
hours, minutes = divmod(minutes, 60)
|
||||||
|
hours = str(hours) + 'h ' if hours != 0 else ''
|
||||||
|
minutes = str(minutes) + 'm ' if minutes != 0 else ''
|
||||||
|
seconds = str(seconds) + 's' if seconds != 0 else ''
|
||||||
|
clients_onlinetime.append((client, hours + minutes + seconds))
|
||||||
|
clients_kicks = sorted([(client, client.kicks) for client in cl_by_uid.values() if client.kicks > 0], key=lambda data: data[1], reverse=True)
|
||||||
|
clients_pkicks = sorted([(client, client.pkicks) for client in cl_by_id.values() if client.pkicks > 0], key=lambda data: data[1], reverse=True)
|
||||||
|
clients_bans = sorted([(client, client.bans) for client in cl_by_uid.values() if client.bans > 0], key=lambda data: data[1], reverse=True)
|
||||||
|
clients_pbans = sorted([(client, client.pbans) for client in cl_by_id.values() if client.pbans > 0], key=lambda data: data[1], reverse=True)
|
||||||
|
objs = [('Onlinetime', clients_onlinetime), ('Kicks', clients_kicks),
|
||||||
|
('passive Kicks', clients_pkicks),
|
||||||
|
('Bans', clients_bans), ('passive Bans', clients_pbans)] # (headline, list)
|
||||||
|
|
||||||
# helper functions
|
with open(output_path, 'w') as f:
|
||||||
def desc(key, data_dict=clients):
|
f.write(template.render(title=title, objs=objs, generation_time='{}.{}'.format(generation_delta.seconds, generation_delta.microseconds), time=generation_end.strftime('%d.%m.%Y %H:%M')))
|
||||||
r = []
|
|
||||||
values = {}
|
|
||||||
for clid in data_dict:
|
|
||||||
if key in data_dict[clid]:
|
|
||||||
values[clid] = data_dict[clid][key]
|
|
||||||
for clid in sorted(values, key=values.get, reverse=True):
|
|
||||||
value = values[clid]
|
|
||||||
r.append((clid, data_dict[clid]['nick'], value))
|
|
||||||
return r
|
|
||||||
|
|
||||||
|
|
||||||
def render_template():
|
|
||||||
env = Environment(loader=FileSystemLoader(path))
|
|
||||||
template = env.get_template('template.html')
|
|
||||||
# format onlinetime
|
|
||||||
onlinetime_desc = desc('onlinetime')
|
|
||||||
for idx, (clid, nick, onlinetime) in enumerate(onlinetime_desc):
|
|
||||||
if onlinetime > 60:
|
|
||||||
onlinetime_str = str(onlinetime // 60) + 'h'
|
|
||||||
m = onlinetime % 60
|
|
||||||
if m > 0:
|
|
||||||
onlinetime_str += ' ' + str(m) + 'm'
|
|
||||||
else:
|
|
||||||
onlinetime_str = str(onlinetime) + 'm'
|
|
||||||
onlinetime_desc[idx] = (clid, nick, onlinetime_str, clients[clid]['connected'])
|
|
||||||
|
|
||||||
kicks_desc = desc('kicks', data_dict=kicks)
|
|
||||||
pkicks_desc = desc('pkicks')
|
|
||||||
bans_desc = desc('bans')
|
|
||||||
pbans_desc = desc('pbans')
|
|
||||||
show_kicks = len(kicks_desc) > 0
|
|
||||||
show_pkicks = len(pkicks_desc) > 0
|
|
||||||
show_bans = len(bans_desc) > 0
|
|
||||||
show_pbans = len(pbans_desc) > 0
|
|
||||||
with open(output_path, 'w+') as f:
|
|
||||||
f.write(template.render(title=title, onlinetime=onlinetime_desc, kicks=kicks_desc, pkicks=pkicks_desc, bans=bans_desc, pbans=pbans_desc, seconds='{}.{}'.format(generation_delta.seconds, generation_delta.microseconds),
|
|
||||||
date=generation_end.strftime('%d.%m.%Y %H:%M'),
|
|
||||||
show_onlinetime=show_onlinetime,
|
|
||||||
show_kicks=show_kicks,
|
|
||||||
show_pkicks=show_pkicks,
|
|
||||||
show_bans=show_bans,
|
|
||||||
show_pbans=show_pbans))
|
|
||||||
|
|
||||||
if len(clients) < 1:
|
|
||||||
print('Not enough data!')
|
|
||||||
else:
|
|
||||||
render_template()
|
|
||||||
|
|
Loading…
Reference in New Issue