Delete src/all/animeworldindia directory

This commit is contained in:
Arkai1 2025-04-15 22:33:07 +05:30 committed by GitHub
parent 96cb8d34c9
commit f2e2d08323
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 0 additions and 499 deletions

View file

@ -1,11 +0,0 @@
ext {
extName = 'AnimeWorld India'
extClass = '.AnimeWorldIndiaFactory'
extVersionCode = 15
}
apply from: "$rootDir/common.gradle"
dependencies {
implementation(project(":lib:playlist-utils"))
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

View file

@ -1,246 +0,0 @@
package eu.kanade.tachiyomi.animeextension.all.animeworldindia
import android.app.Application
import androidx.preference.ListPreference
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.Video
import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.util.asJsoup
import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
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
class AnimeWorldIndia(
final override val lang: String,
private val language: String,
) : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
override val name = "AnimeWorld India"
override val baseUrl = "https://anime-world.co"
override val supportsLatest = true
private val json: Json by injectLazy()
private val preferences by lazy {
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
}
// ============================== Popular ===============================
override fun popularAnimeRequest(page: Int) = GET("$baseUrl/advanced-search/page/$page/?s_lang=$lang&s_orderby=viewed")
override fun popularAnimeSelector() = searchAnimeSelector()
override fun popularAnimeFromElement(element: Element) = searchAnimeFromElement(element)
override fun popularAnimeNextPageSelector() = searchAnimeNextPageSelector()
// =============================== Latest ===============================
override fun latestUpdatesNextPageSelector() = searchAnimeNextPageSelector()
override fun latestUpdatesSelector() = searchAnimeSelector()
override fun latestUpdatesFromElement(element: Element) = searchAnimeFromElement(element)
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/advanced-search/page/$page/?s_lang=$lang&s_orderby=update")
// =============================== Search ===============================
override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request {
val searchParams = AnimeWorldIndiaFilters().getSearchParams(filters)
return GET("$baseUrl/advanced-search/page/$page/?s_keyword=$query&s_lang=$lang$searchParams")
}
override fun searchAnimeSelector() = "div.col-span-1"
override fun searchAnimeFromElement(element: Element) = SAnime.create().apply {
setUrlWithoutDomain(element.selectFirst("a")!!.attr("href"))
thumbnail_url = element.selectFirst("img")!!.attr("abs:src")
title = element.selectFirst("div.font-medium.line-clamp-2.mb-3")!!.text()
}
override fun searchAnimeNextPageSelector() = "ul.page-numbers li:has(span.current) + li"
override fun getFilterList() = AnimeWorldIndiaFilters().filters
// =========================== Anime Details ============================
override fun animeDetailsParse(document: Document) = SAnime.create().apply {
title = document.selectFirst("h2.text-4xl")!!.text()
genre = document.select("span.leading-6 a[class~=border-opacity-30]").joinToString { it.text() }
description = document.selectFirst("div[data-synopsis]")?.text()
author = document.selectFirst("span.leading-6 a[href*=\"producer\"]:first-child")?.text()
artist = document.selectFirst("span.leading-6 a[href*=\"studio\"]:first-child")?.text()
status = parseStatus(document)
}
private val selector = "ul li:has(div.w-1.h-1.bg-gray-500.rounded-full) + li"
private fun parseStatus(document: Document): Int {
return when (document.selectFirst("$selector a:not(:contains(Ep))")?.text()) {
null -> SAnime.UNKNOWN
"Movie" -> SAnime.COMPLETED
else -> {
val epParts = document.selectFirst("$selector a:not(:contains(TV))")
?.text()
?.drop(3)
?.split("/")
?.takeIf { it.size >= 2 }
?: return SAnime.UNKNOWN
if (epParts.first().trim().compareTo(epParts[1].trim()) == 0) {
SAnime.COMPLETED
} else {
SAnime.ONGOING
}
}
}
}
// ============================== Episodes ==============================
override fun episodeListSelector() = throw UnsupportedOperationException()
override fun episodeFromElement(element: Element): SEpisode = throw UnsupportedOperationException()
@Serializable
data class SeasonDto(val episodes: EpisodeTypeDto)
@Serializable
data class EpisodeTypeDto(val all: List<EpisodeDto>) {
@Serializable
data class EpisodeDto(val id: Int, val metadata: MetadataDto)
@Serializable
data class MetadataDto(
val number: String,
val title: String,
val released: String? = null,
)
}
override fun episodeListParse(response: Response): List<SEpisode> {
val document = response.asJsoup()
val isMovie = document.selectFirst("nav li > a[href*=\"type/movies/\"]") != null
val seasonsJson = json.decodeFromString<List<SeasonDto>>(
document.html()
.substringAfter("var season_list = ")
.substringBefore("var season_label =")
.trim().dropLast(1),
)
var episodeNumberFallback = 1F
val isSingleSeason = seasonsJson.size == 1
return seasonsJson.flatMapIndexed { seasonNumber, season ->
val seasonName = if (isSingleSeason) "" else "Season ${seasonNumber + 1}"
season.episodes.all.reversed().map { episode ->
val episodeTitle = episode.metadata.title
val epNum = episode.metadata.number.toIntOrNull() ?: episodeNumberFallback.toInt()
val episodeName = when {
isMovie -> "Movie"
else -> buildString {
if (seasonName.isNotBlank()) append("$seasonName - ")
append("Episode $epNum")
if (episodeTitle.isNotBlank()) append(" - $episodeTitle")
}
}
SEpisode.create().apply {
name = episodeName
episode_number = when {
isSingleSeason -> epNum.toFloat()
else -> episodeNumberFallback
}
episodeNumberFallback++
setUrlWithoutDomain("$baseUrl/wp-json/kiranime/v1/episode?id=${episode.id}")
date_upload = episode.metadata.released?.toLongOrNull()?.times(1000) ?: 0L
}
}
}.sortedByDescending { it.episode_number }
}
// ============================ Video Links =============================
override fun videoFromElement(element: Element): Video = throw UnsupportedOperationException()
override fun videoUrlParse(document: Document) = throw UnsupportedOperationException()
override fun videoListSelector() = throw UnsupportedOperationException()
@Serializable
private data class PlayerDto(
val type: String,
val url: String,
val language: String,
val server: String,
)
private val mystreamExtractor by lazy { MyStreamExtractor(client, headers) }
override fun videoListParse(response: Response): List<Video> {
val body = response.body.string()
val documentTrimmed = body
.substringAfterLast("\"players\":")
.substringBefore(",\"noplayer\":")
.trim()
val playersList = json.decodeFromString<List<PlayerDto>>(documentTrimmed)
.filter { it.type == "stream" && it.url.isNotBlank() }
.also { require(it.isNotEmpty()) { "No streams available!" } }
.filter { language.isEmpty() || it.language.equals(language) }
.also { require(it.isNotEmpty()) { "No videos for your language!" } }
return playersList.flatMap {
when (it.server) {
"Mystream" -> mystreamExtractor.videosFromUrl(it.url, it.language)
else -> emptyList()
}
}
}
override fun List<Video>.sort(): List<Video> {
val quality = preferences.getString(PREF_QUALITY_KEY, PREF_QUALITY_DEFAULT)!!
return sortedWith(
compareBy { it.quality.contains(quality) },
).reversed()
}
// ============================ Preferences =============================
override fun setupPreferenceScreen(screen: PreferenceScreen) {
ListPreference(screen.context).apply {
key = PREF_QUALITY_KEY
title = PREF_QUALITY_TITLE
entries = PREF_QUALITY_ENTRIES
entryValues = PREF_QUALITY_VALUES
setDefaultValue(PREF_QUALITY_DEFAULT)
summary = "%s"
setOnPreferenceChangeListener { _, newValue ->
val selected = newValue as String
val index = findIndexOfValue(selected)
val entry = entryValues[index] as String
preferences.edit().putString(key, entry).commit()
}
}.also(screen::addPreference)
}
companion object {
private const val PREF_QUALITY_KEY = "preferred_quality"
private const val PREF_QUALITY_TITLE = "Preferred quality"
private const val PREF_QUALITY_DEFAULT = "1080"
private val PREF_QUALITY_ENTRIES = arrayOf("1080p", "720p", "480p", "360p", "240p")
private val PREF_QUALITY_VALUES = arrayOf("1080", "720", "480", "360", "240")
}
}

