diff --git a/Aniworld/build.gradle.kts b/Aniworld/build.gradle.kts index 004864a6..d303a028 100644 --- a/Aniworld/build.gradle.kts +++ b/Aniworld/build.gradle.kts @@ -1,12 +1,12 @@ // use an integer for version numbers -version = 4 +version = 5 cloudstream { language = "de" // All of these properties are optional, you can safely remove them - // description = "Lorem Ipsum" + description = "Include: Serienstream" authors = listOf("Hexated") /** diff --git a/Aniworld/src/main/kotlin/com/hexated/Aniworld.kt b/Aniworld/src/main/kotlin/com/hexated/Aniworld.kt index f0765f52..a5c6b08f 100644 --- a/Aniworld/src/main/kotlin/com/hexated/Aniworld.kt +++ b/Aniworld/src/main/kotlin/com/hexated/Aniworld.kt @@ -13,12 +13,11 @@ import org.jsoup.nodes.Document import org.jsoup.nodes.Element import java.net.URI -class Aniworld : MainAPI() { +open class Aniworld : MainAPI() { override var mainUrl = "https://aniworld.to" override var name = "Aniworld" override val hasMainPage = true override var lang = "de" - override val hasDownloadSupport = true override val supportedTypes = setOf( TvType.Anime, diff --git a/Aniworld/src/main/kotlin/com/hexated/AniworldPlugin.kt b/Aniworld/src/main/kotlin/com/hexated/AniworldPlugin.kt index b70bad8f..7eee506e 100644 --- a/Aniworld/src/main/kotlin/com/hexated/AniworldPlugin.kt +++ b/Aniworld/src/main/kotlin/com/hexated/AniworldPlugin.kt @@ -10,6 +10,7 @@ class AniworldPlugin: Plugin() { override fun load(context: Context) { // All providers should be added in this manner. Please don't edit the providers list directly. registerMainAPI(Aniworld()) + registerMainAPI(Serienstream()) registerExtractorAPI(Urochsunloath()) registerExtractorAPI(Simpulumlamerop()) registerExtractorAPI(Dooood()) diff --git a/Aniworld/src/main/kotlin/com/hexated/Serienstream.kt b/Aniworld/src/main/kotlin/com/hexated/Serienstream.kt new file mode 100644 index 00000000..d7a88ed5 --- /dev/null +++ b/Aniworld/src/main/kotlin/com/hexated/Serienstream.kt @@ -0,0 +1,12 @@ +package com.hexated + +import com.lagradost.cloudstream3.TvType + +class Serienstream : Aniworld() { + override var mainUrl = "https://s.to" + override var name = "Serienstream" + override val supportedTypes = setOf( + TvType.Movie, + TvType.TvSeries, + ) +} \ No newline at end of file diff --git a/Nimegami/build.gradle.kts b/Nimegami/build.gradle.kts index 82d96dc1..e861ae1d 100644 --- a/Nimegami/build.gradle.kts +++ b/Nimegami/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 1 +version = 2 cloudstream { diff --git a/Nimegami/src/main/kotlin/com/hexated/Nimegami.kt b/Nimegami/src/main/kotlin/com/hexated/Nimegami.kt index 69541e2e..7b2babd5 100644 --- a/Nimegami/src/main/kotlin/com/hexated/Nimegami.kt +++ b/Nimegami/src/main/kotlin/com/hexated/Nimegami.kt @@ -2,6 +2,7 @@ package com.hexated import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson import org.jsoup.nodes.Element @@ -21,9 +22,12 @@ class Nimegami : MainAPI() { companion object { fun getType(t: String): TvType { - return if (t.contains("OVA", true) || t.contains("Special", true)) TvType.OVA - else if (t.contains("Movie", true)) TvType.AnimeMovie - else TvType.Anime + return when { + t.contains("Tv", true) -> TvType.AnimeMovie + t.contains("Movie", true) -> TvType.AnimeMovie + t.contains("OVA", true) || t.contains("Special", true) -> TvType.OVA + else -> TvType.Anime + } } fun getStatus(t: String?): ShowStatus { @@ -94,7 +98,7 @@ class Nimegami : MainAPI() { val status = getStatus(document.selectFirst("h1[itemprop=headline]")?.text()) val type = table.getContent("Type").text() val description = document.select("div#Sinopsis p").text().trim() - + val trailer = document.selectFirst("div#Trailer iframe")?.attr("src") val episodes = document.select("div.list_eps_stream li") .mapNotNull { @@ -124,6 +128,7 @@ class Nimegami : MainAPI() { plot = description this.tags = tags this.recommendations = recommendations + addTrailer(trailer) } } diff --git a/Xcineio/build.gradle.kts b/Xcineio/build.gradle.kts index 3261137f..2434acfa 100644 --- a/Xcineio/build.gradle.kts +++ b/Xcineio/build.gradle.kts @@ -1,12 +1,12 @@ // use an integer for version numbers -version = 3 +version = 4 cloudstream { language = "de" // All of these properties are optional, you can safely remove them - // description = "Lorem Ipsum" + description = "Include: Movie4k" authors = listOf("Hexated") /** diff --git a/Xcineio/src/main/kotlin/com/hexated/Movie4k.kt b/Xcineio/src/main/kotlin/com/hexated/Movie4k.kt new file mode 100644 index 00000000..f5eca865 --- /dev/null +++ b/Xcineio/src/main/kotlin/com/hexated/Movie4k.kt @@ -0,0 +1,16 @@ +package com.hexated + +import com.lagradost.cloudstream3.mainPageOf + +class Movie4k : XCine() { + override var name = "Movie4k" + override var mainUrl = "https://movie4k.stream" + override var mainAPI = "https://api.movie4k.stream" + + override val mainPage = mainPageOf( + "data/browse/?lang=2&keyword=&year=&rating=&votes=&genre=&country=&cast=&directors=&type=movies&order_by=trending" to "Derzeit Beliebt Filme", + "data/browse/?lang=2&keyword=&year=&rating=&votes=&genre=&country=&cast=&directors=&type=movies&order_by=releases" to "Neu Filme", + "data/browse/?lang=2&keyword=&year=&rating=&votes=&genre=&country=&cast=&directors=&type=tvseries&order_by=trending" to "Derzeit Beliebt Serien", + "data/browse/?lang=2&keyword=&year=&rating=&votes=&genre=&country=&cast=&directors=&type=tvseries&order_by=releases" to "Neu Serien", + ) +} \ No newline at end of file diff --git a/Xcineio/src/main/kotlin/com/hexated/XCine.kt b/Xcineio/src/main/kotlin/com/hexated/XCine.kt index aaf68804..0431f393 100644 --- a/Xcineio/src/main/kotlin/com/hexated/XCine.kt +++ b/Xcineio/src/main/kotlin/com/hexated/XCine.kt @@ -9,22 +9,22 @@ import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.Qualities import com.lagradost.cloudstream3.utils.loadExtractor -class XCine : MainAPI() { +open class XCine : MainAPI() { override var name = "XCine" - override var mainUrl = "https://xcine.info" + override var mainUrl = "https://xcine.ru" override var lang = "de" override val hasQuickSearch = true override val usesWebView = false override val hasMainPage = true override val supportedTypes = setOf(TvType.TvSeries, TvType.Movie) - private val mainAPI = "https://api.xcine.info" + open var mainAPI = "https://api.xcine.ru" override val mainPage = mainPageOf( - "$mainAPI/data/browse/?lang=2&keyword=&year=&rating=&votes=&genre=&country=&cast=&directors=&type=movies&order_by=trending&page=" to "Trending", - "$mainAPI/data/browse/?lang=2&keyword=&year=&rating=&votes=&genre=&country=&cast=&directors=&type=movies&order_by=Views&page=" to "Most View Filme", - "$mainAPI/data/browse/?lang=2&keyword=&year=&rating=&votes=&genre=&country=&cast=&directors=&type=tvseries&order_by=Trending&page=" to "Trending Serien", - "$mainAPI/data/browse/?lang=2&keyword=&year=&rating=&votes=&genre=&country=&cast=&directors=&type=movies&order_by=Updates&page=" to "Updated Filme", - "$mainAPI/data/browse/?lang=2&keyword=&year=&rating=&votes=&genre=&country=&cast=&directors=&type=tvseries&order_by=Updates&page=" to "Updated Serien", + "data/browse/?lang=2&keyword=&year=&rating=&votes=&genre=&country=&cast=&directors=&type=movies&order_by=trending" to "Trending", + "data/browse/?lang=2&keyword=&year=&rating=&votes=&genre=&country=&cast=&directors=&type=movies&order_by=Views" to "Most View Filme", + "data/browse/?lang=2&keyword=&year=&rating=&votes=&genre=&country=&cast=&directors=&type=tvseries&order_by=Trending" to "Trending Serien", + "data/browse/?lang=2&keyword=&year=&rating=&votes=&genre=&country=&cast=&directors=&type=movies&order_by=Updates" to "Updated Filme", + "data/browse/?lang=2&keyword=&year=&rating=&votes=&genre=&country=&cast=&directors=&type=tvseries&order_by=Updates" to "Updated Serien", ) private fun getImageUrl(link: String?): String? { @@ -32,12 +32,17 @@ class XCine : MainAPI() { return if (link.startsWith("/")) "https://image.tmdb.org/t/p/w500/$link" else link } + private fun getBackupImageUrl(link: String?): String? { + if (link == null) return null + return "https://cdn.movie4k.stream/data${link.substringAfter("/data")}" + } + override suspend fun getMainPage( page: Int, request: MainPageRequest ): HomePageResponse { val home = - app.get(request.data + page, referer = "$mainUrl/") + app.get("$mainAPI/${request.data}&page=$page", referer = "$mainUrl/") .parsedSafe()?.movies?.mapNotNull { res -> res.toSearchResponse() } ?: throw ErrorLoadingException() @@ -48,11 +53,11 @@ class XCine : MainAPI() { return newAnimeSearchResponse( title ?: original_title ?: return null, // Data(_id).toJson(), - "$_id", + Link(id=_id).toJson(), TvType.TvSeries, false ) { - this.posterUrl = getImageUrl(poster_path ?: backdrop_path) + this.posterUrl = getImageUrl(poster_path ?: backdrop_path) ?: getBackupImageUrl(img) addDub(last_updated_epi?.toIntOrNull()) addSub(totalEpisodes?.toIntOrNull()) } @@ -61,16 +66,14 @@ class XCine : MainAPI() { override suspend fun quickSearch(query: String): List = search(query) override suspend fun search(query: String): List { - return app.get( - "$mainAPI/data/browse/?lang=2&keyword=$query&year=&rating=&votes=&genre=&country=&cast=&directors=&type=&order_by=&page=1", - referer = "$mainUrl/" - ).parsedSafe()?.movies?.mapNotNull { res -> - res.toSearchResponse() + val res = app.get("$mainAPI/data/search/?lang=2&keyword=$query", referer = "$mainUrl/").text + return tryParseJson>(res)?.mapNotNull { + it.toSearchResponse() } ?: throw ErrorLoadingException() } override suspend fun load(url: String): LoadResponse? { - val id = url.replace("$mainUrl/", "") + val id = parseJson(url).id val res = app.get("$mainAPI/data/watch/?_id=$id", referer = "$mainUrl/") .parsedSafe() ?: throw ErrorLoadingException() @@ -84,20 +87,13 @@ class XCine : MainAPI() { } return if (type == "tv") { - val episodes = mutableListOf() - val json = - app.get("$mainAPI/data/seasons/?lang=2&original_title=${res.original_title}").text.let { - tryParseJson>(it) - } - json?.map { season -> - season.streams?.distinctBy { it.e }?.map { eps -> - episodes.add(Episode(data = season.streams.filter { it.e == eps.e } - .map { Link(it.stream) } - .toJson(), episode = eps.e, season = season.s)) - } - } + val episodes = res.streams?.groupBy { it.e.toString().toIntOrNull() }?.mapNotNull { eps -> + val epsNum = eps.key + val epsLink = eps.value.map { it.stream }.toJson() + Episode(epsLink, episode = epsNum) + } ?: emptyList() newTvSeriesLoadResponse( - res.original_title ?: res.title ?: return null, + res.title ?: res.original_title ?: return null, url, TvType.TvSeries, episodes @@ -135,7 +131,7 @@ class XCine : MainAPI() { val loadData = parseJson>(data) loadData.apmap { val link = fixUrlNull(it.link) ?: return@apmap null - if(link.startsWith("https://dl.streamcloud")) { + if (link.startsWith("https://dl.streamcloud")) { callback.invoke( ExtractorLink( this.name, @@ -159,7 +155,8 @@ class XCine : MainAPI() { } data class Link( - val link: String?, + val link: String? = null, + val id: String? = null, ) data class Season( @@ -173,7 +170,7 @@ class XCine : MainAPI() { data class Streams( @JsonProperty("_id") val _id: String? = null, @JsonProperty("stream") val stream: String? = null, - @JsonProperty("e") val e: Int? = null, + @JsonProperty("e") val e: Any? = null, @JsonProperty("e_title") val e_title: String? = null, ) @@ -199,6 +196,7 @@ class XCine : MainAPI() { @JsonProperty("title") val title: String? = null, @JsonProperty("poster_path") val poster_path: String? = null, @JsonProperty("backdrop_path") val backdrop_path: String? = null, + @JsonProperty("img") val img: String? = null, @JsonProperty("imdb_id") val imdb_id: String? = null, @JsonProperty("totalEpisodes") val totalEpisodes: String? = null, @JsonProperty("last_updated_epi") val last_updated_epi: String? = null, diff --git a/Xcineio/src/main/kotlin/com/hexated/XCinePlugin.kt b/Xcineio/src/main/kotlin/com/hexated/XCinePlugin.kt index 625945aa..8989499f 100644 --- a/Xcineio/src/main/kotlin/com/hexated/XCinePlugin.kt +++ b/Xcineio/src/main/kotlin/com/hexated/XCinePlugin.kt @@ -10,6 +10,7 @@ class XCinePlugin: Plugin() { override fun load(context: Context) { // All providers should be added in this manner. Please don't edit the providers list directly. registerMainAPI(XCine()) + registerMainAPI(Movie4k()) registerExtractorAPI(StreamTapeAdblockuser()) registerExtractorAPI(StreamTapeTo()) registerExtractorAPI(Mixdrp())