updated viewer:pie chart
authorMarius Sandu-Popa <sandupopamarius@gmail.com>
Fri, 11 Dec 2009 09:38:29 +0000 (11:38 +0200)
committerMarius Sandu-Popa <sandupopamarius@gmail.com>
Fri, 11 Dec 2009 09:38:29 +0000 (11:38 +0200)
auto/db/DatabaseAccess.py
viewer/DbObjects.py
viewer/p2p-nexteditor.py

index 116eb30..fd117d8 100644 (file)
@@ -2,6 +2,7 @@
 
 import sys
 import sqlite3
+import os.path
 
 DEBUG = False
 
@@ -22,8 +23,11 @@ class DatabaseAccess:
         self.dbname = dbname
 
     def connect(self):
+       if not os.path.isfile(self.dbname):
+               return False
         self.conn = sqlite3.connect(self.dbname)
         self.cursor = self.conn.cursor()
+       return True
 
     def disconnect(self):
         self.cursor.close()
index bb287ea..10cad8d 100644 (file)
@@ -2,146 +2,188 @@ from DatabaseAccess import DatabaseAccess
 import sqlite3
 
 class Swarm:
-    def __init__(self, dbname, id, row=None):
-       dba=DatabaseAccess(dbname);
-       dba.connect();
-       curs = dba.select_swarms(False, id);
-       row = curs.fetchone(); 
-       dba.disconnect();
-       
-       self.id = row[0];
-       self.torrent = row[1];
-       self.filesize = row[2];
-       self.purpose = row[3];
-       self.source = row[4];
-    
-    def __str__(self):
-       return '[%s, %s, %s, %s, %s]' \
-           %(self.id, self.torrent, self.filesize, self.purpose, self.source);
+       def __init__(self, dbname, id, row=None):
+               dba=DatabaseAccess(dbname);
+               if not dba.connect():
+                       raise DbObjException("swarm", "database connection error")
+                       return
+               curs = dba.select_swarms(False, id);
+               if not curs:
+                       raise DbObjException("swarm", "database query error")
+                       return
+               row = curs.fetchone(); 
+               dba.disconnect();
+               self.id = row[0];
+               self.torrent = row[1];
+               self.filesize = row[2];
+               self.purpose = row[3];
+               self.source = row[4];
+               
+       def __str__(self):
+               return '[%s, %s, %s, %s, %s]' \
+                       %(self.id, self.torrent, self.filesize, self.purpose, self.source);
 
 class BtClient:
-    def __init__(self, dbname, id, name=None):
-       dba=DatabaseAccess(dbname);
-       dba.connect();
-       if name:
-           curs = dba.select_btclient_by_name(name, False);
-       else:
-           curs = dba.select_btclients(False, id);
-       row = curs.fetchone();
-       dba.disconnect();
-       
-       self.id = id;
-       self.name = row[1];
-       self.language = row[2];
-       self.dht = row[3];
-       self.streaming = row[4];
+       def __init__(self, dbname, id, name=None):
+               dba=DatabaseAccess(dbname);
+               if not dba.connect():
+                       raise DbObjException("btclient", "database connection error")
+                       return
+               dba.connect();
+               if name:
+                       curs = dba.select_btclient_by_name(name, False);
+               else:
+                       curs = dba.select_btclients(False, id);
+               if not curs:
+                       raise DbObjException("btclient", "database query error")
+                       return
+               row = curs.fetchone();
+               dba.disconnect();
+               self.id = id;
+               self.name = row[1];
+               self.language = row[2];
+               self.dht = row[3];
+               self.streaming = row[4];
        
-    def __str__(self):
-       return '[%s %s, %s, %s, %s]' \
-           %(self.id, self.name, self.language, self.dht, self.streaming);
+       def __str__(self):
+               return '[%s %s, %s, %s, %s]' \
+                       %(self.id, self.name, self.language, self.dht, self.streaming);
 
 class ClientSession:
-    def __init__(self, dbname=None, id=None, row=None):
-       if not row:
-           dba=DatabaseAccess(dbname);
-           dba.connect();
-           curs = dba.select_client_sessions_by_id(False, id);
-           row = curs.fetchone();
-           dba.disconnect();
-           
-       self.id = row[0];
-       self.swarm_id = row[1];
-       self.client_id = row[2];
-       #self.swarm = Swarm(curs[1]);
-       #self.btclient = BtClient(curs[2]);
-       self.system_os = row[3];
-       self.system_os_version = row[4];
-       self.system_ram = row[5];
-       self.system_cpu = row[6];
-       self.public_ip = row[7];
-       self.public_port = row[8];
-       self.ds_limit = row[9];
-       self.us_limit = row[10];
-       self.start_time = row[11];
+       def __init__(self, dbname=None, id=None, row=None):
+               if not row:
+                       dba=DatabaseAccess(dbname);
+                       if not dba.connect():
+                               raise DbObjException("clientsession", "database connection error")
+                               return
+                       curs = dba.select_client_sessions_by_id(False, id);
+                       if not curs:
+                               raise DbObjException("clientsession", "database query error")
+                               return
+                       row = curs.fetchone();
+                       dba.disconnect();
+               
+               if not row:
+                       raise DbObjException("clientsession", "database query error")
+                       return
+               self.id = row[0];
+               self.swarm_id = row[1];
+               self.client_id = row[2];
+               #self.swarm = Swarm(curs[1]);
+               #self.btclient = BtClient(curs[2]);
+               self.system_os = row[3];
+               self.system_os_version = row[4];
+               self.system_ram = row[5];
+               self.system_cpu = row[6];
+               self.public_ip = row[7];
+               self.public_port = row[8];
+               self.ds_limit = row[9];
+               self.us_limit = row[10];
+               self.start_time = row[11];
        
