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
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
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