feat(scraper): import club events from TartanConnect #93

Merged
jalenluorion merged 4 commits from feat/tartanconnect-import into main 2026-10-03 22:47:01 +00:00
Member

Imports club events from TartanConnect, so Explore has non-class events. Closes #70.

  • python -m scraper.scripts.export_tartanconnect [--dry-run]: one CLUB org per host club, a TartanConnect category in each, one event per listing (RSVP link in source_url, tags in the description). Also a tartanconnect choice in scrape.yml.
  • The monitor parses the public feed with json.loads and pages through all of it (it fetched 300 by string splitting before), with retries on the feed's 502/503s.
  • fix(api): batch occurrence regeneration skipped events without a recurrence rule, so one-time events never reached the calendar or saved events. They now get exactly one ONETIME occurrence. SOC events all have rules, so they are unaffected.
  • Events this source created that are still in the future but no longer in the feed are deleted (cancelled or changed). Past events, hand-made events and other sources are never touched, and the deletion is skipped if more than a fifth of the source's future events would go, so a short feed cannot wipe saves.
  • regenerate_occurrences moved out of export_soc.py so both exports share it.

Tested on dev: 785 events from 60 clubs, one occurrence each, four reruns with identical ids and no duplicates. 270 API tests pass; the fixture is a trimmed copy of the real feed.

Not in this PR: a Register button (no component renders source_url yet; see #74).

Imports club events from TartanConnect, so Explore has non-class events. Closes #70. - `python -m scraper.scripts.export_tartanconnect [--dry-run]`: one CLUB org per host club, a TartanConnect category in each, one event per listing (RSVP link in source_url, tags in the description). Also a `tartanconnect` choice in scrape.yml. - The monitor parses the public feed with json.loads and pages through all of it (it fetched 300 by string splitting before), with retries on the feed's 502/503s. - fix(api): batch occurrence regeneration skipped events without a recurrence rule, so one-time events never reached the calendar or saved events. They now get exactly one ONETIME occurrence. SOC events all have rules, so they are unaffected. - Events this source created that are still in the future but no longer in the feed are deleted (cancelled or changed). Past events, hand-made events and other sources are never touched, and the deletion is skipped if more than a fifth of the source's future events would go, so a short feed cannot wipe saves. - `regenerate_occurrences` moved out of export_soc.py so both exports share it. Tested on dev: 785 events from 60 clubs, one occurrence each, four reruns with identical ids and no duplicates. 270 API tests pass; the fixture is a trimmed copy of the real feed. Not in this PR: a Register button (no component renders source_url yet; see #74).
Move regenerate_occurrences from export_soc.py to
scraper/persistence/api_occurrences.py so the TartanConnect export can
call it too. No behavior change.
regenerate_occurrences_by_events skipped every event without a recurrence
rule, so a scraper importing one-time events got no event_occurrences and
the events never reached the calendar or saved events. Replace such an
event's occurrences with one ONETIME row built from the event instead.
Rewrite the TartanConnect monitor on json.loads: skip separator rows,
page through range until the feed runs out, and keep the event ID, RSVP
URL, host club, categories and times (America/New_York; the few events
listed in another zone are converted).

Add scraper/scripts/export_tartanconnect.py, modeled on export_soc.py:
one CLUB org and one TartanConnect category per host club, one-time CLUB
events upserted on the existing identity, then occurrence regeneration.
Future events from earlier runs that the feed no longer lists (cancelled,
removed or changed) are deleted; past events and other sources' events
are left alone.

Refs #70
fix(scraper): skip stale-event deletion when the feed looks short
All checks were successful
kennel/build build succeeded
CI / check-1 (pull_request) Successful in 2m23s
CI / build (pull_request) Successful in 2m18s
CI / check (pull_request) Successful in 0s
4c50a23e60
Deleting cascades to users' saves, so a feed that loads but is missing
events must not wipe them. Skip the deletion when more than a fifth of the
source's future events would go, and never delete rows without a run id.
jalenluorion deleted branch feat/tartanconnect-import 2026-10-03 22:47:01 +00:00
Sign in to join this conversation.
No reviewers
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
ScottyLabs/cal!93
No description provided.