From 1b1cc537824edaf94a9308f9ce09c3a7e5901d1f Mon Sep 17 00:00:00 2001 From: E3FxGaming <8276268+E3FxGaming@users.noreply.github.com> Date: Fri, 12 Jun 2020 10:19:58 +0200 Subject: [PATCH] Adding source Manga Mutiny (#3498) * Adding source Manga Mutiny Webview doesn't work. Reason: it's an HttpSource based on an undocumented API - it's not based on web scraping Credit: - the concept for the Filter was taken from the MangaPark extension and changed to fit the circumstances - the JsonObject extension function stems from stackoverflow * MangaMutiny - multiple fixes Moved mangamutiny to /src/en removed "open" from class changed if condition --- src/en/mangamutiny/build.gradle | 12 + .../res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 1279 bytes .../res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 930 bytes .../res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 1706 bytes .../res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 2628 bytes .../res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 3749 bytes src/en/mangamutiny/res/web_hi_res_512.png | Bin 0 -> 23780 bytes .../extension/en/mangamutiny/MangaMutiny.kt | 391 ++++++++++++++++++ 8 files changed, 403 insertions(+) create mode 100644 src/en/mangamutiny/build.gradle create mode 100644 src/en/mangamutiny/res/mipmap-hdpi/ic_launcher.png create mode 100644 src/en/mangamutiny/res/mipmap-mdpi/ic_launcher.png create mode 100644 src/en/mangamutiny/res/mipmap-xhdpi/ic_launcher.png create mode 100644 src/en/mangamutiny/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 src/en/mangamutiny/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 src/en/mangamutiny/res/web_hi_res_512.png create mode 100644 src/en/mangamutiny/src/eu/kanade/tachiyomi/extension/en/mangamutiny/MangaMutiny.kt diff --git a/src/en/mangamutiny/build.gradle b/src/en/mangamutiny/build.gradle new file mode 100644 index 000000000..a2939eea2 --- /dev/null +++ b/src/en/mangamutiny/build.gradle @@ -0,0 +1,12 @@ +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' + +ext { + appName = 'Tachiyomi: Manga Mutiny' + pkgNameSuffix = "en.mangamutiny" + extClass = '.MangaMutiny' + extVersionCode = 1 + libVersion = '1.2' +} + +apply from: "$rootDir/common.gradle" diff --git a/src/en/mangamutiny/res/mipmap-hdpi/ic_launcher.png b/src/en/mangamutiny/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..994f934780842c9184058061d360977b55634305 GIT binary patch literal 1279 zcmVJPT8#ivYZ*IivFx-13$K&7+-m{kje1ME26UcSshRwJx&V5|OQm`bsV-$IY zfWvquVzVSkd3`M>cYFZF+y95ONporJBpgScX=zbxB?v{X{X%@tSSP%pr)qAau6LT;c8~(uMtgJJkuP#v>5Gp!|M6q*5tZ zU0sE~zCKH1lI$;0&L5p!&>9Nuub{QHHQ3tPk|b4BR9F(U(sdeMBPqFH_Hl4L=d)7_9pvXeIc(mk)zT$G+xmO zA}Eu>;jkq^GTDhq$gQoL5)>43PFgWeQ3|5VZEkMP@am=|DAU~o*&7q^@wsz`C**4= zXGJ+iu?iwKH#cEsW(I0&Yj^(Cakcs!vm~7tm_*MRxOP0LSpq0IfJ-^ad7Ur0m<16V z8yk|OXf&!_|KRdFGBN@yPoJvg2xt`=#??(vk|d|;7%b!KwE7pdAf=@IOrp#oIaDHS zzIdT4NR~9BAxX|0Jvp`zBuk=+Tb`4s`lcc@p$9EG)>*f)*DSr48p!a;T_$iK|>%C%~8Qy{|4JH7>hf@pZNnL@U+M(2(wN zl0$p9^R2D$Mko0Gx;pqK(V{DfP02+qXmD^4LU?i{N^3hp^-(+?hn`qW zS5O}onYBJ2eA}XyL~=oZB?q#pUn<=mTke?|_ASWW-Y0ClQDdc;6Z%b;J7vm!>X%VG;64M>~EOfrzC|#8&Pqpi$a|kUAuRoIu{OIVVIc2ayA=J^Bw1pGZaer-Hc6 piHcZ!uK%IA9RfFQ+_>4I{R40j#f)T@!hrw)002ovPDHLkV1lHTOO5~l literal 0 HcmV?d00001 diff --git a/src/en/mangamutiny/res/mipmap-mdpi/ic_launcher.png b/src/en/mangamutiny/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..2576992625025364c48544408d09f80df1ce959e GIT binary patch literal 930 zcmV;T16}-yP)m&=%G=L{s)Z-fdmq{k{A;M8V(jD zk!VPOi^d}X!bzh*dK`EPRcpGvP2_W;F3D7JyEfVa_TL|ck+lWa` zfE7y)@|m8rii9|`O0#@H?6Rz3%}iepAdB>*kPbe1mf;&xCd;ZQa1dG0slXwv0(u>R z!-jw%UD8!{p?oCJC=7!s}``oWj?h?rxZ#o(2)OV})?{)R?q5dcYA3uRtv$LuKB>YtjKj-$qQf=Md34}r+Nn&bh z3Y<=7Oaa1=(`R6&w->}Hx6q&4MuhhskJNw91sLPw=;ACzt zB+82$_b=z?L%>tB**9(igt4(PsV3MAL&A4;b-~Yj{xAW;i^?jguoKy=hUZ+u@E^B? zkGlYqAS02Hks*a&TU&!){rwRFgqKvp5+ytr0m8(@1PlxeNa4wTGy%d)RW)>$lqiPh zCLl*mAQo{GSYBR+_4W0L@MM;nzjHS%)FOsjK$HT1s;T88FfuX%?d|Ol3- zIOUSQ#VIL#1;~3uB8xt}sR^+8-;UetiBlH>a?}Lm7y|!|KvPo_baZrV;`Mr^Us_6` z+*qKU__WIKVR5HN>6?Qe!q&bwN}S+8DdRV>Az%pXT;QMnpCtUx!Of4-l)CH8O$TYY%BHEYaaxiZkq*B*P?|%N*6XJM&m}K zBqqAEHA*dMw=R5;E^GqjX$Z!ovA{4O!azU2?{W?d!whq0=1@D_?@NAxlso5U{=a+f zIp+@aXc`w67Z(>77Z(>-T$L5EF*?@A8N56x*Z+`<-S2w`l8YQd4w{rhA_GT=jFcOu zdJ5@629O7c2bmRL&4hf<4@4GSA{%WddV;ii1Q|kr2?}NNg6f_iZDt_%#fg>>AF{&e z_(Ud@%`oCp*%M?V-Qonx$Robmx9~`0L*IX(N`RbRB_el4<0~9?NMts@BWVE{#&q@5 zi2t`}e3gR^iOlAq7%yY)1@vNz7+Ab4z_5UMBqS&eqAt@3-xrs_fglnn{9CtfL1Sa1 z(sSA@7C7s4!cQ-j#gBlYp&^)^oz*2ICMGHi<24Lo`s69-D=C5feiCH(%gf8q)YPOj z{MVf>7(HGI_mQ{~u)4Ym)6>(?-rlZE0tuK!0iIJea1$lCvE7`U96fxW&!?YLl>iFA z9>X8T;JtXhxD-Il%*-g0AO%n$bI9$|qj0CU7gj|0ss!layIe3L!jEeKguETaIwtrF zkStud0KTy?SY26BBETx{`J;Z}$GrezZf*`*TU)_yw<{H}CgI|`gjfVvkXLb_pQxpP~CabE0w!bR`5KBu-(A?Y%Hk&Qtkj}cE z4k{%{20?|K1&D`pCxuKX3T zxQbSQlt4Wp7u%JO7e*os-xLDmm~i>>W$5ec3;OeD1W10sG2voX7K|Afa7`;99I*(H z<3hBrWdRBVcv%1ocp?PQ;2Jo<8e#GJjU5v(XC?ttQ&Vv5+BN;*oYC+H2M6J!h6eD2 z5zt#$1izG(8xEeHEqzsV1bzVo17T)DDoOqiUUgqoTfu;A)d9v6uKDWL)-+&fmW>7M^Z;YRo@z)wO? zPmlgt0S(f0=q5hBA~T1kpr{erkft1&^poHdU5;7H zLWVyj2H-tNf(ii^A%MEnd2s^1;)C-i^0vrokH}6*(XMb#B;Rhgzl2}EMn<)@?fe$R zsJ~z`NW?ApeLcU)XtTwGjSTwI3gKdxDxYwgEf*#H0l07*qoM6N<$g7sel A4*&oF literal 0 HcmV?d00001 diff --git a/src/en/mangamutiny/res/mipmap-xxhdpi/ic_launcher.png b/src/en/mangamutiny/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..9e7f7e2e85d2f648830e6e3907f9983fde4d2144 GIT binary patch literal 2628 zcmaJ@X*kKPLWG)5JCs^e9U(LtYwT+*wT8At+E+zTX-g$7#Rx4S_O%_R zOoiHJN*StUf~u{S=vazkXl<=GI?wxMKD_5S_nzN#&iQc8z4!N=%W%NsBp@&d000tJ zmRKjgO+Q>mg!%jYh1o^`fQVUP&0HvBE0csPvLlKjk+ItEd;(#!Hs*1RODz}Ses37g zLV+@t>JA91S$ttJhTh0K;X0W7>6A9c)gp}HtmsR>xcaHzSn)v4>G@6r?)iY_P)gZ)i;_GWd?#InHM>nl>N7< z^Gad@-_a?#v`sbAKw{9q$plvnl}E5GVkY2D88E$i-H+NkX`tyLi&^t>`r^yMz2i)? z-g)LY^FWn7*RXlffx1x#vL7H(-Z+1?a-`RGpvR^auvB1NT%hH6PRWEtT!ztkzyB2Y zZoo3w5Y#c@D0ur!TiO#GtHn!ZF)QxjhU(hf>0%A0hqb*AD}GxjT2Yb^YJ0=t^YR|| z&#X!M`yE%#PO z6_|-LB~tEhO!H23=pVuCh|y!WA8+a}%Oh_T$#+~r&^F)>$(uuRn0>XQ)^GrQhIX#3 z!Xg4ph0qYkFg`%yoLu2a03Asy1`+`%7;^*wLHT+JQ~^N@Uk?F4bm;#Ez?kbGq1$Ht zQ+?))vTj-V69O27z*s{#%UWHU-IfzP^UH2XOw(OqaQTh4%1X=d(K?Ia;o%sQ)zq|X zlL?xn^0`ti-9cbhYF+gS2REX2HiCyICYDDZ+KBd(;ILu1 z#u6d|lPsm;R$pJg^gKzd=MIJJK}m7gqo`6x1w%VOE6oxAo|%BAq|DCG=c{rXj-Ee7&#DUz!v#hY2D3RS9km)>Zq z_O&~TKxhM^$b9Dtd{uU~y!%l_5cz9;gL9O-Yn7UrZ28o7YwYLh4)FyJ-Q22<&5X9ja$qVd?WB|lf$BnX=`5&FoOYJj&yEWB&zFP} znUchW{aw`1(85B?dXp%%o-oudNw@x=#I&*J08fo(>CGH*1su2(*(Fi(W`kpR;qnxz!F!_Pfx@$q&T7d z>$6LYZe>$fQ{SmbQYMsk6`)_+-3;r7ei!`^MRGe2N9BlgR%{Q=sTl9fwJ2Zy9wiDo ziKA_Xl=xuzgl+0DK6j?j+a$yK z+2~6F0p^oU)F?;V*%3;2E;LD=L09N&_fkgyb)s~IH}m}koR-l)DA!jfszQSNx+RgX zJ%|s+2%cezj#bNN>`zNe0i%MY9jw$4`}LjMj_jBaan`NtpfK#Dyd<&3YWv4?<8`-1 zXiDHx6nuPatWN7;%&U&%(>z{2P%1@S)Dr6XwZqt7MhY+z{6k!=>)P~hAOk}~!;eq! zAgRs#wAc%&ujn)|NNbJ#mpF;AcR{WKfyf zY`tFBwY6!psFks&DQRTb02+HIr&9Auc(NkR7#w8$f)mwKVzQBZ{6qhH2y|Z0OJ?gSI(YAj7|j?6GHeoLe)xyL-?)9qFIdX&gdj+7w1<1yRmM;Kl4|=rLlcV%9U@O!S{bwMXLZ!z{1-nfjz7*+s}fUDR{PV zm0^u%iHXOce-&9}us@->*!)XX(+k7m5BWYzsn4Fx&4&&G%vcOA4dMF4!B}lSie8K~#1jdvV$&dG0fQK zAPqRe*FymPr@TYJ4;}iyfta@-^l5EL%#KuOK8t3)5g^)Y2lU2b{2bm`+jm3&kluT) zP9_;fL)!#8CqbiZ8HIO zv1B+P${v@-UGYdM(%H!fs)dM&nU)+FT5FeZ3GP5r@YtgwB}?UFKPgbQ5BxF_**5k* z0tr|QaWP?{N#@G>jlQtCsl}<|OhWNj$yuwA zGLhpGGE1+tD{(FJgKB7k7FxX7Xzv(N)z?P*hLqS+Np`&sGtM2ga+)S{g?^{FjYVKd;9Rq}!c z6XNMH;q<% literal 0 HcmV?d00001 diff --git a/src/en/mangamutiny/res/mipmap-xxxhdpi/ic_launcher.png b/src/en/mangamutiny/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..edf0fe9310f9d0e66c7bee9e6c9398b964b00706 GIT binary patch literal 3749 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 F{sn9KVgLXD literal 0 HcmV?d00001 diff --git a/src/en/mangamutiny/res/web_hi_res_512.png b/src/en/mangamutiny/res/web_hi_res_512.png new file mode 100644 index 0000000000000000000000000000000000000000..c160cb69133d0dc2a39f35bb5408503feed60b79 GIT binary patch literal 23780 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 z z7~8R|47#FvDJ*O4B30Co3l0UCsq}*Kvf||4vFR?%Eor+g@Qa6|RnGi#atlqB^AMUs zILB`Tml|?EcIFN;sq0SKKi4jfj5FialMUlkYD968wS5Bft^Td8y=Y2M+b@u*?D~9k>E6Tc!Cy#S$VvX$5C_&CoR5gnl!t+Zwh!`F^ic7Wr7h zA{r_tClcP(p+z$eElDSQzFhfbE4T888^}X%4~_RVG#eC!Z%5rA9OY(Bo;R34q`MoQcNTVC2kBO+EB6!6!{t>SM$n1PNuGTp;fbmMvf-RS^ zB`Psw8J8BgA3#*t?5jEZ=hCgPZO@T$MPo$?pmy%4b&RxskNtOst(ks3aYIo~Zj(=} zV-_80?A$|PS!g8*(4ACxOW_SUtlb&q^Wa2zc{&Ju@qPPwVPko-X|S%6_l`55&;80P zoQ>UJ@ix!x#K-hZMj5vmkWv?_GV&hO`VkBeynG*v{9JUj)KrZLgosz6s{GjF>XrRD z@I@aD&TocAAAcl^g%7%4jaL^kG^9dr{8s-RL*nOR44%Z@rNr=1; zE10Tt25hOD)uN2-wv0cVWpweHP2aT8v|+|DP$K2f$o0#*XM)R^GCw`forwY}@=Bu? zwZ0qi36~y}yVv}ZZ}PF17g$AOkF7a=P9@UFxp#lr6NLno{Qqt^U@;D*&}mI3Xf|Du z5qH)F_7Yq@$}1iv$MYz;(h+tXA@6lTVbkqT&u$^42|^QAOPn5si)BB5VV==yYk`@n z$?y}YJ>~=D-+4g$^IFIp@OxdTATH-*22iz=T@H}vjg-eZ*T>IzO@G5fYCqh(LUMAx zl9OI?v1Fx`*ZiQbNrColA;0{i6F za7w@jH=#z0;u;BqLD_mq3`MyDUa?ZRTa4t~b)B0ig9dx>7>Fu5uA@8n!F*E`cPM)H zt}#fsS0%}Njzs?a_M4rvzLv6eUY1pA-ibB|U#A;^!$0g2HuqpmWV#vD!W0~ZPx`Ur zir5xD()^XT6^fo`A8#{eIoAo~?6S0*zhDNYN}iJey&oWJS%ilE3DodxgYMRsjrGlu z2>*yz=B3f>=McR6UWVkU(F=t8Ll^#7;0MMQWQ;7o=r1H$nph=1?BB0xdA+bL$& znL2VPd%1eOu6oLE_4WE+f#{<+wj3M#JyT~Ecb-MqxJG(4dt93VwqWuFjfoAmnB;|HXh#6&O#e-&_* zc8jd`4=^b_o$La(MN(`Xrwrg`WSXlI2dw~m>1Ocy8mo?;A<0-=s=RFm`G!Hu2IMne zr&l^_ROlzWF}$`08U|rf!vnRC?q6%4lD>a$;q7fQ_Jk?_nn+5U02wJhA4=dmti+Oc5 zW6q+@Bo5n|n$qIk7?iyI4i_aIblA*~*wlBto!OM#!Qd{avzyhM5NliopE2V}*=b=i z`#pQ=AL0+?3Jk#oW!K&Y&$adH^mco@e3GFFV5K_ydHQVu%~+RYUO|ULrabLD{POU< z>Uk_dCK10pq$j3GS71N)?CTax@3Y0S3G>FY*%kit6;HmSl0=DrRWq(CeLhK!*>n>; z^u)T<*UitE#9Kw{amGR;p=FY#wA)h0E%8aPOPt$zM0PCKjR%4?1dNLXj&0yBpgDgn zwxXM%7o);Nxn*AJUwkvY@+Jqx=?fi`loeh2NH&>Qc_T^`{=O`#&fos9?q0)$qH*RY zjZeV(1zh>i?y|?Q;Ko97^PI(hdcFN7iL+Ltp;K3V_Lu=^o4NDhuRAG9hNu$y42i zL>zC2t=R8of5&DxVp37TZ18s>=sk!=Yu6b0Ua+;G#k*XXq+EBOXpp=6W9iH-=-&EQ z(}s~?Tl-aYV-k@T^+8lHXnM5eR&8Z%9fh;T { + val chapterList = ArrayList() + val responseBody = response.body() + + if (responseBody != null) { + val jsonChapters = JsonParser().parse(responseBody.charStream()).asJsonObject + .get("chapters").asJsonArray + for (singleChapterJsonElement in jsonChapters) { + val singleChapterJsonObject = singleChapterJsonElement.asJsonObject + + chapterList.add(SChapter.create().apply { + name = chapterTitleBuilder(singleChapterJsonObject) + url = singleChapterJsonObject.get("slug").asString + date_upload = parseDate(singleChapterJsonObject.get("releasedAt").asString) + }) + } + } + + return chapterList + } + + private fun chapterTitleBuilder(rootNode: JsonObject): String { + val volume = rootNode.getNullable("volume")?.asInt + + val chapter = rootNode.getNullable("chapter")?.asInt + + val textTitle = rootNode.getNullable("title")?.asString + + val chapterTitle = StringBuilder() + if (volume != null) chapterTitle.append("Vol. $volume") + if (chapter != null) { + if (volume != null) chapterTitle.append(" ") + chapterTitle.append("Chapter $chapter") + } + if (textTitle != null && textTitle != "") { + if (volume != null || chapter != null) chapterTitle.append(" ") + chapterTitle.append(textTitle) + } + + return chapterTitle.toString() + } + + private fun parseDate(dateAsString: String): Long { + val format = SimpleDateFormat("YYYY-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH) + format.timeZone = TimeZone.getTimeZone("UTC") + + return format.parse(dateAsString)?.time ?: 0 + } + + // latest + override fun latestUpdatesRequest(page: Int): Request = + mangaRequest(page, FilterList(SortFilter().apply { this.state = 1 })) + + override fun latestUpdatesParse(response: Response): MangasPage = mangaParse(response) + + // browse + latest + search + override fun mangaDetailsRequest(manga: SManga): Request = mangaDetailsRequestCommon(manga) + + private fun mangaDetailsRequestCommon(manga: SManga, lite: Boolean = true): Request { + val uri = Uri.parse(baseUrl).buildUpon() + .appendEncodedPath(apiMangaUrlPath) + .appendPath(manga.url) + + if (lite) uri.appendQueryParameter("lite", "1") + + return GET(uri.build().toString(), headers) + } + + override fun mangaDetailsParse(response: Response): SManga { + val manga = SManga.create() + val responseBody = response.body() + + if (responseBody != null) { + val rootNode = parser.parse(responseBody.charStream()).asJsonObject + manga.apply { + status = when (rootNode.get("status").asString) { + "ongoing" -> SManga.ONGOING + "completed" -> SManga.COMPLETED + else -> SManga.UNKNOWN + } + description = rootNode.get("summary").asString + thumbnail_url = rootNode.get("thumbnail")?.asString + title = rootNode.get("title").asString + url = rootNode.get("slug").asString + artist = rootNode.get("artists").asString + author = rootNode.get("authors").asString + + genre = rootNode.get("genres").asJsonArray + .joinToString { singleGenre -> singleGenre.asString } + } + } + + return manga + } + + override fun pageListRequest(chapter: SChapter): Request { + val uri = Uri.parse(baseUrl).buildUpon() + .appendEncodedPath(apiChapterUrlPath) + .appendEncodedPath(chapter.url) + + return GET(uri.build().toString(), headers) + } + + override fun pageListParse(response: Response): List { + val pageList = ArrayList() + + val responseBody = response.body() + + if (responseBody != null) { + val rootNode = parser.parse(responseBody.charStream()).asJsonObject + + // Build chapter url for every image of this chapter + val storageLocation = rootNode.get("storage").asString + val manga = rootNode.get("manga").asString + val chapterId = rootNode.get("id").asString + + val chapterUrl = "$storageLocation/$manga/$chapterId/" + + // Process every image of this chapter + val images = rootNode.get("images").asJsonArray + + for (i in 0 until images.size()) { + pageList.add(Page(i, "", chapterUrl + images[i].asString)) + } + } + + return pageList + } + + // Search + override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = + mangaRequest(page, filters, query) + + override fun searchMangaParse(response: Response): MangasPage = mangaParse(response) + + // commonly functions + private fun mangaParse(response: Response): MangasPage { + val mangasPage = ArrayList() + val responseBody = response.body() + + if (responseBody != null) { + val rootNode = parser.parse(responseBody.charStream()) + + if (rootNode.isJsonObject) { + val rootObject = rootNode.asJsonObject + val itemsArray = rootObject.get("items").asJsonArray + + for (singleItem in itemsArray) { + val mangaObject = singleItem.asJsonObject + mangasPage.add(SManga.create().apply { + this.title = mangaObject.get("title").asString + this.thumbnail_url = mangaObject.get("thumbnail")?.asString + this.url = mangaObject.get("slug").asString + }) + } + } + + responseBody.close() + } + + return MangasPage(mangasPage, mangasPage.size == 20) + } + + private fun mangaRequest(page: Int, filters: FilterList? = null, query: String? = null): Request { + val uri = Uri.parse(baseUrl).buildUpon() + uri.appendEncodedPath(apiMangaUrlPath) + if (query?.isNotBlank() == true) { + uri.appendQueryParameter("text", query) + } + if (filters != null) { + for (singleFilter in filters) { + if (singleFilter is UriFilter) { + singleFilter.addToUri(uri) + } + } + } else { + uri.appendQueryParameter("sort", "-rating -ratingCount") + } + uri.appendQueryParameter("limit", "20") + + if (page != 1) { + uri.appendQueryParameter("skip", (page * 20).toString()) + } + return GET(uri.build().toString(), headers) + } + + // Filter + override fun getFilterList(): FilterList { + return FilterList( + StatusFilter(), + CategoryFilter(), + GenreGroup(), + SortFilter() + ) + } + + override fun imageUrlParse(response: Response): String { + throw Exception("Not used") + } + + private interface UriFilter { + fun addToUri(uri: Uri.Builder) + } + private open class UriSelectFilter( + displayName: String, + val uriParam: String, + val vals: Array>, + val firstIsUnspecified: Boolean = true, + defaultValue: Int = 0 + ) : + Filter.Select(displayName, vals.map { it.second }.toTypedArray(), defaultValue), UriFilter { + override fun addToUri(uri: Uri.Builder) { + if (state != 0 || !firstIsUnspecified) + uri.appendQueryParameter(uriParam, vals[state].first) + } + } + + private class StatusFilter : UriSelectFilter("Status", "status", arrayOf( + Pair("", "All"), + Pair("completed", "Completed"), + Pair("ongoing", "Ongoing") + )) + + private class CategoryFilter : UriSelectFilter("Category", "category", arrayOf( + Pair("", "All"), + Pair("josei", "Josei"), + Pair("seinen", "Seinen"), + Pair("shoujo", "Shoujo"), + Pair("shounen", "Shounen") + )) + + private class GenreFilter(val uriParam: String, displayName: String) : Filter.CheckBox(displayName) + + private class GenreGroup : Filter.Group("Genres", listOf( + GenreFilter("4-koma", "4-koma"), + GenreFilter("action", "Action"), + GenreFilter("adaptation", "Adaptation"), + GenreFilter("adult", "Adult"), + GenreFilter("adventure", "Adventure"), + GenreFilter("aliens", "Aliens"), + GenreFilter("animals", "Animals"), + GenreFilter("anthology", "Anthology"), + GenreFilter("award_winning", "Award winning"), + GenreFilter("comedy", "Comedy"), + GenreFilter("cooking", "Cooking"), + GenreFilter("crossdressing", "Crossdressing"), + GenreFilter("delinquents", "Delinquents"), + GenreFilter("demons", "Demons"), + GenreFilter("doujinshi", "Doujinshi"), + GenreFilter("drama", "Drama"), + GenreFilter("ecchi", "Ecchi"), + GenreFilter("fan_colored", "Fan colored"), + GenreFilter("fantasy", "Fantasy"), + GenreFilter("full_color", "Full color"), + GenreFilter("gender_bender", "Gender bender"), + GenreFilter("genderswap", "Genderswap"), + GenreFilter("ghosts", "Ghosts"), + GenreFilter("gore", "Gore"), + GenreFilter("gyaru", "Gyaru"), + GenreFilter("harem", "Harem"), + GenreFilter("historical", "Historical"), + GenreFilter("horror", "Horror"), + GenreFilter("incest", "Incest"), + GenreFilter("isekai", "Isekai"), + GenreFilter("josei", "Josei"), + GenreFilter("loli", "Loli"), + GenreFilter("long_strip", "Long strip"), + GenreFilter("magic", "Magic"), + GenreFilter("magical_girls", "Magical girls"), + GenreFilter("manga", "Manga"), + GenreFilter("mangamutiny", "Mangamutiny"), + GenreFilter("manhua", "Manhua"), + GenreFilter("manhwa", "Manhwa"), + GenreFilter("martial_arts", "Martial arts"), + GenreFilter("mature", "Mature"), + GenreFilter("mecha", "Mecha"), + GenreFilter("medical", "Medical"), + GenreFilter("military", "Military"), + GenreFilter("monster_girls", "Monster girls"), + GenreFilter("monsters", "Monsters"), + GenreFilter("mystery", "Mystery"), + GenreFilter("ninja", "Ninja"), + GenreFilter("office_workers", "Office workers"), + GenreFilter("official_colored", "Official colored"), + GenreFilter("oneshot", "Oneshot"), + GenreFilter("philosophical", "Philosophical"), + GenreFilter("psychological", "Psychological"), + GenreFilter("reincarnation", "Reincarnation"), + GenreFilter("reverse_harem", "Reverse harem"), + GenreFilter("romance", "Romance"), + GenreFilter("school_life", "School life"), + GenreFilter("sci_fi", "Sci fi"), + GenreFilter("sci-fi", "Sci-fi"), + GenreFilter("seinen", "Seinen"), + GenreFilter("sexual_violence", "Sexual violence"), + GenreFilter("shota", "Shota"), + GenreFilter("shoujo", "Shoujo"), + GenreFilter("shounen", "Shounen"), + GenreFilter("shounen_ai", "Shounen ai"), + GenreFilter("slice_of_life", "Slice of life"), + GenreFilter("smut", "Smut"), + GenreFilter("sports", "Sports"), + GenreFilter("superhero", "Superhero"), + GenreFilter("supernatural", "Supernatural"), + GenreFilter("survival", "Survival"), + GenreFilter("time_travel", "Time travel"), + GenreFilter("tragedy", "Tragedy"), + GenreFilter("video_games", "Video games"), + GenreFilter("virtual_reality", "Virtual reality"), + GenreFilter("web_comic", "Web comic"), + GenreFilter("webtoons", "Webtoons"), + GenreFilter("wuxia", "Wuxia"), + GenreFilter("zombies", "Zombies") + )), UriFilter { + override fun addToUri(uri: Uri.Builder) { + val genresParameterValue = state.filter { it.state }.joinToString("+") { it.uriParam } + if (genresParameterValue.isNotEmpty()) { + uri.appendQueryParameter("genres", genresParameterValue) + } + } + } + + private class SortFilter : UriSelectFilter("Sort", "sort", arrayOf( + Pair("-rating -ratingCount", "Popular"), + Pair("-lastReleasedAt", "Last update"), + Pair("-createdAt", "Newest"), + Pair("title", "Name") + ), firstIsUnspecified = false, defaultValue = 0) +}