added Serienstream & Movie4k

This commit is contained in:
sora 2023-07-25 14:46:32 +07:00
parent 839ec22f67
commit 571f455100
10 changed files with 76 additions and 44 deletions

View file

@ -1,12 +1,12 @@
// use an integer for version numbers // use an integer for version numbers
version = 4 version = 5
cloudstream { cloudstream {
language = "de" language = "de"
// All of these properties are optional, you can safely remove them // All of these properties are optional, you can safely remove them
// description = "Lorem Ipsum" description = "Include: Serienstream"
authors = listOf("Hexated") authors = listOf("Hexated")
/** /**

View file

@ -13,12 +13,11 @@ import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import java.net.URI import java.net.URI
class Aniworld : MainAPI() { open class Aniworld : MainAPI() {
override var mainUrl = "https://aniworld.to" override var mainUrl = "https://aniworld.to"
override var name = "Aniworld" override var name = "Aniworld"
override val hasMainPage = true override val hasMainPage = true
override var lang = "de" override var lang = "de"
override val hasDownloadSupport = true
override val supportedTypes = setOf( override val supportedTypes = setOf(
TvType.Anime, TvType.Anime,

View file

@ -10,6 +10,7 @@ class AniworldPlugin: Plugin() {
override fun load(context: Context) { override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly. // All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(Aniworld()) registerMainAPI(Aniworld())
registerMainAPI(Serienstream())
registerExtractorAPI(Urochsunloath()) registerExtractorAPI(Urochsunloath())
registerExtractorAPI(Simpulumlamerop()) registerExtractorAPI(Simpulumlamerop())
registerExtractorAPI(Dooood()) registerExtractorAPI(Dooood())

View file

@ -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,
)
}

View file

@ -1,5 +1,5 @@
// use an integer for version numbers // use an integer for version numbers
version = 1 version = 2
cloudstream { cloudstream {

View file

@ -2,6 +2,7 @@ package com.hexated
import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer
import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.*
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
@ -21,9 +22,12 @@ class Nimegami : MainAPI() {
companion object { companion object {
fun getType(t: String): TvType { fun getType(t: String): TvType {
return if (t.contains("OVA", true) || t.contains("Special", true)) TvType.OVA return when {
else if (t.contains("Movie", true)) TvType.AnimeMovie t.contains("Tv", true) -> TvType.AnimeMovie
else TvType.Anime t.contains("Movie", true) -> TvType.AnimeMovie
t.contains("OVA", true) || t.contains("Special", true) -> TvType.OVA
else -> TvType.Anime
}
} }
fun getStatus(t: String?): ShowStatus { fun getStatus(t: String?): ShowStatus {
@ -94,7 +98,7 @@ class Nimegami : MainAPI() {
val status = getStatus(document.selectFirst("h1[itemprop=headline]")?.text()) val status = getStatus(document.selectFirst("h1[itemprop=headline]")?.text())
val type = table.getContent("Type").text() val type = table.getContent("Type").text()
val description = document.select("div#Sinopsis p").text().trim() 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") val episodes = document.select("div.list_eps_stream li")
.mapNotNull { .mapNotNull {
@ -124,6 +128,7 @@ class Nimegami : MainAPI() {
plot = description plot = description
this.tags = tags this.tags = tags
this.recommendations = recommendations this.recommendations = recommendations
addTrailer(trailer)
} }
} }

View file

@ -1,12 +1,12 @@
// use an integer for version numbers // use an integer for version numbers
version = 3 version = 4
cloudstream { cloudstream {
language = "de" language = "de"
// All of these properties are optional, you can safely remove them // All of these properties are optional, you can safely remove them
// description = "Lorem Ipsum" description = "Include: Movie4k"
authors = listOf("Hexated") authors = listOf("Hexated")
/** /**

View file

@ -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",
)
}

View file

@ -9,22 +9,22 @@ import com.lagradost.cloudstream3.utils.ExtractorLink
import com.lagradost.cloudstream3.utils.Qualities import com.lagradost.cloudstream3.utils.Qualities
import com.lagradost.cloudstream3.utils.loadExtractor import com.lagradost.cloudstream3.utils.loadExtractor
class XCine : MainAPI() { open class XCine : MainAPI() {
override var name = "XCine" override var name = "XCine"
override var mainUrl = "https://xcine.info" override var mainUrl = "https://xcine.ru"
override var lang = "de" override var lang = "de"
override val hasQuickSearch = true override val hasQuickSearch = true
override val usesWebView = false override val usesWebView = false
override val hasMainPage = true override val hasMainPage = true
override val supportedTypes = setOf(TvType.TvSeries, TvType.Movie) 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( 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", "data/browse/?lang=2&keyword=&year=&rating=&votes=&genre=&country=&cast=&directors=&type=movies&order_by=trending" 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", "data/browse/?lang=2&keyword=&year=&rating=&votes=&genre=&country=&cast=&directors=&type=movies&order_by=Views" 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", "data/browse/?lang=2&keyword=&year=&rating=&votes=&genre=&country=&cast=&directors=&type=tvseries&order_by=Trending" 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", "data/browse/?lang=2&keyword=&year=&rating=&votes=&genre=&country=&cast=&directors=&type=movies&order_by=Updates" 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=tvseries&order_by=Updates" to "Updated Serien",
) )
private fun getImageUrl(link: String?): String? { 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 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( override suspend fun getMainPage(
page: Int, page: Int,
request: MainPageRequest request: MainPageRequest
): HomePageResponse { ): HomePageResponse {
val home = val home =
app.get(request.data + page, referer = "$mainUrl/") app.get("$mainAPI/${request.data}&page=$page", referer = "$mainUrl/")
.parsedSafe<MediaResponse>()?.movies?.mapNotNull { res -> .parsedSafe<MediaResponse>()?.movies?.mapNotNull { res ->
res.toSearchResponse() res.toSearchResponse()
} ?: throw ErrorLoadingException() } ?: throw ErrorLoadingException()
@ -48,11 +53,11 @@ class XCine : MainAPI() {
return newAnimeSearchResponse( return newAnimeSearchResponse(
title ?: original_title ?: return null, title ?: original_title ?: return null,
// Data(_id).toJson(), // Data(_id).toJson(),
"$_id", Link(id=_id).toJson(),
TvType.TvSeries, TvType.TvSeries,
false false
) { ) {
this.posterUrl = getImageUrl(poster_path ?: backdrop_path) this.posterUrl = getImageUrl(poster_path ?: backdrop_path) ?: getBackupImageUrl(img)
addDub(last_updated_epi?.toIntOrNull()) addDub(last_updated_epi?.toIntOrNull())
addSub(totalEpisodes?.toIntOrNull()) addSub(totalEpisodes?.toIntOrNull())
} }
@ -61,16 +66,14 @@ class XCine : MainAPI() {
override suspend fun quickSearch(query: String): List<SearchResponse> = search(query) override suspend fun quickSearch(query: String): List<SearchResponse> = search(query)
override suspend fun search(query: String): List<SearchResponse> { override suspend fun search(query: String): List<SearchResponse> {
return app.get( val res = app.get("$mainAPI/data/search/?lang=2&keyword=$query", referer = "$mainUrl/").text
"$mainAPI/data/browse/?lang=2&keyword=$query&year=&rating=&votes=&genre=&country=&cast=&directors=&type=&order_by=&page=1", return tryParseJson<ArrayList<Media>>(res)?.mapNotNull {
referer = "$mainUrl/" it.toSearchResponse()
).parsedSafe<MediaResponse>()?.movies?.mapNotNull { res ->
res.toSearchResponse()
} ?: throw ErrorLoadingException() } ?: throw ErrorLoadingException()
} }
override suspend fun load(url: String): LoadResponse? { override suspend fun load(url: String): LoadResponse? {
val id = url.replace("$mainUrl/", "") val id = parseJson<Link>(url).id
val res = app.get("$mainAPI/data/watch/?_id=$id", referer = "$mainUrl/") val res = app.get("$mainAPI/data/watch/?_id=$id", referer = "$mainUrl/")
.parsedSafe<MediaDetail>() ?: throw ErrorLoadingException() .parsedSafe<MediaDetail>() ?: throw ErrorLoadingException()
@ -84,20 +87,13 @@ class XCine : MainAPI() {
} }
return if (type == "tv") { return if (type == "tv") {
val episodes = mutableListOf<Episode>() val episodes = res.streams?.groupBy { it.e.toString().toIntOrNull() }?.mapNotNull { eps ->
val json = val epsNum = eps.key
app.get("$mainAPI/data/seasons/?lang=2&original_title=${res.original_title}").text.let { val epsLink = eps.value.map { it.stream }.toJson()
tryParseJson<List<Season>>(it) Episode(epsLink, episode = epsNum)
} } ?: emptyList()
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))
}
}
newTvSeriesLoadResponse( newTvSeriesLoadResponse(
res.original_title ?: res.title ?: return null, res.title ?: res.original_title ?: return null,
url, url,
TvType.TvSeries, TvType.TvSeries,
episodes episodes
@ -135,7 +131,7 @@ class XCine : MainAPI() {
val loadData = parseJson<List<Link>>(data) val loadData = parseJson<List<Link>>(data)
loadData.apmap { loadData.apmap {
val link = fixUrlNull(it.link) ?: return@apmap null val link = fixUrlNull(it.link) ?: return@apmap null
if(link.startsWith("https://dl.streamcloud")) { if (link.startsWith("https://dl.streamcloud")) {
callback.invoke( callback.invoke(
ExtractorLink( ExtractorLink(
this.name, this.name,
@ -159,7 +155,8 @@ class XCine : MainAPI() {
} }
data class Link( data class Link(
val link: String?, val link: String? = null,
val id: String? = null,
) )
data class Season( data class Season(
@ -173,7 +170,7 @@ class XCine : MainAPI() {
data class Streams( data class Streams(
@JsonProperty("_id") val _id: String? = null, @JsonProperty("_id") val _id: String? = null,
@JsonProperty("stream") val stream: 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, @JsonProperty("e_title") val e_title: String? = null,
) )
@ -199,6 +196,7 @@ class XCine : MainAPI() {
@JsonProperty("title") val title: String? = null, @JsonProperty("title") val title: String? = null,
@JsonProperty("poster_path") val poster_path: String? = null, @JsonProperty("poster_path") val poster_path: String? = null,
@JsonProperty("backdrop_path") val backdrop_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("imdb_id") val imdb_id: String? = null,
@JsonProperty("totalEpisodes") val totalEpisodes: String? = null, @JsonProperty("totalEpisodes") val totalEpisodes: String? = null,
@JsonProperty("last_updated_epi") val last_updated_epi: String? = null, @JsonProperty("last_updated_epi") val last_updated_epi: String? = null,

View file

@ -10,6 +10,7 @@ class XCinePlugin: Plugin() {
override fun load(context: Context) { override fun load(context: Context) {
// All providers should be added in this manner. Please don't edit the providers list directly. // All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(XCine()) registerMainAPI(XCine())
registerMainAPI(Movie4k())
registerExtractorAPI(StreamTapeAdblockuser()) registerExtractorAPI(StreamTapeAdblockuser())
registerExtractorAPI(StreamTapeTo()) registerExtractorAPI(StreamTapeTo())
registerExtractorAPI(Mixdrp()) registerExtractorAPI(Mixdrp())