def get_date(self): '''Get the datetime object for the selected date''' year, month, day = gtk.Calendar.get_date(self) if day == 0: day = 1 try: date = datetime.date(year, month + 1, day) except ValueError: # This error may mean that day number is higher than allowed. # If so, set date to the last day of the month. if day > 27: date = datetime.date(year, month + 2, 1) - datetime.timedelta(days=1) else: raise return date
def _task_from_text(self, text, isopen=True, tags=None, parent=None): # Return task record for single line of text prio = text.count('!') if prio == 0 and parent: prio = parent[1] # inherit prio start = parent[2] if parent else 0 # inherit start date due = parent[3] if parent else _MAX_DUE_DATE # inherit due date for string in _date_re.findall(text): try: if string.startswith('[d:'): # backward compat date = old_parse_date(string[3:-1].strip()) if date: (year, month, day) = date due = datetime.date(year, month, day).isoformat() elif string.startswith('>'): start = parse_date(string[1:]).first_day.isoformat() elif string.startswith('<'): due = parse_date(string[1:]).last_day.isoformat() else: logger.warn('False postive matching date: %s', string) except ValueError: logger.warn('Invalid date format in task: %s', string) return [isopen, prio, start, due, tags, unicode(text.strip())]
def testParsing(self): date = datetime.date(2017, 3, 27) for text in ( '2017-03-27', '2017-03', '2017-W13', '2017-W13-1', '2017W13', '2017W13-1', '2017w13', '2017w13-1', 'W1713', 'W1713-1', 'W1713.1', 'Wk1713', 'Wk1713-1', 'Wk1713.1', 'wk1713', 'wk1713-1', 'wk1713.1', ): m = date_re.match(text) self.assertIsNotNone(m, 'Failed to match: %s' % text) self.assertEqual(m.group(0), text) obj = parse_date(m.group(0)) self.assertIsInstance(obj, (Day, Week, Month)) self.assertTrue(obj.first_day <= date <= obj.last_day) for text in ('foo', '123foo', '2017-03-270', '20170317', '17-03-27', '17-03' '17W', '2017W131', '2017-W131'): m = date_re.match(text) if m: print('>>', m.group(0)) self.assertIsNone(m, 'Did unexpectedly match: %s' % text)
def render_date(col, cell, model, i, data): date = model.get_value(i, self.DUE_COL) if date.strip() == '' or date.strip() == '9999': date_diff = None else: logger.debug("Date to split is '%s'" % str(date)) dsplit = date.split('-') try: date_date = datetime.date(int(dsplit[0]),int(dsplit[1]),int(dsplit[2])) date_diff = (date_date - datetime.date.today()).days except Exception as e: logger.error(str(e)) date_diff = None if date == _MAX_DUE_DATE: cell.set_property('text', '') else: if date_diff is None: cell.set_property('text', date) else: cell.set_property('text', "%s (%s)" % (date,date_diff)) # TODO allow strftime here if date <= today: color = HIGH_COLOR elif date <= tomorrow: color = MEDIUM_COLOR elif date <= dayafter: color = ALERT_COLOR # "<=" because tomorrow and/or dayafter can be after the weekend else: color = None cell.set_property('cell-background', color)
def on_suggest_link(self, notebook, source, text): #~ if date_path_re.match(path.text): #~ return Path(text) if re.match(r'^\d{4}-\d{2}-\d{2}$', text): year, month, day = text.split('-') year, month, day = map(int, (year, month, day)) date = datetime.date(year, month, day) return self.plugin.path_from_date(date) # TODO other formats else: return None
def daterange_from_path(path): '''Determine the calendar dates mapped by a specific page @param path: a L{Path} object @returns: a 3-tuple of: - the page type (one of "C{day}", "C{week}", "C{month}", or "C{year}") - a C{datetime.date} object for the start date - a C{datetime.date} object for the end date or C{None} when the page does not map a date ''' if date_path_re.match(path.name): type = 'day' year, month, day = map(int, path.name.rsplit(':', 3)[-3:]) date = datetime.date(year, month, day) end_date = date elif week_path_re.match(path.name): type = 'week' year, week = path.name.rsplit(':', 2)[-2:] year, week = map(int, (year, week[5:])) # Assumes "Week XX" string date, end_date = dates_for_week(year, week) elif month_path_re.match(path.name): type = 'month' year, month = map(int, path.name.rsplit(':', 2)[-2:]) date = datetime.date(year, month, 1) if month == 12: end_date = datetime.date(year, 12, 31) else: end_date = datetime.date(year, month+1, 1) + datetime.timedelta(-1) elif year_path_re.match(path.name): type = 'year' year = int(path.name.rsplit(':', 1)[-1]) date = datetime.date(year, 1, 1) end_date = datetime.date(year, 12, 31) else: return None # Not a calendar path return type, date, end_date
def _append_tasks(self, task, iter, path_cache): task_label_re = _task_labels_re(self.task_labels) today = datetime.date.today() today_str = str(today) if self.flatlist: assert task is None tasks = self.tasksview.list_open_tasks_flatlist() else: tasks = self.tasksview.list_open_tasks(task) for prio_sort_int, row in enumerate(tasks): if row['source'] not in path_cache: # TODO: add pagename to list_open_tasks query - need new index path = self.tasksview.get_path(row) if path is None: # Be robust for glitches - filter these out continue else: path_cache[row['source']] = path path = path_cache[row['source']] # Update labels for label in task_label_re.findall(row['description']): self._labels[label] = self._labels.get(label, 0) + 1 # Update tag count tags = [t for t in row['tags'].split(',') if t] if self.tag_by_page: tags = tags + path.parts if tags: for tag in tags: self._tags[tag] = self._tags.get(tag, 0) + 1 else: self._tags[_NO_TAGS] = self._tags.get(_NO_TAGS, 0) + 1 lowertags = [t.lower() for t in tags] actionable = not any(t in lowertags for t in self.nonactionable_tags) # Format label for "prio" column if row['start'] > today_str: actionable = False y, m, d = row['start'].split('-') td = datetime.date(int(y), int(m), int(d)) - today prio_sort_label = '>' + days_to_str(td.days) if row['prio'] > 0: prio_sort_label += ' ' + '!' * min(row['prio'], 3) elif row['due'] < _MAX_DUE_DATE: y, m, d = row['due'].split('-') td = datetime.date(int(y), int(m), int(d)) - today prio_sort_label = \ '!' * min(row['prio'], 3) + ' ' if row['prio'] > 0 else '' if td.days < 0: prio_sort_label += '<b><u>OD</u></b>' # over due elif td.days == 0: prio_sort_label += '<u>TD</u>' # today else: prio_sort_label += days_to_str(td.days) else: prio_sort_label = '!' * min(row['prio'], 3) # Format description desc = _date_re.sub('', row['description'], count=1) desc = re.sub('\s*!+\s*', ' ', desc) # get rid of exclamation marks desc = encode_markup_text(desc) if actionable: desc = _tag_re.sub( r'<span color="#ce5c00">@\1</span>', desc) # highlight tags - same color as used in pageview desc = task_label_re.sub(r'<b>\1</b>', desc) # highlight labels else: desc = r'<span color="darkgrey">%s</span>' % desc # Insert all columns modelrow = [ False, actionable, row['prio'], row['start'], row['due'], tags, desc, path.name, row['id'], prio_sort_int, prio_sort_label ] # VIS_COL, ACT_COL, PRIO_COL, START_COL, DUE_COL, TAGS_COL, DESC_COL, PAGE_COL, TASKID_COL, PRIO_SORT_COL, PRIO_SORT_LABEL_COL modelrow[0] = self._filter_item(modelrow) myiter = self.real_model.append(iter, modelrow) if row['haschildren'] and not self.flatlist: self._append_tasks(row, myiter, path_cache) # recurs
def get_date(self): '''Get the datetime object for the selected date''' year, month, day = gtk.Calendar.get_date(self) if day == 0: day = 1 return datetime.date(year, month + 1, day)