Files
mangabaka-seeder/docs/specs/003-tapas.md
T
Lucas WintherandClaude Opus 5.5 5b2ad867b3 feat: KakaoPage source (웹툰 and 웹소설), registered; correct the Tapas cookie claim
KakaoPage is read from its data endpoint (current covers) and from archived
server-rendered pages under both addresses (history). The userscript never sent
Tapas cookies (anonymous: true): docs and the age-check warning now say so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 14:20:29 +02:00

71 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
status: approved
---
# 003 — Tapas source
A second source (spec 001 §4.1): covers of a [Tapas](https://tapas.io) series, comics and novels. Design approved
by the user in chat on 2026-10-15 ("Comics and novels"). Everything else — inspection, dedupe, Wayback history,
hosting, download, history — is the existing pipeline.
## 1. Verified facts (2026-10-15)
Checked against *Villains Are Destined to Die* (comic, id 186414) and its novel (id 266599), a mature series
(id 286112) and Wayback captures since 2020-10. Fixtures in `test/fixtures/tapas/` and `test/fixtures/wayback/tapas-*`.
- **Series page:** `https://tapas.io/series/<slug>/info` (its own canonical URL). `/series/<slug>` serves the
episode reader (canonical `/episode/<id>`). `/series/<id>/info` redirects to the slug form. Slugs may contain
capitals and underscores (`/series/RU_Screwed`).
- **Series id:** on the info page `pageMeta : { id: <id>, type: 'series_id' }`; on the reader `seriesId: <id>`.
- **Comic or novel:** the stats row links `/static-landing/genre?category=COMIC` or `…=NOVEL`. `og:type` is
`comicpanda:webcomic_series` for both.
- **Title:** the cover image's `alt` in `.thumb-wrapper`; `og:title` is "Read <title> | Tapas Web Comics".
- **Images** (`us-a.tapas.io/sa/<xx>/<uuid>[_<size>].<ext>`, no token, no Referer needed):
- **Portrait cover:** the `<img>` in `.thumb-wrapper` (both the info page and the 2020 reader page),
`…_z.jpg` = 400×600. Without the suffix: the original, 960×1440.
- **Banner:** `og:image` (also the `js-top-banner` / `header-layer` background), 1280×460, no suffix.
- Lists use `_m` (180 px) of other images; `pc/…` images are signed promotions of other series. Neither is used.
- Older pages use `d30womf5coomej.cloudfront.net/sa/…`; the same paths answer on `us-a.tapas.io`.
- **Mature series:** without a signed-in, age-verified account, `/series/…/info` redirects to
`/account/verify-age?from=https://tapas.io/series/<slug>/info`, a page with no series data.
*Corrected 2026-10-15 (spec 004 work):* the userscript's `GM_xmlhttpRequest` runs with `anonymous: true`, so it
does **not** send the user's tapas.io cookies; the userscript sees the age check too.
- **Language:** English only (MangaBaka `en`).
- **Wayback:** `tapas.io/series/<slug>` captured about monthly since 2020; the prefix also matches
`<slug>-novel` and other longer slugs.
## 2. Behaviour
- **Links accepted:** `tapas.io/series/<slug>`, `…/info`, `…/<id>`, `…/<id>/info`, and `tapas.io/episode/<id>`
(the reader page names its series id). `www.` and `m.` hosts too. Fetched as `https://tapas.io/series/<slug or
id>/info`; an episode link first fetches the episode page for its series id.
- **Series:** `externalId` = the numeric id, `title`, `language: "en"`, `canonicalUrl` =
`https://tapas.io/series/<slug>/info`, `flags.novel`, `archiveUrls` = [`tapas.io/series/<slug>`].
- **Current covers:** portrait (role `poster`, suffix removed) and banner (role `banner`). The poster is the
suggested main cover as for Webtoons.
- **Mature (age check):** the series is resolved from the `from=` link (slug; title from the slug), `mature: true`,
no current covers, and a warning that Tapas shows it only to signed-in adults; tick the Wayback history.
History still runs.
- **Image URLs:** `normalizeImageUrl` maps both image hosts to `us-a.tapas.io`, drops `_<letters>` size suffixes
after the UUID and any query.
- **Same series:** a link is the same series when it is a tapas.io `/series/<slug>[/info][/]` with the same slug
(case-insensitive) or `/series/<id>[/info]` with the same id. This also filters Wayback rows (`-novel`).
- **Hosts:** fetch `tapas.io`, `www.tapas.io`, `m.tapas.io`, `us-a.tapas.io`, `d30womf5coomej.cloudfront.net`;
images `us-a.tapas.io`, `d30womf5coomej.cloudfront.net`. The userscript `@connect`s `tapas.io` and the
CloudFront host.
- **Chrome:** source-neutral where it named WEBTOON: the link hint ("WEBTOON or Tapas for now"), the
"No rehosting" warning ("the source's own image URL"), the userscript description.
## 3. Testing
Unit tests on the captured pages, no network: link parsing (every form, rejects), page parsing (comic, novel,
reader, 2020 archive, age check), URL normalisation, same-series (slug, id, `-novel` rejected), and the source
end to end through the fake transport (info page, episode link, age check, `/series/<id>` redirect).
Then a real run in headless Chrome for one comic and one novel.
## 4. Risks
- Tapas markup changes; the parser looks for two stable hooks (`thumb-wrapper`, `og:image`) and the page type link.
- The info page may show a mature badge to signed-in users that we never saw; mature is only known from the
age check.