#!/usr/bin/python
#needs at least python 1.5 

#***************************************************************************
#               copyright            : (C) 2001 by McRee                   *
#               email                : mcree@freemail.hu                   *
#***************************************************************************
 
#***************************************************************************
#*                                                                         *
#*   This program is free software; you can redistribute it and/or modify  *
#*   it under the terms of the GNU General Public License as published by  *
#*   the Free Software Foundation; either version 2 of the License, or     *
#*   (at your option) any later version.                                   *
#*                                                                         *
#***************************************************************************

####################################################################################################
#
#	GLOBALS - PLEASE EDIT THESE TO FIT YOUR SYSTEM
#
####################################################################################################

# database file 
database = "/var/local/muddlestats.db";
# directories change these
wwwroot = "/var/www"; 			# must _NOT_ end with '/'
targetdir = "/muddlestats/"; 		# must start _and_ end with '/'
# stat files - these will be generated at 'wwwroot'+'targetdir'
mainfile = "index.html";
fileprefix = "stats_";

# if uploads have higher priority during sorting
uploads_first = 1;

bgcolor 	= '#449999';
textcolor 	= '#000000';
linkcolor 	= '#333333';
tablecolor1 	= '#dddd77';
tablecolor2 	= '#dd9922';
tableheader 	= '#bb6600';
chartbgcolor 	= '#44bb99';

####################################################################################################
#
#	GLOBALS - FROM NOW ON DO NOT EDIT THE FILE UNLESS YOU KNOW WHAT YOU ARE DOING
#
####################################################################################################

import re;
import pprint;
import cPickle;
from os import stat;
from zlib import compress, decompress;
from time import *;

userlist = {};

# load database
dbfile = open (database,"r");
oldstamp = dbfile.readline()[:-len('\n')];
l = cPickle.loads(decompress(dbfile.read()));
userlist = l[0];
dbfile.close();

out = [];

def head():
    global out;
    global bgcolor, textcolor, linkcolor;
	
    out.append("""<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <title>MuddleFTPD Stats v0.3</title>
    </head>
    """);
    out.append('<body bgcolor="'+bgcolor+'" text="'+textcolor+'" link="'+linkcolor+'" vlink="#111111" alink="#FFFFFF">');

def tail():
    global out;

    out.append("""
    <br>
    <hr>
    <center>
    <table width="100%" border="0">
    <tr>
    <td align="left" valign="top"><A href="http://www.pythonlabs.com"><img border="0" src="http://www.pythonlabs.com/pics/PythonPoweredSmall.gif" alt="Python Powered"></A></td>
    <td align="center" valign="top" width="80%">Page generated by MuddleStats written by <A href="mailto:mcree_at_freemail.hu">Erno Rigo</A>, 2001</td>
    <td align="right" valign="top"><a href="http://validator.w3.org/check/referer"><img border="0" src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" height="31" width="88"></a></td>
    </tr>
    </table>
    </center>
    </body>
    </html>
    """);


def psiz(bytes):	# bytewise size prettyformatter
    if bytes == 0:
	return "nothing";
    elif bytes < 1024:
	return "%d bytes" % bytes;
    elif bytes < 1024L**2:
	return "%.1f Kbytes" % (float(bytes)/1024);
    elif bytes < 1024L**3:
	return "%.1f Mbytes" % (float(bytes)/1024L**2);
    elif bytes < 1024L**4:
	return "%.1f Gbytes" % (float(bytes)/1024L**3);
    else:
	return "%.1f Tbytes" % (float(bytes)/1024L**4);

