Chandler logo

Reminders

A Reminder defines an instant in time when something should happen.

>>> from chandler.reminder import *
>>> rem = Reminder()
>>> rem.type
'triage'

What exactly happens when a reminder fires will depend on the reminder’s type. The simplest example is to change an item’s triage status.

trigger for a Reminder is determined either relative to an event, by setting a delta or with a fixed_trigger. By default, both are None.

>>> rem.delta is None
True
>>> rem.fixed_trigger is None
True
>>> rem.trigger is None
True

To associate a Reminder with an item, it should be added to the item’s ReminderList AddOn. Note that ReminderList isn’t an Extension, so there’s no need to call add().

>>> from chandler import time_services
>>> from chandler.core import Item
>>> from datetime import datetime, timedelta
>>> april_fools = datetime(2006, 4, 1, 12, tzinfo=time_services.TimeZone.eastern)
>>> time_services.setNow(april_fools)
>>> item = Item()
>>> rem.item = item
>>> ReminderList(item).reminders.append(rem)

Setting delta for an item that isn’t an event leaves trigger as None:

>>> rem.delta = timedelta(hours=1)
>>> rem.trigger is None
True

Similarly, if start is None, trigger will be, too.

>>> from chandler.event import Event
>>> event = Event(item).add()
>>> event.start is None
True
>>> rem.trigger is None
True

But if start is set, trigger will be, too.

>>> event.tzinfo = time_services.TimeZone.eastern
>>> event.base_start = april_fools + timedelta(hours=3)
>>> rem.trigger
datetime.datetime(2006, 4, 1, 16, 0, tzinfo=<ICUtzinfo: US/Eastern>)

If a Reminder has both a delta and a fixed_start, the fixed_start takes precedence.

>>> rem.fixed_trigger = april_fools + timedelta(minutes=5)
>>> rem.trigger
datetime.datetime(2006, 4, 1, 12, 5, tzinfo=<ICUtzinfo: US/Eastern>)

Shortcut Methods

Rather than creating a Reminder and setting its item, you can use ReminderList.add_reminder().

>>> rem2 = ReminderList(item).add_reminder()
>>> rem2.item == item
True
>>> ReminderList(item).reminders == [rem, rem2]
True

You can pass in cell values for the new reminder, too:

>>> rem3 = ReminderList(item).add_reminder(delta=timedelta(days=2))
>>> rem3.delta
datetime.timedelta(2)

You can also remove all reminders:

>>> len(ReminderList(item).reminders)
3
>>> ReminderList(item).remove_all_reminders()
>>> len(ReminderList(item).reminders)
0

Reminders and Triage Status

When a reminder is added to an item, its triage status and triage position depend on the reminder.

>>> from chandler.triage import *
>>> item = Item()
>>> triage = Triage(item)
>>> triage.calculated == NOW
True
>>> triage_position = TriagePosition(item)
>>> triage_position.position == item.created
True
>>> rem = ReminderList(item).add_reminder(fixed_trigger=april_fools + timedelta(days=2))
>>> triage.calculated == LATER
True
>>> triage_position.position == time_services.timestamp(rem.trigger)
True
>>> time_services.setNow(april_fools + timedelta(days=3))
>>> triage.calculated == NOW
True

An Event with an associated Reminder may have its triage position depend on either.

>>> rem.fixed_trigger = None
>>> rem.delta = timedelta(hours=-1)
>>> event = Event(item).add()
>>> event.base_start = april_fools
>>> triage_position.position == time_services.timestamp(event.start)
True

If both the event and the reminder are in the past, position will be the latter of the two.

>>> rem.delta = timedelta(hours=1)
>>> triage_position.position == time_services.timestamp(event.start)
False
>>> triage_position.position == time_services.timestamp(rem.trigger)
True

If one is in the future, the other in the past, position will depend on calculated triage.

>>> event.base_start = april_fools + timedelta(days=3)
>>> triage.calculated
100.0
>>> triage_position.position == time_services.timestamp(event.start)
True
>>> triage.manual = LATER
>>> triage_position.position == time_services.timestamp(rem.trigger)
True

XXX Reminder should be a scheduled, test/document reminder fire

XXX should all reminders get the triage behavior?

XXX snooze_until, cleared

XXX Hook for adding different types of reminders?

XXX reversible in time explanation