diff --git a/src/en/fmovies/build.gradle b/src/en/fmovies/build.gradle deleted file mode 100644 index 3d5bb63a..00000000 --- a/src/en/fmovies/build.gradle +++ /dev/null @@ -1,13 +0,0 @@ -ext { - extName = 'FMovies' - extClass = '.FMovies' - extVersionCode = 26 -} - -apply from: "$rootDir/common.gradle" - -dependencies { - implementation(project(':lib:vidsrc-extractor')) - implementation(project(':lib:filemoon-extractor')) - implementation(project(':lib:streamtape-extractor')) -} diff --git a/src/en/fmovies/res/mipmap-hdpi/ic_launcher.png b/src/en/fmovies/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index 20e890a4..00000000 Binary files a/src/en/fmovies/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/fmovies/res/mipmap-mdpi/ic_launcher.png b/src/en/fmovies/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 341c5611..00000000 Binary files a/src/en/fmovies/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/fmovies/res/mipmap-xhdpi/ic_launcher.png b/src/en/fmovies/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 7732fbf3..00000000 Binary files a/src/en/fmovies/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/fmovies/res/mipmap-xxhdpi/ic_launcher.png b/src/en/fmovies/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index fede27d7..00000000 Binary files a/src/en/fmovies/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/fmovies/res/mipmap-xxxhdpi/ic_launcher.png b/src/en/fmovies/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 62f3def9..00000000 Binary files a/src/en/fmovies/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/en/fmovies/src/eu/kanade/tachiyomi/animeextension/en/fmovies/FMovies.kt b/src/en/fmovies/src/eu/kanade/tachiyomi/animeextension/en/fmovies/FMovies.kt deleted file mode 100644 index 9e062a7e..00000000 --- a/src/en/fmovies/src/eu/kanade/tachiyomi/animeextension/en/fmovies/FMovies.kt +++ /dev/null @@ -1,368 +0,0 @@ -package eu.kanade.tachiyomi.animeextension.en.fmovies - -import android.app.Application -import android.content.SharedPreferences -import androidx.preference.ListPreference -import androidx.preference.MultiSelectListPreference -import androidx.preference.PreferenceScreen -import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource -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.Track -import eu.kanade.tachiyomi.animesource.model.Video -import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource -import eu.kanade.tachiyomi.lib.filemoonextractor.FilemoonExtractor -import eu.kanade.tachiyomi.lib.streamtapeextractor.StreamTapeExtractor -import eu.kanade.tachiyomi.lib.vidsrcextractor.VidsrcExtractor -import eu.kanade.tachiyomi.network.GET -import eu.kanade.tachiyomi.network.await -import eu.kanade.tachiyomi.network.awaitSuccess -import eu.kanade.tachiyomi.util.asJsoup -import eu.kanade.tachiyomi.util.parallelCatchingFlatMap -import eu.kanade.tachiyomi.util.parseAs -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json -import okhttp3.HttpUrl.Companion.toHttpUrl -import okhttp3.Request -import okhttp3.Response -import org.jsoup.Jsoup -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 FMovies : ConfigurableAnimeSource, ParsedAnimeHttpSource() { - - override val name = "FMovies" - - override val baseUrl = "https://fmovies24.to" - - override val lang = "en" - - override val supportsLatest = true - - private val json: Json by injectLazy() - - private val preferences: SharedPreferences by lazy { - Injekt.get().getSharedPreferences("source_$id", 0x0000) - } - - private val utils by lazy { FmoviesUtils(client, headers) } - - // ============================== Popular =============================== - - override fun popularAnimeRequest(page: Int): Request = GET("$baseUrl/trending${page.toPageQuery()}", headers) - - override fun popularAnimeSelector(): String = "div.items > div.item" - - override fun popularAnimeFromElement(element: Element): SAnime = SAnime.create().apply { - element.selectFirst("div.meta a")!!.let { a -> - title = a.text() - setUrlWithoutDomain(a.attr("abs:href")) - } - - thumbnail_url = element.select("div.poster img").attr("data-src") - } - - override fun popularAnimeNextPageSelector(): String = "ul.pagination > li.active + li" - - // =============================== Latest =============================== - - override fun latestUpdatesRequest(page: Int): Request = - GET("$baseUrl/filter?keyword=&sort=recently_updated${page.toPageQuery(false)}", headers) - - 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 params = FMoviesFilters.getSearchParameters(filters) - - return GET("$baseUrl/filter?keyword=$query${params.filter}${page.toPageQuery(false)}", headers) - } - - override fun searchAnimeSelector(): String = popularAnimeSelector() - - override fun searchAnimeFromElement(element: Element): SAnime = popularAnimeFromElement(element) - - override fun searchAnimeNextPageSelector(): String = popularAnimeNextPageSelector() - - // ============================== Filters =============================== - - override fun getFilterList(): AnimeFilterList = FMoviesFilters.FILTER_LIST - - // =========================== Anime Details ============================ - - override fun animeDetailsParse(document: Document): SAnime { - val info = document.selectFirst("section#w-info > div.info")!! - val detail = info.selectFirst("div.detail") - - val descElement = info.selectFirst("div.description") - val desc = descElement?.selectFirst("div[data-name=full]")?.ownText() ?: descElement?.ownText() ?: "" - val extraInfo = detail?.select("> div")?.joinToString("\n") { it.text() } ?: "" - - val mediaTitle = info.selectFirst("h1.name")!!.text() - val mediaDetail = utils.getDetail(mediaTitle) - - return SAnime.create().apply { - title = mediaTitle - status = when (mediaDetail?.status) { - "Ended", "Released" -> SAnime.COMPLETED - "In Production" -> SAnime.LICENSED - "Canceled" -> SAnime.CANCELLED - "Returning Series" -> { - mediaDetail.nextEpisode?.let { SAnime.ONGOING } ?: SAnime.ON_HIATUS - } - else -> SAnime.UNKNOWN - } - thumbnail_url = document.selectFirst("section#w-info > div.poster img")!!.attr("src") - description = buildString { - appendLine(desc.ifBlank { mediaDetail?.overview }) - appendLine() - mediaDetail?.nextEpisode?.let { - appendLine("Next: Ep ${it.epNumber} - ${it.name}") - appendLine("Air Date: ${it.airDate}") - appendLine() - } - appendLine(extraInfo) - } - genre = detail?.let { dtl -> - dtl.select("> div:has(> div:contains(Genre:)) span").joinToString { it.text() } - } - author = detail?.let { dtl -> - dtl.select("> div:has(> div:contains(Production:)) span").joinToString { it.text() } - } - } - } - - // ============================== Episodes ============================== - - override fun episodeListRequest(anime: SAnime): Request { - val id = client.newCall(GET(baseUrl + anime.url)).execute().asJsoup() - .selectFirst("div[data-id]")!!.attr("data-id") - - val vrf = utils.vrfEncrypt(id) - val vrfHeaders = headers.newBuilder().apply { - add("Accept", "application/json, text/javascript, */*; q=0.01") - add("Host", baseUrl.toHttpUrl().host) - add("Referer", baseUrl + anime.url) - add("X-Requested-With", "XMLHttpRequest") - }.build() - - return GET("$baseUrl/ajax/episode/list/$id?vrf=$vrf", headers = vrfHeaders) - } - - override fun episodeListParse(response: Response): List { - val document = Jsoup.parse( - response.parseAs().result, - ) - val episodeList = mutableListOf() - val seasons = document.select("div.body > ul.episodes") - seasons.forEach { season -> - val seasonPrefix = if (seasons.size > 1) { - "Season ${season.attr("data-season")} " - } else { - "" - } - - season.select("li").forEach { ep -> - episodeList.add( - SEpisode.create().apply { - name = "$seasonPrefix${ep.text().trim()}".replace("Episode ", "Ep. ") - - ep.selectFirst("a")!!.let { a -> - episode_number = a.attr("data-num").toFloatOrNull() ?: 0F - url = json.encodeToString( - EpisodeInfo( - id = a.attr("data-id"), - url = "$baseUrl${a.attr("href")}", - ), - ) - } - }, - ) - } - } - - return episodeList.reversed() - } - - override fun episodeListSelector() = throw UnsupportedOperationException() - - override fun episodeFromElement(element: Element): SEpisode = throw UnsupportedOperationException() - - // ============================ Video Links ============================= - - override suspend fun getVideoList(episode: SEpisode): List