-    def __str__(self):
-       return '[%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s]' \
-           %(self.id, self.swarm_id, self.client_id, self.system_os, \
-           self.system_os_version, self.system_ram, self.system_cpu, \
-           self.public_ip, self.public_port, self.ds_limit, self.us_limit, self.start_time);
+       def __str__(self):
+               return '[%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s]' \
+                       %(self.id, self.swarm_id, self.client_id, self.system_os, \
+                       self.system_os_version, self.system_ram, self.system_cpu, \
+                       self.public_ip, self.public_port, self.ds_limit, self.us_limit, self.start_time);
 
 class ClientSessionCollection:
-    def __init__(self, dbname, swarm_id, client_id=None):
-       dba=DatabaseAccess(dbname);
-       dba.connect();
-       curs = dba.select_client_sessions_by_swarm(False, swarm_id, client_id);
-       self.css = [];
-       for row in curs:
-           self.css.append(ClientSession(None, None, row));
-       dba.disconnect();
-    
-    def getIter(self):
-       return iter(self.css);
-    
+       def __init__(self, dbname, swarm_id, client_id=None):
+               dba=DatabaseAccess(dbname);
+               if not dba.connect():
+                       raise DbObjException("clientsession", "database connection error")
+                       return
+               curs = dba.select_client_sessions_by_swarm(False, swarm_id, client_id);
+               self.css = [];
+               for row in curs:
+                       self.css.append(ClientSession(None, None, row));
+               dba.disconnect();
+       
+       def getIter(self):
+               return iter(self.css);
+       
 
 class StatusMessage:
-    def __init__(self, row):
-       self.client_session = row[0]
-       self.timestamp = row[1];
-       self.peers_num = row[2];
-       self.dht = row[3];
-       self.download_speed = row[4];
-       self.upload_speed = row[5];
-       self.download_size = row[6];
-       self.upload_size = row[7];
-       self.eta = row[8];
+       def __init__(self, row):
+               self.client_session = row[0]
+               self.timestamp = row[1];
+               self.peers_num = row[2];
+               self.dht = row[3];
+               self.download_speed = row[4];
+               self.upload_speed = row[5];
+               self.download_size = row[6];
+               self.upload_size = row[7];
+               self.eta = row[8];
        
-    def __str__(self):
-       return '[%s, %s, %s, %s, %s, %s, %s, %s, %s]' \
-           %(self.client_session, self.timestamp, self.peers_num, self.dht, \
-           self.download_speed, self.upload_speed, self.download_size, self.upload_size, self.eta);
+       def __str__(self):
+               return '[%s, %s, %s, %s, %s, %s, %s, %s, %s]' \
+                       %(self.client_session, self.timestamp, self.peers_num, self.dht, \
+                       self.download_speed, self.upload_speed, self.download_size, self.upload_size, self.eta);
 
 class StatusMessageCollection:
-    def __init__(self, dbname, cs_id, restrictions=None):
-       dba=DatabaseAccess(dbname);
-       dba.connect();
-       curs = dba.select_status_messages(False, cs_id, restrictions);
-       self.stms = []
-       for row in curs.fetchall():
-           #self.stms.append(StatusMessage(client_session, row))
-           self.stms.append(StatusMessage(row));
-       dba.disconnect();
+       def __init__(self, dbname, cs_id, restrictions=None):
+               dba=DatabaseAccess(dbname);
+               if not dba.connect():
+                       return
+               self.curs = dba.select_status_messages(False, cs_id, restrictions);
+               #~ self.stms = []
+               #~ for row in curs:
+                       #~ #self.stms.append(StatusMessage(client_session, row))
+                       #~ self.stms.append(StatusMessage(row));
+               #~ dba.disconnect();
+               
+       def getNext(self):
+               row = self.curs.fetchone()
+               if row:
+                       return  StatusMessage(row) 
+               return None
        
-    def getIter(self):
-       return iter(self.stms);
+       def getIter(self):
+               return iter(self.stms);
 
 class VerboseMessage:
-    def __init__(self, row):
-       self.client_session = row[0];
-       self.timestamp = row[1];
-       self.peer_ip = row[2];
-       self.peer_port = row[3];
-       self.message_type = row[4];
-       self.index = row[5];
-       self.begin = row[6];
-       self.length = row[7];
-       self.listen_port = row[8];
+       def __init__(self, row):
+               self.client_session = row[0];
+               self.timestamp = row[1];
+               self.direction = row[2];
+               self.peer_ip = row[3];
+               self.peer_port = row[4];
+               self.message_type = row[5];
+               self.index = row[6];
+               self.begin = row[7];
+               self.length = row[8];
+               self.listen_port = row[9];
        
