Conversation
Tangerine Archive lists premium (coin-locked) chapters with href="#", so the template dropped them and parseChapter returned an empty body for their real URLs. Add an opt-in premiumChapterUrls source option that reconstructs the chapter-<n> URL from the row text, keeps the locked chapters in the list, and throws a descriptive error naming the coin price when the server-gated lock notice is served. Only tangerinearchive enables the option, so other Madara sources are unaffected. Bumps the source to 2.2.1. Co-Authored-By: firstmate-crewmate <crewmate@firstmate.local>
Reconstructed premium URLs are exact for ~98% of rows, but a few odd slugs (emoji suffixes, duplicate chapter numbers) fall back to the series page, which has no .reading-content and previously produced a blank chapter. For premiumChapterUrls sources, throw a clear error when the page has no reading area or no readable text, so a wrong derived URL can never come back blank. Co-Authored-By: firstmate-crewmate <crewmate@firstmate.local>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked candidate fix for lnreader#2564
Base is deliberately
fm/lnreader-plugins-2555-tangerine, the head branch of lnreader#2564 — not a default branch. Merge this only after (or together with) that PR.This fixes exactly the gap PR 2564 documented: premium (coin-locked) chapters were dropped from the chapter list because their ajax rows carry
href="#", andparseChapteron their real URLs returned an empty body.What changed
plugins/multisrc/madara/template.ts— new opt-inpremiumChapterUrlssource option, off by default so every other Madara source keeps the old code path:parseNovel: premium rows (li ... premium-block) withhref="#"get their realseries/<slug>/chapter-<n>/path reconstructed from the row's chapter text instead of being dropped. If no number can be read, the row is still dropped (no invented URL). The existing🔒prefix and the existinghideLockedhandling are untouched.parseChapter: for sources with the option, a server-gated body (.reading-content .content-blocked/.reading-content .premium-block, or the "This chapter is locked!" text) now throwsPremium chapter locked: costs <coin-N> coins and requires a site account to unlock.instead of silently returning an empty chapter. The coin price is read from thecoin-Nclass, so it is not hardcoded to 10.parseChapteralso throwsChapter content unavailable: the page has no readable bodywhen the fetched page has no.reading-contentor no readable text — a few odd premium slugs (emoji suffixes, duplicate chapter numbers) resolve to the series page, and that must never come back blank either.plugins/multisrc/madara/sources.json—tangerinearchiveopts in with"premiumChapterUrls": trueand"versionIncrements": 1(generated plugin version2.2.1).plugins/multisrc/madara/README.md— documents the new option.Anonymous read-only probes (no login, no cookies, no purchase, no buy-endpoint call)
POST /series/garden-of-may/ajax/chapters/→ 212 rows: 160free-chap+ 52premium coin-10 data-chapter-<id> premium-block, rows descending 212..1. Every row's anchor text is exactlyChapter N, and for all 160 free rows the href number equals the text number (0 mismatches), which is what makes the reconstruction exact.GET /series/garden-of-may/chapter-161/(also 170, 212) → HTTP 200, but.reading-contentholds only<div class="premium coin-10 data-chapter-16157 content-blocked premium-block">This chapter is locked! <a href="#">Buy it?</a></div>; the prose is absent from the DOM, not hidden.data-chapter-<id>matches the ajax row's class id.chapter-160/contains 4premium-blockoccurrences, alldiv.nav-next ...outside.reading-content; 0 inside. The detector is scoped to.reading-content, so free chapters never throw.popularNovels[0]ajax list has 173 rows (53 free + 120 premium); the plugin now returns all 173.?_formatvariants, wp-json/REST, JSON-LD, sitemaps, cache/CDN variants, reading-nav and manga ajax parameter matrix, Wayback CDX, hidden page data) found no route that serves a locked body — the lock is enforced server-side, consistent with the earlier research report. No session/nonce forging, no login and no buy-endpoint call was made.Verification
npm run build:compileandnpm run build:multisrcpass.npm run check:plugin -- plugins/english/TangerineArchive[madara].ts→ PASS (popularNovels 12 novels, searchNovels PASS, parseNovel 173 chapters, parseChapter 14497 chars).parseNovel('series/garden-of-may/')= 212 chapters (52 locked / 160 free) with premium paths matching the live ajax numbers exactly;parseChapteron locked 161/212 throws the 10-coin message; free 1/80/160 return 7114/8396/6532 chars; a soft-404 series-page URL (.../chapter-173/) throws the no-readable-body error instead of returning''.Lovelyblossoms[madara].tsPASS andSleepyTranslations[madara].tsPASS. (BoxNovel[madara].tswas INCONCLUSIVE — its site returns Cloudflare 403 — unrelated to this change.)NOT tested
releaseTime: 'LL'for Tangerine chapters is the pre-existingdayjs().format('LL')template issue and is intentionally out of scope.Closes the premium-listing part of lnreader#2555.
Co-authored by an AI agent (firstmate crewmate, task
tangerine-premium-fail-loud).