# sometimes i'll use this one too for sure... at least i don't want to erase it 8)
# ------------8<-----------------------------------------------------------------------------------------------------------------------------------------------------------
#def pchart(caption, values, scale = range(1,1000)):	# html table-chart builder - browser must support rowspan and bgcolor fields in the td tag!
#    print '<center><table cellpadding="1" cellspacing="0" border="0" align="center" bgcolor="'+chartbgcolor+'" width="90%"><caption>'+caption+'</caption>';
#    print '<tr><td width="2%" height="1"><font size="-4">&nbsp;</font></td>';
#    for x in values:
#	 print '<td width="2%" rowspan="'+str(20-x)+'"><font size="-4">&nbsp;</font></td>';
#        print '<td width="1%" rowspan="20"><font size="-4">&nbsp;</font></td>';
#    print '</tr>';
#    for y in range(1,20):
#	print '<tr><td width="2%" height="1"><font size="-4">&nbsp;</font></td>';
#	for x in values:
#	    if 20-x==y:
#		print '<td width="2%" bgcolor="'+tablecolor1+'" rowspan="'+str(x)+'"><font size="-4">&nbsp;</font></td>';
#        print '</tr>';    
#    l=0;
#    for x in values:
#        print '<td width="1%"><font size="-4">&nbsp;</font></td>';
#	print '<td width="2%" ><font size="-4"><center>'+("%02d" % int(scale[l]))+'</center></font></td>';
#	l=l+1;
#    print '<td width="1%"><font size="-4">&nbsp;</font></td>';
#    print '</table></center>'
# ------------8<-----------------------------------------------------------------------------------------------------------------------------------------------------------


def pdchart(values, caption='', scale = range(1,1000)):	
    "html table-doublechart builder - browser must support rowspan and bgcolor fields in the td tag!"
    res=[];
    res.append('<center><table cellpadding="0" cellspacing="0" border="0" align="center" bgcolor="'+chartbgcolor+'" width="90%"><caption><B>'+caption+'</B></caption>');
    res.append('<tr><td width="1%" rowspan="20"><font size="-4">&nbsp;</font></td>');
    res.append('<td width="1%" height="1"><font size="-4">_</font></td>');
    lo=0;
    for x in values:
	res.append('<td width="1%" rowspan="'+str(20-x)+'"><font size="-4">&nbsp;</font></td>');
	lo=lo+1;
	if lo%2==0:
    	    res.append('<td width="1%" rowspan="20"><table cellpadding="0" cellspacing="0" border="0" align="center"><tr align="center"><td><font size="-4">_<br>_<br>_<br>_<br>_<br>_<br>_<br>_<br>_<br>_<br>_<br>_<br>_<br>_<br>_<br>_<br>_<br>_<br>_<br>_<br></font></td</tr></table></td>');
    res.append('<td width="1%" rowspan="20"><font size="-4">&nbsp;</font></td>');
    res.append('</tr>');
    for y in range(1,20):
	res.append('<tr><td width="1%" height="1"><font size="-4">_</font></td>');
	lo=0;
	for x in values:
	    lo=lo+1;
	    if 20-x==y:
		if lo%2==1:
    		    res.append('<td width="1%" bgcolor="'+tablecolor1+'" rowspan="'+str(x)+'"><font size="-4">&nbsp;</font></td>');
		else:
    		    res.append('<td width="1%" bgcolor="'+tablecolor2+'" rowspan="'+str(x)+'"><font size="-4">&nbsp;</font></td>');
        res.append('</tr>');    
    l=0;
    lo=0;
    res.append('<tr><td width="1%"><font size="-4">&nbsp;</font></td>');
    for x in values:
	lo=lo+1;
	if lo%2==1:
	    res.append('<td width="1%"><font size="-4">&nbsp;</font></td>');
	    res.append('<td width="1%" colspan="2" align="center"><font size="-4">'+("%02d" % int(scale[l/2]))+'</font></td>');
	l=l+1;
    res.append('<td width="1%"><font size="-4">&nbsp;</font></td>');
    res.append('<td width="1%"><font size="-4">&nbsp;</font></td>');
    res.append('</table></center>');

    return res;


####################################################################################################
#
#	MAIN PAGE
#
####################################################################################################

head();

out.append('<center><b><font size="+4">MuddleFTPD Server Statistics</font></b></center><br>');
out.append("<center> Database last updated: " + ctime(stat(database)[8]) + "</center><br>");

# calculate totals
retr_total = 0;
stor_total = 0;
for user in userlist.keys():
    for host in userlist[user].keys():
	for times in userlist[user][host].keys():
	    retr_total = retr_total + long(userlist[user][host][times]["RETR"]);
	    stor_total = stor_total + long(userlist[user][host][times]["STOR"]);
out.append("<center>Total data downloaded: <B>" + psiz(retr_total) + "</B> , total data uploaded: <B>" + psiz(stor_total) + "</B></center><br>");

