#!/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("""
MuddleFTPD Stats v0.3
""");
out.append('');
def tail():
global out;
out.append("""
 |
Page generated by MuddleStats written by Erno Rigo, 2001 |
 |
""");
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 ''+caption+'';
# print '| | ';
# for x in values:
# print ' | ';
# print ' | ';
# print '
';
# for y in range(1,20):
# print '| | ';
# for x in values:
# if 20-x==y:
# print ' | ';
# print '
';
# l=0;
# for x in values:
# print ' | ';
# print ''+("%02d" % int(scale[l]))+' | ';
# l=l+1;
# print ' | ';
# print '
'
# ------------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(''+caption+'');
res.append('| | ');
res.append('_ | ');
lo=0;
for x in values:
res.append(' | ');
lo=lo+1;
if lo%2==0:
res.append(' | ');
res.append(' | ');
res.append('
');
for y in range(1,20):
res.append('| _ | ');
lo=0;
for x in values:
lo=lo+1;
if 20-x==y:
if lo%2==1:
res.append(' | ');
else:
res.append(' | ');
res.append('
');
l=0;
lo=0;
res.append('| | ');
for x in values:
lo=lo+1;
if lo%2==1:
res.append(' | ');
res.append(''+("%02d" % int(scale[l/2]))+' | ');
l=l+1;
res.append(' | ');
res.append(' | ');
res.append('
');
return res;
####################################################################################################
#
# MAIN PAGE
#
####################################################################################################
head();
out.append('MuddleFTPD Server Statistics
');
out.append(" Database last updated: " + ctime(stat(database)[8]) + "
");
# 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("Total data downloaded: " + psiz(retr_total) + " , total data uploaded: " + psiz(stor_total) + "
");
# 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 timeslast_rec:
last_rec=times;
out.append("First record in database: " + first_rec + " , last record in database: " + last_rec + "");
out.append("
");
out.append('Detailed user statistics
');
out.append('Detailed host summaries
');
out.append('Detailed domain statistics
');
out.append("
");
#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 + "
";
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) + "
";
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 (Downloads/Uploads) [Full scale: 0 to ' + psiz(u) + ']' ));
out.append("
");
#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 + "
";
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) + "
";
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 (Downloads/Uploads) [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('MuddleFTPD Server Statistics - Per user total usage statistics
');
out.append('Total users in database: '+str(userno)+'
');
out.append('
');
if uploads_first:
out.append('| User | Uploaded | Downloaded |
');
else:
out.append('| User | Downloaded | Uploaded |
');
t=u_total.values();
t.sort();
t.reverse();
l=0;
for us in t:
l=l+1;
if l%2==1:
out.append('| '+ us[2] +" | "+ psiz(us[0]) +" | "+ psiz(us[1]) +" |
");
else:
out.append('| '+ us[2] +" | "+ psiz(us[0]) +" | "+ psiz(us[1]) +" |
");
out.append("
");
out.append('Back to main page
');
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('MuddleFTPD Server Statistics - Per host total usage statistics
');
out.append('Total hosts in database: '+str(userno)+'
');
out.append('
');
if uploads_first:
out.append('| Host | Uploaded | Downloaded |
');
else:
out.append('| Host | Downloaded | Uploaded |
');
t=u_total.values();
t.sort();
t.reverse();
l=0;
for us in t:
l=l+1;
if l%2==1:
out.append('| '+ us[2] +" | "+ psiz(us[0]) +" | "+ psiz(us[1]) +" |
");
else:
out.append('| '+ us[2] +" | "+ psiz(us[0]) +" | "+ psiz(us[1]) +" |
");
out.append("
");
out.append('Back to main page
');
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('MuddleFTPD Server Statistics - Per level 1 domain total usage statistics
');
out.append('Total domains in this section: '+str(userno)+'
');
out.append('
');
if uploads_first:
out.append('| Domain | Uploaded | Downloaded |
');
else:
out.append('| Domain | Downloaded | Uploaded |
');
t=u_total.values();
t.sort();
t.reverse();
l=0;
for us in t:
l=l+1;
if l%2==1:
out.append('| '+ us[2] +" | "+ psiz(us[0]) +" | "+ psiz(us[1]) +" |
");
else:
out.append('| '+ us[2] +" | "+ psiz(us[0]) +" | "+ psiz(us[1]) +" |
");
out.append("
");
out.append('Back to main page
');
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('MuddleFTPD Server Statistics - total usage statistics for the '+curr_domain+' domains
');
out.append('Total domains in this section: '+str(userno)+'
');
#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 (Downloads/Uploads) [Full scale: 0 to ' + psiz(u) + ']' ));
out.append("
");
#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 (Downloads/Uploads) [Full scale: 0 to ' + psiz(u) + ']' ,range(0,20)));
out.append("
");
out.append('
');
if uploads_first:
out.append('| Domain | Uploaded | Downloaded |
');
else:
out.append('| Domain | Downloaded | Uploaded |
');
t=u_total.values();
t.sort();
t.reverse();
l=0;
for us in t:
l=l+1;
if l%2==1:
out.append('| '+ us[2] +" | "+ psiz(us[0]) +" | "+ psiz(us[1]) +" |
");
else:
out.append('| '+ us[2] +" | "+ psiz(us[0]) +" | "+ psiz(us[1]) +" |
");
out.append("
");
out.append('Back to main page
');
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('');
out.append('| Statistics for user '+user+' | back |
');
#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('| Total downloaded: '+psiz(uretr_total)+' Total uploaded: '+psiz(ustor_total)+' |
');
out.append('| Last logged activity time: '+lastlogin+' |
');
#favourite hosts
out.append('| Favourite host(s): |
');
out.append('');
for host in userlist[user].keys():
out.append('| '+host+' | [last use: '+max(userlist[user][host].keys())+'] | ');
out.append(' |
');
# 30 days' usage
out.append('| Activity during the previous 30 days: |
');
out.append('');
out.append('');
out.append("| Time | from host | Downloads | Uploads | ");
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("| "+times+" | ["+host+"] | " + psiz(retr_total) + " | " + psiz(stor_total) + " | ");
out.append(' |
');
out.append("
");
#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 (Downloads/Uploads) [Full scale: 0 to ' + psiz(u) + ']' ));
out.append("
");
#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 (Downloads/Uploads) [Full scale: 0 to ' + psiz(u) + ']', range(0,20) ));
tail();
htmlfile = open (wwwroot+targetdir+fileprefix+'user_'+user+'.html',"w+");
htmlfile.writelines(out);
htmlfile.close();