-    def __str__(self):
-       return '[%s, %s, %s, %s, %s, %s, %s, %s, %s]' \
-           %(self.client_session, self.timestamp, self.peer_ip, self.peer_port, \
-           self.message_type, self.index, self.begin, sself.length, self.listen_port);
+       def __str__(self):
+               return '[%s, %s, %s, %s, %s, %s, %s, %s, %s, %s]' \
+                       %(self.client_session, self.timestamp, self.direction, self.peer_ip, self.peer_port, \
+                       self.message_type, self.index, self.begin, self.length, self.listen_port);
 
 class VerboseMessageCollection:
-    def __init__(self, dbname, cs_id, restrictions=None):
-       dba=DatabaseAccess(dbname);
-       dba.connect();
-       curs = dba.select_verbose_messages(False, cs_id, restrictions);
-       self.vbms = [];
-       for row in curs:
-           #self.vbms.append(VerboseMessage(client_session, row))
-           self.vbms.append(VerboseMessage(row));
-       dba.disconnect();
+       def __init__(self, dbname, cs_id, restrictions=None):
+               dba=DatabaseAccess(dbname);
+               if not dba.connect():
+                       return
+               self.curs = dba.select_verbose_messages(False, cs_id, restrictions);
+               #~ self.vbms = [];
+               #~ for row in curs:
+                       #~ #self.vbms.append(VerboseMessage(client_session, row))
+                       #~ self.vbms.append(VerboseMessage(row));
+               #~ dba.disconnect();
        
-    def getIter(self):
-       return iter(self.vbms);
+       def getNext(self):
+               row = self.curs.fetchone()
+               if row:
+                       return  VerboseMessage(row) 
+               return None
+               
+       def getIter(self):
+               return iter(self.vbms);
+               
+
+class DbObjException(Exception):
+       def __init__(self, obj, msg):
+               self.obj = obj
+               self.msg = msg
+        def __str__(self):
+               return "[" + self.obj  + "]: " + self.msg
index 25d6b42..74575dd 100644 (file)
@@ -15,298 +15,391 @@ from config import *
 import sys
 import getopt
 import wx
+import numpy as np
 
 class PlotterThread(Thread):
-    def __init__ (self, dbname, cs_id, axes_id, plot_figure, options):
-       Thread.__init__(self)
-       self.dbname = dbname
-        self.cs_id = cs_id
-        self.axes_id = axes_id
-       self.plot_figure = plot_figure
-        self.options = options
+       def __init__ (self, dbname, cs_id, axes_id, plot_figure, options, type):
+               Thread.__init__(self)
+               self.dbname = dbname
+               self.cs_id = cs_id
+               self.axes_id = axes_id
+               self.plot_figure = plot_figure
+               self.options = options
+               self.type = type
+               self.msg_types = {0:[0, "CHOKE"], 1:[0, "UNCHOKE"], 2:[0, "INTERESTED"], 3: [0, "NOT_INTERESTED"], \
+                 4:[0, "HAVE"], 5:[0, "BITFIELD"], 6:[0, "REQUEST"], 7:[0, "PIECE"], 8:[0, "CANCEL"], \
+                 9:[0, "DHT_PORT"]}
        