# calculate record scope
first_rec = '9999-99-99';
last_rec = '0000-00-00';
for user in userlist.keys():
    for host in userlist[user].keys():
	for times in userlist[user][host].keys():
	    if times<first_rec:
		first_rec=times;
	    if times>last_rec:
		last_rec=times;
out.append("<center>First record in database: <B>" + first_rec + "</B> , last record in database: <B>" + last_rec + "</B></center>");
out.append("<br><hr><br>");

out.append('<CENTER><A HREF="'+targetdir+'userlist_'+mainfile+'">Detailed user statistics</A></CENTER><br>');
out.append('<CENTER><A HREF="'+targetdir+'hostlist_'+mainfile+'">Detailed host summaries</A></CENTER><br>');
out.append('<CENTER><A HREF="'+targetdir+'domainlist_'+mainfile+'">Detailed domain statistics</A></CENTER><br>');

out.append("<br><hr><br>");

#print last 30 days' statistics
statlist=[];
for x in range(1,31):
    ttime = localtime(time()-(60*60*24*long(x)));
    times = "%02d" % ttime[0] + "-%02d" % ttime[1] + "-%02d" % ttime[2];
#    print 'current date is ' + times + "<br>";
    retr_total = 0;
    stor_total = 0;
    for user in userlist.keys():
        for host in userlist[user].keys():
            for timess in userlist[user][host].keys():
                if timess==times:
                    retr_total = retr_total + long(userlist[user][host][timess]["RETR"]);
                    stor_total = stor_total + long(userlist[user][host][timess]["STOR"]);
#    print "retrieved: " + psiz(retr_total) + " stored: " + psiz(stor_total) + "<br>";
    statlist.append(retr_total);
    statlist.append(stor_total);
u=max(statlist);
for x in range(0,len(statlist)/2-1):
    if statlist[x]!=0:
        statlist[x]=int((float(statlist[x])/u)*19);
    else:
        statlist[x]=0;

out.extend(pdchart(statlist, 'Statistics for the last 30 days (<font color="'+tablecolor1+'">Downloads</font>/<font color="'+tablecolor2+'">Uploads</font>) [Full scale: 0 to ' + psiz(u) + ']' )); 

out.append("<br>");

#print last 12 months' statistics
statlist=[];
for x in range(0,12):
    ttime = localtime(time()-(60*60*24*30*long(x)));
    times = "%02d" % ttime[0] + "-%02d" % ttime[1] + "-%02d" % ttime[2];                     
    ttime = localtime(time()-(60*60*24*30*long(x+1)));
    times1 = "%02d" % ttime[0] + "-%02d" % ttime[1] + "-%02d" % ttime[2];                     
#    print 'current date is ' + times + "<br>";
    retr_total = 0;
    stor_total = 0;
    for user in userlist.keys():
	for host in userlist[user].keys():
	    for timess in userlist[user][host].keys():
		if timess>times1 and timess<=times:
		    retr_total = retr_total + long(userlist[user][host][timess]["RETR"]);
		    stor_total = stor_total + long(userlist[user][host][timess]["STOR"]);
#    print "retrieved: " + psiz(retr_total) + " stored: " + psiz(stor_total) + "<br>";
    statlist.append(retr_total);
    statlist.append(stor_total);
u=max(statlist);
for x in range(0,len(statlist)/2-1):
    if statlist[x]!=0:
	statlist[x]=int((float(statlist[x])/u)*19);
    else:
	statlist[x]=0;
out.extend(pdchart(statlist, 'Statistics for the last 12 months (<font color="'+tablecolor1+'">Downloads</font>/<font color="'+tablecolor2+'">Uploads</font>) [Full scale: 0 to ' + psiz(u) + ']', range(0,20) ));


tail();


htmlfile = open (wwwroot+targetdir+mainfile,"w+");
htmlfile.writelines(out);
htmlfile.close();

####################################################################################################
#
#	GLOBAL USER STATISTICS
#
####################################################################################################

out = [];

head();
	
