def occurs_later_today(self): if self.deleted: return False if self.tdelta.seconds == 0: return True x = now() return self.tdelta.seconds > 3600*x.hour + 60*x.minute
def __init__(self, text, date, prio): self.text = text self.date = date self.prio = prio self.removed = False self.prefix = '' self.last_updated = now()
def date_sweep(self): if self.show_events: self.update() if self.last_date_sweep.day == now().day: return True self.update_date_store() self.last_date_sweep = now() iter = self.model.get_iter_first() while iter: task = self.model.get_value(iter, 0) dest = self.where_it_should_go(task) if dest != self: self.remove(iter) dest.add(task) iter = self.model.get_iter_first() else: iter = self.model.iter_next(iter) self.update() return True
def sync(self): swap = self.path + '~' backup = self.path + '.backup-%d' % now().weekday() with open(swap, 'w') as s: data = { 'tasks': self.tasks, 'events': self.events, 'day': get_today(), } s.write(dumps(data)) file_api.update(data) if os.path.exists(self.path): os.rename(self.path, backup) os.rename(swap, self.path)
def inotifywait(self): """ Blocks until file change event happens and self.last_update is not recent """ while True: events = inotifyx.get_events(self.fd) if (now() - self.last_update).total_seconds() < 1.0: continue for e in events: sys.stdout.flush() if e.name == FILE_NAME and e.mask & self.NOTABLE: while inotifyx.get_events(self.fd, 0.5): pass return True
def parse_date(text): x = None out = '<?>' date = TaskDate(None) try: x = text.split()[-1] except: return '<?>', text, date x = x.lower() found = True if re.match(r'\d{1,2}/\d{1,2}/\d{4}', x): out = x x = map(int, x.split('/')) date = TaskDate(date=make_time(x[2], x[0], x[1])) elif '/' in x: today = now() try: x = x.split('/') a = make_time(today.year, int(x[0]), int(x[1])) b = make_time(today.year + 1, int(x[0]), int(x[1])) if (a - today).days < -30: out = "%s next year" % b.strftime("%b %d") date = TaskDate(date=b) elif (a - today).days < 0: out = "%s (past)" % a.strftime("%b %d") date = TaskDate(date=a) else: out = a.strftime("%b %d") date = TaskDate(date=a) except: found = False elif len(x) >= 3: o, f = out, found # save in case date match fails verify, out, f_date, found = DATE_MATCH_DICT.get(x[0:3], ['', out, lambda: date, False]) if found and not verify.startswith(x): out, found = o, f # reset on failed date match else: date = f_date() # assign date else: found = False if found: text = ' '.join(text.split()[:-1]) return out, text, date
def _callback(data): self.clear_all() new = filter(lambda t: not t.removed, data.get('tasks', [])) taskhat_write = data.get('last_taskhat_update', now()) taskhat_write += datetime.timedelta(seconds=1) closed = set() for task in new: closed.add(repr(task)) for task in self.persist.tasks: if task.last_updated > taskhat_write and repr(task) not in closed: new.append(task) self.persist.tasks = new for task in new: self.insert_task(task) task.last_updated = taskhat_write self.persist.events =\ filter(lambda e: not e.deleted, data.get('events', [])) self.persist.sync() self.update_events() return False
def offsets_to_next(self): today = now().weekday() return map(lambda d: (d - today) % 7, self.days)
def pause_change_monitoring(self): self.last_update = now()
def __init__(self, name, realizedparent, persist, daterange, top=False, events=False): super(gtk.VBox, self).__init__() TaskGroup.groups.append(self) self.top = top self.title = name self.show_events = events self.eventbuf = '' self.nextbuf = '' self.persist = persist self.daterange = daterange self.model = gtk.ListStore(gobject.TYPE_PYOBJECT) self.tree_view = gtk.TreeView(self.model) self.ebox = gtk.EventBox() self.label = gtk.Label() self.realizedparent = realizedparent self.concurrent_modification = False self.model.set_sort_func(42, self.sort_func) self.model.set_sort_column_id(42, gtk.SORT_DESCENDING) self.ebox.add(self.label) self.label.set_alignment(0,0) self.label.set_padding(3,3) self.pack_start(self.ebox, False, False) self.sep = gtk.HSeparator() if self.show_events: self.pack_start(self.sep, False, False) l2 = gtk.Label() l2.set_markup(SPACER_NO_NEWLINE) l2.show() self.pack_start(l2, False, False) self.pack_start(self.tree_view, False, False) self.tree_view.set_headers_visible(False) checkbox = gtk.TreeViewColumn('Done') renderer = gtk.CellRendererText() checkbox.pack_start(renderer, True) checkbox.set_cell_data_func(renderer, prefixformatter) renderer = gtk.CellRendererToggle() renderer.connect('toggled', self.destroy_cal) renderer.connect('toggled', self.destroy_task) checkbox.pack_end(renderer, False) checkbox.set_cell_data_func(renderer, togformatter) checkbox.set_min_width(45) column = gtk.TreeViewColumn('Tasks') renderer = gtk.CellRendererText() renderer.set_property('editable', True) renderer.set_property('ellipsize', pango.ELLIPSIZE_END) column.pack_start(renderer, True) column.set_expand(True) column.set_cell_data_func(renderer, taskformatter) renderer.connect('edited', self.text_changed) renderer = gtk.CellRendererCombo() renderer.set_property('editable', True) renderer.set_property('has_entry', False) prio_store = self.prio_store = gtk.ListStore(gobject.TYPE_STRING) prio_store.set(prio_store.append(), 0, str(Task.PRIORITY_ADMIN)) prio_store.set(prio_store.append(), 0, str(Task.PRIORITY_HIGH)) prio_store.set(prio_store.append(), 0, str(Task.PRIORITY_MEDIUM)) prio_store.set(prio_store.append(), 0, str(Task.PRIORITY_LOW)) renderer.set_property('model', prio_store) renderer.set_property('text_column', 0) prio = gtk.TreeViewColumn("Type") prio.pack_start(renderer, True) prio.set_cell_data_func(renderer, prioformatter) prio.set_min_width(30) renderer.connect('changed', self.prio_changed) def init_editing(*args): self.concurrent_modification = False # XXX need this to get rid of conflict with row_changed()? # also adding edit lock to stop updating old iters renderer.connect('editing-started', init_editing) renderer = gtk.CellRendererCombo() renderer.set_property('editable', True) renderer.set_property('has_entry', False) renderer.set_property('ellipsize', pango.ELLIPSIZE_END) date_store = self.date_store = gtk.ListStore(gobject.TYPE_STRING) self.update_date_store() renderer.set_property('model', date_store) renderer.set_property('text_column', 0) dates = gtk.TreeViewColumn("Dates") dates.set_min_width(100) dates.pack_start(renderer, True) dates.set_cell_data_func(renderer, dateformatter) renderer.connect('changed', self.date_changed) # XXX need this to get rid of conflict with row_changed()? # also adding edit lock to stop updating old iters renderer.connect('editing-started', init_editing) renderer = gtk.CellRendererPixbuf() notes = gtk.TreeViewColumn("Notes", renderer) self.tree_view.connect('button-press-event', self.destroy_cal) def activate_row(treeview, path, column): pass # TODO hook up to pixbuf for NOTE TAKING self.tree_view.connect('row-activated', activate_row) renderer = gtk.CellRendererText() notes.pack_end(renderer, True) notes.set_min_width(20) self.tree_view.append_column(checkbox) self.tree_view.append_column(prio) self.tree_view.append_column(column) self.tree_view.append_column(dates) self.tree_view.append_column(notes) self.tree_view.set_hover_selection(True) self.tree_view.show() self.ebox.show() self.pull_styles_from_window() self.show() self.realizedparent.connect('notify::style', self.pull_styles_from_window) self.last_date_sweep = now() # incremented when removed bit is set # decremented when removed from model OR removed bit is unset self.garbage_num = 0 gobject.timeout_add(60*1000, self.date_sweep)