-    def run(self):
-        self.plot_graph()
-    
-    def plot_stat_graph(self):
-        pass
-    
-    def plot_graph(self):
-        cs = ClientSession(self.dbname, self.cs_id)
-        x = []; y = {'ds':[], 'us':[], 'acc_us':[], 'acc_ds':[]}
-        restrictions = [];
-        prev_us = 0; prev_ds = 0;
-        date2 = julianToDatetime(cs.start_time)
-        td = timedelta(days=date2.day, \
-             seconds=date2.second, \
-             minutes=date2.minute, \
-             hours=date2.hour, \
-             microseconds=date2.microsecond)
-        
-        if self.options[3]:
-            date_start = self.time_from_date(date2, self.options[3])            
-            restrictions.append(('timestamp', float(datetimeToJulian(date_start)), 'gte'))
-        
-        if self.options[4]:
-            date_stop = self.time_from_date(date2, self.options[4])
-            restrictions.append(('timestamp', float(datetimeToJulian(date_stop)), 'lte'))
-           
-        stmc = StatusMessageCollection(self.dbname, self.cs_id, restrictions)
-        stmit = stmc.getIter()
-        while True:
-            try:
-                  stm = next(stmit)
-            except StopIteration:
-                  break
-            date1 = julianToDatetime(stm.timestamp)
-            difftime = date1 - td
-            x.append(date2num(difftime))
-            if self.options[1]:
-                  y['ds'].append(stm.download_speed)
-                  if self.options[0]:
-                      y['acc_ds'].append(stm.download_speed - prev_ds);
-                      prev_ds = stm.download_speed;
-            if self.options[2]:    
-                  y['us'].append(stm.upload_speed)
-                  if self.options[0]:
-                      y['acc_us'].append(stm.upload_speed - prev_us);
-                      prev_us = stm.upload_speed;
-        self.plot_figure(self.cs_id, self.axes_id, x, y)
+       def run(self):
+               if self.type:
+                       self.plot_graph()
+               else:
+                       self.plot_stat_graph()
+       
+       def plot_stat_graph(self):
+               try:
+                       cs = ClientSession(self.dbname, self.cs_id)
+               except DbObjException as e:
+                       print e
+                       return
+               restrictions = [];
+               date = julianToDatetime(cs.start_time)
+               if self.options[3]:
+                       date_start = self.time_from_date(date, self.options[3])            
+                       restrictions.append(('timestamp', float(datetimeToJulian(date_start)), 'gte'))
+               
+               if self.options[4]:
+                       date_stop = self.time_from_date(date, self.options[4])
+                       restrictions.append(('timestamp', float(datetimeToJulian(date_stop)), 'lte'))
+               
+               vbmc = VerboseMessageCollection(self.dbname, self.cs_id, restrictions)
+               while True:
+                       vbm = vbmc.getNext()
+                       if not vbm:
+                               break
+                       self.msg_types[vbm.message_type][0] = self.msg_types[vbm.message_type][0] + 1
+               #~ vbmc = VerboseMessageCollection(self.dbname, self.cs_id, restrictions)
+               #~ vbmcit = vbmc.getIter()
+               #~ while True:
+                       #~ try:
+                               #~ vbm = next(vbmcit)
+                       #~ except StopIteration:
+                               #~ break
+                       #~ self.msg_types[vbm.message_type][0] = self.msg_types[vbm.message_type][0] + 1
+                       #~ total = total+1
+               self.plot_figure(self.cs_id, self.axes_id, self.msg_types)
+       
+       def plot_graph(self):
+               try:
+                       cs = ClientSession(self.dbname, self.cs_id)
+               except DbObjException as e:
+                       print e
+                       return
+               x = []; y = {'ds':[], 'us':[], 'acc_us':[], 'acc_ds':[]}
+               restrictions = [];
+               prev_us = 0; prev_ds = 0;
+               date2 = julianToDatetime(cs.start_time)
+               td = timedelta(days=date2.day, \
+                        seconds=date2.second, \
+                        minutes=date2.minute, \
+                        hours=date2.hour, \
+                        microseconds=date2.microsecond)
+               
+               if self.options[3]:
+                       date_start = self.time_from_date(date2, self.options[3])            
+                       restrictions.append(('timestamp', float(datetimeToJulian(date_start)), 'gte'))
+               
+               if self.options[4]:
+                       date_stop = self.time_from_date(date2, self.options[4])
+                       restrictions.append(('timestamp', float(datetimeToJulian(date_stop)), 'lte'))
+                 
+               stmc = StatusMessageCollection(self.dbname, self.cs_id, restrictions)
+               while True:
+                       stm = stmc.getNext()
+                       if not stm:
+                               break
+               #~ stmc = StatusMessageCollection(self.dbname, self.cs_id, restrictions)
+               #~ stmit = stmc.getIter()
+               #~ while True:
+                       #~ try:
+                                 #~ stm = next(stmit)
+                       #~ except StopIteration:
+                                 #~ break
+                       date1 = julianToDatetime(stm.timestamp)
+                       difftime = date1 - td
+                       x.append(date2num(difftime))
+                       if self.options[1]:
+                                 y['ds'].append(stm.download_speed)
+                                 if self.options[0]:
+                                         y['acc_ds'].append(stm.download_speed - prev_ds);
+                                         prev_ds = stm.download_speed;
+                       if self.options[2]:    
+                                 y['us'].append(stm.upload_speed)
+                                 if self.options[0]:
+                                         y['acc_us'].append(stm.upload_speed - prev_us);
+                                         prev_us = stm.upload_speed;
+               self.plot_figure(self.cs_id, self.axes_id, x, y)
 
-    def time_from_date(self, date, tstr):
-        time = strptime(tstr, "%H:%M:%S")
-        td = timedelta(seconds=time.tm_sec, minutes=time.tm_min, hours=time.tm_hour)
-        return (date + td)
+       def time_from_date(self, date, tstr):
+               time = strptime(tstr, "%H:%M:%S")
+               td = timedelta(seconds=time.tm_sec, minutes=time.tm_min, hours=time.tm_hour)
+               return (date + td)
 
 class ControlPanel(HasTraits):
