LifeHacker & Elyssa
Hey LifeHacker, I’ve been tinkering with a voice‑activated calendar that auto‑organizes meetings, snacks, even meditation breaks—think of it as a personal life‑hacker on steroids. Want to dive into the code and see if we can make it smarter than your current productivity stack?
Sounds like a dream. Let’s pull up the repo and start pruning any redundant triggers. I’ll map the existing workflow first, then we can add smarter context‑sensing so it learns when you’re in a meeting versus just talking to a colleague. Show me the code, and we’ll make it razor‑sharp.
Here’s a quick snapshot of the trigger section in `triggers.py` – it’s still a bit of a spaghetti garden right now.
```
# triggers.py
from events import *
def register_triggers():
triggers = []
# Legacy triggers, many of them overlapping
triggers.append(When('meeting_start').do(schedule_meeting))
triggers.append(When('meeting_end').do(clean_up_meeting))
triggers.append(When('email_sent').do(archive_email))
triggers.append(When('message_received').do(process_message))
triggers.append(When('task_created').do(create_task))
# Repetitive and rarely used
triggers.append(When('calendar_view').do(update_ui))
triggers.append(When('calendar_view').do(log_view))
triggers.append(When('calendar_view').do(cache_view))
return triggers
```
We can prune the `calendar_view` ones, merge `schedule_meeting` and `clean_up_meeting` into a single context‑aware handler, and replace the simple `When` checks with a context sensor that tags events as “in‑meeting”, “off‑screen”, etc. Let’s sketch a lightweight `ContextSensor` that tags events based on current calendar status, then hook it into the loop. You want to see the sensor code next?
Sure thing, here’s a minimal sensor to tag events before they hit the triggers.
```
# context_sensor.py
class ContextSensor:
def __init__(self, calendar):
self.calendar = calendar # simple interface with is_meeting() etc.
def tag(self, event):
if self.calendar.is_meeting():
event.context = 'in_meeting'
elif self.calendar.is_offscreen():
event.context = 'off_screen'
else:
event.context = 'idle'
return event
```
Then in your main loop:
```
sensor = ContextSensor(calendar)
for event in event_stream:
event = sensor.tag(event)
handle(event) # your unified handler
```
Now you can drop the old `When` checks and just look at `event.context`. Gives you a clean, extensible hook for any future tags. Let me know if you want to add more nuanced states or a fallback for unknown events.
Nice, that sensor keeps the loop lean. One quick tweak: make `tag` return a copy instead of mutating the original event, so you avoid accidental side‑effects elsewhere. Also, add an `unknown` context for events that don’t match any rule—helps catch bugs early. Want a small test harness to validate the tags against a fake calendar?
Here’s a quick tweak and a tiny harness to double‑check it works.
```
# context_sensor.py
import copy
class ContextSensor:
def __init__(self, calendar):
self.calendar = calendar
def tag(self, event):
ev = copy.deepcopy(event)
if self.calendar.is_meeting():
ev.context = 'in_meeting'
elif self.calendar.is_offscreen():
ev.context = 'off_screen'
else:
ev.context = 'unknown'
return ev
```
And a basic test harness:
```
# test_context_sensor.py
class FakeCalendar:
def __init__(self, state):
self.state = state
def is_meeting(self): return self.state == 'meeting'
def is_offscreen(self): return self.state == 'off_screen'
class Event:
def __init__(self, name): self.name = name
def run_tests():
for state in ['meeting', 'off_screen', 'idle']:
cal = FakeCalendar(state)
sensor = ContextSensor(cal)
ev = Event('dummy')
tagged = sensor.tag(ev)
print(f"state={state} → context={tagged.context}")
if __name__ == "__main__":
run_tests()
```
Run it, and you should see `in_meeting`, `off_screen`, and `unknown` printed accordingly. This keeps your original event intact and surfaces anything that slips through.
Looks solid! Just one tiny tweak—give the “idle” state its own label instead of lumping it under “unknown.” That way you can later add a specific handler for true idleness. Other than that, the harness should print the three contexts as expected. Ready to drop it into the main loop now?