#calculate per user totals
u_total = {};
userno = 0;
for user in userlist.keys():
    if not u_total.has_key(user):
	u_total[user]=[0,0,user];
	userno=userno+1;
    for host in userlist[user].keys():
	for times in userlist[user][host].keys():
	    if uploads_first:
		u_total[user] = [long(u_total[user][0]) + long(userlist[user][host][times]["STOR"]),
		    long(u_total[user][1]) + long(userlist[user][host][times]["RETR"]),
		    user];
	    else:
		u_total[user] = [long(u_total[user][0]) + long(userlist[user][host][times]["RETR"]),
		    long(u_total[user][1]) + long(userlist[user][host][times]["STOR"]),
		    user];

out.append('<center><b><font size="+4">MuddleFTPD Server Statistics - Per user total usage statistics</font></b></center><br>');
out.append('<center>Total users in database: <B>'+str(userno)+'</b></center><br>');

out.append('<center><br><table border="0" width="60%" cellpadding="0" cellspacing="0">');
if uploads_first:
    out.append('<tr bgcolor="'+tableheader+'"><td><B>User</B></td><td><center><B>Uploaded</B></center></td><td><center><B>Downloaded</B></center></td></tr>');
else:
    out.append('<tr bgcolor="'+tableheader+'"><td><B>User</B></td><td><center><B>Downloaded</B></center></td><td><center><B>Uploaded</B></center></td></tr>');
t=u_total.values();
t.sort();
t.reverse();
l=0;
for us in t:
    l=l+1;
    if l%2==1:
	out.append('<tr bgcolor="'+tablecolor1+'"><td width="20%"><A NAME="'+us[2]+'_back"></A><A HREF="'+targetdir+fileprefix+'user_'+us[2]+'.html">'+ us[2] +"</a></td><td><center>"+ psiz(us[0]) +"</center></td><td><center>"+ psiz(us[1]) +"</center></td></tr>");
    else:
	out.append('<tr bgcolor="'+tablecolor2+'"><td width="20%"><A NAME="'+us[2]+'_back"></A><A HREF="'+targetdir+fileprefix+'user_'+us[2]+'.html">'+ us[2] +"</a></td><td><center>"+ psiz(us[0]) +"</center></td><td><center>"+ psiz(us[1]) +"</center></td></tr>");
out.append("</table></center><br>");


out.append('<CENTER><A HREF="'+targetdir+mainfile+'">Back to main page</A></CENTER><br>');
tail();

htmlfile = open (wwwroot+targetdir+"userlist_"+mainfile,"w+");
htmlfile.writelines(out);
htmlfile.close();

####################################################################################################
#
#	GLOBAL HOST STATISTICS
#
####################################################################################################

out = [];

head();
	
#calculate per user totals
u_total = {};
userno=0;
for user in userlist.keys():
    for host in userlist[user].keys():
	if not u_total.has_key(host):
	    u_total[host]=[0,0,host];
	    userno=userno+1;
	for times in userlist[user][host].keys():
	    if uploads_first:
		u_total[host] = [long(u_total[host][0]) + long(userlist[user][host][times]["STOR"]),
		    long(u_total[host][1]) + long(userlist[user][host][times]["RETR"]),
		    host];
	    else:
		u_total[host] = [long(u_total[host][0]) + long(userlist[user][host][times]["RETR"]),
		    long(u_total[host][1]) + long(userlist[user][host][times]["STOR"]),
		    host];

out.append('<center><b><font size="+4">MuddleFTPD Server Statistics - Per host total usage statistics</font></b></center><br>');
out.append('<center>Total hosts in database: <B>'+str(userno)+'</b></center><br>');

out.append('<center><br><table border="0" width="90%" cellpadding="0" cellspacing="0">');
if uploads_first:
    out.append('<tr bgcolor="'+tableheader+'"><td><B>Host</B></td><td><center><B>Uploaded</B></center></td><td><center><B>Downloaded</B></center></td></tr>');
else:
    out.append('<tr bgcolor="'+tableheader+'"><td><B>Host</B></td><td><center><B>Downloaded</B></center></td><td><center><B>Uploaded</B></center></td></tr>');
t=u_total.values();
t.sort();
t.reverse();
l=0;
for us in t:
    l=l+1;
    if l%2==1:
	out.append('<tr bgcolor="'+tablecolor1+'"><td width="20%">'+ us[2] +"</a></td><td><center>"+ psiz(us[0]) +"</center></td><td><center>"+ psiz(us[1]) +"</center></td></tr>");
    else:
	out.append('<tr bgcolor="'+tablecolor2+'"><td width="20%">'+ us[2] +"</a></td><td><center>"+ psiz(us[0]) +"</center></td><td><center>"+ psiz(us[1]) +"</center></td></tr>");