View file

@ -1,18 +0,0 @@
package eu.kanade.tachiyomi.animeextension.all.animeworldindia
import eu.kanade.tachiyomi.animesource.AnimeSourceFactory
class AnimeWorldIndiaFactory : AnimeSourceFactory {
override fun createSources() = listOf(
AnimeWorldIndia("all", ""),
AnimeWorldIndia("bn", "bengali"),
AnimeWorldIndia("en", "english"),
AnimeWorldIndia("hi", "hindi"),
AnimeWorldIndia("ja", "japanese"),
AnimeWorldIndia("ml", "malayalam"),
AnimeWorldIndia("mr", "marathi"),
AnimeWorldIndia("ta", "tamil"),
AnimeWorldIndia("te", "telugu"),
)
}

View file

@ -1,180 +0,0 @@
package eu.kanade.tachiyomi.animeextension.all.animeworldindia
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
class AnimeWorldIndiaFilters {
private data class StringQuery(val name: String, val query: String)
private class TypeList(types: Array<String>) : AnimeFilter.Select<String>("Type", types)
private val typesName = getTypeList().map {
it.name
}.toTypedArray()
private fun getTypeList() = listOf(
StringQuery("Any", "all"),
StringQuery("TV", "tv"),
StringQuery("Movie", "movie"),
)
private class StatusList(statuses: Array<String>) : AnimeFilter.Select<String>("Status", statuses)
private val statusesName = getStatusesList().map {
it.name
}.toTypedArray()
private fun getStatusesList() = listOf(
StringQuery("Any", "all"),
StringQuery("Currently Airing", "airing"),
StringQuery("Finished Airing", "completed"),
)
private class StyleList(styles: Array<String>) : AnimeFilter.Select<String>("Style", styles)
private val stylesName = getStyleList().map {
it.name
}.toTypedArray()
private fun getStyleList() = listOf(
StringQuery("Any", "all"),
StringQuery("Anime", "anime"),
StringQuery("Cartoon", "cartoon"),
)
private class YearList(years: Array<String>) : AnimeFilter.Select<String>("Year", years)
private val yearsName = getYearList().map {
it.name
}.toTypedArray()
private fun getYearList() = listOf(
StringQuery("Any", "all"),
StringQuery("2025", "2025"),
StringQuery("2024", "2024"),
StringQuery("2023", "2023"),
StringQuery("2022", "2022"),
StringQuery("2021", "2021"),
StringQuery("2020", "2020"),
StringQuery("2019", "2019"),
StringQuery("2018", "2018"),
StringQuery("2017", "2017"),
StringQuery("2016", "2016"),
StringQuery("2015", "2015"),
StringQuery("2014", "2014"),
StringQuery("2013", "2013"),
StringQuery("2012", "2012"),
StringQuery("2011", "2011"),
StringQuery("2010", "2010"),
StringQuery("2009", "2009"),
StringQuery("2008", "2008"),
StringQuery("2007", "2007"),
StringQuery("2006", "2006"),
StringQuery("2005", "2005"),
StringQuery("2004", "2004"),
StringQuery("2003", "2003"),
StringQuery("2002", "2002"),
StringQuery("2001", "2001"),
StringQuery("2000", "2000"),
StringQuery("1999", "1999"),
StringQuery("1998", "1998"),
StringQuery("1997", "1997"),
StringQuery("1996", "1996"),
StringQuery("1995", "1995"),
StringQuery("1994", "1994"),
StringQuery("1993", "1993"),
StringQuery("1992", "1992"),
StringQuery("1991", "1991"),
StringQuery("1990", "1990"),
)
private class SortList(sorts: Array<String>) : AnimeFilter.Select<String>("Sort", sorts)
private val sortsName = getSortList().map {
it.name
}.toTypedArray()
private fun getSortList() = listOf(
StringQuery("Default", "default"),
StringQuery("Ascending", "title_a_z"),
StringQuery("Descending", "title_z_a"),
StringQuery("Updated", "update"),
StringQuery("Published", "date"),
StringQuery("Most Viewed", "viewed"),
StringQuery("Favourite", "favorite"),
)
internal class Genre(val id: String) : AnimeFilter.CheckBox(id)
private class GenreList(genres: List<Genre>) : AnimeFilter.Group<Genre>("Genres", genres)
private fun genresName() = listOf(
Genre("Action"),
Genre("Adult Cast"),
Genre("Adventure"),
Genre("Animation"),
Genre("Comedy"),
Genre("Detective"),
Genre("Drama"),
Genre("Ecchi"),
Genre("Family"),
Genre("Fantasy"),
Genre("Isekai"),
Genre("Kids"),
Genre("Martial Arts"),
Genre("Mecha"),
Genre("Military"),
Genre("Mystery"),
Genre("Otaku Culture"),
Genre("Reality"),
Genre("Romance"),
Genre("School"),
Genre("Sci-Fi"),
Genre("Seinen"),
Genre("Shounen"),
Genre("Slice of Life"),
Genre("Sports"),
Genre("Super Power"),
Genre("SuperHero"),
Genre("Supernatural"),
Genre("TV Movie"),
)
val filters: AnimeFilterList get() = AnimeFilterList(
TypeList(typesName),
StatusList(statusesName),
StyleList(stylesName),
YearList(yearsName),
SortList(sortsName),
GenreList(genresName()),
)
fun getSearchParams(filters: AnimeFilterList): String {
return "&" + filters.mapNotNull { filter ->
when (filter) {
is TypeList -> {
val type = getTypeList()[filter.state].query
"s_type=$type"
}
is StatusList -> {
val status = getStatusesList()[filter.state].query
"s_status=$status"
}
is StyleList -> {
val style = getStyleList()[filter.state].query
"s_sub_type=$style"
}
is YearList -> {
val year = getYearList()[filter.state].query
"s_year=$year"
}
is SortList -> {
val sort = getSortList()[filter.state].query
"s_orderby=$sort"
}
is GenreList -> {
"s_genre=" + filter.state.filter { it.state }
.joinToString("%2C") {
val genre = it.id.replace(" ", "-")
"$genre%2C"
}
}
else -> null
}
}.joinToString("&")
}
}

