Package buildxml :: Package xmlgetter :: Module stats
[hide private]
[frames] | no frames]

Source Code for Module buildxml.xmlgetter.stats

  1  #!/usr/bin/python 
  2  # -*- coding: utf-8 -*- 
  3   
  4  """ 
  5  This module provides a class to store and represent statistics about the 
  6  data acquisition by plugins and portals. 
  7   
  8  @author: Johannes Schwenk 
  9  @copyright: 2010, Johannes Schwenk 
 10  @version: 2.0 
 11  @date: 2010-09-15 
 12   
 13   
 14  """ 
 15   
 16  import sys 
 17  from datetime import datetime, timedelta 
 18   
 19  # Imortant! 
 20  reload(sys) 
 21  sys.setdefaultencoding('utf-8') 
 22   
 23  from operator import itemgetter 
 24   
 25  from xmlgetter.log import BaseLogger 
26 27 28 -class Stats(dict, BaseLogger):
29 """ 30 Stores and represents statistics about the update process. 31 32 This is a dict-like object, that can contain only other instances of 33 C{Stats}. 34 35 """ 36 37 source = None 38 """ 39 @ivar: The sources name. 40 @type: string 41 42 """ 43 44 entries = -1 45 """ 46 @ivar: Number of entries in total. 47 @type: int 48 49 """ 50 51 new_entries = -1 52 """ 53 @ivar: Number of newly added entries since the last update. 54 @type: int 55 56 """ 57 58 modified_entries = -1 59 """ 60 @ivar: Number of entries that hav been modified since the last update. 61 @type: int 62 63 """ 64 65 unmodified_entries = -1 66 """ 67 @ivar: Number of unmodified entries. 68 @type: int 69 70 """ 71 72 static_entries = -1 73 """ 74 @ivar: Number of static entries. "Static" meaning entries that can not be 75 send as a stub, because there is no modification timestamp. 76 @type: int 77 78 """ 79 80 status = None 81 """ 82 @ivar: A string denoting the status of the update process. 83 Currently it is set to C{u'ok'} for success and C{u'FAILED'} 84 for a failed run. 85 TODO update, finish implementation! 86 @type: string 87 88 """ 89 90 messages = None 91 """ 92 @ivar: A list of messages added during the update process. Can be used to 93 notify the user about uncritical errors and warnings. 94 @type: list 95 96 """ 97 98 update_time_start = None 99 """ 100 @ivar: The date and time of the start of the update process. 101 @type: datetime 102 103 """ 104 105 update_time_end = None 106 """ 107 @ivar: The date and time of the end of the update process. 108 @type: datetime 109 110 """ 111 112 113
114 - def __init__(self, source=u'__main__'):
115 """ 116 Initialize instance variables. 117 118 @rtype: L{Stats} 119 @return: New statistics instance initialized with 0, no messages 120 and status 'ok'. 121 122 """ 123 dict.__init__(self) 124 BaseLogger.__init__(self, source_name=source) 125 self.source = source 126 self.static_entries = 0 127 self.entries = 0 128 self.new_entries = 0 129 self.modified_entries = 0 130 self.unmodified_entries = 0 131 self.status = u'ok' 132 self.messages = [] 133 self.update_time_start = None 134 self.update_time_end = None
135 136
137 - def __setitem__(self, key, item):
138 """ 139 Provided to produce dict-like behavior. All it does is logging 140 a warning on DEBUG level, if someone tries to set a item. 141 142 """ 143 self.logger.debug(u'Attempt to set item of Stats object')
144 145
146 - def addStats(self, stat_entry):
147 """ 148 Add a instance of C{Stats} to the internal dictionary using the 149 C{source} property as key. Abort if C{stat_entry} is not an instance of 150 C{Stats} 151 152 @param stat_entry: A C{Stats} instance. 153 @type stat_entry: Stats 154 155 """ 156 if not isinstance(stat_entry, Stats): 157 return 158 dict.__setitem__(self, stat_entry.source, stat_entry)
159 160
161 - def __str__(self):
162 """ 163 Return a table representing the information in this instance and 164 all C{Stats} instances contained in the internal dictionary. 165 166 @return: A table with the statistical information. 167 @rtype: string 168 169 """ 170 p_head = u'[Source] ' 171 s_head = u'[Static] ' 172 e_head = u'[Entries]' 173 ne_head = u'[New] ' 174 mod_head = u'[Modified]' 175 unmod_head = u'[Unmodified]' 176 status_head = u'[Status] ' 177 s_stats = s_head.ljust(len(s_head) + 3, u' ') 178 p_stats = p_head.ljust(len(p_head) + 3, u' ') 179 e_stats = e_head.ljust(len(e_head) + 3, u' ') 180 ne_stats = ne_head.ljust(len(ne_head) + 3, u' ') 181 mod_stats = mod_head.ljust(len(mod_head) + 3, u' ') 182 unmod_stats = unmod_head.ljust(len(unmod_head) + 3, u' ') 183 status_stats = status_head.ljust(len(status_head) + 3, u' ') 184 stats = u'\n%s%s%s%s%s%s%s' % (p_stats, s_stats, e_stats, ne_stats, 185 mod_stats, unmod_stats, status_stats) 186 messages = u'' 187 keys = sorted(self.keys()) 188 for k in keys: 189 p_stats = (u' %s' % self[k].source).ljust(len(p_head) + 5, u' ') 190 s_stats = (u'%s' % self[k].static_entries) \ 191 .ljust(len(s_head) + 3, u' ') 192 e_stats = (u'%s' % self[k].entries).ljust(len(e_head) + 3, u' ') 193 ne_stats = (u'%s' % self[k].new_entries) \ 194 .ljust(len(ne_head) + 3, u' ') 195 mod_stats = (u'%s' % self[k].modified_entries) \ 196 .ljust(len(mod_head) + 3, u' ') 197 unmod_stats = (u'%s' % self[k].unmodified_entries) \ 198 .ljust(len(unmod_head) + 3, u' ') 199 status_stats = (u'%s' % self[k].status) \ 200 .ljust(len(unmod_head) + 3, u' ') 201 stats = u'%s\n%s%s%s%s%s%s%s' % (stats, p_stats, s_stats, e_stats, 202 ne_stats, mod_stats, unmod_stats, status_stats) 203 if len(self[k].messages) > 0: 204 if messages == u'': 205 messages = u'\nThere are messages:\n' 206 messages = u'%s\n[%s]' % (messages, self[k].source) 207 for message in self[k].messages: 208 messages = u'%s\n\t%s' % (messages, message) 209 stats = u'%s\n%s\n' % (stats, messages) 210 stats = u'%s\nTimes [h:m:s.ms]:\nTotal : %s' % (stats, 211 self.update_time_diff) 212 for k in keys: 213 stats = u'%s\n[%s] : %s' % (stats, self[k].source, 214 self[k].update_time_diff) 215 return stats
216 217 218 @property
219 - def update_time_diff(self):
220 """ 221 @return: The C{timedelta} for the two variables L{update_time_end} 222 and L{update_time_start}. 223 @rtype: C{timedelta} 224 225 """ 226 return self.update_time_end - self.update_time_start
227