Commit Graph

45 Commits

Author SHA1 Message Date
achmad 2c928d3298 fix(hentai4free, nyanukafe): match Kotlin source overrides
hentai4free: Use search-based URLs for popular/latest with m_orderby
param (views/latest), matching Kotlin's popularMangaRequest override

nyanukafe: Set custom selectors for popular listing and detail fields
2026-05-14 22:31:18 +07:00
achmad 00e61480c3 fix(base): add override hooks for masonry, madara, keyoapp
Madara:
- Add PopularURL/LatestURL Config hooks for custom URL building
  (needed by hentai4free which uses search-based popular/latest URLs)

Masonry:
- Replace CSS :not(:has(a[href*=/video/])) with programmatic filtering.
  goquery/cascadia doesn't support :has() + attribute selectors
  (Jsoup does, hence Kotlin works but Go didn't)

Keyoapp:
- Add overridable selector fields (PopularSelector, DescriptionSelector,
  StatusSelector, AuthorSelector, ArtistSelector) to Config
2026-05-14 22:31:11 +07:00
achmad 8c642905b7 feat: replace net/http with httpcloak for Chrome TLS fingerprint
- Use httpcloak.Session (Chrome JA3/JA4 fingerprint) as primary transport
- Adaptive: direct request via httpcloak first; FlareSolverr fallback on 403/503
- FS cookies fed into httpcloak session so subsequent requests reuse
  cf_clearance (Chrome fingerprint + cookie = no re-challenge)
- FlareSolverr timeout increased to 120s for slow challenges
- Sanitize FS cookie values (strip quotes/newlines to avoid Go cookie warnings)
- Remove go-cfscraper dependency (pure JS solver was fragile)
2026-05-14 22:31:09 +07:00
achmad bfa66d8102 fix: restore adaptive HTTP (direct first, FS fallback) with session
Re-enables the direct-then-FS approach removed earlier due to TLS
fingerprint mismatch. With FS sessions configured, the fallback path
is fast after the first request per domain (Chrome caches cf_clearance).
Non-Cloudflare sites still benefit from direct HTTP speed.
2026-05-14 21:28:11 +07:00
achmad 1382c2efd5 fix: silent default test output; verbose controlled by SOURCETEST_VERBOSE env var
go test -json implicitly sets testing.Verbose()=true, so the old guard
always printed manga lists through the script. Switched to an env var
(SOURCETEST_VERBOSE=1) set by the script only when -v is passed.
2026-05-14 21:02:45 +07:00
achmad c2f8c1f0f1 chore: reduce default test parallelism to 1
Avoid overwhelming FlareSolverr's single Chrome session.
PARALLELISM env var still available to override.
2026-05-14 20:55:28 +07:00
achmad 6d45576790 fix(httpclient): fix HTTP 0 status and restore FS session default
- Guard isCloudflareChallenge with directStatus >= 400 to prevent
  overriding status to 0 when no direct request was made
- When FS returns challenge page without a prior direct status,
  return an error instead of silently passing HTTP 0
- Restore default FS session ID to 'goyomi' — without a session,
  each request spawns a new Chrome, causing timeouts under load
- Add Message field to FlareSolverrResponse for better error reporting
- Document FLARESOLVERR_SESSION env var: shared session = fast after
  1st request, but serializes. Set empty for parallel (resource-heavy).
2026-05-14 13:54:11 +07:00
achmad aa697af25f fix(base): update guya, iken, kemono, madtheme, mangahub wrappers
- guya: align JSON structs with current API (seriesListEntry, seriesDetail),
  use Cover/Author/Artist fields, fix chapter date parsing via release_date
- iken: update DTO fields to match API (postTitle, featuredImage, etc.),
  add JSON-vs-HTML detection, map seriesStatus to source.Status constants
- kemono: set Accept: text/css header for DDOS-Guard bypass
- madtheme: use .book-detailed-item selector, fix pagination detection,
  use 'updated_at' sort for latest updates
- mangahub: check cookie jar in addition to Set-Cookie headers, add
  retry-once logic for API key expiry (matching Kotlin interceptor)
2026-05-14 13:23:42 +07:00
achmad 6953aa7833 docs: add HTTP Client Architecture section to phase4-standalone
Document the unified httpclient.Client design, FlareSolverr integration,
cookie jar sharing, and Kotlin vs Go mapping.
2026-05-14 13:23:39 +07:00
achmad 44b50937d5 feat(sourcetest): add -v flag with verbose manga list output
When -v is passed, test-sources.sh passes it through to go test -v.
sourcetest.Run uses testing.Verbose() to print the full manga list
from GetPopularManga and GetLatestUpdates, showing title + URL.
2026-05-14 13:23:29 +07:00
achmad 26063e097b fix(aquamanga): update base URL to aquareader.org
The domain aquareader.net now redirects to aquareader.org.
Direct access to aquareader.net hits a JS-based tracking intermediary (mks98.com)
via FlareSolverr, while aquareader.org works reliably.
2026-05-14 13:23:21 +07:00
achmad dd792d4370 feat: add source tests for all wrapper sources 2026-05-14 09:08:06 +07:00
achmad ae56f3037d feat: add batch 5 base-source wrappers (Madara, MangaThemesia, Keyoapp, MangAdventure)
arcrelight (MangAdventure), baektoons/fablescans (MangaThemesia), epicmanga/ero18x/evilflowers
(Madara), erisscans (Keyoapp); fix wrong HttpSource annotations in phase4 doc.
2026-05-14 07:37:21 +07:00
achmad 85f34b1b23 feat: add batch 4 base-source wrappers (MangaCatalog, PizzaReader, Monochrome, MangAdventure, EroMuse)
15 MangaCatalog en/ sources (franchise-specific read* sites), hniscantrad (PizzaReader/all),
monochromescans (Monochrome), assortedscans (MangAdventure), eightmuses (EroMuse).
2026-05-14 07:26:42 +07:00
achmad 97d621d7f1 fix: correct mangahub base and all wrapper sources
- Fix GraphQL x param: was "POPULAR"/"LATEST", must be per-site source ID
  (e.g. "m01"); order type moved to separate mod param
- Add mhub_access cookie acquisition (x-mhub-access header required on all
  API calls); cached 10 min, retried with ?reloadKey=1 on failure
- Fix image URLs: construct as imgx.mghcdn.com/{p}{image} from pages JSON
- Fix thumbnail URLs: add thumb.mghcdn.com/ CDN prefix
- Fix hasNext: use len(rows)==30 instead of non-existent count field
- Fix chapter URL format: /{slug}/chapter-{num} matching Kotlin
- Fix page URL parsing to match new chapter URL format
- Add artist and alternativeTitle fields to manga details
- Fix status parsing: "ongoing"/"completed" string values
- Switch from parameterized GQL variables to direct string interpolation
- Add MangaSource field to Config; update all 11 wrapper sources with
  their correct per-site source IDs
2026-05-13 23:25:32 +07:00
achmad 7fe2c48df7 feat: implement phase 4 batch — 11 en/ MangaHub wrapper sources
mangahubio, mangahereonl, mangakakalotfun, mangafoxfun, manganel,
mangaonlinefun, mangapandaonl, mangareadersite, mangatoday, onemangaco,
onemangainfo — all using the existing mangahub GraphQL base.
2026-05-13 23:20:27 +07:00
achmad 78723bb195 feat: implement phase 4 batch — 21 en/ base-class wrapper sources
6 Madara: boratscans, bunmanga, cucumbermanga, decadencescans, linkmanga,
sleepytranslations. 15 MadTheme: beehentai, boxmanhwa, kaliscancom,
kaliscanio, mangabuddy, mangabuddyme, mangacute, mangafab, mangaforest,
mangamonk, mangasaga, mangaspin, mangaxyz, manhuanow, manhuasite.

Also corrects base-class annotations in phase4-standalone.md for sources
previously misidentified as Madara (arcrelight=MangAdventure; atsumaru,
aurora, azcomic, broccolisoup, buttsmithy, clonemanga, clowncorps=HttpSource).
2026-05-13 23:17:48 +07:00
achmad 316ae2f9db feat: implement phase 4 batch — 54 base-class wrapper sources
Add 8 all/ sources (7 Masonry, 1 Madara) and 38 en/ sources spanning
Madara, MangaThemesia, MadTheme, Keyoapp, and Guya bases, plus 8 earlier
all/ standalone sources from the previous session (ahottie, akuma,
allporncomicsco, asmhentai, baobua, beauty3600000, buondua, comicfury,
comicgrowl, comicklive, comicsvalley, comikey, commitstrip, coomer).

Also annotates phase4-standalone.md with base-class tags for 43 additional
unimplemented en/ sources identified in a full scan.
2026-05-13 23:11:26 +07:00
achmad e17de903b2 refactor: use flare client for sources with cloudflareClient in Kotlin
- Batch 5: mangawork, mangotheme, mccms, multichan → flare (Kotlin uses cloudflareClient)
- Batch 6: natsuid → flare (Kotlin uses cloudflareClient)
- Batch 7: gravureblogger → flare (Kotlin uses cloudflareClient)

All verified against Kotlin multisrc reference.
2026-05-13 21:57:34 +07:00
achmad 71ef2d24fa fix: update HTTP client to flare for Batch 4 sources
Based on Kotlin reference verification:
- madtheme, mangabox, mangacatalog, mangahub → flare

Also updated phase4-standalone.md with project requirement for
checking HTTP client type when porting sources from Kotlin
2026-05-13 21:35:10 +07:00
achmad 46f930718c fix: update HTTP client to flare for misclassified sources
Based on Kotlin reference verification:
- Batch 1: colorlibanime, eromuse, fansubscat → flare
- Batch 2: fmreader, galleryadults, greenshit, grouple → flare
- Batch 3: heancms, lectormoe → flare

Also renamed methods appropriately:
- get() for HTML scraping
- getJSON() for JSON APIs
2026-05-13 10:07:09 +07:00
achmad 9a42dd2ab1 refactor: use per-source HTTP client instead of global proxy
- Remove global ProxyEnabled() logic from httpclient
- Each source now explicitly chooses client at import time:
  - flare client: for JS-rendering/cloudflare sources
  - normal httpclient: for REST API sources
- Updated 29 base sources based on Kotlin reference (network.cloudflareClient)
2026-05-13 09:01:51 +07:00
Achmad b199bad30d refactor: separate httpclient packages for regular and FlareSolverr sources
- Add internal/httpclient/flare package for Cloudflare-protected sites
- Update 7 bases (madara, zmanga, mangaworld, mangathemesia, mangareader,
  libgroup, liliana) to use flare client
- Remove unused internal/config/source.go
2026-05-11 10:48:05 +00:00
Achmad 308d66bd36 update 2026-05-11 10:20:40 +00:00
Achmad 56e910b687 chore: rename compose files for dev/prod split
- compose.yml is now for development (default)
- compose-prod.yml is for production
2026-05-11 10:19:58 +00:00
Achmad 376fc0743a chore: update dev env config
- Add FLARESOLVERR_LOG_LEVEL and FLARESOLVERR_PROXY to .env.example
- Change default port to 3300 in dev.env
- Make compose-dev.yml use ADDR env var for host port
- Enable FLARESOLVERR_PROXY by default in dev.env for testing
2026-05-11 09:31:54 +00:00
Achmad b992080c95 feat: add FlareSolverr proxy support with DB-backed config
- Add config table for storing FlareSolverr proxy setting
- Add HTTP endpoints to get/set proxy status (GET/POST /api/config/flaresolverr)
- Refactor httpclient to support proxy mode (requests go through FlareSolverr)
- Add verbose logging for debugging
- Add POST support to FlareSolverr client

Usage:
  GET /api/config/flaresolverr - returns {flaresolverr_proxy: bool}
  POST /api/config/flaresolverr - body: {enabled: true/false}
2026-05-11 09:25:48 +00:00
Achmad 3741f4f696 change perms 2026-05-11 06:48:23 +00:00
Achmad 63b3f84464 change port for dev compose 2026-05-11 06:45:36 +00:00
achmad 1f7e229493 phase4: add standalone source wrappers and mark checklist progress
Register new all/en standalone wrappers from base sources and add initial smoke tests; several sources are still unverified in live environment.
2026-05-11 13:36:36 +07:00
achmad 90fd773ff1 dev: add make targets for standalone smoke tests 2026-05-11 13:35:58 +07:00
achmad 0c6ccc8a47 dev: add Docker compose development stack with Air reload 2026-05-11 08:39:54 +07:00
achmad 15d9d4225c phase3: add scanr, sinmh, spicytheme, stalkercms, uzaymanga, vercomics, yuyu, zeistmanga bases (68/68)
- Implement 8 remaining base sources
- All 68 bases now compile successfully
- Update TODO.md and phase3-bases.md checklist
2026-05-11 07:48:15 +07:00
achmad 4568edd32d phase3: add natsuid, oceanwp, paprika, peachscan, raijinscans bases (60/68) 2026-05-11 07:21:07 +07:00
achmad 97105640ce phase3: add manhwaz, masonry, mccms, monochrome, multichan bases (55/68) 2026-05-11 07:14:30 +07:00
achmad 409dd0bc5f phase3: add manga18, mangacatalog, mangabox, mangataro, mangawork bases (50/68) 2026-05-11 07:09:04 +07:00
achmad 50ac3f180a phase3: add gravureblogger, greenshit, hotcomics, initmanga, keyoapp bases (45/68) 2026-05-11 06:59:53 +07:00
achmad 224266ffe3 phase3: implement fansubscat, fuzzydoodle, galleryadults, gattsu, goda 2026-05-11 06:45:48 +07:00
achmad 1e6d72b046 phase3: implement colorlibanime, comicaso, comiciviewer, eromuse, ezmanhwa
5 bases: HTML scraping, static JSON index, Japanese viewer API,
album-stack crawl, and JSON REST. 35/68 bases done.
2026-05-10 22:20:17 +07:00
achmad ca609ccae7 phase3: implement first 20 base sources + shared util
Ports bases from previous session:
util (shared helpers), bakkin, fmreader, foolslide, gigaviewer,
gmanga, grouple, guya, heancms, hentaihand, kemono, madara,
madtheme, mangadventure, mangahub, mangathemesia, mangaworld,
mmrcms, senkuro, wpcomics.
2026-05-10 22:15:11 +07:00
achmad f0658472f3 phase3: implement 10 complex base sources
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].
2026-05-10 22:14:04 +07:00
achmad 6d084d3df0 docs: move deferred Phase 2 tasks to Phase 5 where they belong 2026-05-10 21:37:58 +07:00
achmad be46add182 chore: add .env.example and wire compose.yml to env vars
- .env.example documents all env vars with defaults (postgres creds, DATABASE_URL, TTLs, pool sizes)
- compose.yml reads postgres credentials and app config from .env via env_file
- .gitignore: track .env.example, ignore .env
2026-05-10 21:35:31 +07:00
achmad 95cab106d8 feat: Phase 2 — database layer
- PostgreSQL schema: sources, manga, chapters, pages, source_meta with indexes
- golang-migrate runner with embedded SQL via go:embed (pgx5:// scheme)
- sqlc-generated type-safe queries for all tables (pgx/v5 native)
- Config package with all env vars including TTL durations
- Wire DB init and config into cmd/server/main.go
2026-05-10 21:32:40 +07:00
achmad 85d2ea6143 feat: initial Phase 1 implementation — core framework + Docker
- Data types (SManga, SChapter, Page, MangasPage, all Filter variants)
- Source interfaces (Source, CatalogueSource) with MD5-based ID generation matching Tachiyomi/Suwayomi
- HTTP client with per-host rate limiting, cookie jar, and 429 retry
- FlareSolverr v1 client (FLARESOLVERR_URL env)
- Generic GraphQL POST helper
- goquery HTML parser wrappers
- Source registry (panics on duplicate ID)
- Multi-stage Dockerfile (golang:1.26-alpine + distroless) and compose.yml (postgres, flaresolverr, app)
2026-05-10 21:24:38 +07:00