diff --git a/src/all/animexin/build.gradle b/src/all/animexin/build.gradle index e051573e..0dbeb5f3 100644 --- a/src/all/animexin/build.gradle +++ b/src/all/animexin/build.gradle @@ -3,7 +3,7 @@ ext { extClass = '.AnimeXin' themePkg = 'animestream' baseUrl = 'https://animexin.vip' - overrideVersionCode = 9 + overrideVersionCode = 8 } apply from: "$rootDir/common.gradle" diff --git a/src/all/animexin/src/eu/kanade/tachiyomi/animeextension/all/animexin/AnimeXin.kt b/src/all/animexin/src/eu/kanade/tachiyomi/animeextension/all/animexin/AnimeXin.kt index f1a41804..9cc7d089 100644 --- a/src/all/animexin/src/eu/kanade/tachiyomi/animeextension/all/animexin/AnimeXin.kt +++ b/src/all/animexin/src/eu/kanade/tachiyomi/animeextension/all/animexin/AnimeXin.kt @@ -14,7 +14,7 @@ import eu.kanade.tachiyomi.multisrc.animestream.AnimeStream class AnimeXin : AnimeStream( "all", "AnimeXin", - "https://animexin.dev", + "https://animexin.vip", ) { override val id = 4620219025406449669 diff --git a/src/all/anizone/build.gradle b/src/all/anizone/build.gradle deleted file mode 100644 index 9eb77b0c..00000000 --- a/src/all/anizone/build.gradle +++ /dev/null @@ -1,11 +0,0 @@ -ext { - extName = 'AniZone' - extClass = '.AniZone' - extVersionCode = 1 -} - -apply from: "$rootDir/common.gradle" - -dependencies { - implementation(project(":lib:playlist-utils")) -} diff --git a/src/all/anizone/res/mipmap-hdpi/ic_launcher.png b/src/all/anizone/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index 30ff4ee8..00000000 Binary files a/src/all/anizone/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/src/all/anizone/res/mipmap-mdpi/ic_launcher.png b/src/all/anizone/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 4e0d7b6a..00000000 Binary files a/src/all/anizone/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/src/all/anizone/res/mipmap-xhdpi/ic_launcher.png b/src/all/anizone/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 79cd46ee..00000000 Binary files a/src/all/anizone/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/src/all/anizone/res/mipmap-xxhdpi/ic_launcher.png b/src/all/anizone/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 47d0a46c..00000000 Binary files a/src/all/anizone/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/all/anizone/res/mipmap-xxxhdpi/ic_launcher.png b/src/all/anizone/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index f44767b9..00000000 Binary files a/src/all/anizone/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/all/anizone/src/eu/kanade/tachiyomi/animeextension/all/anizone/AniZone.kt b/src/all/anizone/src/eu/kanade/tachiyomi/animeextension/all/anizone/AniZone.kt deleted file mode 100644 index 863b450b..00000000 --- a/src/all/anizone/src/eu/kanade/tachiyomi/animeextension/all/anizone/AniZone.kt +++ /dev/null @@ -1,513 +0,0 @@ -package eu.kanade.tachiyomi.animeextension.all.anizone - -import android.app.Application -import android.content.SharedPreferences -import androidx.preference.ListPreference -import androidx.preference.PreferenceScreen -import androidx.preference.SwitchPreferenceCompat -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.AnimesPage -import eu.kanade.tachiyomi.animesource.model.SAnime -import eu.kanade.tachiyomi.animesource.model.SEpisode -import eu.kanade.tachiyomi.animesource.model.Track -import eu.kanade.tachiyomi.animesource.model.Video -import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource -import eu.kanade.tachiyomi.lib.playlistutils.PlaylistUtils -import eu.kanade.tachiyomi.network.GET -import eu.kanade.tachiyomi.network.POST -import eu.kanade.tachiyomi.util.asJsoup -import eu.kanade.tachiyomi.util.parseAs -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json -import kotlinx.serialization.json.JsonArray -import kotlinx.serialization.json.JsonObject -import kotlinx.serialization.json.add -import kotlinx.serialization.json.addJsonObject -import kotlinx.serialization.json.buildJsonArray -import kotlinx.serialization.json.buildJsonObject -import kotlinx.serialization.json.put -import kotlinx.serialization.json.putJsonArray -import okhttp3.MediaType.Companion.toMediaType -import okhttp3.Request -import okhttp3.RequestBody -import okhttp3.RequestBody.Companion.toRequestBody -import okhttp3.Response -import org.jsoup.Jsoup.parseBodyFragment -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.text.ParseException -import java.text.SimpleDateFormat -import java.util.Locale - -class AniZone : AnimeHttpSource(), ConfigurableAnimeSource { - - override val name = "AniZone" - - override val baseUrl = "https://anizone.to" - - override val lang = "all" - - override val supportsLatest = true - - private val json: Json by injectLazy() - - private val preferences: SharedPreferences by lazy { - Injekt.get().getSharedPreferences("source_$id", 0x0000) - } - - private var token: String = "" - - private val snapShots: MutableMap = mutableMapOf( - ANIME_SNAPSHOT_KEY to "", - EPISODE_SNAPSHOT_KEY to "", - VIDEO_SNAPSHOT_KEY to "", - ) - - private var loadCount: Int = 0 - - // ============================== Popular =============================== - - override fun popularAnimeRequest(page: Int): Request { - return if (page == 1) { - loadCount = 0 - snapShots[ANIME_SNAPSHOT_KEY] = "" - - val updates = buildJsonObject { - put("sort", "title-asc") - } - val calls = buildJsonArray { } - - createLivewireReq(ANIME_SNAPSHOT_KEY, updates, calls) - } else { - val updates = buildJsonObject { } - val calls = buildJsonArray { - addJsonObject { - put("path", "") - put("method", "loadMore") - putJsonArray("params") { } - } - } - - createLivewireReq(ANIME_SNAPSHOT_KEY, updates, calls) - } - } - - override fun popularAnimeParse(response: Response): AnimesPage { - val html = response.parseAs().getHtml(ANIME_SNAPSHOT_KEY) - - val animeList = html.select("div.grid > div").drop(loadCount) - .map(::animeFromElement) - val hasNextPage = html.selectFirst("div[x-intersect~=loadMore]") != null - - loadCount += animeList.size - - return AnimesPage(animeList, hasNextPage) - } - - private fun animeFromElement(element: Element): SAnime { - return SAnime.create().apply { - thumbnail_url = element.selectFirst("img")!!.attr("src") - with(element.selectFirst("a.inline")!!) { - setUrlWithoutDomain(attr("href")) - title = text() - } - } - } - - // =============================== Latest =============================== - - override fun latestUpdatesRequest(page: Int): Request { - return if (page == 1) { - loadCount = 0 - snapShots[ANIME_SNAPSHOT_KEY] = "" - - val updates = buildJsonObject { - put("sort", "release-desc") - } - val calls = buildJsonArray { } - - createLivewireReq(ANIME_SNAPSHOT_KEY, updates, calls) - } else { - popularAnimeRequest(page) - } - } - - override fun latestUpdatesParse(response: Response): AnimesPage { - return popularAnimeParse(response) - } - - // =============================== Search =============================== - - override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request { - val sortFilter = filters.filterIsInstance().first() - - return if (page == 1) { - loadCount = 0 - snapShots[ANIME_SNAPSHOT_KEY] = "" - - val updates = buildJsonObject { - if (query.isNotEmpty()) { - put("search", query) - } - put("sort", sortFilter.toUriPart()) - } - val calls = buildJsonArray { } - - createLivewireReq(ANIME_SNAPSHOT_KEY, updates, calls) - } else { - popularAnimeRequest(page) - } - } - - override fun searchAnimeParse(response: Response): AnimesPage { - return popularAnimeParse(response) - } - - // ============================== Filters =============================== - - override fun getFilterList(): AnimeFilterList { - return AnimeFilterList(SortFilter()) - } - - private class SortFilter : UriPartFilter( - "Sort", - arrayOf( - Pair("A-Z", "title-asc"), - Pair("Z-A", "title-desc"), - Pair("Earliest Release", "release-asc"), - Pair("Latest Release", "release-desc"), - Pair("First Added", "added-asc"), - Pair("Last Added", "added-desc"), - ), - ) - - private open class UriPartFilter(displayName: String, val vals: Array>) : - AnimeFilter.Select(displayName, vals.map { it.first }.toTypedArray()) { - fun toUriPart() = vals[state].second - } - - // =========================== Anime Details ============================ - - override fun animeDetailsParse(response: Response): SAnime { - val document = response.asJsoup() - - val infoDiv = document.select("div.flex.items-start > div")[1] - - return SAnime.create().apply { - thumbnail_url = document.selectFirst("div.flex.items-start img")!!.attr("abs:img") - - with(infoDiv) { - title = selectFirst("h1")!!.text() - status = select("span.flex")[1].parseStatus() - description = selectFirst("div:has(>h3:contains(Synopsis)) > div")?.html() - ?.replace("
", "\n") - ?.replace(MULTILINE_REGEX, "\n\n") - genre = select("div > a").joinToString { it.text() } - } - } - } - - private fun Element.parseStatus(): Int = when (this.text().lowercase()) { - "completed" -> SAnime.COMPLETED - "ongoing" -> SAnime.ONGOING - else -> SAnime.UNKNOWN - } - - // ============================== Episodes ============================== - - private fun getPredefinedSnapshots(slug: String): String { - return when (slug) { - "/anime/uyyyn4kf" -> """{"data":{"anime":[null,{"class":"anime","key":68,"s":"mdl"}],"title":null,"search":"","listSize":1104,"sort":"release-asc","sortOptions":[{"release-asc":"First Aired","release-desc":"Last Aired"},{"s":"arr"}],"view":"list","paginators":[{"page":1},{"s":"arr"}]},"memo":{"id":"GD1OiEMOJq6UQDQt1OBt","name":"pages.anime-detail","path":"anime\/uyyyn4kf","method":"GET","children":[],"scripts":[],"assets":[],"errors":[],"locale":"en"},"checksum":"5800932dd82e4862f34f6fd72d8098243b32643e8accb8da6a6a39cd0ee86acd"}""" - else -> "" - } - } - - override fun episodeListRequest(anime: SAnime): Request { - snapShots[EPISODE_SNAPSHOT_KEY] = getPredefinedSnapshots(anime.url) - - val updates = buildJsonObject { - put("sort", "release-desc") - } - val calls = buildJsonArray { } - - return createLivewireReq(EPISODE_SNAPSHOT_KEY, updates, calls, anime.url) - } - - override fun episodeListParse(response: Response): List { - val document = response.parseAs().getHtml(EPISODE_SNAPSHOT_KEY) - val episodeList = document.select(episodeSelector) - .map(::episodeFromElement) - .toMutableList() - loadCount = episodeList.size - - var hasMore = document.selectFirst("div[x-intersect~=loadMore]") != null - - while (hasMore) { - val updates = buildJsonObject { } - val calls = buildJsonArray { - addJsonObject { - put("path", "") - put("method", "loadMore") - putJsonArray("params") { } - } - } - - val resp = client.newCall( - createLivewireReq(EPISODE_SNAPSHOT_KEY, updates, calls), - ).execute().parseAs().getHtml(EPISODE_SNAPSHOT_KEY) - - val episodes = resp.select(episodeSelector) - .drop(loadCount) - .map(::episodeFromElement) - - episodeList.addAll(episodes) - loadCount += episodes.size - - hasMore = resp.selectFirst("div[x-intersect~=loadMore]") != null - } - - return episodeList - } - - private val episodeSelector = "ul > li" - - private fun episodeFromElement(element: Element): SEpisode { - val url = element.selectFirst("a[href]")!!.attr("abs:href") - - return SEpisode.create().apply { - setUrlWithoutDomain(url) - name = element.selectFirst("h3")!!.text() - date_upload = element.select("div.flex-row > span").getOrNull(1) - ?.text() - ?.let { parseDate(it) } - ?: 0L - } - } - - // ============================ Video Links ============================= - - override fun videoListRequest(episode: SEpisode): Request { - return GET(baseUrl + episode.url, headers) - } - - private val playlistUtils: PlaylistUtils by lazy { PlaylistUtils(client, headers) } - - override fun videoListParse(response: Response): List