code wiki / _hdl_build / nx_manga_sites_gate.nx

nx_manga_sites_gate.nx source

↩ module page · 110 lines · 7672 B

1import "nx_gate_grow.nx" 2import "nx_gate_gn.nx" 3import "nx_gate_base.nx" 4// nx_manga_sites_gate.nx -- SOVEREIGN referee for the per-site adapters (nhentai + MangaDex). Pure logic on FIXTURE 5// JSON (legal posture: build the general capability, gate on fixtures; the operator points it where they like). No 6// network. 7// T1 na_detect: nhentai /g/ -> 1 ; mangadex /chapter/ -> 2 ; a random site -> 0 8// T2 na_nhentai_api: https://nhentai.net/g/424242/ -> https://nhentai.net/api/gallery/424242 9// T3 na_mangadex_api: https://mangadex.org/chapter/abc-123-uuid -> https://api.mangadex.org/at-home/server/abc-123-uuid 10// T4 na_json_str: extract media_id + baseUrl (with escaped \/) from fixture JSON 11// T5 na_nhentai_build: fixture {media_id:987, pages:[j,p,g]} -> 3 URLs i1.nhentai.net/galleries/987/{1.jpg,2.png,3.gif} 12// T6 na_mangadex_build: fixture {baseUrl, hash, data:[a.png,b.jpg]} -> 2 URLs <base>/data/<hash>/{a.png,b.jpg} 13// GREEN iff 6/6. license_tier: ORIGINAL expect_exit: 0 14import "nx_syscalls.nx" 15import "nx_manga_sites.nx" 16 17func gw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 18func g_streq(a: *u8, b: *u8) -> i64 { var i: i64=0; while a[i]!=(0 as u8){ if a[i]!=b[i]{return 0} i=i+1 } if b[i]==(0 as u8){return 1} return 0 } 19func g_nth(url_buf: *u8, offs: *i64, lens: *i64, idx: i64, out: *u8) -> i64 { let bp: *u8=((url_buf as i64)+offs[idx]) as *u8; var k: i64=0; while k<lens[idx]{out[k]=bp[k];k=k+1} out[lens[idx]]=0 as u8; return lens[idx] } 20 21func main() -> i64 { 22 gw("manga-sites SOVEREIGN gate (nhentai + mangadex adapters on fixture JSON)\n" as *u8) 23 var pass: i64 = 0 24 25 // T1 detect 26 var t1: i64 = 0 27 let u1: *u8 = "https://nhentai.net/g/424242/" as *u8 28 let u2: *u8 = "https://mangadex.org/chapter/abc-123-uuid" as *u8 29 let u3: *u8 = "https://somemanga.example/read/ch1" as *u8 30 if na_detect(u1, g_slen(u1))==1 { if na_detect(u2, g_slen(u2))==2 { if na_detect(u3, g_slen(u3))==0 { t1 = 1 } } } 31 pass = pass + grow("T1 na_detect: nhentai=1 mangadex=2 other=0\x00" as *u8, t1) 32 33 // T2 nhentai api url 34 let a1: *u8 = sys_mmap(256); na_nhentai_api(u1, g_slen(u1), a1) 35 var t2: i64 = 0; if g_streq(a1, "https://nhentai.net/api/gallery/424242" as *u8)==1 { t2 = 1 } 36 gw(" nhentai api=" as *u8); gw(a1); gw("\n" as *u8) 37 pass = pass + grow("T2 na_nhentai_api: /g/<id>/ -> api/gallery/<id>\x00" as *u8, t2) 38 39 // T3 mangadex api url 40 let a2: *u8 = sys_mmap(256); na_mangadex_api(u2, g_slen(u2), a2) 41 var t3: i64 = 0; if g_streq(a2, "https://api.mangadex.org/at-home/server/abc-123-uuid" as *u8)==1 { t3 = 1 } 42 gw(" mangadex api=" as *u8); gw(a2); gw("\n" as *u8) 43 pass = pass + grow("T3 na_mangadex_api: /chapter/<uuid> -> at-home/server/<uuid>\x00" as *u8, t3) 44 45 // T4 json str extraction (incl escaped \/) 46 let jx: *u8 = "{\"result\":\"ok\",\"baseUrl\":\"https:\\/\\/cdn.md.org\",\"media_id\":\"987\"}" as *u8 47 let v1: *u8 = sys_mmap(256); na_json_str(jx, g_slen(jx), "baseUrl" as *u8, v1, 256) 48 let v2: *u8 = sys_mmap(64); na_json_str(jx, g_slen(jx), "media_id" as *u8, v2, 64) 49 var t4: i64 = 0; if g_streq(v1, "https://cdn.md.org" as *u8)==1 { if g_streq(v2, "987" as *u8)==1 { t4 = 1 } } 50 pass = pass + grow("T4 na_json_str: baseUrl(\\/-unescaped) + media_id\x00" as *u8, t4) 51 52 // T5 nhentai build 53 let nj: *u8 = "{\"media_id\":\"987\",\"images\":{\"pages\":[{\"t\":\"j\",\"w\":1,\"h\":1},{\"t\":\"p\"},{\"t\":\"g\"}]}}" as *u8 54 let ub: *u8 = sys_mmap(8192); let offs: *i64 = sys_mmap(8*64) as *i64; let lens: *i64 = sys_mmap(8*64) as *i64 55 let nc: i64 = na_nhentai_build(nj, g_slen(nj), ub, 8192, offs, lens, 64) 56 gw(" nhentai pages=" as *u8); gn(nc); gw("\n" as *u8) 57 var t5: i64 = 0 58 if nc == 3 { 59 let p0: *u8=sys_mmap(256); g_nth(ub,offs,lens,0,p0) 60 let p1: *u8=sys_mmap(256); g_nth(ub,offs,lens,1,p1) 61 let p2: *u8=sys_mmap(256); g_nth(ub,offs,lens,2,p2) 62 gw(" "); gw(p0); gw(" | "); gw(p1); gw(" | "); gw(p2); gw("\n" as *u8) 63 if g_streq(p0,"https://i1.nhentai.net/galleries/987/1.jpg" as *u8)==1 { 64 if g_streq(p1,"https://i1.nhentai.net/galleries/987/2.png" as *u8)==1 { 65 if g_streq(p2,"https://i1.nhentai.net/galleries/987/3.gif" as *u8)==1 { t5 = 1 } } } 66 } 67 pass = pass + grow("T5 na_nhentai_build: 3 pages, correct ext(j/p/g) + 1-based numbering\x00" as *u8, t5) 68 69 // T6 mangadex build 70 let mj: *u8 = "{\"result\":\"ok\",\"baseUrl\":\"https:\\/\\/cdn.md\",\"chapter\":{\"hash\":\"HH\",\"data\":[\"a.png\",\"b.jpg\"],\"dataSaver\":[\"z.jpg\"]}}" as *u8 71 let ub2: *u8 = sys_mmap(8192); let of2: *i64 = sys_mmap(8*64) as *i64; let ln2: *i64 = sys_mmap(8*64) as *i64 72 let mc: i64 = na_mangadex_build(mj, g_slen(mj), ub2, 8192, of2, ln2, 64) 73 gw(" mangadex pages=" as *u8); gn(mc); gw("\n" as *u8) 74 var t6: i64 = 0 75 if mc == 2 { 76 let q0: *u8=sys_mmap(256); g_nth(ub2,of2,ln2,0,q0) 77 let q1: *u8=sys_mmap(256); g_nth(ub2,of2,ln2,1,q1) 78 gw(" "); gw(q0); gw(" | "); gw(q1); gw("\n" as *u8) 79 if g_streq(q0,"https://cdn.md/data/HH/a.png" as *u8)==1 { if g_streq(q1,"https://cdn.md/data/HH/b.jpg" as *u8)==1 { t6 = 1 } } 80 } 81 pass = pass + grow("T6 na_mangadex_build: 2 pages from data[] (dataSaver ignored) baseUrl+hash templated\x00" as *u8, t6) 82 83 // T7 title extraction (og:title, entity-decoded, site-suffix stripped) 84 let pg: *u8 = "<html><head><meta property=\"og:title\" content=\"My &amp; Cool Title\"><title>My &amp; Cool Title &#187; nhentai</title></head><body></body></html>" as *u8 85 let ti: *u8 = sys_mmap(512); na_html_title(pg, g_slen(pg), ti, 512) 86 var t7: i64 = 0; if g_streq(ti, "My & Cool Title" as *u8)==1 { t7 = 1 } 87 gw(" title=" as *u8); gw(ti); gw("\n" as *u8) 88 pass = pass + grow("T7 na_html_title: og:title + entity-decode + suffix-strip\x00" as *u8, t7) 89 90 // T8 nhentai PAGE-based extraction (the v1-API-deprecated fix): thumbnails -> full-res, current gallery only 91 let np2: *u8 = "<meta property=\"og:title\" content=\"X\"><img src=\"https://t4.nhentai.net/galleries/4022189/cover.webp\"><img src=\"https://t4.nhentai.net/galleries/4022189/1t.webp\"><img src=\"https://t3.nhentai.net/galleries/4022189/2t.jpg\"><img src=\"https://t2.nhentai.net/galleries/4022189/3t.png\"><div>related<img src=\"https://t1.nhentai.net/galleries/9999999/1t.webp\"></div>" as *u8 92 let ub3: *u8 = sys_mmap(8192); let of3: *i64 = sys_mmap(8*64) as *i64; let ln3: *i64 = sys_mmap(8*64) as *i64 93 let pc: i64 = na_nhentai_from_page(np2, g_slen(np2), ub3, 8192, of3, ln3, 64) 94 gw(" page-based pages=" as *u8); gn(pc); gw("\n" as *u8) 95 var t8: i64 = 0 96 if pc == 3 { 97 let r0: *u8=sys_mmap(256); g_nth(ub3,of3,ln3,0,r0) 98 let r1: *u8=sys_mmap(256); g_nth(ub3,of3,ln3,1,r1) 99 let r2: *u8=sys_mmap(256); g_nth(ub3,of3,ln3,2,r2) 100 gw(" "); gw(r0); gw(" | "); gw(r1); gw(" | "); gw(r2); gw("\n" as *u8) 101 if g_streq(r0,"https://i1.nhentai.net/galleries/4022189/1.webp" as *u8)==1 { 102 if g_streq(r1,"https://i1.nhentai.net/galleries/4022189/2.jpg" as *u8)==1 { 103 if g_streq(r2,"https://i1.nhentai.net/galleries/4022189/3.png" as *u8)==1 { t8 = 1 } } } 104 } 105 pass = pass + grow("T8 na_nhentai_from_page: thumbs->full-res, current gallery only (related 9999999 excluded)\x00" as *u8, t8) 106 107 gw("pass=" as *u8); gn(pass); gw("/8\n" as *u8) 108 if pass == 8 { gw("verdict=GREEN (per-site adapters: detect + api + json + PAGE-based nhentai + title-grab)\n" as *u8); sys_exit(0); return 0 } 109 gw("verdict=RED\n" as *u8); sys_exit(1); return 1 110}