out.append("</table></center><br>");


out.append('<CENTER><A HREF="'+targetdir+mainfile+'">Back to main page</A></CENTER><br>');
tail();

htmlfile = open (wwwroot+targetdir+"hostlist_"+mainfile,"w+");
htmlfile.writelines(out);
htmlfile.close();

####################################################################################################
#
#	LEVEL 1-3 DOMAIN STATISTICS
#
####################################################################################################

#
#	LEVEL 1 DOMAIN STATISTICS
#


out = [];

head();
	
re_domain = re.compile(r'[.][a-zA-Z0-9_-]+\(');
re_baddomain = re.compile(r'[.][0-9]+\(');
#calculate per domain totals
u_total = {};
userno=0;
for user in userlist.keys():
    for host in userlist[user].keys():
	m = re_domain.search(host);
	if m:
	    mm = re_baddomain.search(m.group());
	    if mm:
		domain='other';
#		print host;
	    else:
		domain=m.group()[0:-1];
	else:
	    domain='other';
#	    print host;
	if not u_total.has_key(domain):
	    u_total[domain]=[0,0,domain];
	    userno=userno+1;
	for times in userlist[user][host].keys():
	    if uploads_first:
		u_total[domain] = [long(u_total[domain][0]) + long(userlist[user][host][times]["STOR"]),
		    long(u_total[domain][1]) + long(userlist[user][host][times]["RETR"]),
		    domain];
	    else:
		u_total[domain] = [long(u_total[domain][0]) + long(userlist[user][host][times]["RETR"]),
		    long(u_total[domain][1]) + long(userlist[user][host][times]["STOR"]),
		    domain];

out.append('<center><b><font size="+4">MuddleFTPD Server Statistics - Per level 1 domain total usage statistics</font></b></center><br>');
out.append('<center>Total domains in this section: <B>'+str(userno)+'</b></center><br>');

out.append('<center><br><table border="0" width="60%" cellpadding="0" cellspacing="0">');
if uploads_first:
    out.append('<tr bgcolor="'+tableheader+'"><td><B>Domain</B></td><td><center><B>Uploaded</B></center></td><td><center><B>Downloaded</B></center></td></tr>');
else:
    out.append('<tr bgcolor="'+tableheader+'"><td><B>Domain</B></td><td><center><B>Downloaded</B></center></td><td><center><B>Uploaded</B></center></td></tr>');
t=u_total.values();
t.sort();
t.reverse();
l=0;
for us in t:
    l=l+1;
    if l%2==1:
	out.append('<tr bgcolor="'+tablecolor1+'"><td width="20%"><A HREF="'+targetdir+fileprefix+'domainlist_'+us[2]+'.html">'+ us[2] +"</a></td><td><center>"+ psiz(us[0]) +"</center></td><td><center>"+ psiz(us[1]) +"</center></td></tr>");
    else:
	out.append('<tr bgcolor="'+tablecolor2+'"><td width="20%"><A HREF="'+targetdir+fileprefix+'domainlist_'+us[2]+'.html">'+ us[2] +"</a></td><td><center>"+ psiz(us[0]) +"</center></td><td><center>"+ psiz(us[1]) +"</center></td></tr>");
out.append("</table></center><br>");


out.append('<CENTER><A HREF="'+targetdir+mainfile+'">Back to main page</A></CENTER><br>');
tail();

htmlfile = open (wwwroot+targetdir+"domainlist_"+mainfile,"w+");
htmlfile.writelines(out);
htmlfile.close();

#
#	LEVEL 2 DOMAIN STATISTICS
#

domainlist = t;
t=[];
#pprint.pprint(domainlist);

re_upperdomain = re.compile(r'[.][a-zA-Z0-9_-]+\(');
re_upperbaddomain = re.compile(r'[.][0-9]+\(');
re_domain = re.compile(r'[.][a-zA-Z0-9_-]+[.][a-zA-Z0-9_-]+\(');
	
