f0658472f3
Ports all remaining ⚠️ annotated bases from the phase3 checklist:
zmanga, mangareader, liliana, lectormoe, iken, pizzareader,
mangotheme (AES/CBC decrypt), libgroup (bearer token auth),
scanreader (WP AJAX chapters), mmlook (CF + packed JS pages).
Updates docs/phase3-bases.md to mark all 10 as [x].
262 lines
10 KiB
Markdown
262 lines
10 KiB
Markdown
# Phase 3 — Base Source Implementations
|
|
|
|
Complete port checklist for all 68 bases in `/Users/achmad/Documents/Belajar/Android/extensions-source/lib-multisrc/`.
|
|
Each base goes into `sources/base/{name}/`. Check a box when the base compiles and
|
|
at least one derived source passes a smoke test.
|
|
|
|
Detailed implementation notes for complex bases are in the **Notes** section at the bottom.
|
|
|
|
---
|
|
|
|
## All Bases — 68 total
|
|
|
|
- [x] `base/bakkin` ⚠️ see notes
|
|
- [ ] `base/colorlibanime`
|
|
- [ ] `base/comicaso`
|
|
- [ ] `base/comiciviewer`
|
|
- [ ] `base/eromuse`
|
|
- [ ] `base/ezmanhwa`
|
|
- [ ] `base/fansubscat`
|
|
- [x] `base/fmreader` ⚠️ see notes
|
|
- [x] `base/foolslide` ⚠️ see notes
|
|
- [ ] `base/fuzzydoodle`
|
|
- [ ] `base/galleryadults`
|
|
- [ ] `base/gattsu`
|
|
- [x] `base/gigaviewer` ⚠️ see notes
|
|
- [x] `base/gmanga` ⚠️ see notes
|
|
- [ ] `base/goda`
|
|
- [ ] `base/gravureblogger`
|
|
- [ ] `base/greenshit`
|
|
- [x] `base/grouple` ⚠️ see notes
|
|
- [x] `base/guya` ⚠️ see notes
|
|
- [x] `base/heancms` ⚠️ see notes
|
|
- [x] `base/hentaihand` ⚠️ see notes
|
|
- [ ] `base/hotcomics`
|
|
- [x] `base/iken` ⚠️ see notes
|
|
- [ ] `base/initmanga`
|
|
- [x] `base/kemono` ⚠️ see notes
|
|
- [ ] `base/keyoapp`
|
|
- [x] `base/lectormoe` ⚠️ see notes
|
|
- [x] `base/libgroup` ⚠️ see notes
|
|
- [x] `base/liliana` ⚠️ see notes
|
|
- [x] `base/madara` ⚠️ see notes
|
|
- [x] `base/madtheme` ⚠️ see notes
|
|
- [ ] `base/manga18`
|
|
- [ ] `base/mangabox`
|
|
- [ ] `base/mangacatalog`
|
|
- [x] `base/mangadventure` ⚠️ see notes
|
|
- [x] `base/mangahub` ⚠️ see notes
|
|
- [x] `base/mangareader` ⚠️ see notes
|
|
- [ ] `base/mangataro`
|
|
- [x] `base/mangathemesia` ⚠️ see notes
|
|
- [ ] `base/mangawork`
|
|
- [x] `base/mangaworld` ⚠️ see notes
|
|
- [x] `base/mangotheme` ⚠️ see notes
|
|
- [ ] `base/manhwaz`
|
|
- [ ] `base/masonry`
|
|
- [ ] `base/mccms`
|
|
- [x] `base/mmlook` ⚠️ see notes
|
|
- [x] `base/mmrcms` ⚠️ see notes
|
|
- [ ] `base/monochrome`
|
|
- [ ] `base/multichan`
|
|
- [ ] `base/natsuid`
|
|
- [ ] `base/oceanwp`
|
|
- [ ] `base/paprika`
|
|
- [ ] `base/peachscan`
|
|
- [x] `base/pizzareader` ⚠️ see notes
|
|
- [ ] `base/raijinscans`
|
|
- [ ] `base/scanr`
|
|
- [x] `base/scanreader` ⚠️ see notes
|
|
- [x] `base/senkuro` ⚠️ see notes
|
|
- [ ] `base/sinmh`
|
|
- [ ] `base/spicytheme`
|
|
- [ ] `base/stalkercms`
|
|
- [ ] `base/uzaymanga`
|
|
- [ ] `base/vercomics`
|
|
- [x] `base/wpcomics` ⚠️ see notes
|
|
- [ ] `base/yuyu`
|
|
- [ ] `base/zeistmanga`
|
|
- [x] `base/zmanga` ⚠️ see notes
|
|
|
|
---
|
|
|
|
## Notes — Complex Bases
|
|
|
|
### `base/heancms` ⚠️
|
|
- Config struct: `BaseURL`, `APIURL`, `Lang`, `DateFormat`
|
|
- `GetPopularManga` — `GET {api}/series?page={n}&order=views`
|
|
- `GetLatestUpdates` — `GET {api}/series?page={n}&order=latest`
|
|
- `GetSearchManga` — `GET {api}/series?page={n}&query={q}`
|
|
- `GetMangaDetails` — `GET {api}/series/{slug}`
|
|
- `GetChapterList` — `GET {api}/chapter/query?series_slug={s}&limit=9999`
|
|
- `GetPageList` — `GET {api}/chapter/{slug}` → extract image array
|
|
- Parse `has_next_page` field from list responses
|
|
|
|
### `base/hentaihand` ⚠️
|
|
- Config struct: `BaseURL`, `Lang`
|
|
- `GetPopularManga` — `GET {base}/api/comics?page={n}&order_by=popularity`
|
|
- `GetLatestUpdates` — `GET {base}/api/comics?page={n}&order_by=date`
|
|
- `GetPageList` — `GET {base}/api/comics/{slug}/chapters/{n}` → images array
|
|
|
|
### `base/pizzareader` ⚠️
|
|
- Config struct: `APIURL`, `Lang`
|
|
- `GetPageList` — `GET {api}/comics/{comic}/{chapter}` → page URLs
|
|
- FlareSolverr mode (CF=Yes): inject cookies from clearance
|
|
|
|
### `base/gmanga` ⚠️
|
|
- `GetPopularManga` — `GET {base}/api/releases?page={n}`
|
|
- `GetSearchManga` — `POST {base}/api/mangas/search` with JSON body `{q, page}`
|
|
- `GetPageList` — extract chapter page data (may require resolving CDN token)
|
|
- Handle Arabic/RTL title fields
|
|
|
|
### `base/mangadventure` ⚠️
|
|
- Django manga reader REST API
|
|
- `GET {base}/api/v2/series/` — list; `GET {base}/api/v2/series/{slug}/` — detail
|
|
- `GET {base}/api/v2/chapters/?series={slug}` — chapters; `GET {base}/api/v2/chapters/{vol}/{num}/` — pages
|
|
|
|
### `base/madara` ⚠️
|
|
- Config struct: `BaseURL`, `Lang`, `DateFormat`, overridable CSS selectors
|
|
- `GetPopularManga` — `POST {base}/wp-admin/admin-ajax.php` with `action=madara_load_more`, `vars[paged]={n}`
|
|
- `GetLatestUpdates` — same AJAX with `vars[meta_key]=_latest_update`
|
|
- `GetSearchManga` — `GET {base}/?s={q}&post_type=wp-manga`
|
|
- `GetMangaDetails` — `GET {url}` → parse `.post-title`, `.author-content`, `.genres-content`, `.manga-summary`, `.post-image img`
|
|
- `GetChapterList` — `POST {url}/ajax/chapters/` → parse chapter list HTML
|
|
- `GetPageList` — `GET {chapter_url}` → parse `div.reading-content img`
|
|
- FlareSolverr required; configurable selectors struct (child sources override individual selectors)
|
|
- Date parsing: relative ("X days ago") + absolute ("MMMM dd, yyyy") formats
|
|
|
|
### `base/mangathemesia` ⚠️
|
|
- Config struct: `BaseURL`, `Lang`, `MangaDir` (e.g. "manga"/"manhwa"), overridable selectors
|
|
- `GetPopularManga` — `GET {base}/{dir}/?page={n}&order=popular`
|
|
- `GetChapterList` — parse `#chapterlist li` elements
|
|
- `GetPageList` — extract `ts_reader.run({...})` JS JSON blob, parse `sources[].images`
|
|
- FlareSolverr required
|
|
|
|
### `base/madtheme` ⚠️
|
|
- All list types via `GET {base}/search?page={n}&sort=...`
|
|
- `GetPageList` — parse JSON blob in `<script>` tag containing image array
|
|
- FlareSolverr required
|
|
|
|
### `base/wpcomics` ⚠️
|
|
- Config struct: `BaseURL`, `Lang`, `PopularPath` (default "tim-kiem"), `DateFormat`
|
|
- `GetPopularManga` — `GET {base}/{popularPath}?page={n}`
|
|
- FlareSolverr required
|
|
|
|
### `base/fmreader` ⚠️
|
|
- Config struct: `BaseURL`, `Lang`, `RequestPath`, overridable selectors
|
|
- `GetPopularManga` — `GET {base}/{requestPath}?page={n}&sort=views`
|
|
- FlareSolverr required
|
|
|
|
### `base/mmrcms` ⚠️
|
|
- `GetPopularManga` — `GET {base}/filterList?page={n}&sortBy=views&asc=false`
|
|
- `GetSearchManga` — `POST {base}/advSearchFilter` with form data
|
|
- JSON response; no FlareSolverr required
|
|
|
|
### `base/mangareader` ⚠️
|
|
- Config struct: `BaseURL`, `Lang`, `TypeParam` (comic/manga/manhwa)
|
|
- `GetPopularManga` — `GET {base}/?page={n}&type={t}&status=all&order=popular`
|
|
- FlareSolverr required
|
|
|
|
### `base/zmanga` ⚠️
|
|
- `GetPopularManga` — `GET {base}/advanced-search/page/{n}/?order=popular`
|
|
- FlareSolverr required
|
|
|
|
### `base/mangaworld` ⚠️
|
|
- `GetPopularManga` — `GET {base}/archive?sort=most_read&page={n}`
|
|
- FlareSolverr required
|
|
|
|
### `base/grouple` ⚠️
|
|
- `GetPopularManga` — `GET {base}/list?sortType=rate&offset={50*(n-1)}`
|
|
- No FlareSolverr
|
|
|
|
### `base/foolslide` ⚠️
|
|
- `GetPopularManga` — `GET {base}/directory/{n}/`
|
|
- `GetChapterList` — JSON API: `GET {base}/api/reader/chapters?comic={slug}`
|
|
- `GetPageList` — JSON API: `GET {base}/api/reader/images?chapter={id}`
|
|
- No FlareSolverr
|
|
|
|
### `base/liliana` ⚠️
|
|
- `GetPopularManga` — `GET {base}/ranking/week/{n}`
|
|
- FlareSolverr required
|
|
|
|
### `base/scanreader` ⚠️
|
|
- `GetPopularManga` — `GET {base}/bibliotheque/page/{n}/?sort=views`
|
|
- No FlareSolverr
|
|
|
|
### `base/gigaviewer` ⚠️
|
|
- `GET {base}/series` returns all manga at once; no pagination (`HasNextPage` always false)
|
|
- `GetLatestUpdates` = same request as popular (no separate endpoint)
|
|
- FlareSolverr required; client-side filtering replicated in Go
|
|
|
|
### `base/mangahub` ⚠️ (GraphQL)
|
|
- Cookie acquisition: `GET` to any chapter URL to set `mhub_access` cookie, then reuse for GraphQL
|
|
- All operations via GraphQL POST to `{api}/graphql`
|
|
- `GetPopularManga` — `searchManga(x:POPULAR, genre:"all", page:N)`
|
|
- `GetPageList` — `chapter(mangaId:N, number:N)` → extract pages
|
|
- Inject `mhub_access` cookie header on all GraphQL requests
|
|
|
|
### `base/senkuro` ⚠️ (GraphQL)
|
|
- Config struct: `APIURL` (configurable per source preferences)
|
|
- Standard GraphQL list/detail/chapter/page queries
|
|
- No CF requirement
|
|
|
|
### `base/mangotheme` ⚠️ (encrypted)
|
|
- JSON list + detail (standard REST)
|
|
- Page URL decryption: extract encryption key from embedded JS, then XOR/AES decrypt each page URL
|
|
- Use `crypto/aes` or manual XOR depending on algorithm found in extension source
|
|
|
|
### `base/mmlook` ⚠️ (encrypted + CF)
|
|
- Same page URL decryption as mangotheme
|
|
- FlareSolverr required
|
|
|
|
### `base/guya` ⚠️
|
|
- `GET {base}/api/get_all_series/` returns all manga as a map; no pagination
|
|
- `HasNextPage` always false
|
|
- Scanlation group filter applied client-side
|
|
|
|
### `base/bakkin` ⚠️
|
|
- No list/search; all manga from a single JSON URL; enumerate from object keys
|
|
- `GetSearchManga` does client-side title filtering only
|
|
|
|
### `base/iken` ⚠️
|
|
- CF-protected; FlareSolverr required for cookie acquisition
|
|
- JSON REST after clearance
|
|
|
|
### `base/lectormoe` ⚠️
|
|
- CF-protected; Token auth required
|
|
- Obtain token via FlareSolverr session
|
|
|
|
### `base/libgroup` ⚠️
|
|
- FlareSolverr required to acquire WebView auth token
|
|
- `GET {api}/api/latest-updates`, `GET {api}/api/auth/me`
|
|
- Store acquired token in `source_meta` table for reuse
|
|
|
|
### `base/kemono` ⚠️
|
|
- `GET {base}/api/v1/creators` — all creators (= manga list)
|
|
- `GET {base}/api/v1/{service}/{creator}/posts?o={offset}` — paginate in 50-post increments
|
|
- File URLs: prefix relative paths with `{base}/data`
|
|
- FlareSolverr required
|
|
|
|
---
|
|
|
|
## Shared Helpers (implement once in `sources/base/util/`)
|
|
|
|
- [ ] `parseRelativeDate(s string) int64` — "2 days ago" → unix ms
|
|
- [ ] `parseAbsoluteDate(s, format string) int64` — "January 01, 2024" → unix ms
|
|
- [ ] `slugFromURL(url string) string` — trailing path segment
|
|
- [ ] `cleanText(s string) string` — HTML entity decode + whitespace normalize
|
|
- [ ] `statusFromString(s string) int` — "ongoing"/"completed"/etc. → int constant
|
|
- [ ] `extractNextDataJSON(html string) ([]byte, error)` — pull `__NEXT_DATA__` JSON from NextJS pages
|
|
|
|
---
|
|
|
|
## Checklist: Phase 3 Done When
|
|
|
|
- [ ] All 68 bases compile: `go build ./sources/base/...`
|
|
- [ ] `base/heancms` — `GetPopularManga` returns ≥1 manga from a live site
|
|
- [ ] `base/madara` — `GetChapterList` returns chapters via AJAX endpoint
|
|
- [ ] `base/mangathemesia` — `GetPageList` extracts images from `ts_reader.run()` JS blob
|
|
- [ ] `base/mangahub` — GraphQL popular list works with cookie acquisition
|
|
- [ ] `base/mangotheme` — decrypted page URL returns HTTP 200 image
|
|
- [ ] FlareSolverr path — a CF-protected base returns data when FlareSolverr is running
|