def set_status(self, status, donedate=None): old_status = self.status if status == old_status: return self.can_be_deleted = False # No need to update children or whatever if the task is not loaded if status and self.is_loaded(): # we first modify the status of the children # If Done, we set the done date if status in [self.STA_DONE, self.STA_DISMISSED]: for c in self.get_subtasks(): if c.get_status() in [self.STA_ACTIVE]: c.set_status(status, donedate=donedate) # If we mark a task as Active and that some parent are not # Active, we break the parent/child relation # It has no sense to have an active subtask of a done parent. # (old_status check is necessary to avoid false positive a start) elif status in [self.STA_ACTIVE] and\ old_status in [self.STA_DONE, self.STA_DISMISSED]: if self.has_parent(): for p_tid in self.get_parents(): par = self.req.get_task(p_tid) if par.is_loaded() and par.get_status() in\ [self.STA_DONE, self.STA_DISMISSED]: # we can either break the parent/child relationship # self.remove_parent(p_tid) # or restore the parent too par.set_status(self.STA_ACTIVE) # We dont mark the children as Active because # They might be already completed after all # then the task itself if status: self.status = status # Set closing date if status and status in [self.STA_DONE, self.STA_DISMISSED]: # to the specified date (if any) if donedate: self.closed_date = donedate # or to today else: self.closed_date = Date.today() self._has_been_modified() self.sync()
def set_date(self, date, date_kind): self.__date_kind = date_kind if date_kind == GTGCalendar.DATE_KIND_DUE: self.__fuzzydate_btns.show() else: self.__fuzzydate_btns.hide() if not date: # we set the widget to today's date if there is not a date defined date = Date.today() self.__date = date if not date.is_fuzzy(): self.__calendar.select_day(date.day) # Calendar use 0..11 for a month so we need -1 # We can't use conversion through python's datetime # because it is often an invalid date self.__calendar.select_month(date.month - 1, date.year)
def set_date(self, date, date_kind): self.__date_kind = date_kind if date_kind == GTGCalendar.DATE_KIND_DUE: self.__fuzzydate_btns.show() else: self.__fuzzydate_btns.hide() if not date: # we set the widget to today's date if there is not a date defined date = Date.today() self.__date = date if not date.is_fuzzy(): self.__calendar.select_day(date.day) # Calendar use 0..11 for a month so we need -1 # We can't use conversion through python's datetime # because it is often an invalid date self.__calendar.select_month(date.month - 1, date.year)
def check_commands(commands_list): """ Execute search commands This method is recursive for !or and !and """ def fulltext_search(task, word): """ check if task contains the word """ word = word.lower() text = task.get_excerpt(strip_tags=False).lower() title = task.get_title().lower() return word in text or word in title value_checks = { 'after': lambda t, v: task.get_due_date() > v, 'before': lambda t, v: task.get_due_date() < v, 'tag': lambda t, v: v in task.get_tags_name(), 'word': fulltext_search, 'today': lambda task, v: task.get_due_date() == Date.today(), 'tomorrow': lambda task, v: task.get_due_date() == Date.tomorrow(), 'nodate': lambda task, v: task.get_due_date() == Date.no_date(), 'now': lambda task, v: task.get_due_date() == Date.now(), 'soon': lambda task, v: task.get_due_date() == Date.soon(), 'someday': lambda task, v: task.get_due_date() == Date.someday(), 'notag': lambda task, v: task.get_tags() == [], } for command in commands_list: cmd, positive, args = command[0], command[1], command[2:] result = False if cmd == 'or': for sub_cmd in args[0]: if check_commands([sub_cmd]): result = True break elif value_checks.get(cmd, None): if len(args) > 0: args = args[0] result = value_checks[cmd](task, args) if (positive and not result) or (not positive and result): return False return True
def check_commands(commands_list): """ Execute search commands This method is recursive for !or and !and """ def fulltext_search(task, word): """ check if task contains the word """ word = word.lower() text = task.get_excerpt(strip_tags=False).lower() title = task.get_title().lower() return word in text or word in title value_checks = { 'after': lambda t, v: task.get_due_date() > v, 'before': lambda t, v: task.get_due_date() < v, 'tag': lambda t, v: v in task.get_tags_name(), 'word': fulltext_search, 'today': lambda task, v: task.get_due_date() == Date.today(), 'tomorrow': lambda task, v: task.get_due_date() == Date.tomorrow(), 'nodate': lambda task, v: task.get_due_date() == Date.no_date(), 'now': lambda task, v: task.get_due_date() == Date.now(), 'soon': lambda task, v: task.get_due_date() == Date.soon(), 'someday': lambda task, v: task.get_due_date() == Date.someday(), 'notag': lambda task, v: task.get_tags() == [], } for command in commands_list: cmd, positive, args = command[0], command[1], command[2:] result = False if cmd == 'or': for sub_cmd in args[0]: if check_commands([sub_cmd]): result = True break elif value_checks.get(cmd, None): if len(args) > 0: args = args[0] result = value_checks[cmd](task, args) if (positive and not result) or (not positive and result): return False return True
def delete_old_closed_tasks(self, widget=None): self.__log("Starting deletion of old tasks") today = Date.today() max_days = self.preferences["max_days"] requester = self.plugin_api.get_requester() closed_tree = requester.get_tasks_tree(name='inactive') closed_tasks = [requester.get_task(tid) for tid in closed_tree.get_all_nodes()] to_remove = [t for t in closed_tasks if (today - t.get_closed_date()).days > max_days] for task in to_remove: if requester.has_task(task.get_id()): requester.delete_task(task.get_id()) # If automatic purging is on, schedule another run if self.is_automatic: self.schedule_autopurge()
def set_status(self, status, donedate=None): old_status = self.status self.can_be_deleted = False # No need to update children or whatever if the task is not loaded if status and self.is_loaded(): # we first modify the status of the children # If Done, we set the done date if status in [self.STA_DONE, self.STA_DISMISSED]: for c in self.get_subtasks(): if c.get_status() in [self.STA_ACTIVE]: c.set_status(status, donedate=donedate) # If we mark a task as Active and that some parent are not # Active, we break the parent/child relation # It has no sense to have an active subtask of a done parent. # (old_status check is necessary to avoid false positive a start) elif status in [self.STA_ACTIVE] and\ old_status in [self.STA_DONE, self.STA_DISMISSED]: if self.has_parent(): for p_tid in self.get_parents(): par = self.req.get_task(p_tid) if par.is_loaded() and par.get_status() in\ [self.STA_DONE, self.STA_DISMISSED]: # we can either break the parent/child relationship # self.remove_parent(p_tid) # or restore the parent too par.set_status(self.STA_ACTIVE) # We dont mark the children as Active because # They might be already completed after all # then the task itself if status: self.status = status # Set closing date if status and status in [self.STA_DONE, self.STA_DISMISSED]: # to the specified date (if any) if donedate: self.closed_date = donedate # or to today else: self.closed_date = Date.today() self.sync()
def purge_old_tasks(self, widget=None): log.debug("Deleting old tasks") today = Date.today() max_days = self.config.get('autoclean_days') closed_tree = self.req.get_tasks_tree(name='inactive') closed_tasks = [ self.req.get_task(tid) for tid in closed_tree.get_all_nodes() ] to_remove = [ t for t in closed_tasks if (today - t.get_closed_date()).days > max_days ] [ self.req.delete_task(task.get_id()) for task in to_remove if self.req.has_task(task.get_id()) ]
def get_node_bgcolor(self, node): """ This method checks the urgency of a node (task) and returns its urgency background color""" sdate = node.get_start_date() ddate = node.get_due_date() daysleft = ddate.days_left() # Dates undefined (Fix to bug #1039655) if ddate == Date.today(): return self._get_color(2) # High urgency elif daysleft < 0 and ddate != Date.no_date(): return self._get_color(3) # Overdue elif ( sdate == Date.no_date() # Has no start date and ddate != Date.no_date() # and a due date and not ddate.is_fuzzy() ): # which is not fuzzy, is fixed return self._get_color(1) # Normal # Fuzzy dates (now, soon, someday) # These can ignore the start date if ddate == Date.now(): return self._get_color(2) elif ddate == Date.soon(): return self._get_color(1) elif ddate == Date.someday(): return self._get_color(0) # Dates fully defined. Calculate gradient color elif sdate != Date.no_date() != ddate: dayspan = (ddate - sdate).days redf = self._pref_data["reddays"] reddays = int(ceil(redf / 100.0 * dayspan)) # Gradient variables grad_dayspan = dayspan - reddays grad_half_dayspan = grad_dayspan / 2.0 # Default to low urgency color color = self._get_color(0) # CL : low urgency color # CN : normal urgency color # CH : high urgency color # CO : overdue color # To understand this section, it is easier to draw out a # timeline divided into 3 sections: CL to CN, CN to CH and # the reddays section. Then point out the spans of the # different variables (dayspan, daysleft, reddays, # grad_dayspan, grad_half_dayspan) if daysleft < 0: # CO color = self._get_color(3) elif daysleft <= reddays: # CH color = self._get_color(2) elif daysleft <= (dayspan - grad_half_dayspan): # Gradient CN to CH # Has to be float so division by it is non-zero steps = float(grad_half_dayspan) step = grad_half_dayspan - (daysleft - reddays) color = self._get_gradient_color(self._get_color(1), self._get_color(2), step / steps) elif daysleft <= dayspan: # Gradient CL to CN steps = float(grad_half_dayspan) step = grad_half_dayspan - (daysleft - reddays - grad_half_dayspan) color = self._get_gradient_color(self._get_color(0), self._get_color(1), step / steps) return color # Insufficient data to determine urgency else: return None
def get_node_bgcolor(self, node): """ This method checks the urgency of a node (task) and returns its urgency background color""" sdate = node.get_start_date() ddate = node.get_due_date() daysleft = ddate.days_left() # Dates undefined (Fix to bug #1039655) if (ddate == Date.today()): return self._get_color(2) # High urgency elif (daysleft < 0 and ddate != Date.no_date()): return self._get_color(3) # Overdue elif (sdate == Date.no_date() # Has no start date and ddate != Date.no_date() # and a due date and not ddate.is_fuzzy()): # which is not fuzzy, is fixed return self._get_color(1) # Normal # Fuzzy dates (now, soon, someday) # These can ignore the start date if (ddate == Date.now()): return self._get_color(2) elif (ddate == Date.soon()): return self._get_color(1) elif (ddate == Date.someday()): return self._get_color(0) # Dates fully defined. Calculate gradient color elif (sdate != Date.no_date() != ddate): dayspan = (ddate - sdate).days redf = self._pref_data['reddays'] reddays = int(ceil(redf / 100.0 * dayspan)) # Gradient variables grad_dayspan = dayspan - reddays grad_half_dayspan = grad_dayspan / 2.0 # Default to low urgency color color = self._get_color(0) # CL : low urgency color # CN : normal urgency color # CH : high urgency color # CO : overdue color # To understand this section, it is easier to draw out a # timeline divided into 3 sections: CL to CN, CN to CH and # the reddays section. Then point out the spans of the # different variables (dayspan, daysleft, reddays, # grad_dayspan, grad_half_dayspan) if daysleft < 0: # CO color = self._get_color(3) elif daysleft <= reddays: # CH color = self._get_color(2) elif daysleft <= (dayspan - grad_half_dayspan): # Gradient CN to CH # Has to be float so division by it is non-zero steps = float(grad_half_dayspan) step = grad_half_dayspan - (daysleft - reddays) color = self._get_gradient_color(self._get_color(1), self._get_color(2), step / steps) elif daysleft <= dayspan: # Gradient CL to CN steps = float(grad_half_dayspan) step = grad_half_dayspan - (daysleft - reddays - grad_half_dayspan) color = self._get_gradient_color(self._get_color(0), self._get_color(1), step / steps) return color # Insufficient data to determine urgency else: return None