Skip to content

fix(fictioneer): migrate Illusia to the generator and add per-source overrides - #2567

Merged
rajarsheechatterjee merged 2 commits into
lnreader:masterfrom
nullrender:illusia-fictioneer
Sep 24, 2026
Merged

rajarsheechatterjee merged 2 commits into
lnreader:masterfrom
nullrender:illusia-fictioneer

Conversation

@nullrender

Copy link
Copy Markdown
Contributor

Checklist

  • Update version code if an existing plugin was modified
  • Test changes in Plugin Playground or the app
  • Reference related issues in the PR body (e.g. Closes #xyz)
  • Commit messages follow type(scope): description (e.g. feat(<generator>): add new source)

Summary

plugins/portuguese/illusia.ts (standalone) was failing parseNovel with "Missing novel name": illusia.com.br runs Fictioneer 5.35.3 but customizes the story page and the browse cards (h1.illusia-single-story__title, li.illusia-card, etc.), so the standard h1.story__identity-title selector never matched. The app hid the bug because the novel name comes from the list, but author, cover, summary and status were never populated.

This PR migrates Illusia to the fictioneer generator, as discussed with Traitor on Discord (#plugins). No breaking changes: the plugin id stays illusia and the stored paths keep the exact old format (story/<slug> and story/<slug>/<chapter>, no trailing slash), verified against all 1,459 novel/chapter links in real site responses. Existing libraries and reading progress carry over.

Generator changes (plugins/multisrc/fictioneer/template.ts)

New optional per-source options, all defaulting to the strings the template already used, so the seven existing sources are unaffected:

  • trimTrailingSlash – store paths without the trailing slash
  • selectors.{browseCard, searchCard, cardTitle, cardCover, novelTitle, novelAuthor, novelCover, novelSummary} – override the default Fictioneer markup

Improvements that apply to every fictioneer source:

  • cover read from data-src when present (lazy-loaded images), falling back to src/href
  • status derived from the span.story__status class (_ongoing, _completed, _oneshot, _hiatus, _canceled) instead of English text, so localized sites work; text comparison kept as fallback (and now also matches Fictioneer's actual Canceled spelling)
  • summary keeps paragraph breaks and drops embedded section.small-card-block story cards
  • showLatestNovels supported via the standard ?s=&post_type=fcn_story&orderby=modified search endpoint
  • script/style/iframe stripped from chapter content
  • chapterNumber parsed from names that start with Chapter N / Capítulo N / Ch. N
  • chapter lock check no longer throws when an item has no <i> element
  • resolveUrl implemented; without it the app built site + path with no separator, so "open in browser" produced https://illusia.com.brstory/... for every source whose site has no trailing slash

Version base bumped from 1.1.x to 1.2.x for all fictioneer sources since generated code changed.

Files

  • plugins/multisrc/fictioneer/template.ts, sources.json – as above; Illusia entry added
  • plugins/portuguese/illusia.ts – removed
  • icon moved to public/static/multisrc/fictioneer/illusia/icon.png

Testing

  • npm run check:plugin on the generated Illusia[fictioneer].ts: 4/4 PASS (was 2/4 on the standalone). NovelLib: 4/4 PASS before and after. DaoistQuest, PenguinSquad, CherryMistCafe (FAIL) and Lily, Prizma, DearestRosalie (INCONCLUSIVE, site unreachable/403) give the same result before and after the change.
  • Old vs new bundles compared live for the existing sources: identical JSON output except the intended improvements (NovelLib chapter lost two ad <script>s, summary no longer starts with ad JS).
  • Selectors verified against saved HTML of the browse list (p. 1 and 2), search, story and chapter pages.
  • Tested in the app (Android, LNReader 2.1.x) via the fork's published branch: existing library entries and progress preserved after the update, no duplicated chapters on refresh; novel page with cover/author/status/genres/summary; chapters with footnotes; "Latest" button and pagination; search; add a new novel; "open in browser" from search, novel and chapter.
  • npm run lint / format:check are clean on the changed files (the repo-wide runs report pre-existing issues that are identical on a clean master).

Notes: the old standalone plugin sent a custom User-Agent; the site responds fine without it. The standalone's browse used the search endpoint ordered by comment count; the generator uses /historias/ for browse and the search endpoint for "latest".

Written with AI assistance (Claude Code, reviewed with Codex); every selector was checked against real site responses and the result was tested in the app by me.

…overrides

Illusia's story page uses custom markup, so the standalone plugin failed
parseNovel (missing novel name). Migrate it to the fictioneer generator with
new optional per-source options (selectors.*, trimTrailingSlash) that keep the
plugin id and the stored novel/chapter paths identical to the old plugin.

Template improvements for all fictioneer sources: cover from data-src when
present, status derived from the story__status class, summary with paragraph
breaks and without embedded story cards, showLatestNovels via the search
endpoint, script/style/iframe stripped from chapter content, chapterNumber
parsed from anchored chapter names. Version base bumped to 1.2.x.
…alid URL

The app falls back to site + path when a plugin has no resolveUrl, which
produced URLs like "https://illusia.com.brstory/..." for every fictioneer
source whose site has no trailing slash.
@greptile-apps

greptile-apps Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 4/5

The PR is not yet safe to merge because absolute cover URLs are corrupted during Fictioneer EPUB export.

Summary

The PR migrates Illusia from a standalone implementation to the shared Fictioneer generator and extends that generator with source-specific selectors, path normalization, Latest browsing, localized status parsing, richer metadata extraction, and chapter-content cleanup.

  • Adds Illusia metadata and selector overrides while preserving its plugin id and slashless stored paths.
  • Moves Illusia's icon into the Fictioneer multisource asset hierarchy.
  • Updates shared Fictioneer parsing and raises generated plugin versions to 1.2.x.
  • The new URL resolver needs to preserve absolute cover URLs used during EPUB export.

Reviews (1) · Last reviewed commit: "fix(fictioneer): implement resolveUrl so..."

Comment thread plugins/multisrc/fictioneer/template.ts
@greptile-apps

greptile-apps Bot commented Sep 23, 2026

Copy link
Copy Markdown

Comments Outside Diff

These findings sit on lines the diff does not cover, so they could not be posted inline. Each one leaves this list once its file changes.

  • P1 Absolute cover URLs break plugins/multisrc/fictioneer/template.ts:238 ▶

    When a Fictioneer source returns an absolute cover URL, EPUB export passes it through resolveUrl. This implementation treats it as a relative path, turning a URL such as https://cdn.example/image.jpg into https://illusia.com.br/https://cdn.example/image.jpg/, so the cover download fails. Preserve absolute URLs before joining relative paths to the source site.

      resolveUrl = (path: string) => {
        if (/^https?:\/\//i.test(path)) return path;
        return (
          this.site.replace(/\/+$/, '') +
          '/' +
          path.replace(/^\/+|\/+$/g, '') +
          '/'
        );
      };
    

@rajarsheechatterjee
rajarsheechatterjee merged commit e3c181f into lnreader:master Sep 24, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants