From 9516ee6b1f039a2af26f1e709df0dd85371765d5 Mon Sep 17 00:00:00 2001 From: Claudemirovsky <63046606+Claudemirovsky@users.noreply.github.com> Date: Mon, 30 Oct 2023 09:42:44 -0300 Subject: [PATCH 01/10] fix(ar/anime4up): Update baseUrl + more extractors (#2436) --- src/ar/anime4up/build.gradle | 19 +- .../animeextension/ar/anime4up/Anime4Up.kt | 437 ++++++------------ .../ar/anime4up/Anime4UpFilters.kt | 110 +++++ .../anime4up/extractors/VidYardExtractor.kt | 24 +- 4 files changed, 283 insertions(+), 307 deletions(-) create mode 100644 src/ar/anime4up/src/eu/kanade/tachiyomi/animeextension/ar/anime4up/Anime4UpFilters.kt diff --git a/src/ar/anime4up/build.gradle b/src/ar/anime4up/build.gradle index 9b01407faa..3952706ed3 100644 --- a/src/ar/anime4up/build.gradle +++ b/src/ar/anime4up/build.gradle @@ -1,21 +1,26 @@ -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' +plugins { + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.serialization) +} ext { extName = 'Anime4up' pkgNameSuffix = 'ar.anime4up' extClass = '.Anime4Up' - extVersionCode = 50 + extVersionCode = 51 libVersion = '13' } dependencies { - implementation(project(':lib-streamwish-extractor')) - implementation(project(':lib-gdriveplayer-extractor')) implementation(project(':lib-dood-extractor')) - implementation(project(':lib-voe-extractor')) - implementation(project(':lib-vidbom-extractor')) + implementation(project(':lib-gdriveplayer-extractor')) + implementation(project(':lib-mp4upload-extractor')) implementation(project(':lib-okru-extractor')) + implementation(project(':lib-streamwish-extractor')) + implementation(project(':lib-uqload-extractor')) + implementation(project(':lib-vidbom-extractor')) + implementation(project(':lib-voe-extractor')) implementation "dev.datlag.jsunpacker:jsunpacker:1.0.1" } diff --git a/src/ar/anime4up/src/eu/kanade/tachiyomi/animeextension/ar/anime4up/Anime4Up.kt b/src/ar/anime4up/src/eu/kanade/tachiyomi/animeextension/ar/anime4up/Anime4Up.kt index d528ef2a80..119d0e8601 100644 --- a/src/ar/anime4up/src/eu/kanade/tachiyomi/animeextension/ar/anime4up/Anime4Up.kt +++ b/src/ar/anime4up/src/eu/kanade/tachiyomi/animeextension/ar/anime4up/Anime4Up.kt @@ -1,15 +1,12 @@ package eu.kanade.tachiyomi.animeextension.ar.anime4up import android.app.Application -import android.content.SharedPreferences -import android.os.Build -import androidx.annotation.RequiresApi +import android.util.Base64 import androidx.preference.ListPreference import androidx.preference.PreferenceScreen import eu.kanade.tachiyomi.animeextension.ar.anime4up.extractors.SharedExtractor import eu.kanade.tachiyomi.animeextension.ar.anime4up.extractors.VidYardExtractor import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource -import eu.kanade.tachiyomi.animesource.model.AnimeFilter import eu.kanade.tachiyomi.animesource.model.AnimeFilterList import eu.kanade.tachiyomi.animesource.model.SAnime import eu.kanade.tachiyomi.animesource.model.SEpisode @@ -17,8 +14,10 @@ import eu.kanade.tachiyomi.animesource.model.Video import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource import eu.kanade.tachiyomi.lib.doodextractor.DoodExtractor import eu.kanade.tachiyomi.lib.gdriveplayerextractor.GdrivePlayerExtractor +import eu.kanade.tachiyomi.lib.mp4uploadextractor.Mp4uploadExtractor import eu.kanade.tachiyomi.lib.okruextractor.OkruExtractor import eu.kanade.tachiyomi.lib.streamwishextractor.StreamWishExtractor +import eu.kanade.tachiyomi.lib.uqloadextractor.UqloadExtractor import eu.kanade.tachiyomi.lib.vidbomextractor.VidBomExtractor import eu.kanade.tachiyomi.lib.voeextractor.VoeExtractor import eu.kanade.tachiyomi.network.GET @@ -27,266 +26,184 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.runBlocking +import kotlinx.serialization.Serializable +import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json -import kotlinx.serialization.json.JsonObject -import kotlinx.serialization.json.jsonObject -import okhttp3.Headers -import okhttp3.HttpUrl.Companion.toHttpUrlOrNull -import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.Response import org.jsoup.nodes.Document import org.jsoup.nodes.Element import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get +import uy.kohesive.injekt.injectLazy import java.lang.Exception -import java.util.Base64 class Anime4Up : ConfigurableAnimeSource, ParsedAnimeHttpSource() { override val name = "Anime4Up" - override val baseUrl = "https://w1.anime4up.tv" + override val baseUrl = "https://anime4up.cam" override val lang = "ar" override val supportsLatest = false - override val client: OkHttpClient = network.cloudflareClient + override val client = network.cloudflareClient - private val json = Json { - ignoreUnknownKeys = true - } + private val json: Json by injectLazy() - private val preferences: SharedPreferences by lazy { + private val preferences by lazy { Injekt.get().getSharedPreferences("source_$id", 0x0000) } - override fun headersBuilder(): Headers.Builder { - return super.headersBuilder() - .add("Referer", "https://w1.anime4up.tv/") // https://s12.gemzawy.com https://moshahda.net - } - - // Popular + override fun headersBuilder() = super.headersBuilder().add("Referer", "$baseUrl/") - override fun popularAnimeSelector(): String = "div.anime-list-content div.row div.col-lg-2" + // ============================== Popular =============================== + override fun popularAnimeRequest(page: Int) = GET("$baseUrl/anime-list-3/page/$page/") - override fun popularAnimeRequest(page: Int): Request = GET("$baseUrl/anime-list-3/page/$page/") + override fun popularAnimeSelector() = "div.anime-list-content div.anime-card-poster > div.hover" - override fun popularAnimeFromElement(element: Element): SAnime { - val anime = SAnime.create() - anime.thumbnail_url = element.select("div.anime-card-poster div.ehover6 img").attr("src") - anime.setUrlWithoutDomain(element.select("div.anime-card-poster div.ehover6 a").attr("href")) - anime.title = element.select("div.anime-card-poster div.ehover6 img").attr("alt") - return anime + override fun popularAnimeFromElement(element: Element) = SAnime.create().apply { + element.selectFirst("img")!!.run { + thumbnail_url = absUrl("src") + title = attr("alt") + } + setUrlWithoutDomain(element.selectFirst("a")!!.attr("href")) } - override fun popularAnimeNextPageSelector(): String = "ul.pagination li a.next" + override fun popularAnimeNextPageSelector() = "ul.pagination > li > a.next" - // episodes + // =============================== Latest =============================== + override fun latestUpdatesRequest(page: Int) = throw Exception("not used") + override fun latestUpdatesSelector() = throw Exception("not used") + override fun latestUpdatesFromElement(element: Element) = throw Exception("not used") + override fun latestUpdatesNextPageSelector() = throw Exception("not used") - override fun episodeListParse(response: Response): List { - return super.episodeListParse(response).reversed() - } + // =============================== Search =============================== + override fun getFilterList() = Anime4UpFilters.FILTER_LIST - override fun episodeListSelector() = "div.episodes-list-content div#DivEpisodesList div.col-md-3" // "ul.episodes-links li a" - - override fun episodeFromElement(element: Element): SEpisode { - val episode = SEpisode.create() - val epNum = getNumberFromEpsString(element.select("div.episodes-card-container div.episodes-card div.ehover6 h3 a").text()) - episode.setUrlWithoutDomain(element.select("div.episodes-card-container div.episodes-card div.ehover6 h3 a").attr("href")) - // episode.episode_number = element.select("span:nth-child(3)").text().replace(" - ", "").toFloat() - episode.episode_number = when { - epNum.isNotEmpty() -> epNum.toFloatOrNull() ?: 1F - else -> 1F + override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request { + if (query.isNotBlank()) { + return GET("$baseUrl/?search_param=animes&s=$query", headers) } - episode.name = element.select("div.episodes-card-container div.episodes-card div.ehover6 h3 a").text() - return episode + return with(Anime4UpFilters.getSearchParameters(filters)) { + val url = when { + genre.isNotBlank() -> "$baseUrl/anime-genre/$genre" + type.isNotBlank() -> "$baseUrl/anime-type/$type" + status.isNotBlank() -> "$baseUrl/anime-status/$status" + else -> throw Exception("اختر فلتر") + } + GET(url, headers) + } } - private fun getNumberFromEpsString(epsStr: String): String { - return epsStr.filter { it.isDigit() } - } + override fun searchAnimeFromElement(element: Element) = popularAnimeFromElement(element) + override fun searchAnimeNextPageSelector() = popularAnimeNextPageSelector() + override fun searchAnimeSelector() = popularAnimeSelector() - // Video links + // =========================== Anime Details ============================ + override fun animeDetailsParse(document: Document) = SAnime.create().apply { + val doc = document // Shortcut - @RequiresApi(Build.VERSION_CODES.O) - override fun videoListParse(response: Response): List