-    #swarm widget
-    dbname = String(auto_set=False, enter_set=True)
-    sw_torrent = String()
-    sw_filesize = String()
-    sw_purpose = String ()
-    sw_source = String()   
-    sw_figure = Instance(Figure)
-    
-    #btclients widget
-    btc_id = String()
-    btc_name = String()
-    btc_language = String()
-    btc_dht = Bool()
-    btc_streaming = Bool()
-    
-    #client_sessions widget
-    cs_id = String(auto_set=False, enter_set=True)
-    cs_os = String()
-    cs_os_vs = String()
-    cs_os_cpu = String()
-    cs_os_ram = String()
-    cs_public_ip = String()
-    cs_public_port = String()
-    cs_ds_limit = String()
-    cs_us_limit = String()
-    cs_start_time = CStr()
-    
-    cs_id2 = String(auto_set=False, enter_set=True)
-    cs_ds_limit2 = String()
-    cs_us_limit2 = String()
-    cs_start_time2 = CStr()
-    
-    #options widget
-    time_start = Str()
-    time_stop = Str()
-    download_speed = Bool()
-    upload_speed = Bool()
-    acceleration = Bool()
-    plot = Button()
-    
-    
-    views = Enum('Simple', 'Split', 'Adder')
-    speeds = Enum('Download Speed', 'Upload Speed') 
-    plot2 = Button()
-    
-    help = String('''
-               P2P-Next Analyzer
-               version 1.00
-    ''')
-    
-    def __init__(self, figure):
-       self.figure = figure;
-        axes = self.figure.add_axes((0.03, 0.06, 0.93, 0.91))
-       axes.grid(linestyle='dashed')
+       #swarm widget
+       dbname = String(auto_set=False, enter_set=True)
+       sw_torrent = String()
+       sw_filesize = String()
+       sw_purpose = String ()
+       sw_source = String()   
+       sw_figure = Instance(Figure)
+       
+       #btclients widget
+       btc_id = String()
+       btc_name = String()
+       btc_language = String()
+       btc_dht = Bool()
+       btc_streaming = Bool()
+       
+       #client_sessions widget
+       cs_id = String(auto_set=False, enter_set=True)
+       cs_os = String()
+       cs_os_vs = String()
+       cs_os_cpu = String()
+       cs_os_ram = String()
+       cs_public_ip = String()
+       cs_public_port = String()
+       cs_ds_limit = String()
+       cs_us_limit = String()
+       cs_start_time = CStr()
+       
+       cs_id2 = String(auto_set=False, enter_set=True)
+       cs_ds_limit2 = String()
+       cs_us_limit2 = String()
+       cs_start_time2 = CStr()
+       
+       #options widget
+       time_start = Str()
+       time_stop = Str()
+       download_speed = Bool()
+       upload_speed = Bool()
+       acceleration = Bool()
+       stats = Bool()
+       plot = Button()
+       
+       
+       views = Enum('Simple', 'Split', 'Adder')
+       speeds = Enum('Download Speed', 'Upload Speed') 
+       plot2 = Button()
+       
+       help = String('''
+               P2P-Next Viewer
+               version 1.0
+       ''')
        
-    view = View(Group(
-                    Group(
-                        Item('dbname', label='Database File', style='text'),
-                               Item('20'),
-                        Group(
-                                   Item('sw_torrent', label='Torrent'),
-                                   Item('sw_filesize', label='Filesize(Kb)'),
-                                   Item('sw_purpose', label='Purpose'),
-                                   Item('sw_source', label='Source'),
-                                   show_border=True, label='Swarm', style='readonly'),
-                               Item('10'),
-                        Group(
-                                   Item('cs_id', label='Id', style='simple'),
-                                   Item('10'),
-                                   Item('cs_os', label='OS'),
-                                   Item('cs_os_vs', label='OS Version'),
-                                   Item('cs_os_cpu', label='System CPU'),
-                                   Item('cs_os_ram', label='System RAM'),
-                                   Item('cs_public_ip', label='Public IP'),
-                                   Item('cs_public_port', label='Public PORT'),
-                               Item('cs_ds_limit', label='Download LMT'),
-                                   Item('cs_us_limit', label='Upload LMT'),
-                                   Item('cs_start_time', label='Start Time'),
-                                   show_border=True, label='Client Session', style='readonly'),
-                               Group(
-                        HGroup(Item('time_start', label='Start'),
-                               Item('40'),
-                               Item('time_stop', label='Stop')),
-                        HGroup('download_speed',Item('30'), 'upload_speed'),
-                        Item('acceleration'),
-                               show_border=True, label='Plotting Options'),
-                        Item('10'),
-                               Item('plot', show_label=False),
-                               label="Client", dock='tab', style='simple'),
-                    Group(
-                        Item('dbname', label='Database File', style='text'),
-                        Item('20'),
-                        Group(
-                            Item('cs_id', label='Id', style='simple'),
-                            Item('10'),
-                            Item('cs_ds_limit', label='Download LMT'),
-                            Item('cs_us_limit', label='Upload LMT'),
-                            Item('cs_start_time', label='Start Time'),
-                            show_border=True, label='Client Session 1', style='readonly'),
-                        Group(
-                            Item('cs_id2', label='Id', style='simple'),
-                            Item('10'),
-                            Item('cs_ds_limit2', label='Download LMT'),
-                            Item('cs_us_limit2', label='Upload LMT'),
-                            Item('cs_start_time2', label='Start Time'),
-                            show_border=True, label='Client Session 2', style='readonly', 
-                                enabled_when='object.views != \'Adder\''), 
-                        Group(
-                        HGroup(Item('time_start', label='Start'),
-                               Item('40'),
-                               Item('time_stop', label='Stop')),
-                        Group(
-                        Item('speeds', show_label=False, style='simple'),
-                        Item('views', show_label=False, style='simple')),
-                        Item('acceleration'),
-                        show_border=True, label='Plotting Options'),
-                        Item('10'),
-                        Item('plot2', show_label=False, height=100),
-                    label='Comparison', dock="tab"),
-                Item('help', style='readonly', show_label=False, dock="tab"),
-                layout='tabbed')
-                )
-    
-    def _dbname_changed(self):
-       sw = Swarm(dbpath + self.dbname + dbextension, -1);
-       self.sw_id = sw.id;
-       self.sw_torrent = sw.torrent
-       self.sw_filesize = sw.filesize;
-       self.sw_purpose = sw.purpose;
-       self.sw_source = sw.source;
-    
-    def _cs_id_changed(self, new):
-       cs = ClientSession(dbpath + self.dbname + dbextension, new);
-       self.cs_os = cs.system_os
-       self.cs_os_vs = cs.system_os_version
-       self.cs_os_cpu = cs.system_cpu
-       self.cs_os_ram = cs.system_ram
-       self.cs_public_ip = cs.public_ip
-       self.cs_public_port = cs.public_port
-       self.cs_ds_limit = cs.ds_limit
-       self.cs_us_limit = cs.us_limit
-       self.cs_start_time = julianToDatetime(cs.start_time)
-    
-    def _cs_id2_changed(self, new):
-        cs = ClientSession(dbpath + self.dbname + dbextension, new);
-        self.cs_ds_limit2 = cs.ds_limit
-        self.cs_us_limit2 = cs.us_limit
-        self.cs_start_time2 = julianToDatetime(cs.start_time)
+       def __init__(self, figure):
+               self.figure = figure;
+               axes = self.figure.add_axes((0.03, 0.06, 0.93, 0.91))
+               axes.grid(linestyle='dashed')
        
