[Series60-remote-commits] SF.net SVN: series60-remote:[516] trunk/pc
Brought to you by:
lukashetzi
From: <Luk...@us...> - 2010-04-05 14:06:48
|
Revision: 516 http://series60-remote.svn.sourceforge.net/series60-remote/?rev=516&view=rev Author: LukasHetzi Date: 2010-04-05 14:06:42 +0000 (Mon, 05 Apr 2010) Log Message: ----------- Improve message statistics - Show also null values in graph (e.g. days where no message was sent in months view) - Do not reset statistics when filter, contact or view is changed - Link to summary page when in detailed view Modified Paths: -------------- trunk/pc/lib/classes.py trunk/pc/lib/database.py trunk/pc/window/statistics.py Modified: trunk/pc/lib/classes.py =================================================================== --- trunk/pc/lib/classes.py 2010-04-04 15:05:13 UTC (rev 515) +++ trunk/pc/lib/classes.py 2010-04-05 14:06:42 UTC (rev 516) @@ -503,7 +503,7 @@ return self.__message.replace(u'\n', u'\u2029') # LINE FEED (\u000a) replaced by PARAGRAPH SEPARATOR (\u2029) class StatisticsRequest(object): - def __init__(self, statisticFor = StatisticFor.Periods, contact = Contact(), period = StatisticPeriod.Unknown, \ + def __init__(self, statisticFor = StatisticFor.Unknown, contact = Contact(), period = StatisticPeriod.Unknown, \ type = MessageType.Unknown, start = None, duration = None, orderBy = StatisticOrderBy.Number, \ year = None, month = None, day = None): @@ -517,6 +517,9 @@ self.setMonth(month) self.setDay(day) + def __bool__(self): + return self.statisticsFor() != StatisticFor.Unknown + def setStatisticFor(self, statisticFor): assert isinstance(statisticFor, int), "expected an int" self.__statisticsFor = statisticFor @@ -627,6 +630,19 @@ self.__outgoing = False self.__total = False + def __len__(self): + return len(self.__values) + + def __getitem__(self, key): + return self.__values[key] + + def __iter__(self): + for item in self.__values: + yield item + + def __bool__(self): + return len(self) != 0 + def append(self, year, month, day, weekday, hour, incoming, outgoing, total): self.__values.append( StatisticResponseLine( [year, month, day, weekday, hour, incoming, outgoing, total] ) ) Modified: trunk/pc/lib/database.py =================================================================== --- trunk/pc/lib/database.py 2010-04-04 15:05:13 UTC (rev 515) +++ trunk/pc/lib/database.py 2010-04-05 14:06:42 UTC (rev 516) @@ -976,7 +976,7 @@ count = "SUM(CASE type WHEN 1 THEN 1 ELSE 0 END) incoming, SUM(CASE type WHEN 2 THEN 1 ELSE 0 END) outgoing" if period == StatisticPeriod.Years: - query = "SELECT " + self.__getYear() + " AS year, " + count + " FROM messages GROUP BY year " + query = "SELECT " + self.__getYear() + " AS year, " + count + " FROM messages " + where + " GROUP BY year " elif period == StatisticPeriod.YearsAndMonths: query = "SELECT " + self.__getYear() + " AS year, " + self.__getMonth() + " AS month, " + count + " FROM messages " + \ where + " GROUP BY year,month " Modified: trunk/pc/window/statistics.py =================================================================== --- trunk/pc/window/statistics.py 2010-04-04 15:05:13 UTC (rev 515) +++ trunk/pc/window/statistics.py 2010-04-05 14:06:42 UTC (rev 516) @@ -44,11 +44,12 @@ main.setupButtonBox(self.buttonBox) self.graphLayout = StatisticGraphLayout.Stacked + self.lastRequest = None self.connect(self.statisticTab, SIGNAL("currentChanged(int)"), lambda x : self.refreshStatistic()) self.connect(self.infoBrowser, SIGNAL("anchorClicked(const QUrl &)"), self.refreshStatistic) - self.connect(self.filterBox, SIGNAL("currentIndexChanged(int)"), lambda x : self.refreshStatistic()) - self.connect(self.contactBox, SIGNAL("currentIndexChanged(int)"), lambda x : self.refreshStatistic()) + self.connect(self.filterBox, SIGNAL("currentIndexChanged(int)"), lambda x : self.refreshStatistic(reset=False)) + self.connect(self.contactBox, SIGNAL("currentIndexChanged(int)"), lambda x : self.refreshStatistic(reset=False)) self.connect(self.viewBox, SIGNAL("currentIndexChanged(int)"), lambda x : self.refreshStatistic()) self.connect(self.stackedAction, SIGNAL("triggered()"), self.stackedGraph) self.connect(self.separateAction, SIGNAL("triggered()"), self.separateGraph) @@ -72,7 +73,7 @@ self.refreshStatistic() def insertContacts(self, currentContact): - self.contactBox.addItem(self.tr("All")) + self.contactBox.addItem(self.tr("All"), QVariant(Contact())) self.contactBox.insertSeparator(1) for contact in self.database.contactsWithMessages(): @@ -86,9 +87,9 @@ self.contactBox.setCurrentIndex(index) - def refreshStatistic(self, url=None): + def refreshStatistic(self, url=None, reset=True): if self.statisticTab.currentIndex() == 0: - + if USE_MATPLOTLIB: self.statisticPlot.addAction(self.stackedAction) self.statisticPlot.addAction(self.separateAction) @@ -96,10 +97,22 @@ self.statisticPlot.ax.clear() self.statisticPlot.format_labels() - request = StatisticsRequest() + if reset or not self.lastRequest: + request = StatisticsRequest() + else: + request = self.lastRequest + request.setStatisticFor(StatisticFor.Periods) - - if url: + if url == QUrl('#YearsAndMonths'): + request.setPeriod(StatisticPeriod.YearsAndMonths) + elif url == QUrl('#Years'): + request.setPeriod(StatisticPeriod.Years) + elif url == QUrl('#Months'): + request.setPeriod(StatisticPeriod.Months) + elif url == QUrl('#Days'): + request.setPeriod(StatisticPeriod.Days) + + elif url: parts = str(url.toString()).split("#")[1:] for part in parts: key, value = part.split("_") @@ -113,7 +126,7 @@ request.setPeriod(StatisticPeriod.Hours) request.setDay(int(value)) - else: + elif reset or not self.lastRequest: if self.viewBox.currentIndex() == 0: request.setPeriod(StatisticPeriod.YearsAndMonths) elif self.viewBox.currentIndex() == 1: @@ -134,18 +147,72 @@ else: request.setType(MessageType.Outgoing) - if self.contactBox.currentText() != self.tr("All"): - request.setContact(self.contactBox.itemData(self.contactBox.currentIndex()).toPyObject()) + request.setContact(self.contactBox.itemData(self.contactBox.currentIndex()).toPyObject()) + self.lastRequest = request get = self.database.statistics(request) period = get.request().period() cursor = self.infoBrowser.textCursor() if USE_MATPLOTLIB: - x = list() - y1 = list() - y2 = list() + # This is needed to show also zero values + # (e.g. days where no message was sent when view is set to month) + + # The list is filled with zeros which are replaced by the correct values afterwards + # So days/months where no data is available has zero by default in the plot + + if period == StatisticPeriod.Years: + first = get[0].year() + last = get[-1].year() + y1 = [0 for i in range(last - first + 1)] + x = [str(first+i) for i in range(last - first + 1)] + + elif period == StatisticPeriod.YearsAndMonths: + first = get[0] + last = get[-1] + + months = last.year() - first.year() + 1 + months *= 12 + months -= first.month() - 1 + months -= 12 - last.month() + + y1 = list() + x = list() + cur = QDate(first.year(), first.month(), 1) + for month in range(months): + y1.append(0) + #x.append(unicode(cur.toString("MMM yy"))) + x.append(datetime.datetime(cur.year(), cur.month(), 1)) + cur = cur.addMonths(1) + + elif period == StatisticPeriod.Months: + y1 = [0 for i in range(12)] + x = [unicode(QDate.longMonthName(i+1)) for i in range(12)] + + elif period == StatisticPeriod.Days: + mon = get.request().month() + year = get.request().year() + if mon and year: + days = QDate(year, mon, 1).daysInMonth() + else: + days = 31 + y1 = [0 for i in range(days)] + x = [str(i+1) for i in range(days)] + + elif period == StatisticPeriod.Weekdays: + y1 = [0 for i in range(7)] + x = [unicode(QDate.longDayName(i+1)) for i in range(7)] + + elif period == StatisticPeriod.Hours: + y1 = [0 for i in range(24)] + x = [str(QTime(i, 0, 0).toString("hh:mm")) for i in range(24)] + + if get.request().type() == MessageType.All: + y2 = y1[:] + else: + y2 = None + html = "" if period == StatisticPeriod.YearsAndMonths: @@ -155,34 +222,41 @@ html += "<p><table border='1' cellspacing='2' cellpadding='3'>" html += self.tableHead(get) - for line in get.values(): + for line in get: if USE_MATPLOTLIB: - if line.hour() != None: - x.append(str(QTime(line.hour(), 0, 0).toString("hh:mm"))) - elif line.year() != None and line.month() != None and line.day() != None: - x.append(datetime.datetime(line.year(), line.month(), line.day())) - elif line.year() != None and line.month() != None: - x.append(datetime.datetime(line.year(), line.month(), 1)) - elif line.year() != None: - x.append(datetime.datetime(line.year(), 1, 1)) - elif line.month() != None: - x.append(unicode(QDate.longMonthName(line.month()))) - elif line.day() != None: - x.append(line.day()) - elif line.weekday() != None: - x.append(unicode(QDate.longDayName(line.weekday()))) + if period == StatisticPeriod.Years: + key = line.year() - get[0].year() + elif period == StatisticPeriod.YearsAndMonths: + first = get[0] + + key = line.year() - first.year() + 1 + key *= 12 + key -= first.month() - 1 + key -= 12 - line.month() + + key -= 1 + if period == StatisticPeriod.Months: + key = line.month() - 1 + elif period == StatisticPeriod.Days: + key = line.day() - 1 + elif period == StatisticPeriod.Weekdays: + key = line.weekday() -1 + elif period == StatisticPeriod.Hours: + key = line.hour() if request.type() == MessageType.All: - y1.append(line.incoming()) + y1[key] = line.incoming() + if self.graphLayout == StatisticGraphLayout.Stacked: - y2.append(line.total()) + y2[key] = line.total() elif self.graphLayout == StatisticGraphLayout.Separate: - y2.append(-line.outgoing()) + y2[key] = -line.outgoing() + else: if line.incoming() != None: - y1.append(line.incoming()) + y1[key] = line.incoming() else: - y1.append(line.outgoing()) + y1[key] = line.outgoing() if period == StatisticPeriod.YearsAndMonths: if line.year() != curYear: @@ -198,8 +272,23 @@ html += self.tableLine(line, period != StatisticPeriod.YearsAndMonths) + if not get: + if get.request().contact(): + html += "<p><b>" + self.tr("No data for this contact available!") + "</b></p>" + else: + html += "<p><b>" + self.tr("No data available!") + "</b></p>" + html += "</table></p>" - + + if period != StatisticPeriod.YearsAndMonths and self.viewBox.currentIndex() == 0: + html += "<p><a href='#YearsAndMonths'><b>" + self.tr("go back to summary...") + "</b></a></p>" + elif period != StatisticPeriod.Years and self.viewBox.currentIndex() == 1: + html += "<p><a href='#Years'><b>" + self.tr("go back to summary...") + "</b></a></p>" + elif period != StatisticPeriod.Months and self.viewBox.currentIndex() == 2: + html += "<p><a href='#Months'><b>" + self.tr("go back to summary...") + "</b></a></p>" + elif period != StatisticPeriod.Days and self.viewBox.currentIndex() == 3: + html += "<p><a href='#Days'><b>" + self.tr("go back to summary...") + "</b></a></p>" + self.infoBrowser.setHtml(html) if USE_MATPLOTLIB: @@ -388,9 +477,9 @@ def stackedGraph(self): if self.graphLayout != StatisticGraphLayout.Stacked: self.graphLayout = StatisticGraphLayout.Stacked - self.refreshStatistic() + self.refreshStatistic(reset=False) def separateGraph(self): if self.graphLayout != StatisticGraphLayout.Separate: self.graphLayout = StatisticGraphLayout.Separate - self.refreshStatistic() + self.refreshStatistic(reset=False) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |