From 9092d6f1af04fa6deb8dce2614347c3e83dd625e Mon Sep 17 00:00:00 2001 From: Claudemirovsky <63046606+Claudemirovsky@users.noreply.github.com> Date: Sat, 23 Jul 2022 17:33:56 -0300 Subject: [PATCH] New source: HentaiYabu (#687) --- src/pt/hentaiyabu/AndroidManifest.xml | 24 ++ src/pt/hentaiyabu/build.gradle | 18 ++ .../res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 2093 bytes .../res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 1320 bytes .../res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 2890 bytes .../res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 4763 bytes .../res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 6528 bytes .../pt/hentaiyabu/HYConstants.kt | 10 + .../animeextension/pt/hentaiyabu/HYFilters.kt | 275 +++++++++++++++++ .../pt/hentaiyabu/HYUrlActivity.kt | 42 +++ .../pt/hentaiyabu/HentaiYabu.kt | 291 ++++++++++++++++++ .../pt/hentaiyabu/dto/SearchResultDto.kt | 26 ++ .../extractors/PlayerOneExtractor.kt | 30 ++ 13 files changed, 716 insertions(+) create mode 100644 src/pt/hentaiyabu/AndroidManifest.xml create mode 100644 src/pt/hentaiyabu/build.gradle create mode 100644 src/pt/hentaiyabu/res/mipmap-hdpi/ic_launcher.png create mode 100644 src/pt/hentaiyabu/res/mipmap-mdpi/ic_launcher.png create mode 100644 src/pt/hentaiyabu/res/mipmap-xhdpi/ic_launcher.png create mode 100644 src/pt/hentaiyabu/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 src/pt/hentaiyabu/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 src/pt/hentaiyabu/src/eu/kanade/tachiyomi/animeextension/pt/hentaiyabu/HYConstants.kt create mode 100644 src/pt/hentaiyabu/src/eu/kanade/tachiyomi/animeextension/pt/hentaiyabu/HYFilters.kt create mode 100644 src/pt/hentaiyabu/src/eu/kanade/tachiyomi/animeextension/pt/hentaiyabu/HYUrlActivity.kt create mode 100644 src/pt/hentaiyabu/src/eu/kanade/tachiyomi/animeextension/pt/hentaiyabu/HentaiYabu.kt create mode 100644 src/pt/hentaiyabu/src/eu/kanade/tachiyomi/animeextension/pt/hentaiyabu/dto/SearchResultDto.kt create mode 100644 src/pt/hentaiyabu/src/eu/kanade/tachiyomi/animeextension/pt/hentaiyabu/extractors/PlayerOneExtractor.kt diff --git a/src/pt/hentaiyabu/AndroidManifest.xml b/src/pt/hentaiyabu/AndroidManifest.xml new file mode 100644 index 000000000..648a5d4ff --- /dev/null +++ b/src/pt/hentaiyabu/AndroidManifest.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + diff --git a/src/pt/hentaiyabu/build.gradle b/src/pt/hentaiyabu/build.gradle new file mode 100644 index 000000000..4cd8d1083 --- /dev/null +++ b/src/pt/hentaiyabu/build.gradle @@ -0,0 +1,18 @@ +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply plugin: 'kotlinx-serialization' + +ext { + extName = 'HentaiYabu' + pkgNameSuffix = 'pt.hentaiyabu' + extClass = '.HentaiYabu' + extVersionCode = 1 + libVersion = '12' + containsNsfw = true +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" +} + +apply from: "$rootDir/common.gradle" diff --git a/src/pt/hentaiyabu/res/mipmap-hdpi/ic_launcher.png b/src/pt/hentaiyabu/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..3bba6f76df26f1f6253470c61eb47af07ec5c3d2 GIT binary patch literal 2093 zcmb7_dobHw8pnT9iThiWr9@E@s=SS`8WALQOIr83(-M;OO-ZRni&B@qw5TF3aVuK4 zCae0Q4M9+)Y)fytsuwNMYJ%`m_h|d(ot@d4ot>T8o%5XYo%1~3&pdyebLM1uy1OXJ zYsmuuphUnsdP@}l=ahv=R$oz@i$tVP;oNWl(2}RHLj+6qdJ%YUHvmY413>Dp0I)4d zr3wHb4gmmjVE}+G1ptkh%1$qgqyPy&=Hdwa_;b|o8Ve;E89KquNoH0?LwT3JtdrCy ziRT-^5$6;CR#ZuIRTJv;rC4+=EVTCF5?H1R3-W5HHP5D#Q4vc=2gk#CiNc)M_d*et zcgEp95wTQpJweWD<&L^r;)U@?c9h^r@g$r=eS|YTeI7dF#GhiKf04^biP9zAg z*s^k`Ok>r4st#RADodbL{n(kc|2py%^DG^!r!4Dd>dja)#j1G9PB3i*PO9J}UG;x7 z#Uj($X_v7|`3eC{v8+ZGNRB7a3 zQaU5qE@*8y=i}g-574n zvbC*^dir$#=h(B$e5a>3Y+NW5xOii!k8iHXTC(a~S} zGZdh9Nu{)R9AeuW)VW#3Gwl^RHs{0I-*J<+kf)wi!L)K!bA|$<56zTSHYQLvec`Y4 zLZ380(0^ApzW)`8_V9qs=KQCNJH%Cw+nGmOys>Q?#@SIbd9^9ip*JgD-Q9xI_N08F zbX@85NLF#;EWe$o2g@BrU#6dEY;9!-h16}a*gE!;EDQ#NqGD3Z%e9(Axc!+*+9T(1yEr^I}l0M56xd<`XlIanASY)F50dM(3pG5kTd{V9%vtrCPqBXb(CA9Dq@w&)yze>o@8ks~- zKR@T-U~K~f1E~F_%7OwFiRDxqX{^ER9*3i<2-&NnL;kkCR>WjR+z%pnc({yNDvs71 z=Fi-ivS*EMW4@OWk#~gM*2}x$_w}?ZKgTa*;PIq@m-(=)b(VXOJtk*pakh9Rbh@Q0 zYu*In%$L?iqqkqmfvygQ3p%e8HE*-CM=1_oYMEEAWI5M{@DhuI+t1u&o3Pops9Fp| zmAs*rpgY5@*9>8cDw1OzANR9#Gtg8FzaNw}G}A_7Wj?OnMe7b&-L+0xsyl?n`{cc7 zU2imQ&Fxw~8|5u;;S9~cI@jWOZCkPYrtR~;P42m0mu^TXx5WmQ$YmVaOtOO;8CfT9 zTXMNv$6BxMlS@&&i|=rJq_0}W&Q6lmnfF&;&)4_#RK0&6!e+B68Alnvn*KecBC)z_ zS+42{tA21JcqQtMPhIn8Bi$X>n7A&Lq~%qtmddEY^Xb;9$uc;O}gG1u8KK z49UF*rS(N|a`W=`bzUR-Cvu}-XE=%d#js)*n z@~rACS!d0^_ce-7>8z;M(A}?G9Y&%kR#f(fMP0Rh6UzU*LQx}3*H8O%_byK7F1K&F zf7sWRT$B+AkbpD38CBU>} z^339Ut^*4C=yR->kI%s7CW^=7)z#JIGnqqEQ+nkMUY?#oZ=eowsUj59xCAg=hgeMINH z<57q7#>yWIk7)KxC_^CGQMDt}xWkH&2!{!B#_fGGV;t!AEjyoxb+2&9ghB}3ig=!( z`J}z+p|{pbFRgp|)l#m=BPwu?6W-^q5tn5qlTxuTHOZQ%XLgpDWvZJAoI6f&9h7@# zN0rlE|HmlxcwU|NBfj#Bnyryt)Rbdc09r;}L$OHYIgSS}DKO|9eMF z@c?uZyd0={yn%VKU*xT!``en=s9o=4*j8#Z#ubaaOyvOfpemTTO}tZz908=>q0kN9 z(Td+778mN!NZ@R#!}*=5B0nvNGW>J+{`0s#&D;*>O mjQ`bvPNk90(TTK}|70x8|JlSXQaNA300bv@$L1qp>3;x&Nw*vT literal 0 HcmV?d00001 diff --git a/src/pt/hentaiyabu/res/mipmap-mdpi/ic_launcher.png b/src/pt/hentaiyabu/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..74d6e197113f0a26294e6d5cbc8ec503bd2bf023 GIT binary patch literal 1320 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sEa{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)pT}UnMXwSj}Ky5HFasE6|34fhjb=C&U$~fQo>Zm)G0d zn}vmim6g@U$45m~MSz9RS-^^sfl*3IYWno)=H}*da&qG0;)aHXe0+QY0s=}(N_u*F z`T6-#QBj(jnmRfN4yS3LG*$N|gpYS|Y51+{~Op zEc~pDtP&CuTefWJ>FJp_Z=R{C>BNZ>Crz4EQ&W?bl{J6<{FyUn78e(lE zF;$%fa@b2eeO=j~v5N~ZD?js2I02L{_jGX#@i?BGAhD)lV&_bTge1qHbEl4-JLt(! zP*Aw}km-hx9zu*2I}=|;?&t{A*F4EyEGo=iC{^)eq0|h^&dUl47ON6Nn7^8Oc%D9R zH1(j5WhIBdV<6{jwp7tjQ_oUfU)@|;-&kAST4rbEWMR)><6>@a?QH32>uO`w5MI7M zzjJ!)^4`hKi@RsHukIgXqvJuvg^3RZCk9?L+*tULv(s~h)TH2`%a@Fe?rz#tT=bbq z_7gW(cbB)<=~LQTt5;=bz1DgqEp>6ulciH{Ub(aA;;n1<9^Sus_3q`{*Xx7Qs$<~v(?Th0wD z>%!aLWLF&ACCs5({+6w2?xeO!ZPw-Q?`$rgKPhF>rGL!qs;d05K~@Db0&Fy7Ev>dp zI<}(CaY5q?F4vADTHX;XVJ8be3oVWd;R$?O^!X!)0E5k;q(>g6rri5m6zUG>A2Ntw zWKf;);I_pwP8VRTsFt`!l%yn{G%7)Sv;kp(HamwYVfPw*XU*u`$GwTVEJ=0`)L>y85}S Ib4q9e0B3ZXVgLXD literal 0 HcmV?d00001 diff --git a/src/pt/hentaiyabu/res/mipmap-xhdpi/ic_launcher.png b/src/pt/hentaiyabu/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..c511591b4f5ce6a0757eb05ac1616bd875dd8c39 GIT binary patch literal 2890 zcmb_ec{J4T8vh#GWN8$UrA!zmTVs$l`-B)VD8?_QY=g3nM6yRSmh5E9meHV4mMj^{ z5+fwJim^t>P8v;hr+d%2=iGD8{p;TIp7(vu^SsaJJfG)0?>X;>Xl-T6&m+bI006(a znF)qvaep?Li*?TBhG?=3ho>Rh5CH1#^D?h;vV5qk83qjiVX^=a6$bzZtWeY!00>3^ zzzPlkv~vMK#J`}$MwfNLbi$Soqk4uinEe*yrHn7N6e z-K~#ng+AA9$4^irUyi5D%UBhJfRiqR1uA(I__E9g`>@ty4aHm^-4JJqhGRrXjo5dL zS9RISS$m@&!@{x`_M;o~TRu3M0o zY013b|}1|vEk?J~BXQG$QtZ!@;*tF+~lV2`tGLN`!LH>AJ2(Af*c6&@dg zi`L96N#AGQ!kpMFbLc$rX79H8<_vyrp*q*X3j6Vm=O;7~2L=K54i7Qgse z9O88=?dyk13Tfi{NgF!MBHP;0@lBq(&)l!J>$b9y3gHi2JoHso?hsLvo(9g&Cr_U~ z4L)_g!SHN;vXWC{t@jw^$Y(!4Kl00$MT?7z&HA?Ll}V~gxJ&E5!i-(pIMvb80$_w| z4<8RN@ABGOw{O$vr%${lF!V#c!k8Ek7Z(>EkEhOW;gApDii+j!?S)Kcxa`HEr14c& zu5?^+b93(JfgIO5huTkT&l?-xjf`}bn`h)|2g?g5-d$Yu5EB_9pKxZYzYo3|4HiMZQ|!(r!S>MfUdO_^%n&kPH$vqPoS)HwF#hM*d! z@-3n-DIZMX@e6VbslJx;bH(|^!csOWs)I;kinZKYXVr97F*yn`jg81CDpF37(2`nN zUA;TyD}qL&OKWP-ZNCmyyROxNQ8up+_Ex(YJ4+~A+YG#y*O4Fl8zQ6Riz1GWj&n1e zvDY@}?WH9phRsvH0gP?;y3idDmB?S=Bg4Z`Z5xpsp(lbBT$dAAegOu z<$|FhThP+mN2R4PvD}dQ>k~+Md3m_J{I$>hS#VO!pvU~nAM5jDmtEYuNypxQ_<(VC zPO0!}+wND`-P^OVx9@HVUah21N*fxon&@GP_4Ua9{{GEdx|umSuE+=0_F3=W+tDgG ztab}a@h7I>3PPk4rNAeN$7mipIK_WOS_O4FRLaL z8{=q>3)=CiZrzl+VF(#od@7}XDuE-GD5Ng>8QUxrYedR3iMiG?FRi<7kxHRR=-fy}8+%L_;Mi-+)kKQ+sa~j@!v;`qV(CRo)0mZUF@~yQCCl&`FJ6FAJXx z1xM}c$TNPH?^!lj%7g`we(|edrClaL0E<;#1)BhvL%;~9CibSkzYDL1!D26HN}PQE?Banz0djDmu2j|0TX`KlpYp2vIgV(53->4Cz{g!w|!tY+8dRU@RsMedh;)v90tQkhp(n?~eo@R>Y zZwv~cqC=WRs`6;G^2ZKiZrL8^Vg@tgfpj6>s=(~6(f8bQB>PFvs8YCwL^r9lm?A$m zHuiPmSwe%)c>S%dYhAMlEiEnG-^?8e{Rn1!Jy$GSY$q$55F9*vvo-W!nS5GVx#G!_ zlvfE5Th@^6?T-m3a%Q|S!C>BP4t{J})tL;6QRu8%kZ}uqz9a*fhFNX8eK_iz|Bd@V zN{<%L!S&qmUDBn=SeFrztvbaZm7w&*T2b3NIFb3tUA!nYr-eRBNVv@y%}gf5x0u_} znz^vG6myzoUcaQAey?XcS#u&JyBK_jtVvO!KSb|#N=$3o#tE?a**G~R4txedg?MHI zUsP6Ay;|MF*xJU9E|+(7NG81M%=dd~9vrORi4%A_ZgJy=l5dmvy%dNQIjFh%)hu;s zCt#5#dUNe#H@*F~myb_bYis^gYsfR#-oul=8ix~NqodidSgd9QQ}goE^Gge?VX&Ub z7jP)!N7j`%RIWwzfZ9O;AD->)?!%?z4^3KYKS1L+UZv=>tVf0C4f}FZW%d?F-0~}%x11Lbv1ie4(~~n!TdRU4Fua~BlOnv;)6CTG-4$I&-ru1eqoaS zXUJ-0_PS||+VA1?gloa;8DULwi+89e_`CL{F1qXY#2@m}8VSk1GhUIokJQ&>Q$HuS z$?-I>enXLN-9#TGzJXX#Lpu_8B68@1$5pm@MgK2XTk~$ZbLHf`_>a z*c;i-fWD;(r)b=IU=lJhVCuWOD6M_vce>4Sf7m~?n3+s^EA=;s2i))wBOBa*w8bl7#`xQC22TjBqi32cB6z_y7O^ literal 0 HcmV?d00001 diff --git a/src/pt/hentaiyabu/res/mipmap-xxhdpi/ic_launcher.png b/src/pt/hentaiyabu/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..88515b652609f4d01a1aea4752d5dbe96d0bc4cd GIT binary patch literal 4763 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 + ) : AnimeFilter.Select( + displayName, + vals.map { it.first }.toTypedArray() + ) { + fun toQueryPart() = vals[state].second + } + + open class TriStateFilterList(name: String, values: List) : AnimeFilter.Group(name, values) + private class TriStateVal(name: String) : AnimeFilter.TriState(name) + + private inline fun AnimeFilterList.getFirst(): R { + return this.filterIsInstance().first() + } + + private inline fun AnimeFilterList.asQueryPart(): String { + return this.getFirst().let { + (it as QueryPartFilter).toQueryPart() + } + } + + class InitialLetterFilter : QueryPartFilter("Primeira letra", HYFiltersData.initialLetter) + + class EpisodeFilter : AnimeFilter.Text("Episódios") + class EpisodeFilterMode : QueryPartFilter("Modo de filtro", HYFiltersData.episodeFilterMode) + class SortFilter : AnimeFilter.Sort( + "Ordenar", + HYFiltersData.orders.map { it.first }.toTypedArray(), + Selection(0, true) + ) + + class GenresFilter : TriStateFilterList( + "Gêneros", + HYFiltersData.genres.map { TriStateVal(it) } + ) + + val filterList = AnimeFilterList( + InitialLetterFilter(), + SortFilter(), + AnimeFilter.Separator(), + EpisodeFilter(), + EpisodeFilterMode(), + AnimeFilter.Separator(), + GenresFilter(), + ) + + data class FilterSearchParams( + val initialLetter: String = "", + val episodesFilterMode: String = ">=", + var numEpisodes: Int = 0, + var orderAscending: Boolean = true, + var sortBy: String = "", + val blackListedGenres: ArrayList = ArrayList(), + val includedGenres: ArrayList = ArrayList(), + var animeName: String = "" + ) + + internal fun getSearchParameters(filters: AnimeFilterList): FilterSearchParams { + val searchParams = FilterSearchParams( + filters.asQueryPart(), + filters.asQueryPart(), + ) + + searchParams.numEpisodes = try { + filters.getFirst().state.toInt() + } catch (e: NumberFormatException) { 0 } + + filters.getFirst().state?.let { + val order = HYFiltersData.orders[it.index].second + searchParams.orderAscending = it.ascending + searchParams.sortBy = order + } + + filters.getFirst() + .state.forEach { genre -> + if (genre.isIncluded()) { + searchParams.includedGenres.add(genre.name) + } else if (genre.isExcluded()) { + searchParams.blackListedGenres.add(genre.name) + } + } + + return searchParams + } + + private fun mustRemove(anime: SearchResultDto, params: FilterSearchParams): Boolean { + val epFilterMode = params.episodesFilterMode + return when { + params.animeName != "" && params.animeName.lowercase() !in anime.title.lowercase() -> true + anime.title == "null" -> true + params.initialLetter != "" && !anime.title.startsWith(params.initialLetter) -> true + params.blackListedGenres.size > 0 && params.blackListedGenres.any { + it.lowercase() in anime.genre.lowercase() + } -> true + params.includedGenres.size > 0 && params.includedGenres.any { + it.lowercase() !in anime.genre.lowercase() + } -> true + params.numEpisodes > 0 -> { + when (epFilterMode) { + "==" -> params.numEpisodes != anime.videos + ">=" -> params.numEpisodes >= anime.videos + "<=" -> params.numEpisodes <= anime.videos + else -> false + } + } + else -> false + } + } + + fun MutableList.applyFilterParams(params: FilterSearchParams) { + this.removeAll { anime -> mustRemove(anime, params) } + when (params.sortBy) { + "A-Z" -> { + if (!params.orderAscending) + this.reverse() + } + "num" -> { + if (params.orderAscending) + this.sortBy { it.videos } + else + this.sortByDescending { it.videos } + } + } + } + + private object HYFiltersData { + + val orders = arrayOf( + Pair("Alfabeticamente", "A-Z"), + Pair("Por número de eps", "num") + ) + + val initialLetter = arrayOf(Pair("Qualquer uma", "")) + ('A'..'Z').map { + Pair(it.toString(), it.toString()) + }.toTypedArray() + + val episodeFilterMode = arrayOf( + Pair("Maior ou igual", ">="), + Pair("Menor ou igual", "<="), + Pair("Igual", "=="), + ) + + val genres = arrayOf( + "Ahegao", + "Anal", + "Artes Marciais", + "Ashikoki", + "Aventura", + "Ação", + "BDSM", + "Bara", + "Boquete", + "Boys Love", + "Brinquedos", + "Brinquedos Sexuais", + "Bukkake", + "Bunda Grande", + "Chikan", + "Científica", + "Comédia", + "Cosplay", + "Creampie", + "Dark Skin", + "Demônio", + "Drama", + "Dupla Penetração", + "Ecchi", + "Elfos", + "Empregada", + "Enfermeira", + "Eroge", + "Erótico", + "Escolar", + "Esporte", + "Estupro", + "Facial", + "Fantasia", + "Femdom", + "Ficção", + "Ficção Científica", + "Futanari", + "Gang Bang", + "Garotas De Escritório", + "Gender Bender", + "Gerakuro", + "Gokkun", + "Golden Shower", + "Gore", + "Gozando Dentro", + "Grupo", + "Grávida", + "Guerra", + "Gyaru", + "Harém", + "Hipnose", + "Histórico", + "Horror", + "Incesto", + "Jogos Eróticos", + "Josei", + "Kemono", + "Kemonomimi", + "Lactação", + "Lolicon", + "Magia", + "Maid", + "Masturbação", + "Mecha", + "Menage", + "Metrô", + "Milf", + "Mind Break", + "Mind Control", + "Mistério", + "Moe", + "Monstros", + "Médico", + "Nakadashi", + "Nerd", + "Netorare", + "Ninjas", + "Óculos", + "Oral", + "Orgia", + "Paizuri", + "Paródia", + "Peitões", + "Pelos Pubianos", + "Pettanko", + "Policial", + "Preservativo", + "Professor", + "Psicológico", + "Punição", + "Raio-X", + "Romance", + "Ronin", + "Sci-Fi", + "Seinen", + "Sexo Público", + "Shotacon", + "Shoujo Ai", + "Shounen", + "Shounen Ai", + "Slice Of Life", + "Sobrenatural", + "Submissão", + "Succubus", + "Super Poder", + "Swimsuit", + "Tentáculos", + "Terror", + "Tetas", + "Thriller", + "Traição", + "Trem", + "Vampiros", + "Vanilla", + "Vida Escolar", + "Virgem", + "Voyeur", + "Yaoi", + "Yuri", + "Zoofilia", + ) + } +} diff --git a/src/pt/hentaiyabu/src/eu/kanade/tachiyomi/animeextension/pt/hentaiyabu/HYUrlActivity.kt b/src/pt/hentaiyabu/src/eu/kanade/tachiyomi/animeextension/pt/hentaiyabu/HYUrlActivity.kt new file mode 100644 index 000000000..b78eb49d5 --- /dev/null +++ b/src/pt/hentaiyabu/src/eu/kanade/tachiyomi/animeextension/pt/hentaiyabu/HYUrlActivity.kt @@ -0,0 +1,42 @@ +package eu.kanade.tachiyomi.animeextension.pt.hentaiyabu + +import android.app.Activity +import android.content.ActivityNotFoundException +import android.content.Intent +import android.os.Bundle +import android.util.Log +import kotlin.system.exitProcess + +/** + * Springboard that accepts https://hentaiyabu.com/hentai/intents + * and redirects them to the main Aniyomi process. + */ +class HYUrlActivity : Activity() { + + private val TAG = "HYUrlActivity" + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val pathSegments = intent?.data?.pathSegments + if (pathSegments != null && pathSegments.size > 1) { + val slug = pathSegments[1] + val searchQuery = HYConstants.PREFIX_SEARCH_SLUG + slug + val mainIntent = Intent().apply { + action = "eu.kanade.tachiyomi.ANIMESEARCH" + putExtra("query", searchQuery) + 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/hentaiyabu/src/eu/kanade/tachiyomi/animeextension/pt/hentaiyabu/HentaiYabu.kt b/src/pt/hentaiyabu/src/eu/kanade/tachiyomi/animeextension/pt/hentaiyabu/HentaiYabu.kt new file mode 100644 index 000000000..4a0e320e2 --- /dev/null +++ b/src/pt/hentaiyabu/src/eu/kanade/tachiyomi/animeextension/pt/hentaiyabu/HentaiYabu.kt @@ -0,0 +1,291 @@ +package eu.kanade.tachiyomi.animeextension.pt.hentaiyabu + +import android.app.Application +import android.content.SharedPreferences +import androidx.preference.ListPreference +import androidx.preference.PreferenceScreen +import eu.kanade.tachiyomi.animeextension.pt.hentaiyabu.HYFilters.applyFilterParams +import eu.kanade.tachiyomi.animeextension.pt.hentaiyabu.extractors.PlayerOneExtractor +import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource +import eu.kanade.tachiyomi.animesource.model.AnimeFilterList +import eu.kanade.tachiyomi.animesource.model.AnimesPage +import eu.kanade.tachiyomi.animesource.model.SAnime +import eu.kanade.tachiyomi.animesource.model.SEpisode +import eu.kanade.tachiyomi.animesource.model.Video +import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource +import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.network.asObservableSuccess +import eu.kanade.tachiyomi.util.asJsoup +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.json.Json +import okhttp3.Headers +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.Response +import org.jsoup.nodes.Document +import org.jsoup.nodes.Element +import rx.Observable +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get +import java.lang.Exception + +class HentaiYabu : ConfigurableAnimeSource, ParsedAnimeHttpSource() { + + override val name = "HentaiYabu" + + override val baseUrl = "https://hentaiyabu.com" + + override val lang = "pt-BR" + + override val supportsLatest = true + + override val client: OkHttpClient = network.cloudflareClient + + private val json = Json { + ignoreUnknownKeys = true + } + + private var searchJson: List? = null + + private val preferences: SharedPreferences by lazy { + Injekt.get().getSharedPreferences("source_$id", 0x0000) + } + + override fun headersBuilder(): Headers.Builder = Headers.Builder() + .add("Accept-Language", HYConstants.ACCEPT_LANGUAGE) + .add("Referer", baseUrl) + .add("User-Agent", HYConstants.USER_AGENT) + + // ============================== Popular =============================== + override fun popularAnimeSelector(): String = "div.main-index > div.index-size > div.episodes-container > div.anime-episode" + override fun popularAnimeRequest(page: Int): Request = GET(baseUrl) + + override fun popularAnimeFromElement(element: Element): SAnime { + val anime: SAnime = SAnime.create() + val img = element.selectFirst("img") + val elementA = element.selectFirst("a") + anime.setUrlWithoutDomain(elementA.attr("href")) + anime.title = element.selectFirst("h3").text() + anime.thumbnail_url = img.attr("src") + return anime + } + + override fun popularAnimeNextPageSelector() = throw Exception("not used") + + override fun popularAnimeParse(response: Response): AnimesPage { + val document = response.asJsoup() + val animes = document.select(popularAnimeSelector()).map { element -> + popularAnimeFromElement(element) + } + return AnimesPage(animes, false) + } + + // ============================== Episodes ============================== + override fun episodeListSelector(): String = "div.left-single div.anime-episode" + + override fun episodeListParse(response: Response): List { + val url = response.request.url.toString() + val doc = if (url.contains("/video/")) { + getRealDoc(response.asJsoup()) + } else { + response.asJsoup() + } + return doc.select(episodeListSelector()).map { + episodeFromElement(it) + }.reversed() + } + override fun episodeFromElement(element: Element): SEpisode { + val episode = SEpisode.create() + val elementA = element.selectFirst("a") + episode.setUrlWithoutDomain(elementA.attr("href")) + val name = element.selectFirst("h3").text() + val epName = name.substringAfterLast("– ") + episode.name = epName + episode.episode_number = try { + epName.substringAfter(" ").substringBefore(" ").toFloat() + } catch (e: NumberFormatException) { 0F } + return episode + } + + // ============================ Video Links ============================= + override fun videoListParse(response: Response): List