def do_t_due(self, line): """Set task's due date t_due <id> <date> Date can be specified as a relative offset: - +5M: in 5 minutes - +3H: in 3 hours - +1D: in 1 day - +6W: in 6 weeks As a day in the week: - tomorrow: tomorrow, same hour - tuesday 12:10: next tuesday, at 12:10 - fr 15:30: next friday, at 15:30 Or as an absolute date or time: - 10:38: at 10:38 today - 25/09/2010 12:10: on the 25th of September, 2010, at 12:10 - 23/02/2010: on the 23th of February, 2010 - 01/04: on the 1st of April - 12: on the 12th of current month To reset a due date, use "none".""" line = parseutils.simplifySpaces(line) if len(line.split()) < 2: raise YokadiException("Give a task id and time, date or date & time") taskId, line = line.strip().split(" ", 1) task = self.getTaskFromId(taskId) if line.lower() == "none": task.dueDate = None print "Due date for task '%s' reset" % task.title else: task.dueDate = ydateutils.parseHumaneDateTime(line) print "Due date for task '%s' set to %s" % (task.title, task.dueDate.ctime())
def testParseHumaneDateTime(self): for date in ("+5M", "+1m", "+2H", "+3h", "+9D", "+14d", "+432W", "+0w", "01/01/2009", "10/10/2008 12", "7/7/2007 10:15", "1/2/2003 1:2:3"): ydateutils.parseHumaneDateTime(date) for invalidDate in ("2008", "01/2009", "01//02/01", "02/20/2009", "", "+3e", "lkjljlkjlkj", "200/200/2009"): self.assertRaises(YokadiException, ydateutils.parseHumaneDateTime, invalidDate) # Fake today to a fixed date. This is a saturday (weekday=5). today = datetime(2009, 1, 3) endOfDay = dict(hour=23, minute=59, second=59) startOfDay = dict(hour=0, minute=0, second=0) testData = [ ("06/02/2009", None, datetime(2009, 2, 6)), ("06/02/09", None, datetime(2009, 2, 6)), ("06/02/2009 12:30", None, datetime(2009, 2, 6, 12, 30)), ("06/02/2009", ydateutils.TIME_HINT_BEGIN, datetime(2009, 2, 6, 0, 0, 0)), ("06/02/2009", ydateutils.TIME_HINT_END, datetime(2009, 2, 6, 23, 59, 59)), ("tomorrow 18:00", None, today + timedelta(days=1, hours=18)), ("tomorrow", ydateutils.TIME_HINT_END, today.replace(day=4, hour=23, minute=59, second=59)), ("sunday", None, datetime(2009, 1, 4)), ("tu 11:45", None, datetime(2009, 1, 6, 11, 45)), ("today", ydateutils.TIME_HINT_END, today.replace(**endOfDay)), ("today", ydateutils.TIME_HINT_BEGIN, today.replace(**startOfDay)), ("now", None, today), ("today 5 PM", None, today.replace(hour=17)), ("6:32pm", None, today.replace(hour=18, minute=32)), ("06/02 2:40 am", None, datetime(2009, 2, 6, 2, 40)), ("+2w", None, datetime(2009, 1, 17)), ("+1d", None, datetime(2009, 1, 4)), ("-1d", None, datetime(2009, 1, 2)), ("+3h", None, datetime(2009, 1, 3, 3, 0)), ("-1M", None, datetime(2009, 1, 2, 23, 59)), ] for text, hint, expected in testData: output = ydateutils.parseHumaneDateTime(text, hint=hint, today=today) self.assertEquals(expected, output)
def main(): parser = ArgumentParser() parser.add_argument('db', metavar='<db>') args = parser.parse_args() dbname = args.db if os.path.exists(dbname): os.unlink(dbname) db.connectDatabase(dbname) db.setDefaultConfig() session = db.getSession() for name in PROJECTS: session.add(db.Project(name=name)) for name in KEYWORDS: dbutils.getOrCreateKeyword(name, interactive=False) dbutils.addTask("birthday", "Buy food", {"grocery": None}) dbutils.addTask("birthday", "Buy drinks", {"grocery": None}) dbutils.addTask("birthday", "Invite Bob", {"phone": None}) dbutils.addTask("birthday", "Invite Wendy", {"phone": None}) dbutils.addTask("birthday", "Bake a yummy cake") dbutils.addTask("birthday", "Decorate living-room") task = dbutils.addTask("home", "Fix leak in the roof") task.dueDate = ydateutils.parseHumaneDateTime("-2d") dbutils.addTask("home", "Buy AAA batteries for kid toys", {"grocery": None}) task = dbutils.addTask("home", "Bring the car to the garage") task.dueDate = ydateutils.parseHumaneDateTime("-1d") task.status = "done" task = dbutils.addTask("work", "Finish weekly report") task.dueDate = ydateutils.parseHumaneDateTime("+4d") task.description = """Include results from Acme department: http://acme.intranet/results. Don't forget to CC [email protected]. """ session.commit() return 0
def testPastTime(self): # Fake now to a fixed date and time now = datetime(2009, 1, 3, 11, 0) testData = [ ("1:00pm", now.replace(hour=13, minute=0)), ("10:00am", now.replace(hour=10, minute=0) + timedelta(days=1)), ] for text, expected in testData: output = ydateutils.parseHumaneDateTime(text, hint=None, today=now) self.assertEqual(expected, output)
def testParseHumaneDateTime(self): for date in ("+5M", "+1m", "+2H", "+3h", "+9D", "+14d", "+432W", "+0w", "01/01/2009", "10/10/2008 12", "7/7/2007 10:15", "1/2/2003 1:2:3"): ydateutils.parseHumaneDateTime(date) for invalidDate in ("2008", "01/2009", "01//02/01", "02/20/2009", "", "+3e", "lkjljlkjlkj", "200/200/2009"): self.assertRaises(YokadiException, ydateutils.parseHumaneDateTime, invalidDate) # Fake today to a fixed date. This is a saturday (weekday=5). today = datetime(2009, 1, 3) endOfDay = dict(hour=23, minute=59, second=59) startOfDay = dict(hour=0, minute=0, second=0) testData = [ ("06/02/2009", None, datetime(2009, 2, 6)), ("06/02/09", None, datetime(2009, 2, 6)), ("06/02/2009 12:30", None, datetime(2009, 2, 6, 12, 30)), ("06/02/2009", ydateutils.TIME_HINT_BEGIN, datetime(2009, 2, 6, 0, 0, 0)), ("06/02/2009", ydateutils.TIME_HINT_END, datetime(2009, 2, 6, 23, 59, 59)), ("tomorrow 18:00", None, today + timedelta(days=1, hours=18)), ("tomorrow", ydateutils.TIME_HINT_END, today.replace(day=4, hour=23, minute=59, second=59)), ("sunday", None, datetime(2009, 1, 4)), ("tu 11:45", None, datetime(2009, 1, 6, 11, 45)), ("today", ydateutils.TIME_HINT_END, today.replace(**endOfDay)), ("today", ydateutils.TIME_HINT_BEGIN, today.replace(**startOfDay)), ("now", None, today), ("today 5 PM", None, today.replace(hour=17)), ("6:32pm", None, today.replace(hour=18, minute=32)), ("06/02 2:40 am", None, datetime(2009, 2, 6, 2, 40)), ("+2w", None, datetime(2009, 1, 17)), ("+1d", None, datetime(2009, 1, 4)), ("-1d", None, datetime(2009, 1, 2)), ("+3h", None, datetime(2009, 1, 3, 3, 0)), ("-1M", None, datetime(2009, 1, 2, 23, 59)), ] for text, hint, expected in testData: output = ydateutils.parseHumaneDateTime(text, hint=hint, today=today) self.assertEqual(expected, output)
def do_t_due(self, line): """Set task's due date t_due <id> <date> Date can be specified as a relative offset: - +5M: in 5 minutes - +3H: in 3 hours - +1D: in 1 day - +6W: in 6 weeks As a day in the week: - tomorrow: tomorrow, same hour - tuesday 12:10: next tuesday, at 12:10 - fr 15:30: next friday, at 15:30 Or as an absolute date or time: - 10:38: at 10:38 today - 25/09/2010 12:10: on the 25th of September, 2010, at 12:10 - 23/02/2010: on the 23th of February, 2010 - 01/04: on the 1st of April - 12: on the 12th of current month To reset a due date, use "none".""" line = parseutils.simplifySpaces(line) if len(line.split()) < 2: raise YokadiException( "Give a task id and time, date or date & time") taskId, line = line.strip().split(" ", 1) task = self.getTaskFromId(taskId) if line.lower() == "none": task.dueDate = None print("Due date for task '%s' reset" % task.title) else: task.dueDate = ydateutils.parseHumaneDateTime(line) print("Due date for task '%s' set to %s" % (task.title, task.dueDate.ctime())) self.session.merge(task) self.session.commit()
def fromHumaneString(line): """Take a string following t_recurs format, returns a RecurrenceRule instance or None """ freq = byminute = byhour = byweekday = bymonthday = bymonth = None tokens = line.split() tokens[0] = tokens[0].lower() if tokens[0] == "none": return RecurrenceRule() if tokens[0] == "daily": if len(tokens) != 2: raise YokadiException("You should give time for daily task") freq = rrule.DAILY byhour, byminute = getHourAndMinute(tokens[1]) elif tokens[0] == "weekly": freq = rrule.WEEKLY if len(tokens) != 3: raise YokadiException( "You should give day and time for weekly task") byweekday = getWeekDayNumberFromDay(tokens[1].lower()) byhour, byminute = getHourAndMinute(tokens[2]) elif tokens[0] in ("monthly", "quarterly"): if tokens[0] == "monthly": freq = rrule.MONTHLY else: # quarterly freq = rrule.YEARLY bymonth = (1, 4, 7, 10) if len(tokens) < 3: raise YokadiException( "You should give day and time for %s task" % (tokens[0], )) try: bymonthday = int(tokens[1]) byhour, byminute = getHourAndMinute(tokens[2]) except ValueError: POSITION = { "first": 1, "second": 2, "third": 3, "fourth": 4, "last": -1 } if tokens[1].lower() in POSITION and len(tokens) == 4: byweekday = RecurrenceRule.createWeekDay( weekday=getWeekDayNumberFromDay(tokens[2].lower()), pos=POSITION[tokens[1]]) byhour, byminute = getHourAndMinute(tokens[3]) bymonthday = None # Default to current day number - need to be blanked else: raise YokadiException( "Unable to understand date. See help t_recurs for details" ) elif tokens[0] == "yearly": freq = rrule.YEARLY rDate = parseHumaneDateTime(" ".join(tokens[1:])) bymonth = rDate.month bymonthday = rDate.day byhour = rDate.hour byminute = rDate.minute else: raise YokadiException( "Unknown frequency. Available: daily, weekly, monthly and yearly" ) return RecurrenceRule( freq, bymonth=bymonth, bymonthday=bymonthday, byweekday=byweekday, byhour=byhour, byminute=byminute, )
def do_t_recurs(self, line): """Make a task recurs t_recurs <id> yearly <dd/mm> <HH:MM> t_recurs <id> monthly <dd> <HH:MM> t_recurs <id> monthly <first/second/third/last> <mo, tu, we, th, fr, sa, su> <hh:mm> t_recurs <id> quarterly <dd> <HH:MM> t_recurs <id> quarterly <first/second/third/last> <mo, tu, we, th, fr, sa, su> <hh:mm> t_recurs <id> weekly <mo, tu, we, th, fr, sa, su> <hh:mm> t_recurs <id> daily <HH:MM> t_recurs <id> none (remove recurrence)""" tokens = parseutils.simplifySpaces(line).split() if len(tokens) < 2: raise YokadiException("You should give at least two arguments: <task id> <recurrence>") task = self.getTaskFromId(tokens[0]) # Define recurrence: freq = byminute = byhour = byweekday = bymonthday = bymonth = None tokens[1] = tokens[1].lower() if tokens[1] == "none": if task.recurrence: self.session.delete(task.recurrence) task.recurrence = None return elif tokens[1] == "daily": if len(tokens) != 3: raise YokadiException("You should give time for daily task") freq = rrule.DAILY byhour, byminute = ydateutils.getHourAndMinute(tokens[2]) elif tokens[1] == "weekly": freq = rrule.WEEKLY if len(tokens) != 4: raise YokadiException("You should give day and time for weekly task") byweekday = ydateutils.getWeekDayNumberFromDay(tokens[2].lower()) byhour, byminute = ydateutils.getHourAndMinute(tokens[3]) elif tokens[1] in ("monthly", "quarterly"): if tokens[1] == "monthly": freq = rrule.MONTHLY else: # quarterly freq = rrule.YEARLY bymonth = [1, 4, 7, 10] if len(tokens) < 4: raise YokadiException("You should give day and time for %s task" % (tokens[1],)) try: bymonthday = int(tokens[2]) byhour, byminute = ydateutils.getHourAndMinute(tokens[3]) except ValueError: POSITION = {"first": 1, "second": 2, "third": 3, "fourth": 4, "last":-1} if tokens[2].lower() in list(POSITION.keys()) and len(tokens) == 5: byweekday = rrule.weekday(ydateutils.getWeekDayNumberFromDay(tokens[3].lower()), POSITION[tokens[2]]) byhour, byminute = ydateutils.getHourAndMinute(tokens[4]) bymonthday = None # Default to current day number - need to be blanked else: raise YokadiException("Unable to understand date. See help t_recurs for details") elif tokens[1] == "yearly": freq = rrule.YEARLY rDate = ydateutils.parseHumaneDateTime(" ".join(tokens[2:])) bymonth = rDate.month bymonthday = rDate.day byhour = rDate.hour byminute = rDate.minute else: raise YokadiException("Unknown frequency. Available: daily, weekly, monthly and yearly") if task.recurrence is None: task.recurrence = Recurrence() rr = rrule.rrule(freq, byhour=byhour, byminute=byminute, byweekday=byweekday, bymonthday=bymonthday, bymonth=bymonth) task.recurrence.setRrule(rr) task.dueDate = task.recurrence.getNext() self.session.merge(task) self.session.commit()
def fromHumaneString(line): """Take a string following t_recurs format, returns a RecurrenceRule instance or None """ freq = byminute = byhour = byweekday = bymonthday = bymonth = None tokens = line.split() tokens[0] = tokens[0].lower() if tokens[0] == "none": return RecurrenceRule() if tokens[0] == "daily": if len(tokens) != 2: raise YokadiException("You should give time for daily task") freq = rrule.DAILY byhour, byminute = getHourAndMinute(tokens[1]) elif tokens[0] == "weekly": freq = rrule.WEEKLY if len(tokens) != 3: raise YokadiException("You should give day and time for weekly task") byweekday = getWeekDayNumberFromDay(tokens[1].lower()) byhour, byminute = getHourAndMinute(tokens[2]) elif tokens[0] in ("monthly", "quarterly"): if tokens[0] == "monthly": freq = rrule.MONTHLY else: # quarterly freq = rrule.YEARLY bymonth = (1, 4, 7, 10) if len(tokens) < 3: raise YokadiException("You should give day and time for %s task" % (tokens[0],)) try: bymonthday = int(tokens[1]) byhour, byminute = getHourAndMinute(tokens[2]) except ValueError: POSITION = {"first": 1, "second": 2, "third": 3, "fourth": 4, "last":-1} if tokens[1].lower() in POSITION and len(tokens) == 4: byweekday = RecurrenceRule.createWeekDay( weekday=getWeekDayNumberFromDay(tokens[2].lower()), pos=POSITION[tokens[1]]) byhour, byminute = getHourAndMinute(tokens[3]) bymonthday = None # Default to current day number - need to be blanked else: raise YokadiException("Unable to understand date. See help t_recurs for details") elif tokens[0] == "yearly": freq = rrule.YEARLY rDate = parseHumaneDateTime(" ".join(tokens[1:])) bymonth = rDate.month bymonthday = rDate.day byhour = rDate.hour byminute = rDate.minute else: raise YokadiException("Unknown frequency. Available: daily, weekly, monthly and yearly") return RecurrenceRule(freq, bymonth=bymonth, bymonthday=bymonthday, byweekday=byweekday, byhour=byhour, byminute=byminute, )
def do_t_recurs(self, line): """Make a task recurs t_recurs <id> yearly <dd/mm> <HH:MM> t_recurs <id> monthly <dd> <HH:MM> t_recurs <id> monthly <first/second/third/last> <mo, tu, we, th, fr, sa, su> <hh:mm> t_recurs <id> quarterly <dd> <HH:MM> t_recurs <id> quarterly <first/second/third/last> <mo, tu, we, th, fr, sa, su> <hh:mm> t_recurs <id> weekly <mo, tu, we, th, fr, sa, su> <hh:mm> t_recurs <id> daily <HH:MM> t_recurs <id> none (remove recurrence)""" tokens = parseutils.simplifySpaces(line).split() if len(tokens) < 2: raise YokadiException( "You should give at least two arguments: <task id> <recurrence>" ) task = self.getTaskFromId(tokens[0]) # Define recurrence: freq = byminute = byhour = byweekday = bymonthday = bymonth = None tokens[1] = tokens[1].lower() if tokens[1] == "none": if task.recurrence: task.recurrence.destroySelf() task.recurrence = None return elif tokens[1] == "daily": if len(tokens) != 3: raise YokadiException("You should give time for daily task") freq = rrule.DAILY byhour, byminute = ydateutils.getHourAndMinute(tokens[2]) elif tokens[1] == "weekly": freq = rrule.WEEKLY if len(tokens) != 4: raise YokadiException( "You should give day and time for weekly task") byweekday = ydateutils.getWeekDayNumberFromDay(tokens[2].lower()) byhour, byminute = ydateutils.getHourAndMinute(tokens[3]) elif tokens[1] in ("monthly", "quarterly"): if tokens[1] == "monthly": freq = rrule.MONTHLY else: # quarterly freq = rrule.YEARLY bymonth = [1, 4, 7, 10] if len(tokens) < 4: raise YokadiException( "You should give day and time for %s task" % (tokens[1], )) try: bymonthday = int(tokens[2]) byhour, byminute = ydateutils.getHourAndMinute(tokens[3]) except ValueError: POSITION = { "first": 1, "second": 2, "third": 3, "fourth": 4, "last": -1 } if tokens[2].lower() in POSITION.keys() and len(tokens) == 5: byweekday = rrule.weekday( ydateutils.getWeekDayNumberFromDay(tokens[3].lower()), POSITION[tokens[2]]) byhour, byminute = ydateutils.getHourAndMinute(tokens[4]) bymonthday = None # Default to current day number - need to be blanked else: raise YokadiException( "Unable to understand date. See help t_recurs for details" ) elif tokens[1] == "yearly": freq = rrule.YEARLY rDate = ydateutils.parseHumaneDateTime(" ".join(tokens[2:])) bymonth = rDate.month bymonthday = rDate.day byhour = rDate.hour byminute = rDate.minute else: raise YokadiException( "Unknown frequency. Available: daily, weekly, monthly and yearly" ) if task.recurrence is None: task.recurrence = Recurrence() rr = rrule.rrule(freq, byhour=byhour, byminute=byminute, byweekday=byweekday, bymonthday=bymonthday, bymonth=bymonth) task.recurrence.setRrule(rr) task.dueDate = task.recurrence.getNext()