2015-03-05 12:48:10 -05:00
import re
2015-04-16 13:08:59 -04:00
import sys
2015-03-05 12:48:10 -05:00
import configparser
from time import mktime
from datetime import datetime , timedelta
2015-04-16 13:08:59 -04:00
from jinja2 import Environment , FileSystemLoader
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-04-16 13:08:59 -04:00
# parse config
2015-03-05 12:48:10 -05:00
config = configparser . ConfigParser ( )
2015-04-16 13:30:03 -04:00
config . read ( path + ' config.ini ' )
2015-04-22 10:32:28 -04:00
if ' General ' not in config or not ( ' title ' in config [ ' General ' ] and ' logfile ' in config [ ' General ' ] and ' outputfile ' in config [ ' General ' ] ) :
2015-03-05 12:48:10 -05:00
print ( ' Invalid configuration! ' )
import sys
sys . exit ( )
2015-04-22 10:32:28 -04:00
title = config [ ' General ' ] [ ' title ' ]
2015-03-05 12:48:10 -05:00
log_path = config [ ' General ' ] [ ' logfile ' ]
output_path = config [ ' General ' ] [ ' outputfile ' ]
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': ...}
cldata = re . compile ( r " ' (.*) ' \ (id:( \ d*) \ ) " )
cldata_ban = re . compile ( r " by \ client \ ' (.*) ' \ (id:( \ d*) \ ) " )
cldata_invoker = re . compile ( r " invokerid=( \ d*) \ invokername=(.*) \ invokeruid " )
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
def add_kick ( clid , nick ) :
check_client ( clid , nick )
if ' kicks ' in clients [ clid ] :
clients [ clid ] [ ' kicks ' ] + = 1
else :
clients [ clid ] [ ' kicks ' ] = 1
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
with open ( log_path , ' r ' ) as f :
today = datetime . utcnow ( )
for line in f :
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 ]
id = r [ 1 ]
if data . startswith ( ' client connected ' ) :
add_connect ( id , nick , logdatetime )
elif data . startswith ( ' client disconnected ' ) :
add_disconnect ( id , nick , logdatetime )
if ' invokerid ' in data :
add_pkick ( id , nick )
r = cldata_invoker . findall ( data ) [ 0 ]
nick = r [ 1 ]
id = r [ 0 ]
add_kick ( id , nick )
elif data . startswith ( ' ban added ' ) and ' cluid ' in data :
r = cldata_ban . findall ( data ) [ 0 ]
nick = r [ 0 ]
id = r [ 1 ]
add_ban ( id , nick )
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
def desc ( key ) :
r = [ ]
values = { }
for clid in clients :
if key in clients [ clid ] :
values [ clid ] = clients [ clid ] [ key ]
for clid in sorted ( values , key = values . get , reverse = True ) :
value = values [ clid ]
2015-03-05 16:16:46 -05:00
r . append ( ( clid , clients [ 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-04-16 13:08:59 -04:00
with open ( output_path , ' w+ ' ) as f :
2015-04-22 10:32:28 -04:00
f . write ( template . render ( title = title , onlinetime = onlinetime_desc , kicks = desc ( ' kicks ' ) , pkicks = desc ( ' pkicks ' ) , bans = desc ( ' bans ' ) , seconds = ' {} . {} ' . format ( generation_delta . seconds , generation_delta . microseconds ) , date = generation_end . strftime ( ' %d . % m. % Y um % H: % M ' ) ) )
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 ( )