2015-03-05 12:48:10 -05:00
|
|
|
import re
|
2015-04-16 13:08:59 -04:00
|
|
|
import sys
|
2015-06-02 09:13:08 -04:00
|
|
|
import glob
|
2015-05-12 15:38:34 -04:00
|
|
|
import json
|
2015-03-05 12:48:10 -05:00
|
|
|
import configparser
|
2015-05-12 16:00:38 -04:00
|
|
|
from os.path import exists
|
2015-05-18 13:43:37 -04:00
|
|
|
from telnetlib import Telnet
|
|
|
|
from time import mktime, sleep
|
2015-03-05 12:48:10 -05:00
|
|
|
from datetime import datetime, timedelta
|
2015-04-16 13:08:59 -04:00
|
|
|
from jinja2 import Environment, FileSystemLoader
|
|
|
|
|
2015-05-12 16:00:38 -04:00
|
|
|
|
|
|
|
def exit(error):
|
|
|
|
print('FATAL ERROR:', error)
|
|
|
|
import sys
|
|
|
|
sys.exit(1)
|
|
|
|
|
2015-04-16 13:30:03 -04:00
|
|
|
# get path
|
|
|
|
arg = sys.argv[0]
|
|
|
|
arg_find = arg.rfind('/')
|
|
|
|
if arg_find == -1:
|
|
|
|
path = '.'
|
|
|
|
else:
|
|
|
|
path = arg[:arg_find]
|
|
|
|
path += '/'
|
|
|
|
|
2015-05-12 16:00:38 -04:00
|
|
|
config_path = path + 'config.ini'
|
|
|
|
id_map_path = path + 'id_map.json'
|
|
|
|
|
|
|
|
# exists config-file
|
|
|
|
if not exists(config_path):
|
|
|
|
exit('Couldn\'t find config-file at {}'.format(config_path))
|
2015-04-16 13:30:03 -04:00
|
|
|
|
2015-04-16 13:08:59 -04:00
|
|
|
# parse config
|
2015-03-05 12:48:10 -05:00
|
|
|
config = configparser.ConfigParser()
|
2015-05-12 16:00:38 -04:00
|
|
|
config.read(config_path)
|
2015-05-12 15:38:34 -04:00
|
|
|
# check keys
|
2015-05-12 16:00:38 -04:00
|
|
|
if 'General' not in config or 'HTML' not in config:
|
|
|
|
exit('Invalid config!')
|
2015-05-12 15:38:34 -04:00
|
|
|
general = config['General']
|
|
|
|
html = config['HTML']
|
|
|
|
if ('logfile' not in general or 'outputfile' not in general) or ('title' not in html):
|
2015-05-12 16:00:38 -04:00
|
|
|
exit('Invalid config!')
|
2015-05-12 15:38:34 -04:00
|
|
|
log_path = general['logfile']
|
2015-05-12 16:00:38 -04:00
|
|
|
if not exists(log_path):
|
|
|
|
exit('Couldn\'t access log-file!')
|
2015-05-12 15:38:34 -04:00
|
|
|
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)
|
2015-05-18 13:43:37 -04:00
|
|
|
show_pbans = html.get('pbans', True)
|
2015-05-12 16:00:38 -04:00
|
|
|
|
|
|
|
if exists(id_map_path):
|
|
|
|
# read id_map
|
|
|
|
id_map = json.load(open(path + 'id_map.json'))
|
|
|
|
else:
|
|
|
|
id_map = {}
|
2015-04-16 13:08:59 -04:00
|
|
|
|
2015-03-05 12:48:10 -05:00
|
|
|
generation_start = datetime.now()
|
|
|
|
clients = {} # clid: {'nick': ..., 'onlinetime': ..., 'kicks': ..., 'pkicks': ..., 'bans': ..., 'last_connect': ..., 'connected': ...}
|
2015-05-18 13:43:37 -04:00
|
|
|
kicks = {}
|
2015-03-05 12:48:10 -05:00
|
|
|
|
|
|
|
cldata = re.compile(r"'(.*)'\(id:(\d*)\)")
|
|
|
|
cldata_ban = re.compile(r"by\ client\ '(.*)'\(id:(\d*)\)")
|
2015-05-19 15:37:13 -04:00
|
|
|
cldata_invoker = re.compile(r"invokerid=\d*\ invokername=(.*)\ invokeruid=(.*)\ reasonmsg")
|
2015-03-05 12:48:10 -05:00
|
|
|
|
|
|
|
|
|
|
|
def add_connect(clid, nick, logdatetime):
|
|
|
|
check_client(clid, nick)
|
|
|
|
clients[clid]['last_connect'] = mktime(logdatetime.timetuple())
|
|
|
|
clients[clid]['connected'] = True
|
|
|
|
|
|
|
|
|
2015-03-05 16:16:46 -05:00
|
|
|
def add_disconnect(clid, nick, logdatetime, set_connected=True):
|
2015-03-05 12:48:10 -05:00
|
|
|
check_client(clid, nick)
|
|
|
|
connect = datetime.fromtimestamp(clients[clid]['last_connect'])
|
|
|
|
delta = logdatetime - connect
|
|
|
|
minutes = delta.seconds // 60
|
|
|
|
increase_onlinetime(clid, minutes)
|
2015-03-05 16:16:46 -05:00
|
|
|
if set_connected:
|
|
|
|
clients[clid]['connected'] = False
|
2015-03-05 12:48:10 -05:00
|
|
|
|
|
|
|
|
|
|
|
def add_ban(clid, nick):
|
|
|
|
check_client(clid, nick)
|
|
|
|
if 'bans' in clients[clid]:
|
|
|
|
clients[clid]['bans'] += 1
|
|
|
|
else:
|
|
|
|
clients[clid]['bans'] = 1
|
|
|
|
|
|
|
|
|
2015-05-18 13:43:37 -04:00
|
|
|
def add_pban(clid, nick):
|
2015-03-05 12:48:10 -05:00
|
|
|
check_client(clid, nick)
|
2015-05-18 13:43:37 -04:00
|
|
|
if 'pbans' in clients[clid]:
|
|
|
|
clients[clid]['pbans'] += 1
|
2015-03-05 12:48:10 -05:00
|
|
|
else:
|
2015-05-18 13:43:37 -04:00
|
|
|
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
|
2015-03-05 12:48:10 -05:00
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
2015-06-02 09:13:08 -04:00
|
|
|
log_files = [file_name for file_name in glob.glob(log_path)]
|
|
|
|
log_lines = []
|
|
|
|
for log_file in log_files:
|
|
|
|
for line in open(log_file, 'r'):
|
|
|
|
log_lines.append(line)
|
|
|
|
today = datetime.utcnow()
|
|
|
|
for line in log_lines:
|
|
|
|
parts = line.split('|')
|
|
|
|
logdatetime = datetime.strptime(parts[0], '%Y-%m-%d %H:%M:%S.%f')
|
|
|
|
sid = int(parts[3].strip())
|
|
|
|
data = '|'.join(parts[4:]).strip()
|
|
|
|
if data.startswith('client'):
|
|
|
|
r = cldata.findall(data)[0]
|
|
|
|
nick = r[0]
|
|
|
|
clid = r[1]
|
|
|
|
if clid in id_map:
|
|
|
|
clid = id_map[clid]
|
|
|
|
if data.startswith('client connected'):
|
|
|
|
add_connect(clid, nick, logdatetime)
|
|
|
|
elif data.startswith('client disconnected'):
|
|
|
|
add_disconnect(clid, nick, logdatetime)
|
|
|
|
if 'bantime' in data:
|
|
|
|
add_pban(clid, nick)
|
|
|
|
elif 'invokerid' in data:
|
|
|
|
add_pkick(clid, nick)
|
|
|
|
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)
|
2015-03-05 12:48:10 -05:00
|
|
|
|
|
|
|
for clid in clients:
|
|
|
|
if 'connected' not in clients[clid]:
|
|
|
|
clients[clid]['connected'] = False
|
|
|
|
if clients[clid]['connected']:
|
2015-03-05 16:16:46 -05:00
|
|
|
add_disconnect(clid, clients[clid]['nick'], today, set_connected=False)
|
2015-03-05 12:48:10 -05:00
|
|
|
|
|
|
|
|
2015-04-16 13:08:59 -04:00
|
|
|
generation_end = datetime.now()
|
|
|
|
generation_delta = generation_end - generation_start
|
|
|
|
|
|
|
|
|
2015-03-05 12:48:10 -05:00
|
|
|
# helper functions
|
2015-05-18 13:43:37 -04:00
|
|
|
def desc(key, data_dict=clients):
|
2015-03-05 12:48:10 -05:00
|
|
|
r = []
|
|
|
|
values = {}
|
2015-05-18 13:43:37 -04:00
|
|
|
for clid in data_dict:
|
|
|
|
if key in data_dict[clid]:
|
|
|
|
values[clid] = data_dict[clid][key]
|
2015-03-05 12:48:10 -05:00
|
|
|
for clid in sorted(values, key=values.get, reverse=True):
|
|
|
|
value = values[clid]
|
2015-05-18 13:43:37 -04:00
|
|
|
r.append((clid, data_dict[clid]['nick'], value))
|
2015-03-05 12:48:10 -05:00
|
|
|
return r
|
|
|
|
|
|
|
|
|
2015-04-16 13:08:59 -04:00
|
|
|
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):
|
2015-03-05 12:48:10 -05:00
|
|
|
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'
|
2015-04-16 13:08:59 -04:00
|
|
|
onlinetime_desc[idx] = (clid, nick, onlinetime_str, clients[clid]['connected'])
|
2015-03-05 12:48:10 -05:00
|
|
|
|
2015-05-18 13:43:37 -04:00
|
|
|
kicks_desc = desc('kicks', data_dict=kicks)
|
2015-05-17 09:48:08 -04:00
|
|
|
pkicks_desc = desc('pkicks')
|
|
|
|
bans_desc = desc('bans')
|
2015-05-18 13:43:37 -04:00
|
|
|
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
|
2015-04-16 13:08:59 -04:00
|
|
|
with open(output_path, 'w+') as f:
|
2015-05-18 13:43:37 -04:00
|
|
|
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),
|
2015-05-17 09:39:16 -04:00
|
|
|
date=generation_end.strftime('%d.%m.%Y %H:%M'),
|
2015-05-12 15:38:34 -04:00
|
|
|
show_onlinetime=show_onlinetime,
|
|
|
|
show_kicks=show_kicks,
|
|
|
|
show_pkicks=show_pkicks,
|
2015-05-18 13:43:37 -04:00
|
|
|
show_bans=show_bans,
|
|
|
|
show_pbans=show_pbans))
|
2015-03-05 12:48:10 -05:00
|
|
|
|
2015-04-16 13:08:59 -04:00
|
|
|
if len(clients) < 1:
|
|
|
|
print('Not enough data!')
|
|
|
|
else:
|
|
|
|
render_template()
|