From 967416bbe905609c0a75f098bf42823e6bd0f199 Mon Sep 17 00:00:00 2001 From: Chopper <156493704+choppeh@users.noreply.github.com> Date: Sun, 3 Nov 2024 08:52:11 -0300 Subject: [PATCH] Add BlackScans (#5833) --- src/pt/blackscans/AndroidManifest.xml | 22 +++ src/pt/blackscans/build.gradle | 7 + .../res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 2917 bytes .../res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 1637 bytes .../res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 3823 bytes .../res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 6898 bytes .../res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 9450 bytes .../extension/pt/blackscans/BlackScans.kt | 179 ++++++++++++++++++ .../pt/blackscans/BlackScansUrlActivity.kt | 37 ++++ .../pt/blackscans/MangaDetailsDto.kt | 44 +++++ 10 files changed, 289 insertions(+) create mode 100644 src/pt/blackscans/AndroidManifest.xml create mode 100644 src/pt/blackscans/build.gradle create mode 100644 src/pt/blackscans/res/mipmap-hdpi/ic_launcher.png create mode 100644 src/pt/blackscans/res/mipmap-mdpi/ic_launcher.png create mode 100644 src/pt/blackscans/res/mipmap-xhdpi/ic_launcher.png create mode 100644 src/pt/blackscans/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 src/pt/blackscans/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 src/pt/blackscans/src/eu/kanade/tachiyomi/extension/pt/blackscans/BlackScans.kt create mode 100644 src/pt/blackscans/src/eu/kanade/tachiyomi/extension/pt/blackscans/BlackScansUrlActivity.kt create mode 100644 src/pt/blackscans/src/eu/kanade/tachiyomi/extension/pt/blackscans/MangaDetailsDto.kt diff --git a/src/pt/blackscans/AndroidManifest.xml b/src/pt/blackscans/AndroidManifest.xml new file mode 100644 index 000000000..8c685c35c --- /dev/null +++ b/src/pt/blackscans/AndroidManifest.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + diff --git a/src/pt/blackscans/build.gradle b/src/pt/blackscans/build.gradle new file mode 100644 index 000000000..caf40184e --- /dev/null +++ b/src/pt/blackscans/build.gradle @@ -0,0 +1,7 @@ +ext { + extName = 'Black Scans' + extClass = '.BlackScans' + extVersionCode = 1 +} + +apply from: "$rootDir/common.gradle" diff --git a/src/pt/blackscans/res/mipmap-hdpi/ic_launcher.png b/src/pt/blackscans/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..dbbb59182a40980d5794d8f7c5f2b5902750bbba GIT binary patch literal 2917 zcmV-r3!3zaP)=R{@{WT1iw=Kl-OG~Npp z=8NZs&8@AizUu1gh0$oVGnq`5D}hR-QmP#)9XIOpOy_d#O@EfQSS%rz%XK&$4!=1t zFc8FZR44}44F-dYu@hf9owkc9;NNHdEcAVe&r6ui=CShf@^|q6bqMKW zyn&?BH>(E7?DzY9wY9Z7M@B}LQv*sjqIRsrH?Me&a@P?E1oom;d_5EjDJn?~kgct) z?Q4-pNx=B?7d4T0zDGQZu=;9hT_YjRB;` z%+yR!uX(am#yXDu>jQ*7D96O)lwkw_UQm!Wfx}V;9c7opMHSbB*IEUi#Co8A{6BDD z>@^sl9D!6i8yJ@y5X-E%Z&ZFn$#bf9vkU5-=VO@-<@P$Tnw-$!oCEFNFM-7*3eRxL zGZgEE-2 zp6G)eM{a?kiQeJ^^7(vuqZp5gu|V;vj1)4rd?^B24h`E3m4==7fA0m5Vw&F1q0MP3s#Qdxf6Ik5bk`(a+ibzsJSYH;Wn z0ebT28u&1@m*uDnAI0PV@v6uuI28NLt5^n0YHo*G*DPFC!32cN$TdYF>yn~mVuFI+ zV5N$U1EdFz7Qd6JYc<*7>bmuCS=B8VC}vHH2hc=v9Cr5I0q>8!$_g0u0m8g3w~6tn zhE*r?B{wR!4{7ma44&=358fGhuC#!(sE7qa={U{1mf{p+ zPWe??I8&9Gz9&;Hk(z+#Ke`Y8`ROyVPFmErF$z)wlXaH)3zdaL)K&IY_;%|f!qmcS zqQvI(D@QIlta5x$rW%>p?~dOI?*(609mViq;eb3IkK!mM_w6geVnyI|Qv`z|TDNEzH!Z_5<;88sgs#?q;cn zj_WfqrBO_aiOJP9g9TbVm%uj~e+G4~j$D({2uBL;lV}fYIk*_ZqEwE06t3A=Kt`At zMa2sOtKf@)l~87@nhO4;FHWZ{u|P9fYdrQ z<7&ff@0D<6?QNJ2y%ZIb&D-QrlCcpjaZaYazHk@3bYc@68}Gse!|ZlLPB_$zen4EE z;fm+{z)d(pZNO-_R$VnLe{;spvdu{0B~nq?GxQXeCtxf=+YHsW2&!CA;eZ?t2lpse zWp9H!JN}5NP`{v@oQbByvCw)IO(xU$kKV`d{mJNIoHy-<6Os3E#PdOm`x5BzUJfijDN9L;D_x8lYHJFIBhjOuj5bCfMS z^@1?pk}8kw0CQ>>14zldnsM>&o6Qe_-`+5lH%3z;FvoE_O8407xK94EFbwl%BE|J6 z;=Z|M8=CHQa3u7WFvp@`^MkvYK_iJyQd4)>H~8;l-;y~9u8V&Rxjhr*0* z+-=7B(r044qnK7OY&DtSikdZWaP04xx)>20G-V%YZxDq96h}>_;=(So0FH8lXi~JA zN-v6=QZUKMN2iHN0r99wD=c1r#M3t~6;VC?3gW#mRy|%2a_VBWT>zNODTM>FTCH4x zBJ1MyfKdt}bpVl`YAhfY3|7!)1S|vLP*eH z@}Lj87hCud79roj0>R@iw5X^EFr-aV3gPEiet|{P<4}|e^k5{t0-uE0hVMnwbLGos z0X)m#(2dYTbnCG^Km9)M;a;^zGAW_ch;h*4xDD?LB`ho`EamZ>UqmJC!?ssp>BkZ! zBa!x{_E0Z9{!JP8c7*gxEEnQ?dKN$>(LB{W>!w-9iwK08ru+y!pL!4rJxxiOe%fU} zA=j_!W8ruLsi+J~J(h*2q*?gC1B>eO_N*TmC^7)G=1C#+bn_7`Z(=6O`EdPc_<~KVC zNTw+M>H?wW0hFni0mFOF*{q@rDCQ5GeAaKa=wHGNAO_+YKr?{!S>b;H`Y)8w|2)WE P00000NkvXXu0mjfT~d5A literal 0 HcmV?d00001 diff --git a/src/pt/blackscans/res/mipmap-mdpi/ic_launcher.png b/src/pt/blackscans/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..ef73bba4b685b2a1a4e525b9219d80e846739a37 GIT binary patch literal 1637 zcmV-r2AcVaP)O0@3(@8XpwzVz3Iz#ajq! zkVK=eJV=5lmk=KmDZN0Eo6@B%w%c~wZnyqtwzHj`oy(c-YD3~AC$l@}_I>~N|Nl8> z#)7N-vRvi(@jrpFR!~m?R%fF!)+!AVhV*dBvzIEkSS;p^L?W*zlgZk2I$bLD8X96_ z0n%OmTUp2R-)KBmZ?RY|JDtuwgM))F#N+XVl7Sildv$g7=0qZ~)@TA=0z71l#tH-i z+dDcs)>FFyISDlazOu5iKT@ewM9cEU0AvJMs+Z=n*=$$(`}-^DIa49y3M&512!*53 zXxqQ#Hb%hpj6?1mrT*=D1gun9LIhgX{M=}Az4$1GYD8ch&B2Vzf?8DpkpNw-N(I!w zn;|qN1V*bup~SSvaw|Y7G^>D~TZ}fy?G_iV3(UjZ(kI}u`4LZ^#{Nq?a4K;`9I|Kx zj1O0abNMqC@13zsz@anIZ--wzI@u&t>UOGoK3ugF!9@jKC{Zu)vC%*i%?g{v2&{*+y3eUi<@` zP8>yD!;<0<&{M!Hc#kcF)m0y1O5paq;LV`TJU-X`D>j|HTPqXsDL^~Ff)r3%KI*8# zlaqI$)HO*LJgaQ$JC9e6&n^xDr2<-3*Hfd)JB$4N6R>qa=`&K`O4eup|4KGeDxIt9 zLiCVN0l(j$qks}14-p1tW@s^1PTUN;)yV~(H9Fe17hjxV+y49&*)#z&3dkq4Sp+O9 zf04EdkFyh127IPLt_ay({YWrxZM+YST?g}AXm|uZ1$;i=s1+!4O~Heeb(r9}VFb7u zc=1`TFc*4G;O+Vv)g!BE0&3RRb0wA{=TVBBAA1IZ)nOVu>#(zVHIDziPs{qO37-O9 zuU9t|N^lWwrjrsW$@OV6i3fx>$i-qMI;1$A}R#yU5`aG*o4t8Nj z^C~oV9X0~buK**UrGO1~)K09!P2tRbCGRp}`SU%$VRy?q{Fyvyb;4$`kKiZZeS_U-={|<;R0l5h)QgK!ysrfjdj;l{ti+7aqHOzP?cWmk zwIoWK7d*cLE|)7WjY=~I?PX%XP7U0ddBlLz0p!Ql&#}LC2NDC>H!?Zta8_hFR!!W3 zug*M+6_sz|NZZ%gdv=2v@S`UnxzqH}LJ_=22#Ub_)4ezt--RD8Z9~_E86|d3W$W6fOC=(XB?!%tVFIz9BO1}_A)LBKqJJFgvg`g0_Man`Kdrv^HIFTZCbuK;y!>gy znqO$xfG#TIiNr>_vlld8wOM!+FoRB~Z4cFbN9AQI=cpv*ZPmV!v5y>X=0a3_RM?Jf ztUk3eOS6x9?7P?%D!p>|VMMfmvF8jpJEbr}V@ZJdduo`7>@`3}2VP*j?TX|z*E$U_~Q()f4y!#5cfvc8Vy^00000NkvXXu0mjfKIZ#0 literal 0 HcmV?d00001 diff --git a/src/pt/blackscans/res/mipmap-xhdpi/ic_launcher.png b/src/pt/blackscans/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..03373237cc9838712f9a8570fb2e2b3973de060e GIT binary patch literal 3823 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 literal 0 HcmV?d00001 diff --git a/src/pt/blackscans/res/mipmap-xxhdpi/ic_launcher.png b/src/pt/blackscans/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..41df90443c60e7a6525d108b49ec26c9c5b58ec2 GIT binary patch literal 6898 zcma)BRZ|-buuX8+;sFAsSaEk!T#6Mf#jQXoZb3?Lw<1M@yGwDW6f0ib5?qVB-S6IC za3A*U%)XqN-JLnJdm=T}74dPXaR2}SzOs_shyQZI{{|Muf4Hl#(E{t|_`;(1R)2*4T#qi@E6$(B7y7<|~8%qQE*Y`&0QgPH7vGJd>zm>>7{tX+B){-{_zIXq((yE)1lJYZAX{#_WFtGpp{JhwL z;Y(TJ?MtK3=JV?CX_lWzy<=|CXn1CGl3&|H`Pu|mc(;?BxI^DXRaaLR3rXa!46?U+ zM?H@Z-yzT-B?_>(1Tlw_)l|OxMO}ivroyo@VXXLq zpQbW0GI+_z$mW}yn&44%5f*t`n2JzFUg215C@EBgDmh75QI7(w5Z;Q5j2Mq9(u7e_MoP!IvV;-*w_gDo^yg%N^wr7RrKap z@sZ;tu2P$}k&2!ifSK07}zy*@Qn$9kpiXsn(6g?Yx=Y?qSplO#hJ zIL92z6)m;k%{Husuz9%mvAf1(@rXQ9qII^m%PMVdZpIjG z6yFa;gXDiYSxR=1AVQyHd}e^D{Enq*UaNuLLm6U5G3!Cd}c@Z`u6azT2vwPK2&sE%>~5S@|Uy`X)LT`YeEp1%-Kq# z^Qdh-II=!>EhJHG3yIkn2o&%qA;N<+So37(4Ka%8qQX@{_9N?+{V{Fp%R1X^d$B&v^$c}X@_C6)7KD% z;pEo#Sx&c@oJVa9n7x0;2^Z8f_2fxb_}$m^?`Li6mpAU$$FS;W0^5^Soc4z$h0th| zcPG;;9y0JU9HHS?m%%*-sX51ddi?Iv{z2frqJsQhluKF=K2Q`>7id3I`j*bNCl>o zn*hbE86%%R9{u;ju*BdSuaV{pW}21{kp({=oND}S)u!{aCH2NVh7aOSO%<_S)huIS z=8Qt$Td>{%b~%p9HBvDDyk1o{oM3`H z79PK8aXKEDj0HBSOJ+H|O2aHKFSoer)9KYp-2BDH&Sg3XRyQdFOB00N74ejL6M#f^ z#Cb{{u?}CV!#6ibuXosigf%a`9S#0e6^hIiGzWZX`yeBjPDiqSIu9(xFigqh)p%7m ztxXCY0Xn5{Yg>A9beYlDeM8jdN-=Cqnopp5WK9r>Jxm8i8Ar9!&6K!Zgd2Z^?Qssu zq9YnmVtL<+K>&$Q&iTPdP>ArCqw*m!?Xf(p3EEz!r_<$7haPzla6>ABjgFz)J_;>7(SDu)gKD>+QJ ziqhCkUzwgPy|i|N2Sv&^NCMDmE1Jo^HJ_s`EOpvU0F-PXarxTT)==M8xLxf=B2J6D z5Q>h(C>@oX4CA4%7Bz0$_Jy|DShZK!w5xgZDCSO}v#7Wy_xsty(xFgnx{o0F8o_J& z3r>;NYr`*phQy38qCngX5L8s`mI5T`w(vNh+Xyg>SG{Bf4OP`6pq*g40L-Y8_fpL` zg&g$l!#gI-R!M6ckq)sle!Lzh30cg5u5Y) zv(Q5;fA7j5LS_vxM1Z}sd^1*(CYKvk!VyBg{iAm(>4l5{c=f|3K z#b495r=`g(F#H=@N>WRkZIkL3Ag<7!A4qGQHN;uFw&!O^vr`h#zX>Go{UN*R`c zeX~`5$Dw6DEXE=_h)sYT@A$_Vr@)MjyIVcDUXQYyGqP?#%9HTYv_d0TSHzO{iF2Wb zKL|=ujGFLgA&XfRooDe$1SXOayXG;*CQhQB?J1coudR@-$n5GqB#-B7tJp*m~y-yol8HR9W{ z9YlKHts~JQaO2B6qO#sAkP!*@Y)+|&d_B0@^N(|NtPfjOe!cd2@(@L$b^r6}L23~k zsB*v{@!#-v3*~3s*o&hs|5mNz>KQ_vX)6uklu*l>0LTmq3o zPV9H1R#qBLyz2cTjrSY|5@#fLD?5pfiOcz-TqoHhNczm`U}>kW#Sv3tlI9&QzyDTX z=Mv3rx@>5~%Ib7dymFKIg(i+GhhWOj5NU9BTDDK!@c>xqyk@*L8{{t*y1>PR@L9H& z!ISiK^_W@OO{mMloHRNKuB&eqU+3&DSf*W84}X;Pq}!M6&(zPxi_Jc%>x`Gp4hEK1 zR{qiE{xkNZ5+tQB3`UjpG{s5Xx9qiKF~;V1#wNEDHqKk*LnqvBsJ?hXjE7z1Ref$K zpi3JwyapCpY$bYX9iES#rD3dBr+L1STv`8jk<6)~_w zQw4pug2{O(neYczhNG3DpO`c}IT-Mu`;D|D`)CPQ6 zFDKCxoxi#GJYcVExkh-6Mhl*_XdHi;a@3)a@%sr`ufx4Bfu?@$lcj_>)>kR} z47JR7!VY7$+%c#bnbWp9tpwfQbJ-{xT--%7ggcmUqZy681v0qqNj4Ml_3Jz1Q6zey zU~T}LoEa{97_qDMbGVvHr_jYnPSlh*MNVng{qs@a~fA5#|3v$p0@sG<~^JOez7(d z(27D^Mt6{AW}JS_&vZub9B@1*XyApAVs5u z+Y)|@4Ew$e->`8?B@B_bA-IWiC0AGM3L zJx`w_M-_0J9AW@|u66h>ZWkjE4cZUgm&9KWCOfXNLV-IAn)4M@P#V06Cwatp^3Gb3 z!c_cjw@ah3DRwQRJbX$)XJ1Wc+wu3_mdB$lj8N@IDb$%xX<&hUveY|E;#UYccbcvz zYu|--X-~G3S&yb$(U#t0Xt)h^SI3=R*2zWA$Y~)r}Fi04G(QV%kwJ-z5NZGteElp_d_KBVM;d zF=xe1z0OO{glko3b$bZKg1;=@o}A7#Vdl1XyP*y784p*h=0v>`Eobqu$KOz^qmzMxP$S;aH(QU<)z79*x)q7mlnG>t`&>Mw1xN}eL3pMV} zvmA5xHe`N_6&G}Jb~mjL*YY%${oLyft^pKjqjC26yN+?6$?rw(WN>E6mzC|QUK-S3 z+HQUy@5-JG%Uo)57w#GVXY=Tf>*%^{rM8mKR(MT|Qe}>og(2QmOLv2s`Sl8Czd&|Y zZ70cam(=)rZ{|HR(*Fv zt`_x-}i&~jmy+xGz`kD_QqP+NPLkVfLbrofxc z$k_Q9>P;#~50wC{;eS9ak`4?GPbvm3!t{si@$Qun~Z!zp+n%5jo=&-zoDmA)_xSxGEo&| z^mLX?rYS6COlnh}Uo=%GV(ZPtLG4z*9b0;*DfT_JusDL8{`O&f*I9I>J1!%p$U-3f zz40&*Ycl(m-P+rH>_6EI-pvfat)kp~bU4|5y&>WwS?932y>~2TK$JOM7X2I)9r#!Z zIRW>T}aca$piTBluthlHNP+od9XXyzfv<& z-;N@#Hr0EP%O~`_Y3^+^4ha6784#?^pciXjuCs|32a46s{^TX@lUpY%?`MAD7u+APn4&l~lYF~2XI1N8 z5vO(N|0ZQU@ZEK|IJ_aFeAYHiP9>%vC^KiZIL7e1e7vk3A4tvbzQ5T-fvgtXwS=r; zUKL>))|eHi9topqxy`Gz)F4R~S{`2OAC4eCD9Ebu_ySZ)(uN0211}CwdL|t0w@;aR z^GyDlHmzdTY`%qMORDMpFlsKF4s`%IuDTCbDk}aG{VTD$>dX*F&)Iw+Q?N%d)(uLLHva*6MEk)<>v=@tl|I6IM(prK%c!=4Q3!b5Cs;zEL+j-KO$UaWB2c=x)If)N z@n&vi@9#-pp=~KP8eu|t-SlkuD~W<+a@W46pPGq^8u!G%A-8kcZ5y{WxS#j5^!?s+ z@f${0XgjPtc`3@fj+m>YUZWOR2Mm6K;Z-9qT$XbX3`SVy`X@q%PJ(B5A`qV{L1a#b z!@W+rLaX$`9o|SIVx2Ig)!H=JMgA&v*M87s%eP7c0oXMJHD;Lu?-#;y5IwsDf=u2Y zdI35H2DV%g>U!QL1JY*mw_K{jnOz2fxXNp2YI}BKwRX8>a7T??Ht-XzFcF~WIc`A>asZaat2G`}w7avKB9NoLgd-`72mF)ED znYW}qLrosSV%O}@j+pP`-(VqmDm-A?cnxG6T#a&hlEm>G9ubw;s+rKC(&d?Mc!ZTD zz3J%i4P&rsDB#2Uzww>FEG|pYZzHvqwk@Z15)}sQ^lg?jw~xOP8mbw$318Fo5)U^J zg2^^p*c4eh?WyBHYMyUMZHrBN60opiCIhzDC^LdwIiaX{7cW$bAdoZ-TCwsAj6`2_{trw3y} z-b2g({R`}4E}n6WBaI=O@~>WNnW_1X&CKDL=A5D)iq|!}%;gg*dIR}@vE}C4WTTzU zQ5^~CngY0%@bynlJIfDEGOGHoePX%Z>amS*HU>k|-ot~qbS_F54h~MtO`izHSjZspP3@0pK)!i6XUiVxm>s#KY)XCm@Z^yy zb<^I_7we_<2JdUs!hAm#L6;fVEnREfEgdU~g4`ePJb_j+iDFRa>C%z%p|YX9#Z`my zQ&cOJNU=NT>9o}CtP5)MqzA2=-3SFBJWwCajWN%8P#LF?xZ%kO8ZV7}} z-}9S89O;bi5&(#wl-%YR`UvG2Hgt%;GHffSpC?uwrU{Y*Xo2L2Qos;J#Khrg)<%&K zGhS(CxT6^N75=*=W{!T1Ge0s7Vu<#IJU|QZ6$CDCz$#=TATeQu=i~%%C|u}J8vgnS zMR(Q?n;BCSHpYrMDZ=_IaV(d)8iO3HFWhA~k?rJ0i9j$=6$LLJEoAbZ%e=zX(k55b zaA$p%K#x7w4JmuSvdaB>f2Sf-T{#m;k)Kj!`!!uLNg5k;&=!qIpY_x7@BlD!%dtQi zrjoIpbYj6{^7Zku5#)#~Wl(%!egHSXTe;#xQ^H7suwCy3>ZRC3-dCxfb-S zdD=Y%D}MVZa{Hy}`P#o^w<3QjYfi22zpC9|d0TirlwlD`83xNu0^}uSu!)7v*Y&^7 z;3~RRoG;z_DF@*MldMG`^478G+EP(j4c4&G#IW(iu)zn#q>#%bbzthL#K`F$3e)r= zLwzt4BCi{pYD&j7^N-nV&Z?Kj6{L(Pl36w84r{^S=e31qI}1tgPur!C-Mk!`INjQ; zT4H=GRylrVAA@}5hPg`>AGXw8;-U+bgjLc-^Lkm!@WI2*7~4zL(g&@c-v!0hHy{<*H@Og8m1a*;V`i literal 0 HcmV?d00001 diff --git a/src/pt/blackscans/res/mipmap-xxxhdpi/ic_launcher.png b/src/pt/blackscans/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..8e355c5c3fe4ce29b74008b4cce809b58cb65660 GIT binary patch literal 9450 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 J#cPX@{{db!T8RJv literal 0 HcmV?d00001 diff --git a/src/pt/blackscans/src/eu/kanade/tachiyomi/extension/pt/blackscans/BlackScans.kt b/src/pt/blackscans/src/eu/kanade/tachiyomi/extension/pt/blackscans/BlackScans.kt new file mode 100644 index 000000000..d908b87af --- /dev/null +++ b/src/pt/blackscans/src/eu/kanade/tachiyomi/extension/pt/blackscans/BlackScans.kt @@ -0,0 +1,179 @@ +package eu.kanade.tachiyomi.extension.pt.blackscans + +import android.annotation.SuppressLint +import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.network.POST +import eu.kanade.tachiyomi.network.interceptor.rateLimitHost +import eu.kanade.tachiyomi.source.model.FilterList +import eu.kanade.tachiyomi.source.model.MangasPage +import eu.kanade.tachiyomi.source.model.Page +import eu.kanade.tachiyomi.source.model.SChapter +import eu.kanade.tachiyomi.source.model.SManga +import eu.kanade.tachiyomi.source.online.HttpSource +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.decodeFromStream +import okhttp3.HttpUrl.Companion.toHttpUrl +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.Request +import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.toRequestBody +import okhttp3.Response +import okio.Buffer +import rx.Observable +import uy.kohesive.injekt.injectLazy +import java.text.SimpleDateFormat + +class BlackScans : HttpSource() { + + override val name = "Black Scans" + + override val baseUrl = "https://blackscans.site" + + override val lang = "pt-BR" + + override val supportsLatest = true + + override val client = network.cloudflareClient.newBuilder() + .rateLimitHost(API_URL.toHttpUrl(), 2) + .build() + + private val json: Json by injectLazy() + + // ============================== Popular ============================== + + override fun popularMangaRequest(page: Int) = GET("$API_URL/api/series/", headers) + + override fun popularMangaParse(response: Response): MangasPage { + val mangas = response.parseAs>().map { manga -> + SManga.create().apply { + title = manga.title + thumbnail_url = "$API_URL/media/${manga.cover}" + url = "/series/${manga.code}" + } + } + return MangasPage(mangas, false) + } + + // ============================== Latest ============================== + + override fun latestUpdatesRequest(page: Int) = GET("$API_URL/api/series/updates/", headers) + + override fun latestUpdatesParse(response: Response) = popularMangaParse(response) + + // ============================== Search ============================== + + override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = popularMangaRequest(page) + + override fun searchMangaParse(response: Response) = popularMangaParse(response) + + override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable { + if (query.startsWith(PREFIX_SEARCH)) { + val mangaCode = query.substringAfter(PREFIX_SEARCH) + return fetchMangaDetails(SManga.create().apply { url = "/series/$mangaCode" }) + .map { manga -> MangasPage(listOf(manga), false) } + } + + return super.fetchSearchManga(page, query, filters).map { mangasPage -> + val mangas = mangasPage.mangas.filter { manga -> manga.title.contains(query, true) } + mangasPage.copy(mangas) + } + } + + // ============================== Details ============================= + + override fun getMangaUrl(manga: SManga) = "$baseUrl${manga.url}" + + override fun mangaDetailsRequest(manga: SManga) = + POST("$API_URL/api/serie/", headers, manga.createPostPayload()) + + override fun mangaDetailsParse(response: Response): SManga { + return response.parseAs().let { dto -> + SManga.create().apply { + title = dto.title + description = dto.synopsis + thumbnail_url = "$API_URL/media/${dto.cover}" + author = dto.author + artist = dto.artist + genre = dto.genres.joinToString() + url = "/series/${dto.code}" + status = dto.status.toMangaStatus() + } + } + } + + private fun String.toMangaStatus(): Int { + return when (this.lowercase()) { + "ongoing" -> SManga.ONGOING + "completed" -> SManga.COMPLETED + else -> SManga.UNKNOWN + } + } + + // ============================== Chapters ============================ + + override fun getChapterUrl(chapter: SChapter) = "$baseUrl${chapter.url}" + + override fun chapterListRequest(manga: SManga): Request { + val payload = manga.createPostPayload("series_code") + return POST("$API_URL/api/series/chapters/", headers, payload) + } + + override fun chapterListParse(response: Response): List { + val series = response.request.body!!.parseAs() + + return response.parseAs().chapters.map { chapter -> + SChapter.create().apply { + name = chapter.name + date_upload = chapter.uploadAt.toDate() + url = "/series/${series.code}/${chapter.code}" + } + } + } + + // ============================== Pages =============================== + + override fun imageUrlParse(response: Response) = "" + + override fun pageListRequest(chapter: SChapter): Request { + val chapterCode = chapter.url.substringAfterLast("/") + val payload = """{"chapter_code":"$chapterCode"}""" + .toRequestBody("application/json".toMediaType()) + return POST("$API_URL/api/chapter/info/", headers, payload) + } + + override fun pageListParse(response: Response): List { + return response.parseAs().images.mapIndexed { index, imageUrl -> + Page(index, imageUrl = "$API_URL//media/$imageUrl") + } + } + + // ============================== Utils =============================== + + @Serializable + private class SeriesDto(@SerialName("series_code") val code: String) + + private fun SManga.createPostPayload(field: String = "code"): RequestBody { + val mangaCode = url.substringAfterLast("/") + return """{"$field": "$mangaCode"}""".toRequestBody("application/json".toMediaType()) + } + + private inline fun Response.parseAs(): T = use { + json.decodeFromStream(it.body.byteStream()) + } + private inline fun RequestBody.parseAs(): T = + json.decodeFromString(Buffer().also { writeTo(it) }.readUtf8()) + + private fun String.toDate() = + try { dateFormat.parse(this)!!.time } catch (_: Exception) { 0 } + + companion object { + const val API_URL = "https://api.blackscans.site" + const val PREFIX_SEARCH = "id:" + + @SuppressLint("SimpleDateFormat") + val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'") + } +} diff --git a/src/pt/blackscans/src/eu/kanade/tachiyomi/extension/pt/blackscans/BlackScansUrlActivity.kt b/src/pt/blackscans/src/eu/kanade/tachiyomi/extension/pt/blackscans/BlackScansUrlActivity.kt new file mode 100644 index 000000000..3f2b02e16 --- /dev/null +++ b/src/pt/blackscans/src/eu/kanade/tachiyomi/extension/pt/blackscans/BlackScansUrlActivity.kt @@ -0,0 +1,37 @@ +package eu.kanade.tachiyomi.extension.pt.blackscans + +import android.app.Activity +import android.content.ActivityNotFoundException +import android.content.Intent +import android.os.Bundle +import android.util.Log +import kotlin.system.exitProcess + +class BlackScansUrlActivity : Activity() { + + private val tag = javaClass.simpleName + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val pathSegments = intent?.data?.pathSegments + if (pathSegments != null && pathSegments.size > 1) { + val item = pathSegments[1] + val mainIntent = Intent().apply { + action = "eu.kanade.tachiyomi.SEARCH" + putExtra("query", "${BlackScans.PREFIX_SEARCH}$item") + putExtra("filter", packageName) + } + + try { + startActivity(mainIntent) + } catch (e: ActivityNotFoundException) { + Log.e(tag, e.toString()) + } + } else { + Log.e(tag, "could not parse uri from intent $intent") + } + + finish() + exitProcess(0) + } +} diff --git a/src/pt/blackscans/src/eu/kanade/tachiyomi/extension/pt/blackscans/MangaDetailsDto.kt b/src/pt/blackscans/src/eu/kanade/tachiyomi/extension/pt/blackscans/MangaDetailsDto.kt new file mode 100644 index 000000000..14b6cb167 --- /dev/null +++ b/src/pt/blackscans/src/eu/kanade/tachiyomi/extension/pt/blackscans/MangaDetailsDto.kt @@ -0,0 +1,44 @@ +package eu.kanade.tachiyomi.extension.pt.blackscans + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonNames + +@Serializable +class MangaDetailsDto( + val title: String, + val artist: String, + val author: String, + val code: String, + val genres: List, + @SerialName("path_cover") + val cover: String, + val status: String, + val synopsis: String, +) + +@Serializable +class MangaDto( + val code: String, + val title: String, + @JsonNames("path_cover") + val cover: String, +) + +@Serializable +class ChapterList( + val chapters: List, +) + +@Serializable +data class Chapter( + val code: String, + val name: String, + @SerialName("upload_date") + val uploadAt: String, +) + +@Serializable +class PagesDto( + val images: List, +)