[hamster-applet] converted generation into somewhat more class oriented.
- From: Toms Baugis <tbaugis src gnome org>
- To: svn-commits-list gnome org
- Subject: [hamster-applet] converted generation into somewhat more class oriented.
- Date: Sun, 7 Jun 2009 07:26:00 -0400 (EDT)
commit 11e3f6685c2c0ada4ab740451c6874b88ba2babf
Author: Toms Bauģis <toms baugis gmail com>
Date: Sun Jun 7 12:25:48 2009 +0100
converted generation into somewhat more class oriented.
added iCal export and also encoding
name, category and description before export
---
hamster/reports.py | 310 +++++++++++++++++++++++++++++----------------------
hamster/stats.py | 24 +++--
2 files changed, 191 insertions(+), 143 deletions(-)
diff --git a/hamster/reports.py b/hamster/reports.py
index cf984c7..19f14ed 100644
--- a/hamster/reports.py
+++ b/hamster/reports.py
@@ -21,92 +21,150 @@
from hamster import stuff, storage
import os
import datetime as dt
-import webbrowser
from xml.dom.minidom import Document
import csv
-def simple(facts, start_date, end_date, format, filename):
- dates_dict = stuff.dateDict(start_date, "start_")
- dates_dict.update(stuff.dateDict(end_date, "end_"))
+def simple(facts, start_date, end_date, format, path):
+ report_path = stuff.locale_from_utf8(path)
+ if format == "tsv":
+ writer = TSVWriter(report_path)
+ elif format == "xml":
+ writer = XMLWriter(report_path)
+ elif format == "ical":
+ writer = ICalWriter(report_path)
+ else: #default to HTML
+ writer = HTMLWriter(report_path, start_date, end_date)
+
+ writer.write_report(facts)
+
+
+class ReportWriter(object):
+ #a tiny bit better than repeating the code all the time
+ def __init__(self, path, datetime_format = "%Y-%m-%d %H:%M:%S"):
+ self.file = open(path, "w")
+ self.datetime_format = datetime_format
+
+ def write_report(self, facts):
+ try:
+ for fact in facts:
+ fact["name"]= fact["name"].encode('utf-8')
+ fact["description"] = (fact["description"] or u"").encode('utf-8')
+ fact["category"] = (fact["category"] or _("Unsorted")).encode('utf-8')
+
+ if self.datetime_format:
+ fact["start_time"] = fact["start_time"].strftime(self.datetime_format)
+
+ if fact["end_time"]:
+ fact["end_time"] = fact["end_time"].strftime(self.datetime_format)
+ else:
+ fact["end_time"] = ""
+ fact["delta"] = fact["delta"].seconds / 60 + fact["delta"].days * 24 * 60
- if start_date.year != end_date.year:
- title = _(u"Overview for %(start_B)s %(start_d)s, %(start_Y)s â?? %(end_B)s %(end_d)s, %(end_Y)s") % dates_dict
- elif start_date.month != end_date.month:
- title = _(u"Overview for %(start_B)s %(start_d)s â?? %(end_B)s %(end_d)s, %(end_Y)s") % dates_dict
- else:
- title = _(u"Overview for %(start_B)s %(start_d)s â?? %(end_d)s, %(end_Y)s") % dates_dict
-
- if start_date == end_date:
- title = _(u"Overview for %(start_B)s %(start_d)s, %(start_Y)s") % dates_dict
+ self._write_fact(self.file, fact)
-
- report_path = stuff.locale_from_utf8(filename)
- report = open(report_path, "w")
+ self._finish(self.file, facts)
+ finally:
+ self.file.close()
+ def _start(self, file, facts):
+ raise NotImplementedError
- if format == "tsv":
- writer = csv.writer(report, dialect='excel-tab')
- writer.writerow(["activity", "start time", "end time",
- "duration minutes", "category", "description"])
- for fact in facts:
- description = fact["description"] or ""
- category = fact["category"] or _("Unsorted")
- start_time = fact["start_time"].strftime("%Y-%m-%d %H:%M:%S")
- if fact["end_time"]:
- end_time = fact["end_time"].strftime("%Y-%m-%d %H:%M:%S")
- else:
- end_time = ""
- delta = fact["delta"].seconds / 60 + fact["delta"].days * 24 * 60
-
- writer.writerow([fact["name"], start_time, end_time,
- delta, category, description])
-
- elif format == "xml":
- doc = Document()
- activity_list = doc.createElement("activities")
+ def _write_fact(self, file, fact):
+ raise NotImplementedError
- for fact in facts:
- fact["description"] = fact["description"] or ""
- fact["category"] = fact["category"] or _("Unsorted")
- fact["start_time"] = fact["start_time"].strftime("%Y-%m-%d %H:%M:%S")
- if fact["end_time"]:
- fact["end_time"] = fact["end_time"].strftime("%Y-%m-%d %H:%M:%S")
- else:
- fact["end_time"] = ""
- fact["delta"] = str(fact["delta"].seconds / 60 + fact["delta"].days * 24 * 60)
-
- doc_fact = doc.createElement("activity")
- doc_fact.setAttribute("name", fact["name"])
- doc_fact.setAttribute("start_time", fact["start_time"])
- doc_fact.setAttribute("end_time", fact["end_time"])
- doc_fact.setAttribute("duration_minutes", fact["delta"])
- doc_fact.setAttribute("category", fact["category"])
- doc_fact.setAttribute("description", fact["description"])
+ def _finish(self, file, facts):
+ raise NotImplementedError
+
+class ICalWriter(ReportWriter):
+ """a lame ical writer, could not be bothered with finding a library"""
+ def __init__(self, path):
+ ReportWriter.__init__(self, path, datetime_format = "%Y%m%dT%H%M%SZ")
+ self.file.write("BEGIN:VCALENDAR\nVERSION:1.0\n")
+
+
+ def _write_fact(self, file, fact):
+ if fact["category"] == _("Unsorted"):
+ fact["category"] = None
- activity_list.appendChild(doc_fact)
-
- doc.appendChild(activity_list)
- report.write(doc.toxml())
+ self.file.write("""BEGIN:VEVENT
+CATEGORIES:%(category)s
+DTSTART:%(start_time)s
+DTEND:%(end_time)s
+SUMMARY:%(name)s
+DESCRIPTION:%(description)s
+END:VEVENT
+""" % fact)
- else: #default to HTML
- write_html(report, title, facts)
+ def _finish(self, file, facts):
+ self.file.write("END:VCALENDAR\n")
+
+class TSVWriter(ReportWriter):
+ def __init__(self, path):
+ ReportWriter.__init__(self, path)
+ self.csv_writer = csv.writer(self.file, dialect='excel-tab')
+ self.csv_writer.writerow(["activity", "start time", "end time",
+ "duration minutes", "category", "description"])
+
+ def _write_fact(self, file, fact):
+ self.csv_writer.writerow([fact[key] for key in ["name", "start_time",
+ "end_time", "delta", "category", "description"]])
+ def _finish(self, file, facts):
+ pass
- report.close()
+class XMLWriter(ReportWriter):
+ def __init__(self, path):
+ ReportWriter.__init__(self, path)
+ self.doc = Document()
+ self.activity_list = self.doc.createElement("activities")
-def write_html(report, title, facts):
- """TODO bring template to external file or write to PDF"""
+ def _write_fact(self, file, fact):
+ activity = self.doc.createElement("activity")
+ activity.setAttribute("name", fact["name"])
+ activity.setAttribute("start_time", fact["start_time"])
+ activity.setAttribute("end_time", fact["end_time"])
+ activity.setAttribute("duration_minutes", str(fact["delta"]))
+ activity.setAttribute("category", fact["category"])
+ activity.setAttribute("description", fact["description"])
+ self.activity_list.appendChild(activity)
+
+ def _finish(self, file, facts):
+ self.doc.appendChild(self.activity_list)
+ file.write(self.doc.toxml())
+
+
+
+class HTMLWriter(ReportWriter):
+ def __init__(self, path, start_date, end_date):
+ ReportWriter.__init__(self, path, datetime_format = None)
+
+ dates_dict = stuff.dateDict(start_date, "start_")
+ dates_dict.update(stuff.dateDict(end_date, "end_"))
+ if start_date.year != end_date.year:
+ self.title = _(u"Overview for %(start_B)s %(start_d)s, %(start_Y)s â?? %(end_B)s %(end_d)s, %(end_Y)s") % dates_dict
+ elif start_date.month != end_date.month:
+ self.title = _(u"Overview for %(start_B)s %(start_d)s â?? %(end_B)s %(end_d)s, %(end_Y)s") % dates_dict
+ else:
+ self.title = _(u"Overview for %(start_B)s %(start_d)s â?? %(end_d)s, %(end_Y)s") % dates_dict
- report.write("""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ if start_date == end_date:
+ self.title = _(u"Overview for %(start_B)s %(start_d)s, %(start_Y)s") % dates_dict
+
+ self.sum_time = {}
+ self.even_row = True
+
+ """TODO bring template to external file or write to PDF"""
+
+ self.file.write("""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="author" content="hamster-applet" />
- <title>%s</title>
+ <title>%(title)s</title>
<style type="text/css">
body {
- font-family: "Sans" ;
+ font-family: "Sans";
font-size: 12px;
padding: 12px;
color: #303030;
@@ -139,37 +197,30 @@ def write_html(report, title, facts):
text-align: left;
padding: 3px 3px 3px 5px;
}
- .row1 {
- background-color: #EAE8E3;
+ .row0 {
+ background-color: #EAE8E3;
}
- .row2 {
- background-color: #ffffff;
+ .row1 {
+ background-color: #ffffff;
}
</style>
</head>
-<body>""" % title)
-
-
- report.write("<h1>%s</h1>" % title)
-
- report.write("""<table>
- <tr>
- <th class="smallCell">""" + _("Date") + """</th>
- <th class="largeCell">""" + _("Activity") + """</th>
- <th class="smallCell">""" + _("Category") + """</th>
- <th class="smallCell">""" + _("Start") + """</th>
- <th class="smallCell">""" + _("End") + """</th>
- <th class="smallCell">""" + _("Duration") + """</th>
- <th class="largeCell">""" + _("Description") + """</th>
- </tr>""")
-
- sum_time = {}
- rowcount = 1
+<body>
+<h1>%(title)s</h1>""" % {"title": self.title} + """
+<table>
+ <tr>
+ <th class="smallCell">""" + _("Date") + """</th>
+ <th class="largeCell">""" + _("Activity") + """</th>
+ <th class="smallCell">""" + _("Category") + """</th>
+ <th class="smallCell">""" + _("Start") + """</th>
+ <th class="smallCell">""" + _("End") + """</th>
+ <th class="smallCell">""" + _("Duration") + """</th>
+ <th class="largeCell">""" + _("Description") + """</th>
+ </tr>""")
- for fact in facts:
- duration = None
+ def _write_fact(self, report, fact):
end_time = fact["end_time"]
# ongoing task in current day
@@ -177,9 +228,6 @@ def write_html(report, title, facts):
if end_time:
end_time_str = end_time.strftime('%H:%M')
- if fact["delta"]:
- duration = 24 * 60 * fact["delta"].days + fact["delta"].seconds / 60
-
category = ""
if fact["category"] != _("Unsorted"): #do not print "unsorted" in list
category = fact["category"]
@@ -187,7 +235,7 @@ def write_html(report, title, facts):
description = fact["description"] or ""
# fact date column in HTML report
- report.write("""<tr class="row%s">
+ report.write("""<tr class="row%d">
<td class="smallCell">%s</td>
<td class="largeCell">%s</td>
<td class="smallCell">%s</td>
@@ -196,50 +244,44 @@ def write_html(report, title, facts):
<td class="smallCell">%s</td>
<td class="largeCell">%s</td>
</tr>
- """ % (rowcount, _("%(report_b)s %(report_d)s, %(report_Y)s") % stuff.dateDict(fact["start_time"], "report_"),
- fact["name"],
- category,
- fact["start_time"].strftime('%H:%M'),
- end_time_str,
- stuff.format_duration(duration) or "",
- description))
-
- if rowcount == 1:
- rowcount = 2
- else:
- rowcount = 1
+ """ % (int(self.even_row),
+ _("%(report_b)s %(report_d)s, %(report_Y)s") % stuff.dateDict(fact["start_time"], "report_"),
+ fact["name"],
+ category,
+ fact["start_time"].strftime('%H:%M'),
+ end_time_str,
+ stuff.format_duration(fact["delta"]) or "",
+ description))
+
+ self.even_row = not self.even_row
# save data for summary table
- if duration:
+ if fact["delta"]:
id_string = "<td class=\"smallCell\">%s</td><td class=\"largeCell\">%s</td>" % (fact["category"], fact["name"])
- if id_string in sum_time:
- sum_time[id_string] += duration
- else:
- sum_time[id_string] = duration
-
- report.write("</table>")
-
- # summary table
- report.write("\n<h2>%s</h2>\n" % _("Totals"))
- report.write("""<table>
- <tr>
- <th class="smallCell">""" + _("Category") + """</th>
- <th class="largeCell">""" + _("Activity") + """</th>
- <th class="smallCell">""" + _("Duration") + """</th>
- </tr>\n""")
- tot_time = 0
- rowcount = 1
- for key in sorted(sum_time.keys()):
- report.write(" <tr class=\"row%s\">%s<td class=\"smallCell\">%s</td></tr>\n" % (rowcount, key, stuff.format_duration(sum_time[key])))
- tot_time += sum_time[key]
-
- if rowcount == 1:
- rowcount = 2
- else:
- rowcount = 1
- report.write(" <tr><th colspan=\"2\" style=\"text-align:right;\">" + _("Total Time") + ":</th><th>%s</th></tr>\n" % (stuff.format_duration(tot_time)))
- report.write("</table>\n")
+ self.sum_time[id_string] = self.sum_time.get(id_string, 0) + fact["delta"]
+
+ def _finish(self, report, facts):
+ report.write("</table>")
+
+ # summary table
+ report.write("\n<h2>%s</h2>\n" % _("Totals"))
+ report.write("""<table>
+ <tr>
+ <th class="smallCell">""" + _("Category") + """</th>
+ <th class="largeCell">""" + _("Activity") + """</th>
+ <th class="smallCell">""" + _("Duration") + """</th>
+ </tr>\n""")
+ tot_time = 0
+ even_row = False
+ for key in sorted(self.sum_time.keys()):
+ report.write(" <tr class=\"row%d\">%s<td class=\"smallCell\">%s</td></tr>\n" % (int(even_row), key, stuff.format_duration(self.sum_time[key])))
+ tot_time += self.sum_time[key]
+
+ even_row = not even_row
- report.write("</body>\n</html>")
+ report.write(" <tr><th colspan=\"2\" style=\"text-align:right;\">" + _("Total Time") + ":</th><th>%s</th></tr>\n" % (stuff.format_duration(tot_time)))
+ report.write("</table>\n")
+ report.write("</body>\n</html>")
+
\ No newline at end of file
diff --git a/hamster/stats.py b/hamster/stats.py
index 761b9a5..a1f48cc 100644
--- a/hamster/stats.py
+++ b/hamster/stats.py
@@ -29,6 +29,7 @@ from hamster import dispatcher, storage, SHARED_DATA_DIR, stuff
from hamster import charting
from hamster.edit_activity import CustomFactController
+import webbrowser
import datetime as dt
import calendar
@@ -575,7 +576,7 @@ class StatsViewer(object):
filter.add_mime_type("text/html")
filter.add_pattern("*.html")
filter.add_pattern("*.htm")
- filters["html"] = filter
+ filters[filter] = "html"
chooser.add_filter(filter)
filter = gtk.FileFilter()
@@ -583,14 +584,21 @@ class StatsViewer(object):
filter.add_mime_type("text/plain")
filter.add_pattern("*.tsv")
filter.add_pattern("*.txt")
- filters["tsv"] = filter
+ filters[filter] = "tsv"
chooser.add_filter(filter)
filter = gtk.FileFilter()
filter.set_name(_("XML"))
filter.add_mime_type("text/xml")
filter.add_pattern("*.xml")
- filters["xml"] = filter
+ filters[filter] = "xml"
+ chooser.add_filter(filter)
+
+ filter = gtk.FileFilter()
+ filter.set_name(_("iCal"))
+ filter.add_mime_type("text/calendar")
+ filter.add_pattern("*.ics")
+ filters[filter] = "ical"
chooser.add_filter(filter)
filter = gtk.FileFilter()
@@ -602,10 +610,8 @@ class StatsViewer(object):
response = chooser.run()
if response == gtk.RESPONSE_OK:
format = "html"
- if chooser.get_filter() == filters["tsv"]:
- format = "tsv"
- elif chooser.get_filter() == filters["xml"]:
- format = "xml"
+ if chooser.get_filter() in filters:
+ format = filters[chooser.get_filter()]
from hamster import reports
facts = storage.get_facts(self.start_date, self.end_date)
@@ -619,9 +625,9 @@ class StatsViewer(object):
if format in ("tsv", "xml"):
gtk.show_uri(gtk.gdk.Screen(),
- "file://" + os.path.split(path)[0], 0L)
+ "file://%s" % os.path.split(path)[0], 0L)
else:
- webbrowser.open_new("file://"+report_path)
+ webbrowser.open_new("file://%s" % path)
chooser.destroy()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]