-    def _plot_fired(self):
-       if len(self.cs_id)  and (self.download_speed or self.upload_speed):
-           self.figure.clf();
-            self.axes = self.figure.add_subplot(1,1,1)
-            self.axes.grid(linestyle='dashed')
-            self.figure.subplots_adjust(left=0.03, right=0.97, top=0.98)
-            dbfile = dbpath + self.dbname + dbextension
-            options = [self.acceleration, self.download_speed, self.upload_speed, self.time_start, self.time_stop]
-           PlotterThread(dbfile, self.cs_id, 0, self.plot_figure, options).start()
-    
-    def _views_changed(self, new):
-        if new == 'Adder':
-            self.figure.clf();
-            axes = self.figure.add_subplot(1,1,1)
-            axes.grid(linestyle='dashed')
-            self.figure.subplots_adjust(left=0.03, right=0.97, top=0.98)
-    
-    def _plot2_fired(self):
-        if (len(self.cs_id) or len(self.cs_id2)):
-            #self.axes.grid(linestyle='dashed')
-            dbfile = dbpath + self.dbname + dbextension
-            print self.speeds
-            if self.speeds=='Download Speed':   
-                options = [self.acceleration, True, False, self.time_start, self.time_stop] 
-            else:
-                options = [self.acceleration, False, True, self.time_start, self.time_stop]
-            
-            if self.views == 'Split':
-                self.figure.clf();
-                axes = self.figure.add_subplot(2,1,1)
-                axes.grid(linestyle='dashed')
-                axes = self.figure.add_subplot(2,1,2)
-                axes.grid(linestyle='dashed')
-                self.figure.subplots_adjust(left=0.03, right=0.97, top=0.98)
-                PlotterThread(dbfile, self.cs_id, 0, self.plot_figure, options).start() 
-                PlotterThread(dbfile, self.cs_id2, 1, self.plot_figure, options).start() 
-            elif self.views == 'Adder':
-                PlotterThread(dbfile, self.cs_id, 0, self.plot_figure, options).start() 
-            else:
-                self.figure.clf();
-                axes = self.figure.add_subplot(1,1,1)
-                axes.grid(linestyle='dashed')
-                self.figure.subplots_adjust(left=0.03, right=0.97, top=0.98)
-                PlotterThread(dbfile, self.cs_id, 0, self.plot_figure, options).start() 
-                PlotterThread(dbfile, self.cs_id2, 0, self.plot_figure, options).start()      
-    
-    def plot_figure(self, cs_id, axes_id, x, y):
-        axes_list = self.figure.get_axes()
-        axes = axes_list[axes_id]
-        for key in y.keys():
-            if y[key]:
-                axes.plot_date(x, y[key],'-', label=key+' Client '+cs_id)
-        axes.xaxis.set_major_formatter(DateFormatter('%H:%M:%S'))
-       #self.axes.set_xlabel("time (s)")
-        axes.legend(shadow=True, fancybox=True)
-        self.figure.autofmt_xdate(bottom=0.05, rotation=25)
-       wx.CallAfter(self.figure.canvas.draw)
-    
+       view = View(Group(
+                                       Group(
+                                               Item('dbname', label='Database File', style='text'),
+                                               Item('20'),
+                                               Group(
+                                                       Item('sw_torrent', label='Torrent'),
+                                                       Item('sw_filesize', label='Filesize(Kb)'),
+                                                       Item('sw_purpose', label='Purpose'),
+                                                       Item('sw_source', label='Source'),
+                                                       show_border=True, label='Swarm', style='readonly'),
+                                               Item('10'),
+                                               Group(
+                                                       Item('cs_id', label='Id', style='simple'),
+                                                       Item('10'),
+                                                       Item('cs_os', label='OS'),
+                                                       Item('cs_os_vs', label='OS Version'),
+                                                       Item('cs_os_cpu', label='System CPU'),
+                                                       Item('cs_os_ram', label='System RAM'),
+                                                       Item('cs_public_ip', label='Public IP'),
+                                                       Item('cs_public_port', label='Public PORT'),
+                                                       Item('cs_ds_limit', label='Download LMT'),
+                                                       Item('cs_us_limit', label='Upload LMT'),
+                                                       Item('cs_start_time', label='Start Time'),
+                                                       show_border=True, label='Client Session', style='readonly'),
+                                               Group(
+                                               HGroup(Item('time_start', label='Start'),
+                                                          Item('40'),
+                                                          Item('time_stop', label='Stop')),
+                                               HGroup('download_speed',Item('30'), 'upload_speed'),
+                                               HGroup(
+                                                       Item('acceleration'),
+                                                       Item('58'),
+                                                       Item('stats', label="Statistics")),
+                                               show_border=True, label='Plotting Options'),
+                                               Item('10'),
+                                               Item('plot', show_label=False),
+                                               label="Client", dock='tab', style='simple'),
+                                       Group(
+                                               Item('dbname', label='Database File', style='text'),
+                                               Item('20'),
+                                               Group(
+                                                       Item('cs_id', label='Id', style='simple'),
+                                                       Item('10'),
+                                                       Item('cs_ds_limit', label='Download LMT'),
+                                                       Item('cs_us_limit', label='Upload LMT'),
+                                                       Item('cs_start_time', label='Start Time'),
+                                                       show_border=True, label='Client Session 1', style='readonly'),
+                                               Group(
+                                                       Item('cs_id2', label='Id', style='simple'),
+                                                       Item('10'),
+                                                       Item('cs_ds_limit2', label='Download LMT'),
+                                                       Item('cs_us_limit2', label='Upload LMT'),
+                                                       Item('cs_start_time2', label='Start Time'),
+                                                       show_border=True, label='Client Session 2', style='readonly', 
+                                                               enabled_when='object.views != \'Adder\''), 
+                                               Group(
+                                               HGroup(Item('time_start', label='Start'),
+                                                          Item('40'),
+                                                          Item('time_stop', label='Stop')),
+                                               Group(
+                                               Item('speeds', show_label=False, style='simple'),
+                                               Item('views', show_label=False, style='simple')),
+                                               Item('acceleration'),
+                                               show_border=True, label='Plotting Options'),
+                                               Item('10'),
+                                               Item('plot2', show_label=False, height=100),
+                                       label='Comparison', dock="tab"),
+                               Item('help', style='readonly', show_label=False, dock="tab"),
+                               layout='tabbed')
+                               )
+       
+       def _dbname_changed(self):
+               try:
+                       sw = Swarm(dbpath + self.dbname + dbextension, -1);
+                       self.sw_id = sw.id;
+                       self.sw_torrent = sw.torrent
+                       self.sw_filesize = sw.filesize;
+                       self.sw_purpose = sw.purpose;
+                       self.sw_source = sw.source;
+               except DbObjException as e:
+                       print e
+       
+       def _cs_id_changed(self, new):
+               try:
+                       cs = ClientSession(dbpath + self.dbname + dbextension, new);
+                       self.cs_os = cs.system_os
+                       self.cs_os_vs = cs.system_os_version
+                       self.cs_os_cpu = cs.system_cpu
+                       self.cs_os_ram = cs.system_ram
+                       self.cs_public_ip = cs.public_ip
+                       self.cs_public_port = cs.public_port
+                       self.cs_ds_limit = cs.ds_limit
+                       self.cs_us_limit = cs.us_limit
+                       self.cs_start_time = julianToDatetime(cs.start_time)
+               except DbObjException as e:
+                       print e
+                       
+       
+       def _cs_id2_changed(self, new):
+               try:
+                       cs = ClientSession(dbpath + self.dbname + dbextension, new);
+                       self.cs_ds_limit2 = cs.ds_limit
+                       self.cs_us_limit2 = cs.us_limit
+                       self.cs_start_time2 = julianToDatetime(cs.start_time)
+               except DbObjException as e:
+                       print e
+       
+       def _plot_fired(self):
+               if len(self.cs_id)  and (self.download_speed or self.upload_speed):
+                       dbfile = dbpath + self.dbname + dbextension
+                       options = [self.acceleration, self.download_speed, self.upload_speed, self.time_start, self.time_stop]
+                       self.figure.clf();
+                       if not self.stats:
+                               axes = self.figure.add_subplot(1,1,1)
+                               axes.grid(linestyle='dashed')
+                               self.figure.subplots_adjust(left=0.03, right=0.97, top=0.98)
+                               PlotterThread(dbfile, self.cs_id, 0, self.plot_figure, options, 1).start()
+                       else:
+                               axes = self.figure.add_subplot(2,1,2)
+                               axes.grid(linestyle='dashed')
+                               axes = self.figure.add_subplot(2,2,1)
+                               axes = self.figure.add_subplot(2,2,2)
+                               axes.grid(linestyle='dashed')
+                               self.figure.subplots_adjust(left=0.03, right=0.97, top=0.98, hspace=0.07, wspace=0.6)
+                               PlotterThread(dbfile, self.cs_id, 1, self.plot_stats_figure, options, 0).start()
+                               PlotterThread(dbfile, self.cs_id, 0, self.plot_figure, options, 1).start()
+       
+       def _views_changed(self, new):
+               if new == 'Adder':
+                       self.figure.clf();
+                       axes = self.figure.add_subplot(1,1,1)
+                       axes.grid(linestyle='dashed')
+                       self.figure.subplots_adjust(left=0.03, right=0.97, top=0.98)
+       
+       def _plot2_fired(self):
+               if (len(self.cs_id) or len(self.cs_id2)):
+                       #self.axes.grid(linestyle='dashed')
+                       dbfile = dbpath + self.dbname + dbextension
+                       print self.speeds
+                       if self.speeds=='Download Speed':   
+                               options = [self.acceleration, True, False, self.time_start, self.time_stop] 
+                       else:
+                               options = [self.acceleration, False, True, self.time_start, self.time_stop]
+                       
+                       if self.views == 'Split':
+                               self.figure.clf();
+                               axes = self.figure.add_subplot(2,1,1)
+                               axes.grid(linestyle='dashed')
+                               axes = self.figure.add_subplot(2,1,2)
+                               axes.grid(linestyle='dashed')
+                               self.figure.subplots_adjust(left=0.03, right=0.97, top=0.98)
+                               PlotterThread(dbfile, self.cs_id, 0, self.plot_figure, options, 1).start() 
+                               PlotterThread(dbfile, self.cs_id2, 1, self.plot_figure, options, 1).start() 
+                       elif self.views == 'Adder':
+                               PlotterThread(dbfile, self.cs_id, 0, self.plot_figure, options, 1).start() 
+                       else:
+                               self.figure.clf();
+                               axes = self.figure.add_subplot(1,1,1)
+                               axes.grid(linestyle='dashed')
+                               self.figure.subplots_adjust(left=0.03, right=0.97, top=0.98)
+                               PlotterThread(dbfile, self.cs_id, 0, self.plot_figure, options, 1).start() 
+                               PlotterThread(dbfile, self.cs_id2, 0, self.plot_figure, options, 1).start()      
+       
+       def plot_figure(self, cs_id, axes_id, x, y):
+               axes_list = self.figure.get_axes()
+               axes = axes_list[axes_id]
+               for key in y.keys():
+                       if y[key]:
+                               axes.plot_date(x, y[key],'-', label=key+' Client '+cs_id)
+               axes.xaxis.set_major_formatter(DateFormatter('%H:%M:%S'))
+               #self.axes.set_xlabel("time (s)")
+               axes.legend(shadow=True, fancybox=True)
+               self.figure.autofmt_xdate(bottom=0.05, rotation=25)
+               wx.CallAfter(self.figure.canvas.draw)
+       
+       def plot_stats_figure(self, cs_id, axes_id, msg_types):
+               explode = []
+               vals = []
+               ticks = []
+               pos = np.arange(len(msg_types))+.3
+               for list in msg_types.values():
+                       explode.append(0.05)
+                       vals.append(list[0])
+                       ticks.append(list[1])
+               axes_list = self.figure.get_axes()
+               axes = axes_list[axes_id]
+               axes.pie(vals, labels=ticks, explode=explode, colors = ['b', 'c', 'g', 'm', 'r', 'y'], autopct='%1.1f%%', shadow=False)
+               
+               axes = axes_list[axes_id+1]
+               axes.barh(pos, vals, color = ['b', 'c', 'g', 'm', 'r', 'y'], height=0.3, align='center')
+               for t in axes.get_xticklabels():
+                       t.set_fontsize(5.)
+               axes.set_yticks(pos)
+               axes.set_yticklabels(ticks)
+               
+               wx.CallAfter(self.figure.canvas.draw)
+               
 class MainWindow(HasTraits):