#calculate per domain totals
for c_domain in domainlist:
    curr_domain=c_domain[2];
    re_curr_upperdomain = re.compile(r''+curr_domain+'\(');
    u_total = {};
    userno=0;
    for user in userlist.keys():
	for host in userlist[user].keys():

	    m = re_curr_upperdomain.search(host);
	    if m:
		upperdomain=curr_domain;
		mm = re_domain.search(host);
		if mm:
		    domain=mm.group()[0:-1];
	    else:
		m = re_upperdomain.search(host);
		if m:
		    mm = re_upperbaddomain.search(host);
		    if mm:
			upperdomain='other';
			domain=host;			
		    else:
			upperdomain=m.group()[0:-1];
		else:
		    upperdomain='other';
		    domain=host;
	
	    if upperdomain==curr_domain:
		if not u_total.has_key(domain):
		    u_total[domain]=[0,0,domain];
		    userno=userno+1;
		for times in userlist[user][host].keys():
		    if uploads_first:
			u_total[domain] = [long(u_total[domain][0]) + long(userlist[user][host][times]["STOR"]),
			    long(u_total[domain][1]) + long(userlist[user][host][times]["RETR"]),
			    domain];
		    else:
			u_total[domain] = [long(u_total[domain][0]) + long(userlist[user][host][times]["RETR"]),
			    long(u_total[domain][1]) + long(userlist[user][host][times]["STOR"]),
			    domain];

    out = [];

    head();
    out.append('<center><b><font size="+4">MuddleFTPD Server Statistics - total usage statistics for the '+curr_domain+' domains</font></b></center><br>');
    out.append('<center>Total domains in this section: <B>'+str(userno)+'</b></center><br>');

    #print last 30 days' statistics
    statlist=[];
    for x in range(1,31):
	ttime = localtime(time()-(60*60*24*long(x)));
	times = "%02d" % ttime[0] + "-%02d" % ttime[1] + "-%02d" % ttime[2];                     
	retr_total = 0;
	stor_total = 0;
	for user in userlist.keys():
	    for host in userlist[user].keys():
		m = re_curr_upperdomain.search(host);
		if m:
		    upperdomain=curr_domain;
		    mm = re_domain.search(host);
		    if mm:
			domain=mm.group()[0:-1];
		else:
		    m = re_upperdomain.search(host);
		    if m:
			mm = re_upperbaddomain.search(host);
			if mm:
			    upperdomain='other';
			    domain=host;			
			else:
			    upperdomain=m.group()[0:-1];
		    else:
			upperdomain='other';
			domain=host;
	
		if upperdomain==curr_domain:
		    for timess in userlist[user][host].keys():
			if timess==times:
			    retr_total = retr_total + long(userlist[user][host][times]["RETR"]);
			    stor_total = stor_total + long(userlist[user][host][times]["STOR"]);
	statlist.append(retr_total);
	statlist.append(stor_total);

    u=max(statlist);
    for x in range(0,len(statlist)/2-1):
	if statlist[x]!=0:
	    statlist[x]=int((float(statlist[x])/u)*19);
	else:
	    statlist[x]=0;
    out.extend(pdchart(statlist, 'Statistics for the previous 30 days (<font color="'+tablecolor1+'">Downloads</font>/<font color="'+tablecolor2+'">Uploads</font>) [Full scale: 0 to ' + psiz(u) + ']' ));

    out.append("<br>");

    #print last 12 months' statistics
    statlist=[];
    for x in range(0,12):
	ttime = localtime(time()-(60*60*24*30*long(x)));
	times = "%02d" % ttime[0] + "-%02d" % ttime[1] + "-%02d" % ttime[2];                     
	ttime = localtime(time()-(60*60*24*30*long(x+1)));
	times1 = "%02d" % ttime[0] + "-%02d" % ttime[1] + "-%02d" % ttime[2];                     
	retr_total = 0;
	stor_total = 0;
	for user in userlist.keys():
	    for host in userlist[user].keys():
		m = re_curr_upperdomain.search(host);
		if m:
		    upperdomain=curr_domain;
		    mm = re_domain.search(host);
		    if mm:
			domain=mm.group()[0:-1];
		else:
		    m = re_upperdomain.search(host);
		    if m:
			mm = re_upperbaddomain.search(host);
			if mm:
			    upperdomain='other';
			    domain=host;			
			else:
			    upperdomain=m.group()[0:-1];
		    else:
			upperdomain='other';
			domain=host;
	
		if upperdomain==curr_domain:
		    for timess in userlist[user][host].keys():
			if timess>times1 and timess<=times:
			    retr_total = retr_total + long(userlist[user][host][timess]["RETR"]);
			    stor_total = stor_total + long(userlist[user][host][timess]["STOR"]);
	statlist.append(retr_total);
	statlist.append(stor_total);

    u=max(statlist);
    for x in range(0,len(statlist)/2-1):
	if statlist[x]!=0:
	    statlist[x]=int((float(statlist[x])/u)*19);
	else:
	    statlist[x]=0;
    out.extend(pdchart(statlist, 'Statistics for the last 12 months (<font color="'+tablecolor1+'">Downloads</font>/<font color="'+tablecolor2+'">Uploads</font>) [Full scale: 0 to ' + psiz(u) + ']' ,range(0,20)));

    out.append("<br>");
    out.append('<center><br><table border="0" width="60%" cellpadding="0" cellspacing="0">');
    if uploads_first:
	out.append('<tr bgcolor="'+tableheader+'"><td><B>Domain</B></td><td><center><B>Uploaded</B></center></td><td><center><B>Downloaded</B></center></td></tr>');
    else:
	out.append('<tr bgcolor="'+tableheader+'"><td><B>Domain</B></td><td><center><B>Downloaded</B></center></td><td><center><B>Uploaded</B></center></td></tr>');
    t=u_total.values();
    t.sort();
    t.reverse();
    l=0;
    for us in t:
	l=l+1;
	if l%2==1:
	    out.append('<tr bgcolor="'+tablecolor1+'"><td width="20%">'+ us[2] +"</a></td><td><center>"+ psiz(us[0]) +"</center></td><td><center>"+ psiz(us[1]) +"</center></td></tr>");
        else:
	    out.append('<tr bgcolor="'+tablecolor2+'"><td width="20%">'+ us[2] +"</a></td><td><center>"+ psiz(us[0]) +"</center></td><td><center>"+ psiz(us[1]) +"</center></td></tr>");
    out.append("</table></center><br>");


    out.append('<CENTER><A HREF="'+targetdir+mainfile+'">Back to main page</A></CENTER><br>');
    tail();

    htmlfile = open (wwwroot+targetdir+fileprefix+"domainlist_"+curr_domain+'.html',"w+");
    htmlfile.writelines(out);
    htmlfile.close();

