diff --git a/src/en/animeflix/build.gradle b/src/en/animeflix/build.gradle deleted file mode 100644 index 928c3f9c..00000000 --- a/src/en/animeflix/build.gradle +++ /dev/null @@ -1,7 +0,0 @@ -ext { - extName = 'AnimeFlix' - extClass = '.AnimeFlix' - extVersionCode = 7 -} - -apply from: "$rootDir/common.gradle" diff --git a/src/en/animeflix/res/mipmap-hdpi/ic_launcher.png b/src/en/animeflix/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index 6f64faa7..00000000 Binary files a/src/en/animeflix/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/animeflix/res/mipmap-mdpi/ic_launcher.png b/src/en/animeflix/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index f7ca2d46..00000000 Binary files a/src/en/animeflix/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/animeflix/res/mipmap-xhdpi/ic_launcher.png b/src/en/animeflix/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index d76b68a6..00000000 Binary files a/src/en/animeflix/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/animeflix/res/mipmap-xxhdpi/ic_launcher.png b/src/en/animeflix/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 600b9bb2..00000000 Binary files a/src/en/animeflix/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/animeflix/res/mipmap-xxxhdpi/ic_launcher.png b/src/en/animeflix/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index b7784bc4..00000000 Binary files a/src/en/animeflix/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/animeflix/res/web_hi_res_512.png b/src/en/animeflix/res/web_hi_res_512.png deleted file mode 100644 index f6d7fcfb..00000000 Binary files a/src/en/animeflix/res/web_hi_res_512.png and /dev/null differ diff --git a/src/en/animeflix/src/eu/kanade/tachiyomi/animeextension/en/animeflix/AnimeFlix.kt b/src/en/animeflix/src/eu/kanade/tachiyomi/animeextension/en/animeflix/AnimeFlix.kt deleted file mode 100644 index 4f5e1f81..00000000 --- a/src/en/animeflix/src/eu/kanade/tachiyomi/animeextension/en/animeflix/AnimeFlix.kt +++ /dev/null @@ -1,398 +0,0 @@ -package eu.kanade.tachiyomi.animeextension.en.animeflix - -import android.app.Application -import android.util.Base64 -import androidx.preference.ListPreference -import androidx.preference.PreferenceScreen -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 -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.util.asJsoup -import eu.kanade.tachiyomi.util.parallelCatchingFlatMap -import kotlinx.serialization.Serializable -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json -import okhttp3.HttpUrl.Companion.toHttpUrl -import okhttp3.MultipartBody -import okhttp3.Request -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 - -class AnimeFlix : ConfigurableAnimeSource, ParsedAnimeHttpSource() { - - override val name = "AnimeFlix" - - override val baseUrl = "https://animeflix.mobi" - - override val lang = "en" - - override val supportsLatest = true - - private val json: Json by injectLazy() - - private val preferences by lazy { - Injekt.get().getSharedPreferences("source_$id", 0x0000) - } - - // ============================== Popular =============================== - override fun popularAnimeRequest(page: Int) = GET("$baseUrl/page/$page/") - - override fun popularAnimeSelector() = "div#content_box > div.post-cards > article" - - override fun popularAnimeFromElement(element: Element) = SAnime.create().apply { - setUrlWithoutDomain(element.selectFirst("a")!!.attr("href")) - // prevent base64 images - thumbnail_url = element.selectFirst("img")!!.run { - attr("data-pagespeed-high-res-src").ifEmpty { attr("src") } - } - title = element.selectFirst("header")!!.text() - } - - override fun popularAnimeNextPageSelector() = "div.nav-links > a.next" - - // =============================== Latest =============================== - override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/latest-release/page/$page/") - - override fun latestUpdatesSelector(): String = popularAnimeSelector() - - override fun latestUpdatesFromElement(element: Element): SAnime = popularAnimeFromElement(element) - - override fun latestUpdatesNextPageSelector(): String = popularAnimeNextPageSelector() - - // =============================== Search =============================== - override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request { - val cleanQuery = query.replace(" ", "+").lowercase() - - val filterList = if (filters.isEmpty()) getFilterList() else filters - val genreFilter = filterList.find { it is GenreFilter } as GenreFilter - val subpageFilter = filterList.find { it is SubPageFilter } as SubPageFilter - - return when { - query.isNotBlank() -> GET("$baseUrl/page/$page/?s=$cleanQuery", headers = headers) - genreFilter.state != 0 -> GET("$baseUrl/genre/${genreFilter.toUriPart()}/page/$page/", headers = headers) - subpageFilter.state != 0 -> GET("$baseUrl/${subpageFilter.toUriPart()}/page/$page/", headers = headers) - else -> popularAnimeRequest(page) - } - } - - override fun searchAnimeSelector(): String = popularAnimeSelector() - - override fun searchAnimeFromElement(element: Element): SAnime = popularAnimeFromElement(element) - - override fun searchAnimeNextPageSelector(): String = popularAnimeNextPageSelector() - - // ============================== Filters =============================== - override fun getFilterList(): AnimeFilterList = AnimeFilterList( - AnimeFilter.Header("Text search ignores filters"), - GenreFilter(), - SubPageFilter(), - ) - - private class GenreFilter : UriPartFilter( - "Genres", - arrayOf( - Pair("", ""), - Pair("Ongoing", "ongoing"), - Pair("Latest Release", "latest-release"), - Pair("Movies", "movies"), - ), - ) - - 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(document: Document) = SAnime.create().apply { - title = document.selectFirst("div.single_post > header > h1")!!.text() - thumbnail_url = document.selectFirst("img.imdbwp__img")?.attr("src") - - val infosDiv = document.selectFirst("div.thecontent h3:contains(Anime Info) ~ ul")!! - status = when (infosDiv.getInfo("Status").toString()) { - "Completed" -> SAnime.COMPLETED - "Currently Airing" -> SAnime.ONGOING - else -> SAnime.UNKNOWN - } - artist = infosDiv.getInfo("Studios") - author = infosDiv.getInfo("Producers") - genre = infosDiv.getInfo("Genres") - val animeInfo = infosDiv.select("li").joinToString("\n") { it.text() } - description = document.select("div.thecontent h3:contains(Summary) ~ p:not(:has(*)):not(:empty)") - .joinToString("\n\n") { it.ownText() } + "\n\n$animeInfo" - } - - private fun Element.getInfo(info: String) = - selectFirst("li:contains($info)")?.ownText()?.trim() - - // ============================== Episodes ============================== - val seasonRegex by lazy { Regex("""season (\d+)""", RegexOption.IGNORE_CASE) } - val qualityRegex by lazy { """(\d+)p""".toRegex() } - - override suspend fun getEpisodeList(anime: SAnime): List { - val document = client.newCall(GET(baseUrl + anime.url)).execute() - .asJsoup() - - val seasonList = document.select("div.inline > h3:contains(Season),div.thecontent > h3:contains(Season)") - - val episodeList = if (seasonList.distinctBy { seasonRegex.find(it.text())!!.groupValues[1] }.size > 1) { - val seasonsLinks = document.select("div.thecontent p:has(span:contains(Gdrive))").groupBy { - seasonRegex.find(it.previousElementSibling()!!.text())!!.groupValues[1] - } - - seasonsLinks.flatMap { (seasonNumber, season) -> - val serverListSeason = season.map { - val previousText = it.previousElementSibling()!!.text() - val quality = qualityRegex.find(previousText)?.groupValues?.get(1) ?: "Unknown quality" - - val url = it.selectFirst("a")!!.attr("href") - val episodesDocument = client.newCall(GET(url)).execute() - .asJsoup() - episodesDocument.select("div.entry-content > h3 > a").map { - EpUrl(quality, it.attr("href"), "Season $seasonNumber ${it.text()}") - } - } - - transposeEpisodes(serverListSeason) - } - } else { - val driveList = document.select("div.thecontent p:has(span:contains(Gdrive))").map { - val quality = qualityRegex.find(it.previousElementSibling()!!.text())?.groupValues?.get(1) ?: "Unknown quality" - Pair(it.selectFirst("a")!!.attr("href"), quality) - } - - // Load episodes - val serversList = driveList.map { drive -> - val episodesDocument = client.newCall(GET(drive.first)).execute() - .asJsoup() - episodesDocument.select("div.entry-content > h3 > a").map { - EpUrl(drive.second, it.attr("href"), it.text()) - } - } - - transposeEpisodes(serversList) - } - - return episodeList.reversed() - } - - private fun transposeEpisodes(serversList: List>) = - transpose(serversList).mapIndexed { index, serverList -> - SEpisode.create().apply { - name = serverList.first().name - episode_number = (index + 1).toFloat() - setUrlWithoutDomain(json.encodeToString(serverList)) - } - } - - override fun episodeListSelector(): String = throw UnsupportedOperationException() - - override fun episodeFromElement(element: Element): SEpisode = throw UnsupportedOperationException() - - // ============================ Video Links ============================= - override suspend fun getVideoList(episode: SEpisode): List