From f3cf2a11610ec80dc471bd1e8c615748b6e0507c Mon Sep 17 00:00:00 2001 From: Claudemirovsky <63046606+Claudemirovsky@users.noreply.github.com> Date: Thu, 22 Dec 2022 09:03:32 -0300 Subject: [PATCH] New source: SukiAnimes (#1102) * feat: SukiAnimes base, nothing works for now * feat: Implement latest animes page * feat: Implement anime details page * feat: Implement popular animes page * feat: Implement episodes list page * feat: Implement search engine * feat: Implement URL intent handler * feat: Implement video list Almost finished.... * fix: Fixes episodes order and episode list after latest animes page --- src/pt/sukianimes/AndroidManifest.xml | 24 ++ src/pt/sukianimes/build.gradle | 14 + .../res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3187 bytes .../res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 1901 bytes .../res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4674 bytes .../res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 8231 bytes .../res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 12258 bytes .../animeextension/pt/sukianimes/SKFilters.kt | 170 +++++++++++ .../pt/sukianimes/SKUrlActivity.kt | 41 +++ .../pt/sukianimes/SukiAnimes.kt | 274 ++++++++++++++++++ .../pt/sukianimes/dto/SukiAnimesDto.kt | 21 ++ .../sukianimes/extractors/BloggerExtractor.kt | 23 ++ 12 files changed, 567 insertions(+) create mode 100644 src/pt/sukianimes/AndroidManifest.xml create mode 100644 src/pt/sukianimes/build.gradle create mode 100644 src/pt/sukianimes/res/mipmap-hdpi/ic_launcher.png create mode 100644 src/pt/sukianimes/res/mipmap-mdpi/ic_launcher.png create mode 100644 src/pt/sukianimes/res/mipmap-xhdpi/ic_launcher.png create mode 100644 src/pt/sukianimes/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 src/pt/sukianimes/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 src/pt/sukianimes/src/eu/kanade/tachiyomi/animeextension/pt/sukianimes/SKFilters.kt create mode 100644 src/pt/sukianimes/src/eu/kanade/tachiyomi/animeextension/pt/sukianimes/SKUrlActivity.kt create mode 100644 src/pt/sukianimes/src/eu/kanade/tachiyomi/animeextension/pt/sukianimes/SukiAnimes.kt create mode 100644 src/pt/sukianimes/src/eu/kanade/tachiyomi/animeextension/pt/sukianimes/dto/SukiAnimesDto.kt create mode 100644 src/pt/sukianimes/src/eu/kanade/tachiyomi/animeextension/pt/sukianimes/extractors/BloggerExtractor.kt diff --git a/src/pt/sukianimes/AndroidManifest.xml b/src/pt/sukianimes/AndroidManifest.xml new file mode 100644 index 000000000..6a0cda01c --- /dev/null +++ b/src/pt/sukianimes/AndroidManifest.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + diff --git a/src/pt/sukianimes/build.gradle b/src/pt/sukianimes/build.gradle new file mode 100644 index 000000000..c15a13c50 --- /dev/null +++ b/src/pt/sukianimes/build.gradle @@ -0,0 +1,14 @@ +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply plugin: 'kotlinx-serialization' + +ext { + extName = 'SukiAnimes' + pkgNameSuffix = 'pt.sukianimes' + extClass = '.SukiAnimes' + extVersionCode = 1 + libVersion = '13' +} + + +apply from: "$rootDir/common.gradle" diff --git a/src/pt/sukianimes/res/mipmap-hdpi/ic_launcher.png b/src/pt/sukianimes/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..726f2db9c84ea749fc8e198a17a926330ec65871 GIT binary patch literal 3187 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 literal 0 HcmV?d00001 diff --git a/src/pt/sukianimes/res/mipmap-xhdpi/ic_launcher.png b/src/pt/sukianimes/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..b5f961251d25e840c13a70344f8d0bea976115c2 GIT binary patch literal 4674 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�>mXGOe{>& z1~;M58R;j+6X`EEIwcmQ!@rUS9sNNHhaGVnk`GaC;9Hh0b#^kG%sUz)$HP`0Yon4h zdGysO?%uuo>2i|q4KCAztdhyywWDcoS$5&{+mS`4pe8U3eJZ$k&f-4Vrc%}rjfM*e z+Hk)J@b0|_3OM%dI*HwCeQ^e9GDlF)_z5;uAV#6}6bz+zti+3*9QlnmS4F2AF8ws|`k80&v;VZil+N{Hp&y9(2SnY8+>u>oH@BGu7E>+G(! zOnc0EFk9C8l39De_El^M)<%r~31wxxX-!cTPJVn|5`J$|OP@{8`(l=iaz{4RarKo| zcYJ3%rIBg=dO-%aC7b;~s!(ust(LdLO#Sx8U};xf-qHe9iJ(h0?E!yTGf1j+_Yw1W zS+nw9KD`-9YKDET5}F}TyyFTbqmjlMx#PmJh5k9Wz3d0Th;7fA$2#7dGN18T-xHnA5R{mW%$ zFjqo&6l^}%djS$DsMd3p}HHF-e`8j51q>F3HfH>;(s z)3$hiO?I=I3rfL1%m)`-L=iUePR&THv^)}ITZ~aP3S=vjdzo4_EUp3y>T?OM{B{RV5z67mmdXDkUwJpOMmU{eCAq>=YPzvHWwFXN()M!C^L{OAi62& z)zC(!^WuZ8y{U`Nqd!IWK@J%;AFGZnX$N>?`|k)6aniMll2p)x=5fCwvvQkCzwi`) zXQXueHQd!yX)}B9hZ6p3QQf4rxA|aV7D01GLl`wl#jVg)Oh6x^s8s#)oBXU{fsDoe z#ZO%hM|K6^ zD*A56XlP94X3#>+F3stv-LY_k%Wx%f;ZvX%k z0Rn|YfkHr0QxQ=a3GtgJAR;0oB4Rl9%Ibd++&v+#PJ#bF;X&3E_J;82zdJx(-5q_P g&)vQLFGoTKDE41X%=xPSk#zuC>iTMRDh^Tq0<7B9@c;k- literal 0 HcmV?d00001 diff --git a/src/pt/sukianimes/res/mipmap-xxhdpi/ic_launcher.png b/src/pt/sukianimes/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..c0caa463db337c1376b40f40335f4ab592824a7d GIT binary patch literal 8231 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 literal 0 HcmV?d00001 diff --git a/src/pt/sukianimes/src/eu/kanade/tachiyomi/animeextension/pt/sukianimes/SKFilters.kt b/src/pt/sukianimes/src/eu/kanade/tachiyomi/animeextension/pt/sukianimes/SKFilters.kt new file mode 100644 index 000000000..818374a09 --- /dev/null +++ b/src/pt/sukianimes/src/eu/kanade/tachiyomi/animeextension/pt/sukianimes/SKFilters.kt @@ -0,0 +1,170 @@ +package eu.kanade.tachiyomi.animeextension.pt.sukianimes + +import eu.kanade.tachiyomi.animesource.model.AnimeFilter +import eu.kanade.tachiyomi.animesource.model.AnimeFilterList + +object SKFilters { + + open class QueryPartFilter( + displayName: String, + val vals: Array> + ) : AnimeFilter.Select( + displayName, + vals.map { it.first }.toTypedArray() + ) { + + fun toQueryPart() = vals[state].second + } + + private class CheckBoxVal(name: String, state: Boolean = false) : AnimeFilter.CheckBox(name, state) + open class CheckBoxFilterList(name: String, values: List) : AnimeFilter.Group(name, values) + + private inline fun AnimeFilterList.getFirst(): R { + return this.filterIsInstance().first() + } + + private inline fun AnimeFilterList.asQueryPart(): String { + return this.filterIsInstance().joinToString("") { + (it as QueryPartFilter).toQueryPart() + } + } + + class AdultFilter : AnimeFilter.CheckBox("Exibir animes adultos", true) + + class FormatFilter : QueryPartFilter("Formato", SKFiltersData.formats) + class StatusFilter : QueryPartFilter("Status do anime", SKFiltersData.status) + class TypeFilter : QueryPartFilter("Tipo de vídeo", SKFiltersData.types) + + class GenresFilter : CheckBoxFilterList( + "Gêneros", + SKFiltersData.genres.map { CheckBoxVal(it.first, false) } + ) + + // Mimicking the order of filters on the source + val filterList = AnimeFilterList( + TypeFilter(), + StatusFilter(), + AdultFilter(), + FormatFilter(), + GenresFilter() + ) + + data class FilterSearchParams( + val adult: Boolean = true, + val format: String = "", + val genres: List = emptyList(), + val status: String = "", + val type: String = "", + ) + + internal fun getSearchParameters(filters: AnimeFilterList): FilterSearchParams { + val genres = filters.getFirst().state + .mapNotNull { genre -> + if (genre.state) { + SKFiltersData.genres.find { it.first == genre.name }!!.second + } else { null } + }.toList() + + return FilterSearchParams( + filters.getFirst().state, + filters.asQueryPart(), + genres, + filters.asQueryPart(), + filters.asQueryPart() + ) + } + + private object SKFiltersData { + val every = Pair("Qualquer um", "") + + val types = arrayOf( + every, + Pair("Legendado", "1"), + Pair("Dublado", "2") + ) + + val status = arrayOf( + every, + Pair("Completo", "Completo"), + Pair("Em lançamento", "Lançamento") + ) + + val formats = arrayOf( + every, + Pair("Anime", "Anime"), + Pair("Filme", "Filme") + ) + + val genres = arrayOf( + Pair("Artes Marciais", "12"), + Pair("Aventura", "13"), + Pair("Ação", "5"), + Pair("Boys Love", "1125"), + Pair("Carros", "945"), + Pair("Chinês", "1032"), + Pair("Comédia Romântica", "15"), + Pair("Comédia", "14"), + Pair("Corrida", "1690"), + Pair("Culinária", "576"), + Pair("Dementia", "164"), + Pair("Demônios", "35"), + Pair("Drama", "9"), + Pair("Ecchi", "16"), + Pair("Erótico", "1203"), + Pair("Escolar", "812"), + Pair("Espaço", "429"), + Pair("Esporte", "17"), + Pair("Fantasia", "10"), + Pair("Ficção Científica", "18"), + Pair("Game", "156"), + Pair("Girls Love", "1228"), + Pair("Gore", "1708"), + Pair("Harém", "69"), + Pair("Histórico", "88"), + Pair("Horror", "165"), + Pair("Idols", "1702"), + Pair("Insanidade", "891"), + Pair("Isekai", "1138"), + Pair("Jogos", "19"), + Pair("Josei", "1345"), + Pair("Kids", "847"), + Pair("Magia", "20"), + Pair("Maid", "1677"), + Pair("Mecha", "21"), + Pair("Militar", "6"), + Pair("Mistério", "7"), + Pair("Munyuu", "1074"), + Pair("Musical", "22"), + Pair("Novel", "252"), + Pair("Parody", "1197"), + Pair("Paródia", "207"), + Pair("Performing Arts", "1564"), + Pair("Piratas", "172"), + Pair("Polícia", "229"), + Pair("Psicológico", "50"), + Pair("RPG", "94"), + Pair("Romance", "23"), + Pair("Samurai", "439"), + Pair("School", "1065"), + Pair("Sci-Fi", "42"), + Pair("Seinen", "24"), + Pair("Shoujo", "210"), + Pair("Shoujo-ai", "25"), + Pair("Shounen", "11"), + Pair("Shounen-AI", "322"), + Pair("Slice of Life", "26"), + Pair("Sobrenatural", "27"), + Pair("Super Poder", "8"), + Pair("Suspense", "230"), + Pair("Terror", "28"), + Pair("Thriller", "51"), + Pair("Tragedia", "269"), + Pair("Vampiro", "134"), + Pair("Vida Diaria", "253"), + Pair("Vida Escolar", "29"), + Pair("Violência", "440"), + Pair("Yaoi", "612"), + Pair("Yuri", "1497") + ) + } +} diff --git a/src/pt/sukianimes/src/eu/kanade/tachiyomi/animeextension/pt/sukianimes/SKUrlActivity.kt b/src/pt/sukianimes/src/eu/kanade/tachiyomi/animeextension/pt/sukianimes/SKUrlActivity.kt new file mode 100644 index 000000000..5829ab1b9 --- /dev/null +++ b/src/pt/sukianimes/src/eu/kanade/tachiyomi/animeextension/pt/sukianimes/SKUrlActivity.kt @@ -0,0 +1,41 @@ +package eu.kanade.tachiyomi.animeextension.pt.sukianimes + +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://sukianimes.com/anime/ intents + * and redirects them to the main Aniyomi process. + */ +class SKUrlActivity : Activity() { + + private val TAG = "SKUrlActivity" + + 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.ANIMESEARCH" + putExtra("query", "${SukiAnimes.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/sukianimes/src/eu/kanade/tachiyomi/animeextension/pt/sukianimes/SukiAnimes.kt b/src/pt/sukianimes/src/eu/kanade/tachiyomi/animeextension/pt/sukianimes/SukiAnimes.kt new file mode 100644 index 000000000..1a02a793c --- /dev/null +++ b/src/pt/sukianimes/src/eu/kanade/tachiyomi/animeextension/pt/sukianimes/SukiAnimes.kt @@ -0,0 +1,274 @@ +package eu.kanade.tachiyomi.animeextension.pt.sukianimes + +import eu.kanade.tachiyomi.animeextension.pt.sukianimes.dto.AnimeDto +import eu.kanade.tachiyomi.animeextension.pt.sukianimes.dto.SearchResultDto +import eu.kanade.tachiyomi.animeextension.pt.sukianimes.extractors.BloggerExtractor +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.POST +import eu.kanade.tachiyomi.network.asObservableSuccess +import eu.kanade.tachiyomi.util.asJsoup +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.json.Json +import okhttp3.FormBody +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.api.get +import kotlin.Exception + +class SukiAnimes : ParsedAnimeHttpSource() { + + override val name = "SukiAnimes" + + override val baseUrl = "https://sukianimes.com" + private val API_URL = "$baseUrl/wp-admin/admin-ajax.php" + private val NONCE_URL = "$baseUrl/?js_global=1&ver=6.1.1" + + override val lang = "pt-BR" + + override val supportsLatest = true + + override val client: OkHttpClient = network.client + + private val json = Json { + ignoreUnknownKeys = true + } + + // ============================== Popular =============================== + // This source doesn't have a popular anime page, so we'll grab + // the latest anime additions instead. + override fun popularAnimeSelector() = "section.animeslancamentos div.aniItem > a" + override fun popularAnimeRequest(page: Int) = GET(baseUrl) + override fun popularAnimeNextPageSelector() = null // disable it + override fun popularAnimeFromElement(element: Element): SAnime { + return SAnime.create().apply { + setUrlWithoutDomain(element.attr("href")) + title = element.attr("title") + thumbnail_url = element.selectFirst("img").attr("src") + } + } + + // ============================== Episodes ============================== + override fun episodeListSelector() = "div.ultEpsContainerItem > a" + private fun episodeListNextPageSelector() = latestUpdatesNextPageSelector() + + override fun fetchEpisodeList(anime: SAnime): Observable> { + return client.newCall(episodeListRequest(anime)) + .asObservableSuccess() + .map { response -> + val realDoc = getRealDoc(response.asJsoup()) + episodeListParse(realDoc).reversed() + } + } + + override fun episodeListParse(response: Response): List { + return episodeListParse(response.asJsoup()) + } + + private fun episodeListParse(doc: Document): List { + val episodeList = mutableListOf() + val eps = doc.select(episodeListSelector()).map(::episodeFromElement) + episodeList.addAll(eps) + val nextPageElement = doc.selectFirst(episodeListNextPageSelector()) + if (nextPageElement != null) { + val nextUrl = nextPageElement.attr("href") + val res = client.newCall(GET(nextUrl)).execute() + episodeList.addAll(episodeListParse(res)) + } + return episodeList + } + + override fun episodeFromElement(element: Element): SEpisode { + return SEpisode.create().apply { + setUrlWithoutDomain(element.attr("href")) + val title = element.attr("title") + name = title + episode_number = runCatching { + title.trim().substringAfterLast(" ").toFloat() + }.getOrDefault(0F) + } + } + + // ============================ Video Links ============================= + override fun videoListParse(response: Response): List