####################################################################################################
#
#	PER USER DETAILED STATISTICS
#
####################################################################################################

#per user detailed statistics
l=0;
for user in userlist.keys():

    out = [];
    
    head();

    out.append('<center><table border="0" width="80%" cellpadding="0" cellspacing="0">');
    out.append('<tr bgcolor="'+tableheader+'"><td>Statistics for user <B>'+user+'</B></td><td align="right"><A HREF="'+targetdir+'userlist_'+mainfile+'#'+user+'_back">back</A></td></tr>');
    #last activity and totals
    lastlogin="0000-00-00";
    uretr_total = 0;
    ustor_total = 0;
    for host in userlist[user].keys():
	for times in userlist[user][host].keys():
	    if times>lastlogin:
		lastlogin=times;
	    uretr_total = uretr_total + long(userlist[user][host][times]["RETR"]);
	    ustor_total = ustor_total + long(userlist[user][host][times]["STOR"]);
    out.append('<tr bgcolor="'+tablecolor1+'"><td colspan="2" >Total downloaded: <B>'+psiz(uretr_total)+'</B> Total uploaded: <B>'+psiz(ustor_total)+'</B></td></tr>');
    out.append('<tr bgcolor="'+tablecolor2+'"><td colspan="2" >Last logged activity time: <B>'+lastlogin+'</B></td></tr>');
    #favourite hosts
    out.append('<tr bgcolor="'+tablecolor1+'"><td colspan="2" ><B>Favourite host(s):</B></td></tr>');
    out.append('<tr><td colspan="2"><table width="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="'+tablecolor1+'">');
    for host in userlist[user].keys():
	out.append('<tr><td>'+host+'</td><td> [last use: '+max(userlist[user][host].keys())+']</td></tr>');
    out.append('</table></td></tr>');
    # 30 days' usage
    out.append('<tr bgcolor="'+tablecolor2+'"><td colspan="2" ><B>Activity during the previous 30 days:</B></td></tr>');
    out.append('<tr><td colspan="2">');
    out.append('<table width="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="'+tablecolor2+'">');
    out.append("<tr><td><B>Time</B></td><td>from host</td><td><B>Downloads</B></td><td><B>Uploads</B></td></tr>");
    statlist=[];
    for x in range(1,31):
        ttime = localtime(time()-(60*60*24*long(x)));
        times = "%02d" % ttime[0] + "-%02d" % ttime[1] + "-%02d" % ttime[2];                     
	for host in userlist[user].keys():
    	    retr_total = 0;
    	    stor_total = 0;
	    for timess in userlist[user][host].keys():
		if timess==times:
		    retr_total = retr_total + long(userlist[user][host][times]["RETR"]);
		    stor_total = stor_total + long(userlist[user][host][times]["STOR"]);
	    if retr_total>0 or stor_total>0:
		out.append("<tr><td><B>"+times+"</B></td><td>["+host+"]</td><td><B>" + psiz(retr_total) + "</B></td><td><B>" + psiz(stor_total) + "</B></td></tr>");
    out.append('</table></td></tr>');	
    out.append("</table></center><br>");

    #print last 30 days' statistics
    statlist=[];
    for x in range(1,31):
	ttime = localtime(time()-(60*60*24*long(x)));
	times = "%02d" % ttime[0] + "-%02d" % ttime[1] + "-%02d" % ttime[2];                     
	retr_total = 0;
	stor_total = 0;
	for host in userlist[user].keys():
	    for timess in userlist[user][host].keys():
		if timess==times:
		    retr_total = retr_total + long(userlist[user][host][times]["RETR"]);
		    stor_total = stor_total + long(userlist[user][host][times]["STOR"]);
	statlist.append(retr_total);
	statlist.append(stor_total);
    u=max(statlist);
    for x in range(0,len(statlist)/2-1):
	if statlist[x]!=0:
	    statlist[x]=int((float(statlist[x])/u)*19);
	else:
	    statlist[x]=0;
    out.extend(pdchart(statlist, 'Statistics for the previous 30 days (<font color="'+tablecolor1+'">Downloads</font>/<font color="'+tablecolor2+'">Uploads</font>) [Full scale: 0 to ' + psiz(u) + ']' ));

    out.append("<br>");

    #print last 12 months' statistics
    statlist=[];
    for x in range(0,12):
	ttime = localtime(time()-(60*60*24*30*long(x)));
	times = "%02d" % ttime[0] + "-%02d" % ttime[1] + "-%02d" % ttime[2];                     
	ttime = localtime(time()-(60*60*24*30*long(x+1)));
	times1 = "%02d" % ttime[0] + "-%02d" % ttime[1] + "-%02d" % ttime[2];                     
	retr_total = 0;
	stor_total = 0;
#	for user in userlist.keys():
	for host in userlist[user].keys():
	    for timess in userlist[user][host].keys():
		if timess>times1 and timess<=times:
		    retr_total = retr_total + long(userlist[user][host][timess]["RETR"]);
		    stor_total = stor_total + long(userlist[user][host][timess]["STOR"]);

	statlist.append(retr_total);
	statlist.append(stor_total);


    u=max(statlist);
    for x in range(0,len(statlist)/2-1):
	if statlist[x]!=0:
	    statlist[x]=int((float(statlist[x])/u)*19);
	else:
	    statlist[x]=0;
    out.extend(pdchart(statlist, 'Statistics for the last 12 months (<font color="'+tablecolor1+'">Downloads</font>/<font color="'+tablecolor2+'">Uploads</font>) [Full scale: 0 to ' + psiz(u) + ']', range(0,20) ));

    tail();

    htmlfile = open (wwwroot+targetdir+fileprefix+'user_'+user+'.html',"w+");
    htmlfile.writelines(out);
    htmlfile.close();



syntax highlighted by Code2HTML, v. 0.9.1