def add(self, start, stop, task=''): """ Adds a time log to the database. Expects either ISO format strings or datetime instances that specifiy the time interval. The name of the task is optional. Note that no checks are done to assert that the new log does not overlap with an existing one. """ parser = Parser() if not isinstance(start, datetime): start = parser.extract_datetime(start) if not isinstance(stop, datetime): stop = parser.extract_datetime(stop) if stop < start: raise ValueError('Your time interval is negative') self.db.add_complete(start, stop, task, append=False) try: self.db.add_task(task, start.year, start.month) except ValueError: pass return '\n'.join([ 'added task {}'.format(task), 'start: {}'.format(prettify_datetime(start)), 'stop: {}'.format(prettify_datetime(stop)) ])
def status(self, extra=None, now=None): """ Returns a human-readable string with status information. The optional argument can be a (key, value) tuple, with the key being one of ('day', 'week', 'month', 'year', 'task'). """ if now is None: now = datetime.now() status = Status(self.db) if not extra: return status.get_current_info(now) key, value = extra if key == 'task': return status.get_task_info(value) parser = Parser(now) if key == 'day': d = parser.extract_date(value) return status.get_day_info(d) elif key == 'week': monday, sunday = parser.extract_week(value) return status.get_span_info(monday, sunday) elif key == 'month': year, month = parser.extract_month(value) return status.get_month_info(year, month) elif key == 'year': year = parser.extract_year(value) return status.get_year_info(year) elif key == 'span': d1, d2 = parser.extract_span(value) return status.get_span_info(d1, d2)
def test_extract_date_words(self, dt): parser = Parser(dt) today = dt.date() yesterday = dt.date() - timedelta(days=1) for word in ['last', 'yesterday']: res = parser.extract_date(word) self.assertEqual(res, yesterday) for word in ['', 'this', 'today']: res = parser.extract_date(word) self.assertEqual(res, today)
def test_extract_month_words(self, dt): parser = Parser(dt) last_month = dt.month - 1 or 12 last_month_year = dt.year - 1 if last_month == 12 else dt.year for word in ['last']: year, month = parser.extract_month(word) self.assertEqual(year, last_month_year) self.assertEqual(month, last_month) for word in ['', 'this']: year, month = parser.extract_month(word) self.assertEqual(year, dt.year) self.assertEqual(month, dt.month)
def edit(self, month): """ Invokes the user's favourite text editor to open the file corresponding to the specified year and month. """ parser = Parser(datetime.now()) year, month = parser.extract_month(month) file_path = self.db.get_path(year, month) if not os.path.exists(file_path): message = 'There are no logs for {}' raise ValueError(message.format(prettify_date(year, month))) spawner = Spawner() spawner.edit(file_path)
def setUp(self): self.now = datetime(2016, 10, 15) self.parser = Parser(self.now)