View file

@ -1,44 +0,0 @@
package eu.kanade.tachiyomi.animeextension.all.animeworldindia
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.lib.playlistutils.PlaylistUtils
import eu.kanade.tachiyomi.network.GET
import okhttp3.Headers
import okhttp3.OkHttpClient
class MyStreamExtractor(private val client: OkHttpClient, private val headers: Headers) {
private val playlistUtils by lazy { PlaylistUtils(client, headers) }
fun videosFromUrl(url: String, language: String): List<Video> {
val host = url.substringBefore("/watch")
return runCatching {
val response = client.newCall(GET(url, headers)).execute()
val body = response.body.string()
val streamCode = body
.substringAfter("sniff(") // Video function
.substringAfter(", \"") // our beloved ID
.substringBefore('"')
val streamUrl = "$host/m3u8/$streamCode/master.txt?s=1&cache=1"
val cookie = response.headers.firstOrNull {
it.first.startsWith("set-cookie", true) && it.second.startsWith("PHPSESSID", true)
}?.second?.substringBefore(";") ?: ""
val newHeaders = headers.newBuilder()
.set("cookie", cookie)
.set("accept", "*/*")
.build()
playlistUtils.extractFromHls(
streamUrl,
masterHeaders = newHeaders,
videoHeaders = newHeaders,
videoNameGen = { "[$language] MyStream: $it" },
)
}.getOrElse { emptyList<Video>() }
}
}