Diary feed: the one a calendar can subscribe to has no deadlines; the one with deadlines needs a browser session #451

Closed
opened 2026-10-01 10:46:48 +00:00 by tiagoagueda · 0 comments
Owner

Found on 2026-09-29 in a read-only review of postulo at 95348908d, comparing the two whole-diary iCalendar feeds and the wiki page that describes them.

Checked again on 2026-10-01 against main at 0a5cad587: still present. The code is now at applications/views.py:1038-1079 (InterviewCalendarView.get and dated_days); the other locations have not moved.

#238 put deadlines, closing dates and answers due into the diary feed, but only into the web view, which needs a signed-in browser. The API feed, the only one a calendar application can hold credentials for, still carries interviews alone. Somebody who subscribes their calendar gets interviews and never the dates #238 was about, and the wiki points them at a Subscribe button that does not exist.

  • Where:
    • api/routers/interviews.py:67-73, calendar_feed: ical.calendar(_queryset(request).upcoming(), url_for=...) with no days=.
    • applications/views.py:998-1039, InterviewCalendarView.get and dated_days: the only caller that builds the whole-day entries. The view inherits OwnedObjectMixin, which is a LoginRequiredMixin (core/mixins.py:7), and answers with Content-Disposition: attachment.
    • templates/applications/interview_list.html:28-30: the page offers a Calendar file download link, not a subscription.
    • postulo.wiki/Tracking-applications.md:412-415: "interviews.ics — Subscribe on the interviews page — holds the deadlines and closing dates of the next six months".
  • What happens: a person subscribes a phone or desktop calendar to /api/v1/interviews/calendar.ics with a read token. The subscription refreshes, and it only ever holds interviews: no deadline, closing date or answer-by day appears. If they subscribe to the interviews page's address instead, the calendar application is sent to the sign-in page and receives HTML. The downloaded file does hold the dates, but it is a snapshot that never refreshes. The docstring of dated_days says it exists "so the feed and the calendar page can never disagree"; the API feed disagrees with both.
  • Why it matters: the dates that close are exactly what #238 set out to put in somebody's calendar, and the one feed that can keep a calendar up to date leaves them out. Tests cover the web view only (tests/test_deadlines.py:228-270); the API feed test (tests/test_interviews.py:696-697) checks only that a VEVENT is present.
  • Fix: move dated_days out of the view into a function that takes the user and a function that makes an address absolute (in agenda or ical, beside FEED_DAYS), and call it from both InterviewCalendarView.get and calendar_feed. Then correct the wiki: the interviews page offers a download, and the address to subscribe to is /api/v1/interviews/calendar.ics with a read-scoped token (The capture API already lists it).

Related to #238 (closed), whose "include both in the ICS feed" reached only the feed a calendar application cannot subscribe to.

Done when

  • A test in tests/test_deadlines.py fetches /api/v1/interviews/calendar.ics with a read token for a user whose application has a deadline five days ahead, and finds DTSTART;VALUE=DATE: for that day; it fails today.
  • The wiki paragraph names an address a calendar application can actually subscribe to.
Found on 2026-09-29 in a read-only review of postulo at 95348908d, comparing the two whole-diary iCalendar feeds and the wiki page that describes them. Checked again on 2026-10-01 against `main` at `0a5cad587`: still present. The code is now at `applications/views.py:1038-1079` (`InterviewCalendarView.get` and `dated_days`); the other locations have not moved. #238 put deadlines, closing dates and answers due into the diary feed, but only into the web view, which needs a signed-in browser. The API feed, the only one a calendar application can hold credentials for, still carries interviews alone. Somebody who subscribes their calendar gets interviews and never the dates #238 was about, and the wiki points them at a *Subscribe* button that does not exist. - **Where:** - `api/routers/interviews.py:67-73`, `calendar_feed`: `ical.calendar(_queryset(request).upcoming(), url_for=...)` with no `days=`. - `applications/views.py:998-1039`, `InterviewCalendarView.get` and `dated_days`: the only caller that builds the whole-day entries. The view inherits `OwnedObjectMixin`, which is a `LoginRequiredMixin` (`core/mixins.py:7`), and answers with `Content-Disposition: attachment`. - `templates/applications/interview_list.html:28-30`: the page offers a *Calendar file* download link, not a subscription. - `postulo.wiki/Tracking-applications.md:412-415`: "`interviews.ics` — *Subscribe* on the interviews page — holds the deadlines and closing dates of the next six months". - **What happens:** a person subscribes a phone or desktop calendar to `/api/v1/interviews/calendar.ics` with a read token. The subscription refreshes, and it only ever holds interviews: no deadline, closing date or answer-by day appears. If they subscribe to the interviews page's address instead, the calendar application is sent to the sign-in page and receives HTML. The downloaded file does hold the dates, but it is a snapshot that never refreshes. The docstring of `dated_days` says it exists "so the feed and the calendar page can never disagree"; the API feed disagrees with both. - **Why it matters:** the dates that close are exactly what #238 set out to put in somebody's calendar, and the one feed that can keep a calendar up to date leaves them out. Tests cover the web view only (`tests/test_deadlines.py:228-270`); the API feed test (`tests/test_interviews.py:696-697`) checks only that a `VEVENT` is present. - **Fix:** move `dated_days` out of the view into a function that takes the user and a function that makes an address absolute (in `agenda` or `ical`, beside `FEED_DAYS`), and call it from both `InterviewCalendarView.get` and `calendar_feed`. Then correct the wiki: the interviews page offers a download, and the address to subscribe to is `/api/v1/interviews/calendar.ics` with a read-scoped token (*The capture API* already lists it). Related to #238 (closed), whose "include both in the ICS feed" reached only the feed a calendar application cannot subscribe to. ## Done when - A test in `tests/test_deadlines.py` fetches `/api/v1/interviews/calendar.ics` with a read token for a user whose application has a deadline five days ahead, and finds `DTSTART;VALUE=DATE:` for that day; it fails today. - The wiki paragraph names an address a calendar application can actually subscribe to.
tiagoagueda added this to the 0.5.0 milestone 2026-10-01 10:46:48 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Postulo/postulo#451
No description provided.