-    figure = Instance(Figure)
-    panel = Instance(ControlPanel)
-    
-    def _figure_default(self):
-        figure = Figure()
-        return figure
+       figure = Instance(Figure)
+       panel = Instance(ControlPanel)
+       
+       def _figure_default(self):
+               figure = Figure()
+               return figure
 
-    def _panel_default(self):
-        return ControlPanel(figure=self.figure)
+       def _panel_default(self):
+               return ControlPanel(figure=self.figure)
 
-    view = View(HSplit(Item('figure', editor=MPLFigureEditor(),
-                            dock='vertical'),
-                       Item('panel', style="custom", springy=True, width= -90),
-                       show_labels=False,
-                      ),
-               title='P2P-NEXT Viewer',
-                resizable=True,
-                height=1, width=1,
-                buttons=NoButtons)
+       view = View(HSplit(Item('figure', editor=MPLFigureEditor(),
+                                                       dock='vertical'),
+                                          Item('panel', style="custom", springy=True, width= -90),
+                                          show_labels=False,
+                                         ),
+               title='P2P-Next Viewer',
+                               resizable=True,
+                               height=1, width=1,
+                               buttons=NoButtons)
 
 if __name__ == '__main__':
-    MainWindow().configure_traits()
+       MainWindow().configure_traits()