[hamster-applet] using class instead of dict
- From: Toms Baugis <tbaugis src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [hamster-applet] using class instead of dict
- Date: Sat, 21 Aug 2010 23:17:53 +0000 (UTC)
commit 201f2ece13df23c742fb43873f11701bd4fb0c3b
Author: Toms Bauģis <toms baugis gmail com>
Date: Sun Aug 22 00:17:28 2010 +0100
using class instead of dict
src/docky_control/2.0/hamster_control.py | 2 +-
src/docky_control/2.1/hamster_control.py | 2 +-
src/hamster-applet | 2 +-
src/hamster-cli | 6 +-
src/hamster-time-tracker | 50 ++++++++--------
src/hamster/applet.py | 66 ++++++++++----------
src/hamster/client.py | 50 ++++++++--------
src/hamster/edit_activity.py | 18 +++---
src/hamster/overview.py | 2 +-
src/hamster/overview_activities.py | 18 +++---
src/hamster/overview_totals.py | 18 +++---
src/hamster/reports.py | 96 +++++++++++++++--------------
src/hamster/stats.py | 64 ++++++++++----------
src/hamster/utils/stuff.py | 20 ++++--
src/hamster/utils/trophies.py | 10 ++--
src/hamster/widgets/dayline.py | 20 +++---
src/hamster/widgets/facttree.py | 18 +++---
17 files changed, 236 insertions(+), 226 deletions(-)
---
diff --git a/src/docky_control/2.0/hamster_control.py b/src/docky_control/2.0/hamster_control.py
index f0acd33..31a7264 100755
--- a/src/docky_control/2.0/hamster_control.py
+++ b/src/docky_control/2.0/hamster_control.py
@@ -66,7 +66,7 @@ class DockyHamsterItem(DockyItem):
fact = today[-1]
self.iface.SetText("%(name)s - %(category)s" % fact)
- self.iface.SetBadgeText(stuff.format_duration(fact['delta'], human=False))
+ self.iface.SetBadgeText(stuff.format_duration(fact.delta, human=False))
else:
self.iface.SetText(_("No activity"))
self.iface.ResetBadgeText()
diff --git a/src/docky_control/2.1/hamster_control.py b/src/docky_control/2.1/hamster_control.py
index 2456191..06835ed 100755
--- a/src/docky_control/2.1/hamster_control.py
+++ b/src/docky_control/2.1/hamster_control.py
@@ -70,7 +70,7 @@ class HamsterItem(DockManagerItem):
fact = today[-1]
self.set_tooltip("%(name)s - %(category)s" % fact)
- self.set_badge(stuff.format_duration(fact['delta'], human=False))
+ self.set_badge(stuff.format_duration(fact.delta, human=False))
else:
self.set_tooltip(_("No activity"))
self.reset_badge()
diff --git a/src/hamster-applet b/src/hamster-applet
index fa9950a..ba8a81f 100755
--- a/src/hamster-applet
+++ b/src/hamster-applet
@@ -45,7 +45,7 @@ def on_destroy(event):
# handle config option to stop tracking on shutdown
if conf.get("stop_on_shutdown"):
todays_facts = runtime.storage.get_todays_facts()
- if todays_facts and todays_facts[-1]['end_time'] is None:
+ if todays_facts and todays_facts[-1].end_time is None:
runtime.storage.stop_tracking()
if gtk.main_level():
diff --git a/src/hamster-cli b/src/hamster-cli
index 394cb10..fc4c86d 100755
--- a/src/hamster-cli
+++ b/src/hamster-cli
@@ -95,7 +95,7 @@ class HamsterClient(object):
print "%s+%s" % ('-' * first_column_width, '-' * second_column_width)
for fact in self.storage.get_facts(start_time, end_time, ""):
- if fact['start_time'] < start_time or fact['start_time'] > end_time:
+ if fact.start_time < start_time or fact.start_time > end_time:
# Hamster returns activities for the whole day, not just the
# time range we sent
# TODO - why should that be a problem? /toms/
@@ -195,14 +195,14 @@ def fact_dict(fact_data, with_date):
else:
fmt = '%H:%M'
- fact['start'] = fact_data['start_time'].strftime(fmt)
+ fact['start'] = fact_data.start_time.strftime(fmt)
if fact_data['end_time']:
fact['end'] = fact_data['end_time'].strftime(fmt)
else:
end_date = dt.datetime.now()
fact['end'] = ''
- fact['duration'] = stuff.format_duration(fact_data['delta'])
+ fact['duration'] = stuff.format_duration(fact_data.delta)
fact['activity'] = fact_data['name']
fact['category'] = fact_data['category']
diff --git a/src/hamster-time-tracker b/src/hamster-time-tracker
index c8e206b..fbd840f 100755
--- a/src/hamster-time-tracker
+++ b/src/hamster-time-tracker
@@ -158,11 +158,11 @@ class ProjectHamster(object):
now = dt.datetime.now()
message = None
if self.last_activity:
- delta = now - self.last_activity['start_time']
+ delta = now - self.last_activity.start_time
duration = delta.seconds / 60
if duration and duration % self.notify_interval == 0:
- message = _(u"Working on <b>%s</b>") % self.last_activity['name']
+ message = _(u"Working on <b>%s</b>") % self.last_activity.name
self.get_widget("last_activity_duration").set_text(stuff.format_duration(duration) or _("Just started"))
@@ -184,16 +184,16 @@ class ProjectHamster(object):
self.treeview.detach_model()
- if facts and facts[-1]["end_time"] == None:
+ if facts and facts[-1].end_time == None:
self.last_activity = facts[-1]
else:
self.last_activity = None
by_category = {}
for fact in facts:
- duration = 24 * 60 * fact["delta"].days + fact["delta"].seconds / 60
- by_category[fact['category']] = \
- by_category.setdefault(fact['category'], 0) + duration
+ duration = 24 * 60 * fact.delta.days + fact.delta.seconds / 60
+ by_category[fact.category] = \
+ by_category.setdefault(fact.category, 0) + duration
self.treeview.add_fact(fact)
self.treeview.attach_model()
@@ -216,19 +216,19 @@ class ProjectHamster(object):
self.get_widget("switch_activity").show()
self.get_widget("start_tracking").hide()
- delta = dt.datetime.now() - activity['start_time']
+ delta = dt.datetime.now() - activity.start_time
duration = delta.seconds / 60
- if activity['category'] != _("Unsorted"):
- self.get_widget("last_activity_name").set_text("%s - %s" % (activity['name'], activity['category']))
+ if activity.category != _("Unsorted"):
+ self.get_widget("last_activity_name").set_text("%s - %s" % (activity.activity, activity.category))
else:
- self.get_widget("last_activity_name").set_text(activity['name'])
+ self.get_widget("last_activity_name").set_text(activity.activity)
self.get_widget("last_activity_duration").set_text(stuff.format_duration(duration) or _("Just started"))
- self.get_widget("last_activity_description").set_text(activity['description'] or "")
+ self.get_widget("last_activity_description").set_text(activity.description or "")
self.get_widget("activity_info_box").show()
- self.tag_box.draw(activity["tags"])
+ self.tag_box.draw(activity.tags)
else:
self.get_widget("switch_activity").hide()
self.get_widget("start_tracking").show()
@@ -259,10 +259,10 @@ class ProjectHamster(object):
def on_today_row_activated(self, tree, path, column):
fact = tree.get_selected_fact()
- fact = stuff.Fact(fact["name"],
- tags = ", ".join(fact["tags"]),
- category = fact["category"],
- description = fact["description"])
+ fact = stuff.Fact(fact.activity,
+ category = fact.category,
+ description = fact.description,
+ tags = ", ".join(fact.tags))
if fact.activity:
runtime.storage.add_fact(fact)
@@ -299,7 +299,7 @@ class ProjectHamster(object):
if state == 0:
self.refresh_hamster()
elif self.timeout_enabled and self.last_activity and \
- self.last_activity['end_time'] is None:
+ self.last_activity.end_time is None:
runtime.storage.stop_tracking(end_time = self.dbusIdleListener.getIdleFrom())
@@ -342,8 +342,8 @@ class ProjectHamster(object):
ressurect = False)
if activity:
# we need dict below
- activity = dict(name = activity['name'],
- category = activity['category'],
+ activity = dict(name = activity.name,
+ category = activity.category,
description = fact.description,
tags = fact.tags)
@@ -360,21 +360,21 @@ class ProjectHamster(object):
# check if maybe there is no need to switch, as field match:
if self.last_activity and \
- self.last_activity['name'].lower() == activity['name'].lower() and \
- (self.last_activity['category'] or "").lower() == (activity['category'] or "").lower() and \
+ self.last_activity.name.lower() == activity.name.lower() and \
+ (self.last_activity.category or "").lower() == (activity.category or "").lower() and \
", ".join(self.last_activity['tags']).lower() == ", ".join(activity['tags']).lower():
return
# ok, switch
- fact = stuff.Fact(activity['name'],
+ fact = stuff.Fact(activity.name,
tags = ", ".join(activity['tags']),
- category = activity['category'],
- description = activity['description']);
+ category = activity.category,
+ description = activity.description);
runtime.storage.add_fact(fact)
if self.notification:
self.notification.update(_("Changed activity"),
- _("Switched to '%s'") % activity['name'],
+ _("Switched to '%s'") % activity.name,
"hamster-applet")
self.notification.show()
diff --git a/src/hamster/applet.py b/src/hamster/applet.py
index f5dbdae..fa0e946 100755
--- a/src/hamster/applet.py
+++ b/src/hamster/applet.py
@@ -291,12 +291,12 @@ class HamsterApplet(object):
def update_label(self):
- if self.last_activity and self.last_activity['end_time'] is None:
- delta = dt.datetime.now() - self.last_activity['start_time']
+ if self.last_activity and self.last_activity.end_time is None:
+ delta = dt.datetime.now() - self.last_activity.start_time
duration = delta.seconds / 60
- label = "%s %s" % (self.last_activity['name'],
+ label = "%s %s" % (self.last_activity.activity,
stuff.format_duration(duration, False))
- self.button.set_text(self.last_activity['name'],
+ self.button.set_text(self.last_activity.activity,
stuff.format_duration(duration, False))
else:
label = "%s" % _(u"No activity")
@@ -313,11 +313,11 @@ class HamsterApplet(object):
now = dt.datetime.now()
message = None
if self.last_activity:
- delta = now - self.last_activity['start_time']
+ delta = now - self.last_activity.start_time
duration = delta.seconds / 60
if duration and duration % self.notify_interval == 0:
- message = self.last_activity['name']
+ message = self.last_activity.activity
elif self.notify_on_idle:
#if we have no last activity, let's just calculate duration from 00:00
@@ -336,7 +336,7 @@ class HamsterApplet(object):
facts = self.todays_facts = runtime.storage.get_todays_facts()
- if facts and facts[-1]["end_time"] == None:
+ if facts and facts[-1].end_time == None:
self.last_activity = facts[-1]
else:
self.last_activity = None
@@ -355,9 +355,9 @@ class HamsterApplet(object):
by_category = {}
for fact in facts:
- duration = 24 * 60 * fact["delta"].days + fact["delta"].seconds / 60
- by_category[fact['category']] = \
- by_category.setdefault(fact['category'], 0) + duration
+ duration = 24 * 60 * fact.delta.days + fact.delta.seconds / 60
+ by_category[fact.category] = \
+ by_category.setdefault(fact.category, 0) + duration
self.treeview.add_fact(fact)
self.treeview.attach_model()
@@ -393,20 +393,20 @@ class HamsterApplet(object):
self.get_widget("switch_activity").show()
self.get_widget("start_tracking").hide()
- delta = dt.datetime.now() - activity['start_time']
+ delta = dt.datetime.now() - activity.start_time
duration = delta.seconds / 60
- if activity['category'] != _("Unsorted"):
- self.get_widget("last_activity_name").set_text("%s - %s" % (activity['name'], activity['category']))
+ if activity.category != _("Unsorted"):
+ self.get_widget("last_activity_name").set_text("%s - %s" % (activity.activity, activity.category))
else:
- self.get_widget("last_activity_name").set_text(activity['name'])
+ self.get_widget("last_activity_name").set_text(activity.activity)
self.get_widget("last_activity_duration").set_text(stuff.format_duration(duration) or _("Just started"))
- self.get_widget("last_activity_description").set_text(activity['description'] or "")
+ self.get_widget("last_activity_description").set_text(activity.description or "")
self.get_widget("activity_info_box").show()
- self.tag_box.draw(activity["tags"])
+ self.tag_box.draw(activity.tags)
else:
self.get_widget("switch_activity").hide()
self.get_widget("start_tracking").show()
@@ -419,7 +419,7 @@ class HamsterApplet(object):
def delete_selected(self):
fact = self.treeview.get_selected_fact()
- runtime.storage.remove_fact(fact["id"])
+ runtime.storage.remove_fact(fact.id)
def __show_toggle(self, is_active):
"""main window display and positioning"""
@@ -504,14 +504,14 @@ class HamsterApplet(object):
def _open_edit_activity(self, row, fact):
"""opens activity editor for selected row"""
- dialogs.edit.show(self.applet, fact_id = fact["id"])
+ dialogs.edit.show(self.applet, fact_id = fact.id)
def on_today_row_activated(self, tree, path, column):
fact = tree.get_selected_fact()
- fact = stuff.Fact(fact["name"],
- tags = ", ".join(fact["tags"]),
- category = fact["category"],
- description = fact["description"])
+ fact = stuff.Fact(fact.activity,
+ tags = ", ".join(fact.tags),
+ category = fact.category,
+ description = fact.description)
if fact.activity:
runtime.storage.add_fact(fact)
@@ -565,7 +565,7 @@ class HamsterApplet(object):
if state == 0:
self.refresh_hamster()
elif self.timeout_enabled and self.last_activity and \
- self.last_activity['end_time'] is None:
+ self.last_activity.end_time is None:
runtime.storage.stop_tracking(self.dbusIdleListener.getIdleFrom())
@@ -607,8 +607,8 @@ class HamsterApplet(object):
ressurect = False)
if activity:
# we need dict below
- activity = dict(name = activity['name'],
- category = activity['category'],
+ activity = dict(name = activity.activity,
+ category = activity.category,
description = fact.description,
tags = fact.tags)
@@ -625,21 +625,21 @@ class HamsterApplet(object):
# check if maybe there is no need to switch, as field match:
if self.last_activity and \
- self.last_activity['name'].lower() == activity['name'].lower() and \
- (self.last_activity['category'] or "").lower() == (activity['category'] or "").lower() and \
- ", ".join(self.last_activity['tags']).lower() == ", ".join(activity['tags']).lower():
+ self.last_activity.activity.lower() == activity.activity.lower() and \
+ (self.last_activity.category or "").lower() == (activity.category or "").lower() and \
+ ", ".join(self.last_activity.tags).lower() == ", ".join(activity.tags).lower():
return
# ok, switch
- fact = stuff.Fact(activity['name'],
- tags = ", ".join(activity['tags']),
- category = activity['category'],
- description = activity['description']);
+ fact = stuff.Fact(activity.activity,
+ tags = ", ".join(activity.tags),
+ category = activity.category,
+ description = activity.description);
runtime.storage.add_fact(fact)
if self.notification:
self.notification.update(_("Changed activity"),
- _("Switched to '%s'") % activity['name'],
+ _("Switched to '%s'") % activity.activity,
"hamster-applet")
self.notification.show()
diff --git a/src/hamster/client.py b/src/hamster/client.py
index f01fe50..256dcc4 100644
--- a/src/hamster/client.py
+++ b/src/hamster/client.py
@@ -29,19 +29,18 @@ from utils import stuff, trophies
def from_dbus_fact(fact):
"""unpack the struct into a proper dict"""
- return dict(id = fact[0],
- start_time = dt.datetime.utcfromtimestamp(fact[1]),
- end_time = dt.datetime.utcfromtimestamp(fact[2]) if fact[2] else None,
- description = fact[3],
- name = fact[4],
- activity_id = fact[5],
- category = fact[6],
- tags = fact[7],
- date = dt.datetime.utcfromtimestamp(fact[8]).date(),
- delta = dt.timedelta(days = fact[9] // (24 * 60 * 60),
- seconds = fact[9] % (24 * 60 * 60))
- )
-
+ return stuff.Fact(fact[4],
+ start_time = dt.datetime.utcfromtimestamp(fact[1]),
+ end_time = dt.datetime.utcfromtimestamp(fact[2]) if fact[2] else None,
+ description = fact[3],
+ activity_id = fact[5],
+ category = fact[6],
+ tags = fact[7],
+ date = dt.datetime.utcfromtimestamp(fact[8]).date(),
+ delta = dt.timedelta(days = fact[9] // (24 * 60 * 60),
+ seconds = fact[9] % (24 * 60 * 60)),
+ id = fact[0]
+ )
class Storage(gobject.GObject):
"""Hamster client class, communicating to hamster storage daemon via d-bus.
@@ -163,7 +162,7 @@ class Storage(gobject.GObject):
"""returns fact by it's ID"""
return from_dbus_fact(self.conn.GetFact(id))
- def add_fact(self, fact, temporary_activity):
+ def add_fact(self, fact, temporary_activity = False):
"""Add fact. activity name can use the
`[-]start_time[-end_time] activity category, description #tag1 #tag2`
syntax, or params can be stated explicitly.
@@ -173,17 +172,18 @@ class Storage(gobject.GObject):
if not fact.activity:
return None
- fact.start_time = fact.start_time or dt.datetime.now()
-
serialized = fact.serialized_name()
- start_timestamp = fact.start_time or 0
- if start_timestamp:
- start_timestamp = timegm(fact.start_time.timetuple())
+ start_timestamp = timegm((fact.start_time or dt.datetime.now()).timetuple())
end_timestamp = fact.end_time or 0
if end_timestamp:
- end_timestamp = timegm(fact.end_time.timetuple())
+ end_timestamp = timegm(end_timestamp.timetuple())
+
+ print serialized
+ print start_timestamp
+ print end_timestamp
+ print temporary_activity
new_id = self.conn.AddFact(serialized,
start_timestamp,
@@ -206,19 +206,17 @@ class Storage(gobject.GObject):
"delete fact from database"
self.conn.RemoveFact(fact_id)
- def update_fact(self, fact_id, fact, temporary_activity):
+ def update_fact(self, fact_id, fact, temporary_activity = False):
"""Update fact values. See add_fact for rules.
Update is performed via remove/insert, so the
fact_id after update should not be used anymore. Instead use the ID
from the fact dict that is returned by this function"""
- start_time = fact.start_time or 0
- if fact.start_time:
- start_time = timegm(fact.start_time.timetuple())
+ start_time = timegm((fact.start_time or dt.datetime.now()).timetuple())
end_time = fact.end_time or 0
- if fact.end_time:
- end_time = timegm(fact.end_time.timetuple())
+ if end_time:
+ end_time = timegm(end_time.timetuple())
new_id = self.conn.UpdateFact(fact_id,
fact.serialized_name(),
diff --git a/src/hamster/edit_activity.py b/src/hamster/edit_activity.py
index 35419f3..505ddf8 100644
--- a/src/hamster/edit_activity.py
+++ b/src/hamster/edit_activity.py
@@ -50,20 +50,20 @@ class CustomFactController:
if fact_id:
fact = runtime.storage.get_fact(fact_id)
- label = fact['name']
- if fact['category'] != _("Unsorted"):
- label += "@%s" % fact['category']
+ label = fact.activity
+ if fact.category != _("Unsorted"):
+ label += "@%s" % fact.category
self.new_name.set_text(label)
- self.new_tags.set_text(", ".join(fact['tags']))
+ self.new_tags.set_text(", ".join(fact.tags))
- start_date = fact["start_time"]
- end_date = fact["end_time"]
+ start_date = fact.start_time
+ end_date = fact.end_time
buf = gtk.TextBuffer()
- buf.set_text(fact["description"] or "")
+ buf.set_text(fact.description or "")
self.get_widget('description').set_buffer(buf)
self.get_widget("save_button").set_label("gtk-save")
@@ -78,8 +78,8 @@ class CustomFactController:
fact_date = dt.date.today()
last_activity = runtime.storage.get_facts(fact_date)
- if last_activity and last_activity[-1]["end_time"]:
- start_date = last_activity[-1]["end_time"]
+ if last_activity and last_activity[-1].end_time:
+ start_date = last_activity[-1].end_time
if fact_date != dt.date.today():
end_date = start_date + dt.timedelta(minutes=30)
diff --git a/src/hamster/overview.py b/src/hamster/overview.py
index dfcf394..d5a9030 100644
--- a/src/hamster/overview.py
+++ b/src/hamster/overview.py
@@ -155,7 +155,7 @@ class Overview(object):
self.range_pick.set_range(self.start_date, self.end_date, self.view_date)
- durations = [(fact["start_time"], fact["delta"]) for fact in self.facts]
+ durations = [(fact.start_time, fact.delta) for fact in self.facts]
self.timechart.draw(durations, self.start_date, self.end_date)
if self.get_widget("window_tabs").get_current_page() == 0:
diff --git a/src/hamster/overview_activities.py b/src/hamster/overview_activities.py
index 70b09b0..ef21057 100644
--- a/src/hamster/overview_activities.py
+++ b/src/hamster/overview_activities.py
@@ -76,7 +76,7 @@ class OverviewBox(gtk.VBox):
dates[self.start_date + dt.timedelta(i)] = []
#update with facts for the day
- for date, facts in groupby(self.facts, lambda fact: fact["date"]):
+ for date, facts in groupby(self.facts, lambda fact: fact.date):
dates[date] = list(facts)
@@ -104,16 +104,16 @@ class OverviewBox(gtk.VBox):
if isinstance(fact, dt.date):
return # heading
- fact_str = "%s-%s %s" % (fact["start_time"].strftime("%H:%M"),
- (fact["end_time"] or dt.datetime.now()).strftime("%H:%M"),
+ fact_str = "%s-%s %s" % (fact.start_time.strftime("%H:%M"),
+ (fact.end_time or dt.datetime.now()).strftime("%H:%M"),
fact["name"])
- if fact["category"]:
- fact_str += "@%s" % fact["category"]
+ if fact.category:
+ fact_str += "@%s" % fact.category
- if fact["description"] or fact["tags"]:
- tag_str = " ".join("#%s" % tag for tag in fact["tags"])
- fact_str += ", %s" % ("%s %s" % (fact["description"] or "", tag_str)).strip()
+ if fact.description or fact.tags:
+ tag_str = " ".join("#%s" % tag for tag in fact.tags)
+ fact_str += ", %s" % ("%s %s" % (fact.description or "", tag_str)).strip()
clipboard = gtk.Clipboard()
clipboard.set_text(fact_str)
@@ -163,7 +163,7 @@ class OverviewBox(gtk.VBox):
if isinstance(fact, dt.date):
selected_date = fact
else:
- selected_date = fact["date"]
+ selected_date = fact.date
fact = stuff.Fact(text.decode("utf-8"))
diff --git a/src/hamster/overview_totals.py b/src/hamster/overview_totals.py
index bb3d6e1..e7d73eb 100644
--- a/src/hamster/overview_totals.py
+++ b/src/hamster/overview_totals.py
@@ -145,19 +145,21 @@ class TotalsBox(gtk.VBox):
category_sums, activity_sums, tag_sums = defaultdict(dt.timedelta), defaultdict(dt.timedelta), defaultdict(dt.timedelta),
for fact in facts:
- if self.selected_categories and fact["category"] not in self.selected_categories:
+ if self.selected_categories and fact.category not in self.selected_categories:
continue
- if self.selected_activities and fact["name"] not in self.selected_activities:
+ if self.selected_activities and fact.activity not in self.selected_activities:
continue
- if self.selected_tags and len(set(self.selected_tags) - set(fact["tags"])) > 0:
+ if self.selected_tags and len(set(self.selected_tags) - set(fact.tags)) > 0:
continue
- category_sums[fact["category"]] += fact["delta"]
- activity_sums[fact["name"]] += fact["delta"]
- for tag in fact["tags"]:
- tag_sums[tag] += fact["delta"]
+ category_sums[fact.category] += fact.delta
+ activity_sums[fact.activity] += fact.delta
- total_label = _("%s hours tracked total") % locale.format("%.1f", stuff.duration_minutes([fact["delta"] for fact in facts]) / 60.0)
+ print fact.activity, fact.tags
+ for tag in fact.tags:
+ tag_sums[tag] += fact.delta
+
+ total_label = _("%s hours tracked total") % locale.format("%.1f", stuff.duration_minutes([fact.delta for fact in facts]) / 60.0)
self.get_widget("total_hours").set_text(total_label)
diff --git a/src/hamster/reports.py b/src/hamster/reports.py
index 743a402..aac6f0b 100644
--- a/src/hamster/reports.py
+++ b/src/hamster/reports.py
@@ -66,19 +66,19 @@ class ReportWriter(object):
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')
+ fact.activity= fact.activity.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)
+ fact.start_time = fact.start_time.strftime(self.datetime_format)
- if fact["end_time"]:
- fact["end_time"] = fact["end_time"].strftime(self.datetime_format)
+ if fact.end_time:
+ fact.end_time = fact.end_time.strftime(self.datetime_format)
else:
- fact["end_time"] = ""
+ fact.end_time = ""
- fact["tags"] = ", ".join(fact["tags"])
+ fact.tags = ", ".join(fact.tags)
self._write_fact(self.file, fact)
@@ -104,10 +104,10 @@ class ICalWriter(ReportWriter):
def _write_fact(self, file, fact):
#for now we will skip ongoing facts
- if not fact["end_time"]: return
+ if not fact.end_time: return
- if fact["category"] == _("Unsorted"):
- fact["category"] = None
+ if fact.category == _("Unsorted"):
+ fact.category = None
self.file.write("""BEGIN:VEVENT
CATEGORIES:%(category)s
@@ -143,9 +143,13 @@ class TSVWriter(ReportWriter):
self.csv_writer.writerow([h.encode('utf-8') for h in headers])
def _write_fact(self, file, fact):
- self.csv_writer.writerow([fact[key] for key in ["name", "start_time",
- "end_time", "delta", "category", "description",
- "tags"]])
+ self.csv_writer.writerow([fact.activity,
+ fact.start_time,
+ fact.end_time,
+ fact.delta,
+ fact.category,
+ fact.description,
+ fact.tags])
def _finish(self, file, facts):
pass
@@ -157,13 +161,13 @@ class XMLWriter(ReportWriter):
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", stuff.duration_minutes(fact["delta"]))
- activity.setAttribute("category", fact["category"])
- activity.setAttribute("description", fact["description"])
- activity.setAttribute("tags", fact["tags"])
+ activity.setAttribute("name", fact.activity)
+ activity.setAttribute("start_time", fact.start_time)
+ activity.setAttribute("end_time", fact.end_time)
+ activity.setAttribute("duration_minutes", str(stuff.duration_minutes(fact.delta)))
+ activity.setAttribute("category", fact.category)
+ activity.setAttribute("description", fact.description)
+ activity.setAttribute("tags", fact.tags)
self.activity_list.appendChild(activity)
def _finish(self, file, facts):
@@ -225,79 +229,79 @@ class HTMLWriter(ReportWriter):
def _write_fact(self, report, fact):
# no having end time is fine
end_time_str, end_time_iso_str = "", ""
- if fact["end_time"]:
- end_time_str = fact["end_time"].strftime('%H:%M')
- end_time_iso_str = fact["end_time"].isoformat()
+ if fact.end_time:
+ end_time_str = fact.end_time.strftime('%H:%M')
+ end_time_iso_str = fact.end_time.isoformat()
category = ""
- if fact["category"] != _("Unsorted"): #do not print "unsorted" in list
- category = fact["category"]
+ if fact.category != _("Unsorted"): #do not print "unsorted" in list
+ category = fact.category
data = dict(
- date = fact["date"].strftime(
+ date = fact.date.strftime(
# date column format for each row in HTML report
# Using python datetime formatting syntax. See:
# http://docs.python.org/library/time.html#time.strftime
C_("html report","%b %d, %Y")),
- date_iso = fact["date"].isoformat(),
- activity = fact["name"],
+ date_iso = fact.date.isoformat(),
+ activity = fact.activity,
category = category,
- tags = fact["tags"],
- start = fact["start_time"].strftime('%H:%M'),
- start_iso = fact["start_time"].isoformat(),
+ tags = fact.tags,
+ start = fact.start_time.strftime('%H:%M'),
+ start_iso = fact.start_time.isoformat(),
end = end_time_str,
end_iso = end_time_iso_str,
- duration = stuff.format_duration(fact["delta"]) or "",
- duration_minutes = "%d" % (stuff.duration_minutes(fact["delta"])),
- duration_decimal = "%.2f" % (stuff.duration_minutes(fact["delta"]) / 60.0),
- description = fact["description"] or ""
+ duration = stuff.format_duration(fact.delta) or "",
+ duration_minutes = "%d" % (stuff.duration_minutes(fact.delta)),
+ duration_decimal = "%.2f" % (stuff.duration_minutes(fact.delta) / 60.0),
+ description = fact.description or ""
)
self.fact_rows.append(Template(self.fact_row_template).safe_substitute(data))
def _finish(self, report, facts):
# group by date
- name_category = lambda fact: (fact['category'], fact['name'])
+ name_category = lambda fact: (fact.category, fact.activity)
by_date = []
- for date, date_facts in itertools.groupby(facts, lambda fact:fact['date']):
+ for date, date_facts in itertools.groupby(facts, lambda fact:fact.date):
by_name = sorted(date_facts, key=name_category)
by_date_rows = []
for (category, activity), ac_facts in itertools.groupby(by_name, name_category):
duration = dt.timedelta()
for fact in ac_facts:
- duration += fact['delta']
+ duration += fact.delta
by_date_rows.append(Template(self.by_date_row_template).safe_substitute(
dict(activity = activity,
category = category,
duration = stuff.format_duration(duration),
- duration_minutes = "%d" % (stuff.duration_minutes(fact["delta"])),
- duration_decimal = "%.2f" % (stuff.duration_minutes(fact["delta"]) / 60.0),
+ duration_minutes = "%d" % (stuff.duration_minutes(fact.delta)),
+ duration_decimal = "%.2f" % (stuff.duration_minutes(fact.delta) / 60.0),
)
))
by_date_total_rows = []
- for category, c_facts in itertools.groupby(by_name, lambda fact:fact['category']):
+ for category, c_facts in itertools.groupby(by_name, lambda fact:fact.category):
duration = dt.timedelta()
for fact in c_facts:
- duration += fact['delta']
+ duration += fact.delta
by_date_total_rows.append(Template(self.by_date_total_row_template).safe_substitute(
dict(category = category,
duration = stuff.format_duration(duration),
- duration_minutes = "%d" % (stuff.duration_minutes(fact["delta"])),
- duration_decimal = "%.2f" % (stuff.duration_minutes(fact["delta"]) / 60.0),
+ duration_minutes = "%d" % (stuff.duration_minutes(fact.delta)),
+ duration_decimal = "%.2f" % (stuff.duration_minutes(fact.delta) / 60.0),
)
))
res = Template(self.by_date_template).safe_substitute(
- dict(date = fact["date"].strftime(
+ dict(date = fact.date.strftime(
# date column format for each row in HTML report
# Using python datetime formatting syntax. See:
# http://docs.python.org/library/time.html#time.strftime
diff --git a/src/hamster/stats.py b/src/hamster/stats.py
index 2a00e5e..e77ebaa 100644
--- a/src/hamster/stats.py
+++ b/src/hamster/stats.py
@@ -73,11 +73,11 @@ class Stats(object):
def init_stats(self):
self.stat_facts = runtime.storage.get_facts(dt.date(1970, 1, 2), dt.date.today())
- if not self.stat_facts or self.stat_facts[-1]["start_time"].year == self.stat_facts[0]["start_time"].year:
+ if not self.stat_facts or self.stat_facts[-1].start_time.year == self.stat_facts[0].start_time.year:
self.get_widget("explore_controls").hide()
else:
by_year = stuff.totals(self.stat_facts,
- lambda fact: fact["start_time"].year,
+ lambda fact: fact.start_time.year,
lambda fact: 1)
year_box = self.get_widget("year_box")
@@ -154,10 +154,10 @@ class Stats(object):
def stats(self, year = None):
facts = self.stat_facts
if year:
- facts = filter(lambda fact: fact["start_time"].year == year,
+ facts = filter(lambda fact: fact.start_time.year == year,
facts)
- if not facts or (facts[-1]["start_time"] - facts[0]["start_time"]) < dt.timedelta(days=6):
+ if not facts or (facts[-1].start_time - facts[0].start_time) < dt.timedelta(days=6):
self.get_widget("statistics_box").hide()
#self.get_widget("explore_controls").hide()
label = self.get_widget("not_enough_records_label")
@@ -176,23 +176,23 @@ A week of usage would be nice!"""))
self.get_widget("not_enough_records_label").hide()
# All dates in the scope
- durations = [(fact["start_time"], fact["delta"]) for fact in facts]
- self.timechart.draw(durations, facts[0]["date"], facts[-1]["date"])
+ durations = [(fact.start_time, fact.delta) for fact in facts]
+ self.timechart.draw(durations, facts[0].date, facts[-1].date)
# Totals by category
categories = stuff.totals(facts,
- lambda fact: fact["category"],
- lambda fact: fact['delta'].seconds / 60 / 60.0)
+ lambda fact: fact.category,
+ lambda fact: fact.delta.seconds / 60 / 60.0)
category_keys = sorted(categories.keys())
categories = [categories[key] for key in category_keys]
self.chart_category_totals.plot(category_keys, categories)
# Totals by weekday
weekdays = stuff.totals(facts,
- lambda fact: (fact["start_time"].weekday(),
- fact["start_time"].strftime("%a")),
- lambda fact: fact['delta'].seconds / 60 / 60.0)
+ lambda fact: (fact.start_time.weekday(),
+ fact.start_time.strftime("%a")),
+ lambda fact: fact.delta.seconds / 60 / 60.0)
weekday_keys = sorted(weekdays.keys(), key = lambda x: x[0]) #sort
weekdays = [weekdays[key] for key in weekday_keys] #get values in the order
@@ -204,18 +204,18 @@ A week of usage would be nice!"""))
# starts and ends by weekday
by_weekday = {}
- for date, date_facts in groupby(facts, lambda fact: fact["start_time"].date()):
+ for date, date_facts in groupby(facts, lambda fact: fact.start_time.date()):
date_facts = list(date_facts)
- weekday = (date_facts[0]["start_time"].weekday(),
- date_facts[0]["start_time"].strftime("%a"))
+ weekday = (date_facts[0].start_time.weekday(),
+ date_facts[0].start_time.strftime("%a"))
by_weekday.setdefault(weekday, [])
start_times, end_times = [], []
for fact in date_facts:
- start_time = fact["start_time"].time()
+ start_time = fact.start_time.time()
start_time = start_time.hour * 60 + start_time.minute
- if fact["end_time"]:
- end_time = fact["end_time"].time()
+ if fact.end_time:
+ end_time = fact.end_time.time()
end_time = end_time.hour * 60 + end_time.minute
if start_time < split_minutes:
@@ -257,19 +257,19 @@ A week of usage would be nice!"""))
# starts and ends by category
by_category = {}
- for date, date_facts in groupby(facts, lambda fact: fact["start_time"].date()):
- date_facts = sorted(list(date_facts), key = lambda x: x["category"])
+ for date, date_facts in groupby(facts, lambda fact: fact.start_time.date()):
+ date_facts = sorted(list(date_facts), key = lambda x: x.category)
- for category, category_facts in groupby(date_facts, lambda x: x["category"]):
+ for category, category_facts in groupby(date_facts, lambda x: x.category):
category_facts = list(category_facts)
by_category.setdefault(category, [])
start_times, end_times = [], []
for fact in category_facts:
- start_time = fact["start_time"]
+ start_time = fact.start_time
start_time = start_time.hour * 60 + start_time.minute
- if fact["end_time"]:
- end_time = fact["end_time"].time()
+ if fact.end_time:
+ end_time = fact.end_time.time()
end_time = end_time.hour * 60 + end_time.minute
if start_time < split_minutes:
@@ -317,12 +317,12 @@ A week of usage would be nice!"""))
# date format for the first record if the year has not been selected
# Using python datetime formatting syntax. See:
# http://docs.python.org/library/time.html#time.strftime
- first_date = facts[0]["start_time"].strftime(C_("first record", "%b %d, %Y"))
+ first_date = facts[0].start_time.strftime(C_("first record", "%b %d, %Y"))
else:
# date of first record when year has been selected
# Using python datetime formatting syntax. See:
# http://docs.python.org/library/time.html#time.strftime
- first_date = facts[0]["start_time"].strftime(C_("first record", "%b %d"))
+ first_date = facts[0].start_time.strftime(C_("first record", "%b %d"))
summary += _("First activity was recorded on %s.") % \
("<b>%s</b>" % first_date)
@@ -330,7 +330,7 @@ A week of usage would be nice!"""))
# total time tracked
total_delta = dt.timedelta(days=0)
for fact in facts:
- total_delta += fact["delta"]
+ total_delta += fact.delta
if total_delta.days > 1:
human_years_str = ngettext("%(num)s year",
@@ -353,16 +353,16 @@ A week of usage would be nice!"""))
# longest fact
max_fact = None
for fact in facts:
- if not max_fact or fact["delta"] > max_fact["delta"]:
+ if not max_fact or fact.delta > max_fact.delta:
max_fact = fact
- longest_date = max_fact["start_time"].strftime(
+ longest_date = max_fact.start_time.strftime(
# How the date of the longest activity should be displayed in statistics
# Using python datetime formatting syntax. See:
# http://docs.python.org/library/time.html#time.strftime
C_("date of the longest activity", "%b %d, %Y"))
- num_hours = max_fact["delta"].seconds / 60 / 60.0 + max_fact["delta"].days * 24
+ num_hours = max_fact.delta.seconds / 60 / 60.0 + max_fact.delta.days * 24
hours = "<b>%s</b>" % locale.format("%.1f", num_hours)
summary += "\n" + ngettext("Longest continuous work happened on \
@@ -388,9 +388,9 @@ A week of usage would be nice!"""))
return round(len(matches) / float(fact_count) * 100)
- early_percent = percent(lambda fact: early_start < fact["start_time"].time() < early_end)
- late_percent = percent(lambda fact: fact["start_time"].time() > late_start or fact["start_time"].time() < late_end)
- short_percent = percent(lambda fact: fact["delta"] <= dt.timedelta(seconds = 60 * 15))
+ early_percent = percent(lambda fact: early_start < fact.start_time.time() < early_end)
+ late_percent = percent(lambda fact: fact.start_time.time() > late_start or fact.start_time.time() < late_end)
+ short_percent = percent(lambda fact: fact.delta <= dt.timedelta(seconds = 60 * 15))
if fact_count < 100:
summary += "\n\n" + _("Hamster would like to observe you some more!")
diff --git a/src/hamster/utils/stuff.py b/src/hamster/utils/stuff.py
index 8f5cf4c..b8ab4a9 100644
--- a/src/hamster/utils/stuff.py
+++ b/src/hamster/utils/stuff.py
@@ -249,8 +249,8 @@ def figure_time(str_time):
class Fact(object):
def __init__(self, activity, category = "", description = "", tags = "",
- start_time = None, end_time = None, id = None,
- temporary = False):
+ start_time = None, end_time = None, id = None, delta = None,
+ date = None, activity_id = None):
"""the category, description and tags can be either passed in explicitly
or by using the "activity category, description #tag #tag" syntax.
explicitly stated values will take precedence over derived ones"""
@@ -258,12 +258,14 @@ class Fact(object):
self.activity = None
self.category = None
self.description = None
- self.tags = None
+ self.tags = []
self.start_time = None
self.end_time = None
- self.temporary = temporary
self.id = id
self.ponies = False
+ self.delta = delta
+ self.date = date
+ self.activity_id = activity_id
# parse activity
input_parts = activity.strip().split(" ")
@@ -318,14 +320,16 @@ class Fact(object):
#only thing left now is the activity name itself
self.activity = activity.strip()
+ tags = tags or ""
if tags and isinstance(tags, list):
tags = " ".join(tags)
+
tags = [tag.strip() for tag in tags.split(",") if tag.strip()]
# override implicit with explicit
self.category = category.replace("#", "").replace(",", "") or self.category or None
- self.description = description.replace("#", "") or self.description or None
- self.tags = tags or self.tags or None
+ self.description = (description or "").replace("#", "") or self.description or None
+ self.tags = tags or self.tags or []
self.start_time = start_time or self.start_time or None
self.end_time = end_time or self.end_time or None
@@ -342,7 +346,9 @@ class Fact(object):
return res
def __str__(self):
- time = self.start_time.strftime("%d %m %Y %H:%M")
+ time = ""
+ if self.start_time:
+ self.start_time.strftime("%d-%m-%Y %H:%M")
if self.end_time:
time = "%s - %s" % (time, self.end_time.strftime("%H:%M"))
return "%s %s" % (time, self.serialized_name())
diff --git a/src/hamster/utils/trophies.py b/src/hamster/utils/trophies.py
index f4fd9cc..a7587a9 100644
--- a/src/hamster/utils/trophies.py
+++ b/src/hamster/utils/trophies.py
@@ -53,24 +53,24 @@ def check_ongoing(todays_facts):
last_activity = None
if todays_facts[-1]['end_time'] is None:
last_activity = todays_facts[-1]
- last_activity['delta'] = dt.datetime.now() - last_activity['start_time']
+ last_activity.delta = dt.datetime.now() - last_activity.start_time
# overwhelmed: tracking for more than 16 hours during one day
- total = stuff.duration_minutes([fact['delta'] for fact in todays_facts])
+ total = stuff.duration_minutes([fact.delta for fact in todays_facts])
if total > 16 * 60:
unlock("overwhelmed")
if last_activity:
# Welcome! â?? track an activity for 10 minutes
- if last_activity['delta'] >= dt.timedelta(minutes = 10):
+ if last_activity.delta >= dt.timedelta(minutes = 10):
unlock("welcome")
# in_the_zone - spend 6 hours non-stop on an activity
- if last_activity['delta'] > dt.timedelta(hours = 6):
+ if last_activity.delta > dt.timedelta(hours = 6):
unlock("in_the_zone")
# insomnia - meet the new day while tracking an activity
- if last_activity['start_time'].date() != dt.date.today():
+ if last_activity.start_time.date() != dt.date.today():
unlock("insomnia")
diff --git a/src/hamster/widgets/dayline.py b/src/hamster/widgets/dayline.py
index 026929d..e54225f 100644
--- a/src/hamster/widgets/dayline.py
+++ b/src/hamster/widgets/dayline.py
@@ -137,11 +137,11 @@ class DayLine(graphics.Scene):
fact_bar = graphics.Rectangle(0, 0, fill = "#aaa", stroke="#aaa") # dimensions will depend on screen situation
fact_bar.fact = fact
- if fact['category'] in self.categories:
- fact_bar.category = self.categories.index(fact['category'])
+ if fact.category in self.categories:
+ fact_bar.category = self.categories.index(fact.category)
else:
fact_bar.category = len(self.categories)
- self.categories.append(fact['category'])
+ self.categories.append(fact.category)
self.plot_area.add_child(fact_bar)
self.fact_bars.append(fact_bar)
@@ -189,8 +189,8 @@ class DayLine(graphics.Scene):
end_time = None
if self.fact_bars:
- times = [bar.fact['start_time'] for bar in self.fact_bars if bar.fact['start_time'] - start_time > dt.timedelta(minutes=5)]
- times.extend([bar.fact['start_time'] + bar.fact['delta'] for bar in self.fact_bars if bar.fact['start_time'] + bar.fact['delta'] - start_time > dt.timedelta(minutes=5)])
+ times = [bar.fact.start_time for bar in self.fact_bars if bar.fact.start_time - start_time > dt.timedelta(minutes=5)]
+ times.extend([bar.fact.start_time + bar.fact.delta for bar in self.fact_bars if bar.fact.start_time + bar.fact.delta - start_time > dt.timedelta(minutes=5)])
if times:
end_time = min(times)
@@ -215,7 +215,7 @@ class DayLine(graphics.Scene):
break
if active_bar:
- self.set_tooltip_text("%s - %s" % (active_bar.fact['name'], active_bar.fact['category']))
+ self.set_tooltip_text("%s - %s" % (active_bar.fact.activity, active_bar.fact.category))
else:
self.set_tooltip_text("")
@@ -247,17 +247,17 @@ class DayLine(graphics.Scene):
bar.y = vertical * bar.category + 5
bar.height = vertical
- bar_start_time = bar.fact['start_time'] - self.view_time
+ bar_start_time = bar.fact.start_time - self.view_time
minutes = bar_start_time.seconds / 60 + bar_start_time.days * self.scope_hours * 60
bar.x = round(minutes / minute_pixel) + 0.5
- bar.width = round((bar.fact['delta']).seconds / 60 / minute_pixel)
+ bar.width = round((bar.fact.delta).seconds / 60 / minute_pixel)
if not snap_points or bar.x - snap_points[-1][0] > 1:
- snap_points.append((bar.x, bar.fact['start_time']))
+ snap_points.append((bar.x, bar.fact.start_time))
if not snap_points or bar.x + bar.width - snap_points[-1][0] > 1:
- snap_points.append((bar.x + bar.width, bar.fact['start_time'] + bar.fact['delta']))
+ snap_points.append((bar.x + bar.width, bar.fact.start_time + bar.fact.delta))
self.snap_points = snap_points
diff --git a/src/hamster/widgets/facttree.py b/src/hamster/widgets/facttree.py
index 726945e..c768fd5 100644
--- a/src/hamster/widgets/facttree.py
+++ b/src/hamster/widgets/facttree.py
@@ -67,14 +67,14 @@ class GroupRow(object):
class FactRow(object):
def __init__(self, fact):
self.fact = fact
- self.id = fact['id']
- self.name = fact['name']
- self.category = fact['category']
- self.description = fact['description']
- self.tags = fact['tags']
- self.start_time = fact['start_time']
- self.end_time = fact['end_time']
- self.delta = fact['delta']
+ self.id = fact.id
+ self.name = fact.activity
+ self.category = fact.category
+ self.description = fact.description
+ self.tags = fact.tags
+ self.start_time = fact.start_time
+ self.end_time = fact.end_time
+ self.delta = fact.delta
def __eq__(self, other):
return isinstance(other, FactRow) and other.id == self.id \
@@ -183,7 +183,7 @@ class FactTree(gtk.TreeView):
def add_group(self, group_label, group_date, facts):
- total_duration = stuff.duration_minutes([fact["delta"] for fact in facts])
+ total_duration = stuff.duration_minutes([fact.delta for fact in facts])
self.new_rows.append(GroupRow(group_label, group_date, total_duration))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]