diff --git a/src/ar/anime4up/AndroidManifest.xml b/src/ar/anime4up/AndroidManifest.xml new file mode 100644 index 0000000000..568741e54f --- /dev/null +++ b/src/ar/anime4up/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/src/ar/anime4up/build.gradle b/src/ar/anime4up/build.gradle index e6f11cb693..54efbf4b82 100644 --- a/src/ar/anime4up/build.gradle +++ b/src/ar/anime4up/build.gradle @@ -16,4 +16,4 @@ dependencies { implementation(project(':lib:vidbom-extractor')) implementation(project(':lib:voe-extractor')) implementation "dev.datlag.jsunpacker:jsunpacker:1.0.1" -} \ No newline at end of file +} 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 68028c00bf..a4fd3d92b6 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 @@ -35,15 +35,16 @@ import uy.kohesive.injekt.api.get import uy.kohesive.injekt.injectLazy import java.lang.Exception -class Anime4Up : ConfigurableAnimeSource, ParsedAnimeHttpSource() { - +class Anime4Up : + ParsedAnimeHttpSource(), + ConfigurableAnimeSource { override val name = "Anime4Up" override val baseUrl = "https://anime4up.cam" override val lang = "ar" - override val supportsLatest = false + override val supportsLatest = true private val json: Json by injectLazy() @@ -58,84 +59,100 @@ class Anime4Up : ConfigurableAnimeSource, ParsedAnimeHttpSource() { override fun popularAnimeSelector() = "div.anime-list-content div.anime-card-poster > div.hover" - override fun popularAnimeFromElement(element: Element) = SAnime.create().apply { - element.selectFirst("img")!!.run { - thumbnail_url = absUrl("src") - title = attr("alt") + 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")) } - setUrlWithoutDomain(element.selectFirst("a")!!.attr("href")) - } override fun popularAnimeNextPageSelector() = "ul.pagination > li > a.next" // =============================== Latest =============================== - override fun latestUpdatesRequest(page: Int) = throw UnsupportedOperationException() - override fun latestUpdatesSelector() = throw UnsupportedOperationException() - override fun latestUpdatesFromElement(element: Element) = throw UnsupportedOperationException() - override fun latestUpdatesNextPageSelector() = throw UnsupportedOperationException() + override fun latestUpdatesRequest(page: Int) = GET(baseUrl + if (page > 1) "/episode/page/$page" else "/episode/", headers) + + override fun latestUpdatesSelector() = popularAnimeSelector() + + override fun latestUpdatesFromElement(element: Element) = popularAnimeFromElement(element) + + override fun latestUpdatesNextPageSelector() = "ul.pagination > li:last-child >a" // =============================== Search =============================== override fun getFilterList() = Anime4UpFilters.FILTER_LIST - override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request { + override fun searchAnimeRequest( + page: Int, + query: String, + filters: AnimeFilterList, + ): Request { if (query.isNotBlank()) { return GET("$baseUrl/?search_param=animes&s=$query", headers) } 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("اختر فلتر") - } + val url = + when { + genre.isNotBlank() -> "$baseUrl/anime-genre/$genre" + type.isNotBlank() -> "$baseUrl/anime-type/$type" + status.isNotBlank() -> "$baseUrl/anime-status/$status" + season.isNotBlank() -> "$baseUrl/anime-season/$season" + else -> throw Exception("اختر فلتر") + } GET(url, headers) } } override fun searchAnimeFromElement(element: Element) = popularAnimeFromElement(element) + override fun searchAnimeNextPageSelector() = popularAnimeNextPageSelector() + override fun searchAnimeSelector() = popularAnimeSelector() // =========================== Anime Details ============================ - override fun animeDetailsParse(document: Document) = SAnime.create().apply { - val doc = document // Shortcut - - thumbnail_url = doc.selectFirst("img.thumbnail")!!.attr("src") - title = doc.selectFirst("h1.anime-details-title")!!.text() - // Genres + useful info - genre = doc.select("ul.anime-genres > li > a, div.anime-info > a").eachText().joinToString() - - description = buildString { - // Additional info - doc.select("div.anime-info").eachText().forEach { - append("$it\n") - } - // Description - doc.selectFirst("p.anime-story")?.text()?.also { - append("\n$it") + override fun animeDetailsParse(document: Document) = + SAnime.create().apply { + val doc = document // Shortcut + + thumbnail_url = doc.selectFirst("img.thumbnail")!!.attr("src") + title = doc.selectFirst("h1.anime-details-title")!!.text() + // Genres + useful info + genre = doc.select("ul.anime-genres > li > a, div.anime-info > a").eachText().joinToString() + + description = + buildString { + // Additional info + doc.select("div.anime-info").eachText().forEach { + append("$it\n") + } + // Description + doc.selectFirst("p.anime-story")?.text()?.also { + append("\n$it") + } + } + + doc.selectFirst("div.anime-info:contains(حالة الأنمي)")?.text()?.also { + status = + when { + it.contains("يعرض الان", true) -> SAnime.ONGOING + it.contains("مكتمل", true) -> SAnime.COMPLETED + else -> SAnime.UNKNOWN + } } } - doc.selectFirst("div.anime-info:contains(حالة الأنمي)")?.text()?.also { - status = when { - it.contains("يعرض الان", true) -> SAnime.ONGOING - it.contains("مكتمل", true) -> SAnime.COMPLETED - else -> SAnime.UNKNOWN - } - } - } - // ============================== Episodes ============================== override fun episodeListParse(response: Response) = super.episodeListParse(response).reversed() override fun episodeListSelector() = "div.ehover6 > div.episodes-card-title > h3 > a, ul.all-episodes-list li > a" - override fun episodeFromElement(element: Element) = SEpisode.create().apply { - setUrlWithoutDomain(element.attr("href")) - name = element.text() - episode_number = name.substringAfterLast(" ").toFloatOrNull() ?: 0F - } + override fun episodeFromElement(element: Element) = + SEpisode.create().apply { + setUrlWithoutDomain(element.attr("href")) + name = element.text() + episode_number = name.substringAfterLast(" ").toFloatOrNull() ?: 0F + } // ============================ Video Links ============================= @Serializable @@ -146,10 +163,13 @@ class Anime4Up : ConfigurableAnimeSource, ParsedAnimeHttpSource() { ) override fun videoListParse(response: Response): List