From 4382ed35ee54098d203227d0ca885c542560dbaa Mon Sep 17 00:00:00 2001 From: Lucas Winther Date: Sat, 12 Sep 2026 09:10:02 +0200 Subject: [PATCH] feat: add Punishing: Gray Raven with karendar.com source Add karendar.com as the event source for Punishing: Gray Raven (PGR). Karendar publishes a dedicated Global event calendar with exact UTC timestamps in clean server-rendered HTML. - Register 'pgr' in GameId and GAMES registry (#CC292B, Kuro Games). - Add parseWeekdayDayMonthYearUtc in src/ingest/dates.ts with unit tests. - Implement karendarParser in src/ingest/parsers/karendar.ts reading 'week', 'ongoing', and 'upcoming' sections, mapping indefinite/permanent ends to endsAt: null, and categorizing tags to EventType. - Register pgr-karendar-events in src/ingest/adapters/index.ts. - Add pinned fixture, expected output, and comprehensive test suites. - Update documentation in AGENTS.md, README.md, docs/INGESTION.md, and docs/SOURCES.md. --- AGENTS.md | 9 +- README.md | 2 +- docs/INGESTION.md | 1 + docs/SOURCES.md | 50 +- .../karendar-events-2026-09-12.expected.json | 1199 +++++++++++++++++ fixtures/pgr/karendar-events-2026-09-12.html | 1 + src/ingest/adapters/index.ts | 10 + src/ingest/dates.ts | 27 + src/ingest/parsers/index.ts | 3 + src/ingest/parsers/karendar.ts | 184 +++ src/shared/games.ts | 4 + src/shared/schema.ts | 1 + test/adapters/game8.test.ts | 2 + test/adapters/karendar.test.ts | 132 ++ test/dates.test.ts | 42 + 15 files changed, 1645 insertions(+), 22 deletions(-) create mode 100644 fixtures/pgr/karendar-events-2026-09-12.expected.json create mode 100644 fixtures/pgr/karendar-events-2026-09-12.html create mode 100644 src/ingest/parsers/karendar.ts create mode 100644 test/adapters/karendar.test.ts diff --git a/AGENTS.md b/AGENTS.md index 24a7ee8..3859c55 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -37,8 +37,8 @@ A web app that aggregates live and upcoming events across popular gacha games, p calendar, sorts them by end date or by what the reader is partway through, tracks day-by-day progress on events that repeat daily, and lets a user mark events completed. -**Status: working app, refreshing itself on a schedule.** Schema, nine parsers, twenty-one sources across -nineteen games, the full interface, offline support, a static server, a Docker image and CI all exist and +**Status: working app, refreshing itself on a schedule.** Schema, ten parsers, twenty-two sources across +twenty games, the full interface, offline support, a static server, a Docker image and CI all exist and are tested. The refresh runner (`bun run refresh`) fetches, caches raw snapshots and rebuilds the feed; `.github/workflows/refresh.yml` runs it twice a day and commits only when a page actually changed. The SQLite layer and the review queue are still specified in `docs/` but not built, so the @@ -133,7 +133,7 @@ src/shared/ schema.ts (the contract), time.ts, daily.ts, effort.ts, games. src/ingest/ html.ts, dates.ts (sixteen formats), merge.ts, sanitize.ts, robots.ts, snapshots.ts health.ts — which of the three empties a source's zero was; pure parsers/ game8.ts, wikigg.ts, akwiki.ts, fandom.ts, bawiki.ts, holodori.ts, iopwiki.ts, - stellasora.ts — keyed by SITE, not game + stellasora.ts, arustats.ts, karendar.ts — keyed by SITE, not game adapters/ index.ts — SOURCES registry binding url+game+parser, and the sanitize seam src/client/ React app, service worker, manifest state/ progress, daily log, ignores, prefs, sort — all localStorage @@ -145,7 +145,7 @@ src/client/ React app, service worker, manifest theme.ts — dark or light, and what a game hue reads as on each scripts/ build-feed.ts, build-static.ts, parse-fixture.ts (offline), refresh-sources.ts (fetches) serve.ts static server + /api/health -test/ 1,071 tests +test/ 1,099 tests fixtures// raw HTML + .expected.json per source — pinned, kept forever snapshots/ current page per source, rewritten by refresh — see its README ``` @@ -386,6 +386,7 @@ re-litigated each pass: | `infinitynikki.miraheze.org` | **Declined.** Exists and serves `robots.txt`, but the wiki is abandoned — front page last edited 11 February 2025 and `/wiki/Events` returns a permission error. Checked as a replacement for the stale Infinity Nikki Game8 page | | `prydwen.gg/infinity-nikki` | **Declined.** 404 — prydwen does not cover Infinity Nikki | | `grayravens.com` (Punishing: Gray Raven) | **Declined.** Conduct is fine; the data is not. The whole 626 KB `/wiki/Events` page contains exactly one date range, written as prose, one event per six-week patch | +| `karendar.com` (Punishing: Gray Raven) | **Built** (2026-09-12). Fan-made PGR event calendar for Global. Full SSR HTML with 57 active events across week/ongoing/upcoming. Exact UTC timestamps, `robots.txt` allows `/`, no auth or API required | | `guardian-tales.fandom.com` | **Declined.** Parses fine and contains no 2026 date at all — newest dated entry is 2025. The `bluearchive.fandom.com` failure again: parses cleanly to nothing live | | `blhx.fandom.com`, `azurlane-archive.fandom.com` | **Declined.** The two Fandom alternatives to the declined koumakan wiki are dead archives — `Event_Calendar` stops in **2021**, and the archive wiki's headings have nothing under them. Azur Lane still has no source | | Aether Gazer | **Do not build.** The developer confirmed no further content updates after 23 July 2026, with store listings removed 17 October 2026. The wiki dates nothing anyway — `Event_Guide_List` is an image gallery. A lane that will be empty by winter | diff --git a/README.md b/README.md index 8af371e..eafe240 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ review queue are specified but not built. | Piece | State | |---|---| | Event schema, date parsing, Game8 parser | Built, tested | -| Twenty-one sources across nineteen games | Built, tested | +| Twenty-two sources across twenty games | Built, tested | | Your own games and events, one-off or repeating | Built, tested | | Cross-source merge and conflict detection | Built, tested | | Input sanitization at the ingest boundary | Built, tested | diff --git a/docs/INGESTION.md b/docs/INGESTION.md index 18d9a16..7178ce7 100644 --- a/docs/INGESTION.md +++ b/docs/INGESTION.md @@ -57,6 +57,7 @@ Consequences worth internalising: | `iopwiki` | iopwiki.com's `gf-table event-period` tables — `Title \| Period (start/end) \| Server \| Type \| Comment`, one table per event and one row per server | Girls' Frontline 2 | | `stellasorawiki` | stellasora.miraheze.org's front-page `Current Banners` module — `