def __init__(self, start_time = None): graphics.Scene.__init__(self) self.set_can_focus(False) # no interaction day_start = conf.get("day_start_minutes") self.day_start = dt.time(day_start / 60, day_start % 60) start_time = start_time or dt.datetime.now() self.view_time = start_time or dt.datetime.combine(start_time.date(), self.day_start) self.scope_hours = 24 self.fact_bars = [] self.categories = [] self.connect("on-enter-frame", self.on_enter_frame) self.plot_area = graphics.Sprite(y=15) self.chosen_selection = Selection() self.plot_area.add_child(self.chosen_selection) self.drag_start = None self.current_x = None self.date_label = graphics.Label(color=self._style.get_color(gtk.StateFlags.NORMAL), x=5, y=16) self.add_child(self.plot_area, self.date_label)
def __init__(self, storage): self.storage = storage # can't use client as then we get in a dbus loop self._last_notification = None dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) self.bus = dbus.SessionBus() self.conf_enable_timeout = conf.get("enable_timeout") self.conf_notify_on_idle = conf.get("notify_on_idle") self.conf_notify_interval = conf.get("notify_interval") conf.connect('conf-changed', self.on_conf_changed) self.idle_listener = idle.DbusIdleListener() self.idle_listener.connect('idle-changed', self.on_idle_changed) gobject.timeout_add_seconds(60, self.check_hamster)
def load_config(self, *args): self.get_widget("shutdown_track").set_active( conf.get("stop_on_shutdown")) self.get_widget("idle_track").set_active(conf.get("enable_timeout")) self.get_widget("notify_interval").set_value( conf.get("notify_interval")) self.get_widget("notify_on_idle").set_active( conf.get("notify_on_idle")) self.get_widget("notify_on_idle").set_sensitive( conf.get("notify_interval") <= 120) day_start = conf.get("day_start_minutes") day_start = dt.time(day_start / 60, day_start % 60) self.day_start.set_time(day_start) self.tags = [ tag["name"] for tag in runtime.storage.get_tags(only_autocomplete=True) ] self.get_widget("autocomplete_tags").set_text(", ".join(self.tags)) current_source = conf.get("activities_source") for i, (code, label) in enumerate(self.activities_sources): if code == current_source: self.todo_combo.set_active(i)
def __get_todays_facts(self): try: from hamster.lib.configuration import conf day_start = conf.get("day_start_minutes") except: day_start = 5 * 60 # default day start to 5am day_start = dt.time(day_start / 60, day_start % 60) today = (dt.datetime.now() - dt.timedelta( hours=day_start.hour, minutes=day_start.minute)).date() return self.__get_facts(today)
def __get_todays_facts(self): try: from hamster.lib.configuration import conf day_start = conf.get("day_start_minutes") except: day_start = 5 * 60 # default day start to 5am day_start = dt.time(day_start / 60, day_start % 60) today = (dt.datetime.now() - dt.timedelta(hours = day_start.hour, minutes = day_start.minute)).date() return self.__get_facts(today)
def __init__(self): gobject.GObject.__init__(self) self.source = conf.get("activities_source") self.__gtg_connection = None if self.source == "evo" and not evolution: self.source == "" # on failure pretend that there is no evolution elif self.source == "gtg": gobject.GObject.__init__(self) dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
def __init__(self): gobject.GObject.__init__(self) self.source = conf.get("activities_source") self.__gtg_connection = None if self.source == "evo" and not evolution: self.source == "" # on failure pretend that there is no evolution elif self.source == "gtg": gobject.GObject.__init__(self) dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
def __init__(self): gtk.Dialog.__init__(self) self.dialog = gtk.FileChooserDialog(title = _(u"Save Report — Time Tracker"), parent = self, action = gtk.FileChooserAction.SAVE, buttons=(gtk.STOCK_CANCEL, gtk.ResponseType.CANCEL, gtk.STOCK_SAVE, gtk.ResponseType.OK)) # try to set path to last known folder or fall back to home report_folder = os.path.expanduser(conf.get("last_report_folder")) if os.path.exists(report_folder): self.dialog.set_current_folder(report_folder) else: self.dialog.set_current_folder(os.path.expanduser("~")) self.filters = {} filter = gtk.FileFilter() filter.set_name(_("HTML Report")) filter.add_mime_type("text/html") filter.add_pattern("*.html") filter.add_pattern("*.htm") self.filters[filter] = "html" self.dialog.add_filter(filter) filter = gtk.FileFilter() filter.set_name(_("Tab-Separated Values (TSV)")) filter.add_mime_type("text/plain") filter.add_pattern("*.tsv") filter.add_pattern("*.txt") self.filters[filter] = "tsv" self.dialog.add_filter(filter) filter = gtk.FileFilter() filter.set_name(_("XML")) filter.add_mime_type("text/xml") filter.add_pattern("*.xml") self.filters[filter] = "xml" self.dialog.add_filter(filter) filter = gtk.FileFilter() filter.set_name(_("iCal")) filter.add_mime_type("text/calendar") filter.add_pattern("*.ics") self.filters[filter] = "ical" self.dialog.add_filter(filter) filter = gtk.FileFilter() filter.set_name("All files") filter.add_pattern("*") self.dialog.add_filter(filter)
def __init__(self): gtk.Dialog.__init__(self) self.dialog = gtk.FileChooserDialog( title=_("Save Report — Time Tracker"), parent=self, action=gtk.FileChooserAction.SAVE, buttons=(gtk.STOCK_CANCEL, gtk.ResponseType.CANCEL, gtk.STOCK_SAVE, gtk.ResponseType.OK)) # try to set path to last known folder or fall back to home report_folder = os.path.expanduser(conf.get("last_report_folder")) if os.path.exists(report_folder): self.dialog.set_current_folder(report_folder) else: self.dialog.set_current_folder(os.path.expanduser("~")) self.filters = {} filter = gtk.FileFilter() filter.set_name(_("HTML Report")) filter.add_mime_type("text/html") filter.add_pattern("*.html") filter.add_pattern("*.htm") self.filters[filter] = "html" self.dialog.add_filter(filter) filter = gtk.FileFilter() filter.set_name(_("Tab-Separated Values (TSV)")) filter.add_mime_type("text/plain") filter.add_pattern("*.tsv") filter.add_pattern("*.txt") self.filters[filter] = "tsv" self.dialog.add_filter(filter) filter = gtk.FileFilter() filter.set_name(_("XML")) filter.add_mime_type("text/xml") filter.add_pattern("*.xml") self.filters[filter] = "xml" self.dialog.add_filter(filter) filter = gtk.FileFilter() filter.set_name(_("iCal")) filter.add_mime_type("text/calendar") filter.add_pattern("*.ics") self.filters[filter] = "ical" self.dialog.add_filter(filter) filter = gtk.FileFilter() filter.set_name("All files") filter.add_pattern("*") self.dialog.add_filter(filter)
def __init__(self, parent=None, fact_date=None, fact_id=None): gobject.GObject.__init__(self) self._gui = load_ui_file("edit_activity.ui") self.window = self.get_widget('custom_fact_window') self.window.set_size_request(600, 200) self.parent, self.fact_id = parent, fact_id #TODO - should somehow hint that time is not welcome here self.activity = widgets.ActivityEntry() self.activity.connect("changed", self.on_activity_changed) self.get_widget("activity_box").add(self.activity) day_start = conf.get("day_start_minutes") self.day_start = dt.time(day_start / 60, day_start % 60) self.date = fact_date if not self.date: self.date = (dt.datetime.now() - dt.timedelta(hours=self.day_start.hour, minutes=self.day_start.minute)).date() self.dayline = widgets.DayLine() self._gui.get_object("day_preview").add(self.dayline) self.activity.grab_focus() if fact_id: fact = runtime.storage.get_fact(fact_id) label = fact.start_time.strftime("%H:%M") if fact.end_time: label += fact.end_time.strftime(" %H:%M") label += " " + fact.serialized_name() with self.activity.handler_block(self.activity.checker): self.activity.set_text(label) self.activity.select_region(len(label) - len(fact.serialized_name()), -1) buf = gtk.TextBuffer() buf.set_text(fact.description or "") self.get_widget('description').set_buffer(buf) self.get_widget("save_button").set_label("gtk-save") self.window.set_title(_("Update activity")) else: self.get_widget("delete_button").set_sensitive(False) self._gui.connect_signals(self) self.validate_fields() self.window.show_all()
def __init__(self, parent=None, fact_date=None, fact_id=None): gobject.GObject.__init__(self) self._gui = load_ui_file("edit_activity.ui") self.window = self.get_widget('custom_fact_window') self.window.set_size_request(600, 200) self.parent, self.fact_id = parent, fact_id #TODO - should somehow hint that time is not welcome here self.activity = widgets.ActivityEntry() self.activity.connect("changed", self.on_activity_changed) self.get_widget("activity_box").add(self.activity) day_start = conf.get("day_start_minutes") self.day_start = dt.time(day_start / 60, day_start % 60) self.date = fact_date if not self.date: self.date = (dt.datetime.now() - dt.timedelta(hours=self.day_start.hour, minutes=self.day_start.minute)).date() self.dayline = widgets.DayLine() self._gui.get_object("day_preview").add(self.dayline) self.activity.grab_focus() if fact_id: fact = runtime.storage.get_fact(fact_id) label = fact.start_time.strftime("%H:%M") if fact.end_time: label += fact.end_time.strftime(" %H:%M") label += " " + fact.serialized_name() with self.activity.handler_block(self.activity.checker): self.activity.set_text(label) self.activity.select_region(len(label) - len(fact.serialized_name()), -1) buf = gtk.TextBuffer() buf.set_text(fact.description or "") self.get_widget('description').set_buffer(buf) self.get_widget("save_button").set_label("gtk-save") self.window.set_title(_("Update activity")) else: self.get_widget("delete_button").set_sensitive(False) self._gui.connect_signals(self) self.validate_fields() self.window.show_all()
def load_config(self, *args): self.get_widget("shutdown_track").set_active(conf.get("stop_on_shutdown")) self.get_widget("idle_track").set_active(conf.get("enable_timeout")) self.get_widget("notify_interval").set_value(conf.get("notify_interval")) self.get_widget("notify_on_idle").set_active(conf.get("notify_on_idle")) self.get_widget("notify_on_idle").set_sensitive(conf.get("notify_interval") <= 120) day_start = conf.get("day_start_minutes") day_start = dt.time(day_start / 60, day_start % 60) self.day_start.set_time(day_start) self.tags = [tag["name"] for tag in runtime.storage.get_tags(only_autocomplete=True)] self.get_widget("autocomplete_tags").set_text(", ".join(self.tags)) current_source = conf.get("activities_source") for i, (code, label) in enumerate(self.activities_sources): if code == current_source: self.todo_combo.set_active(i)
def __get_facts(self, date, end_date=None, search_terms=""): try: from hamster.lib.configuration import conf day_start = conf.get("day_start_minutes") except: day_start = 5 * 60 # default day start to 5am day_start = dt.time(day_start / 60, day_start % 60) split_time = day_start datetime_from = dt.datetime.combine(date, split_time) end_date = end_date or date datetime_to = dt.datetime.combine(end_date, split_time) + dt.timedelta(days=1) query = """ SELECT a.id AS id, a.start_time AS start_time, a.end_time AS end_time, a.description as description, b.name AS name, b.id as activity_id, coalesce(c.name, ?) as category, e.name as tag FROM facts a LEFT JOIN activities b ON a.activity_id = b.id LEFT JOIN categories c ON b.category_id = c.id LEFT JOIN fact_tags d ON d.fact_id = a.id LEFT JOIN tags e ON e.id = d.tag_id WHERE (a.end_time >= ? OR a.end_time IS NULL) AND a.start_time <= ? """ if search_terms: # check if we need changes to the index self.__check_index(datetime_from, datetime_to) search_terms = search_terms.replace('\\', '\\\\').replace( '%', '\\%').replace('_', '\\_').replace("'", "''") query += """ AND a.id in (SELECT id FROM fact_index WHERE fact_index MATCH '%s')""" % search_terms query += " ORDER BY a.start_time, e.name" facts = self.fetchall( query, (self._unsorted_localized, datetime_from, datetime_to)) #first let's put all tags in an array facts = self.__group_tags(facts) res = [] for fact in facts: # heuristics to assign tasks to proper days # if fact has no end time, set the last minute of the day, # or current time if fact has happened in last 12 hours if fact["end_time"]: fact_end_time = fact["end_time"] elif (dt.datetime.now().date() == fact["start_time"].date()) or \ (dt.datetime.now() - fact["start_time"]) <= dt.timedelta(hours=12): fact_end_time = dt.datetime.now().replace(microsecond=0) else: fact_end_time = fact["start_time"] fact_start_date = fact["start_time"].date() \ - dt.timedelta(1 if fact["start_time"].time() < split_time else 0) fact_end_date = fact_end_time.date() \ - dt.timedelta(1 if fact_end_time.time() < split_time else 0) fact_date_span = fact_end_date - fact_start_date # check if the task spans across two dates if fact_date_span.days == 1: datetime_split = dt.datetime.combine(fact_end_date, split_time) start_date_duration = datetime_split - fact["start_time"] end_date_duration = fact_end_time - datetime_split if start_date_duration > end_date_duration: # most of the task was done during the previous day fact_date = fact_start_date else: fact_date = fact_end_date else: # either doesn't span or more than 24 hrs tracked # (in which case we give up) fact_date = fact_start_date if fact_date < date or fact_date > end_date: # due to spanning we've jumped outside of given period continue fact["date"] = fact_date fact["delta"] = fact_end_time - fact["start_time"] res.append(fact) return res
def __get_facts(self, date, end_date = None, search_terms = ""): try: from hamster.lib.configuration import conf day_start = conf.get("day_start_minutes") except: day_start = 5 * 60 # default day start to 5am day_start = dt.time(day_start / 60, day_start % 60) split_time = day_start datetime_from = dt.datetime.combine(date, split_time) end_date = end_date or date datetime_to = dt.datetime.combine(end_date, split_time) + dt.timedelta(days = 1) query = """ SELECT a.id AS id, a.start_time AS start_time, a.end_time AS end_time, a.description as description, b.name AS name, b.id as activity_id, coalesce(c.name, ?) as category, e.name as tag FROM facts a LEFT JOIN activities b ON a.activity_id = b.id LEFT JOIN categories c ON b.category_id = c.id LEFT JOIN fact_tags d ON d.fact_id = a.id LEFT JOIN tags e ON e.id = d.tag_id WHERE (a.end_time >= ? OR a.end_time IS NULL) AND a.start_time <= ? """ if search_terms: # check if we need changes to the index self.__check_index(datetime_from, datetime_to) # flip the query around when it starts with "not " reverse_search_terms = search_terms.lower().startswith("not ") if reverse_search_terms: search_terms = search_terms[4:] search_terms = search_terms.replace('\\', '\\\\').replace('%', '\\%').replace('_', '\\_').replace("'", "''") query += """ AND a.id %s IN (SELECT id FROM fact_index WHERE fact_index MATCH '%s')""" % ('NOT' if reverse_search_terms else '', search_terms) query += " ORDER BY a.start_time, e.name" facts = self.fetchall(query, (self._unsorted_localized, datetime_from, datetime_to)) #first let's put all tags in an array facts = self.__group_tags(facts) res = [] for fact in facts: # heuristics to assign tasks to proper days # if fact has no end time, set the last minute of the day, # or current time if fact has happened in last 12 hours if fact["end_time"]: fact_end_time = fact["end_time"] elif (dt.datetime.now().date() == fact["start_time"].date()) or \ (dt.datetime.now() - fact["start_time"]) <= dt.timedelta(hours=12): fact_end_time = dt.datetime.now().replace(microsecond = 0) else: fact_end_time = fact["start_time"] fact_start_date = fact["start_time"].date() \ - dt.timedelta(1 if fact["start_time"].time() < split_time else 0) fact_end_date = fact_end_time.date() \ - dt.timedelta(1 if fact_end_time.time() < split_time else 0) fact_date_span = fact_end_date - fact_start_date # check if the task spans across two dates if fact_date_span.days == 1: datetime_split = dt.datetime.combine(fact_end_date, split_time) start_date_duration = datetime_split - fact["start_time"] end_date_duration = fact_end_time - datetime_split if start_date_duration > end_date_duration: # most of the task was done during the previous day fact_date = fact_start_date else: fact_date = fact_end_date else: # either doesn't span or more than 24 hrs tracked # (in which case we give up) fact_date = fact_start_date if fact_date < date or fact_date > end_date: # due to spanning we've jumped outside of given period continue fact["date"] = fact_date fact["delta"] = fact_end_time - fact["start_time"] res.append(fact) return res