mirror of
https://github.com/hexated/cloudstream-extensions-hexated.git
synced 2024-08-15 00:03:22 +00:00
moved providers
This commit is contained in:
parent
50024b610c
commit
4f77c2e7d4
115 changed files with 6819 additions and 52 deletions
28
KisskhProvider/build.gradle.kts
Normal file
28
KisskhProvider/build.gradle.kts
Normal file
|
@ -0,0 +1,28 @@
|
|||
// use an integer for version numbers
|
||||
version = 3
|
||||
|
||||
|
||||
cloudstream {
|
||||
language = "en"
|
||||
// All of these properties are optional, you can safely remove them
|
||||
|
||||
// description = "Lorem Ipsum"
|
||||
authors = listOf("Hexated")
|
||||
|
||||
/**
|
||||
* Status int as the following:
|
||||
* 0: Down
|
||||
* 1: Ok
|
||||
* 2: Slow
|
||||
* 3: Beta only
|
||||
* */
|
||||
status = 1 // will be 3 if unspecified
|
||||
tvTypes = listOf(
|
||||
"AsianDrama",
|
||||
"TvSeries",
|
||||
"Anime",
|
||||
"Movie",
|
||||
)
|
||||
|
||||
iconUrl = "https://www.google.com/s2/favicons?domain=kisskh.me&sz=%size%"
|
||||
}
|
2
KisskhProvider/src/main/AndroidManifest.xml
Normal file
2
KisskhProvider/src/main/AndroidManifest.xml
Normal file
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest package="com.hexated"/>
|
217
KisskhProvider/src/main/kotlin/com/hexated/KisskhProvider.kt
Normal file
217
KisskhProvider/src/main/kotlin/com/hexated/KisskhProvider.kt
Normal file
|
@ -0,0 +1,217 @@
|
|||
package com.hexated
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
import com.lagradost.cloudstream3.*
|
||||
import com.lagradost.cloudstream3.mvvm.safeApiCall
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.toJson
|
||||
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
|
||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||
import com.lagradost.cloudstream3.utils.M3u8Helper
|
||||
import com.lagradost.cloudstream3.utils.loadExtractor
|
||||
import java.util.ArrayList
|
||||
|
||||
class KisskhProvider : MainAPI() {
|
||||
override var mainUrl = "https://kisskh.me"
|
||||
override var name = "Kisskh"
|
||||
override val hasMainPage = true
|
||||
override val hasDownloadSupport = true
|
||||
override val supportedTypes = setOf(
|
||||
TvType.AsianDrama,
|
||||
TvType.Anime
|
||||
)
|
||||
|
||||
override val mainPage = mainPageOf(
|
||||
"&type=2&sub=0&country=2&status=0&order=1" to "Movie Popular",
|
||||
"&type=2&sub=0&country=2&status=0&order=2" to "Movie Last Update",
|
||||
"&type=1&sub=0&country=2&status=0&order=1" to "TVSeries Popular",
|
||||
"&type=1&sub=0&country=2&status=0&order=2" to "TVSeries Last Update",
|
||||
"&type=3&sub=0&country=0&status=0&order=1" to "Anime Popular",
|
||||
"&type=3&sub=0&country=0&status=0&order=2" to "Anime Last Update",
|
||||
"&type=4&sub=0&country=0&status=0&order=1" to "Hollywood Popular",
|
||||
"&type=4&sub=0&country=0&status=0&order=2" to "Hollywood Last Update",
|
||||
)
|
||||
|
||||
override suspend fun getMainPage(
|
||||
page: Int,
|
||||
request: MainPageRequest
|
||||
): HomePageResponse {
|
||||
val home = app.get("$mainUrl/api/DramaList/List?page=$page${request.data}")
|
||||
.parsedSafe<Responses>()?.data
|
||||
?.mapNotNull { media ->
|
||||
media.toSearchResponse()
|
||||
} ?: throw ErrorLoadingException("Invalid Json reponse")
|
||||
return newHomePageResponse(
|
||||
list = HomePageList(
|
||||
name = request.name,
|
||||
list = home,
|
||||
isHorizontalImages = true
|
||||
),
|
||||
hasNext = true
|
||||
)
|
||||
}
|
||||
|
||||
private fun Media.toSearchResponse(): SearchResponse? {
|
||||
|
||||
return newAnimeSearchResponse(
|
||||
title ?: return null,
|
||||
"$title/$id",
|
||||
TvType.TvSeries,
|
||||
) {
|
||||
this.posterUrl = thumbnail
|
||||
addSub(episodesCount)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun search(query: String): List<SearchResponse> {
|
||||
val searchResponse =
|
||||
app.get("$mainUrl/api/DramaList/Search?q=$query&type=0", referer = "$mainUrl/").text
|
||||
return tryParseJson<ArrayList<Media>>(searchResponse)?.mapNotNull { media ->
|
||||
media.toSearchResponse()
|
||||
} ?: throw ErrorLoadingException("Invalid Json reponse")
|
||||
}
|
||||
|
||||
private fun getTitle(str: String): String {
|
||||
return str.replace(Regex("[^a-zA-Z0-9]"), "-")
|
||||
}
|
||||
|
||||
override suspend fun load(url: String): LoadResponse? {
|
||||
val id = url.split("/")
|
||||
val res = app.get(
|
||||
"$mainUrl/api/DramaList/Drama/${id.last()}?isq=false",
|
||||
referer = "$mainUrl/Drama/${
|
||||
getTitle(id.first())
|
||||
}?id=${id.last()}"
|
||||
).parsedSafe<MediaDetail>()
|
||||
?: throw ErrorLoadingException("Invalid Json reponse")
|
||||
|
||||
val episodes = res.episodes?.map { eps ->
|
||||
Episode(
|
||||
data = Data(res.title, eps.number, res.id, eps.id).toJson(),
|
||||
episode = eps.number
|
||||
)
|
||||
} ?: throw ErrorLoadingException("No Episode")
|
||||
|
||||
return newTvSeriesLoadResponse(
|
||||
res.title ?: return null,
|
||||
url,
|
||||
if (res.type == "Movie" || episodes.size == 1) TvType.Movie else TvType.TvSeries,
|
||||
episodes
|
||||
) {
|
||||
this.posterUrl = res.thumbnail
|
||||
this.year = res.releaseDate?.split("-")?.first()?.toIntOrNull()
|
||||
this.plot = res.description
|
||||
this.tags = listOf("${res.country}", "${res.status}", "${res.type}")
|
||||
this.showStatus = when (res.status) {
|
||||
"Completed" -> ShowStatus.Completed
|
||||
"Ongoing" -> ShowStatus.Ongoing
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun getLanguage(str: String): String {
|
||||
return when (str) {
|
||||
"Indonesia" -> "Indonesian"
|
||||
else -> str
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun loadLinks(
|
||||
data: String,
|
||||
isCasting: Boolean,
|
||||
subtitleCallback: (SubtitleFile) -> Unit,
|
||||
callback: (ExtractorLink) -> Unit
|
||||
): Boolean {
|
||||
|
||||
val loadData = parseJson<Data>(data)
|
||||
|
||||
app.get(
|
||||
"$mainUrl/api/DramaList/Episode/${loadData.epsId}.png?err=false&ts=&time=",
|
||||
referer = "$mainUrl/Drama/${getTitle("${loadData.title}")}/Episode-${loadData.eps}?id=${loadData.id}&ep=${loadData.epsId}&page=0&pageSize=100"
|
||||
).parsedSafe<Sources>()?.let { source ->
|
||||
listOf(source.video, source.thirdParty).apmap { link ->
|
||||
safeApiCall {
|
||||
if (link?.contains(".m3u8") == true) {
|
||||
M3u8Helper.generateM3u8(
|
||||
this.name,
|
||||
link,
|
||||
referer = "$mainUrl/",
|
||||
headers = mapOf("Origin" to mainUrl)
|
||||
).forEach(callback)
|
||||
} else {
|
||||
loadExtractor(
|
||||
link?.substringBefore("=http") ?: return@safeApiCall,
|
||||
"$mainUrl/",
|
||||
subtitleCallback,
|
||||
callback
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// parsedSafe doesn't work in <List<Object>>
|
||||
app.get("$mainUrl/api/Sub/${loadData.epsId}").text.let { res ->
|
||||
tryParseJson<List<Subtitle>>(res)?.map { sub ->
|
||||
subtitleCallback.invoke(
|
||||
SubtitleFile(
|
||||
getLanguage(sub.label ?: return@map),
|
||||
sub.src ?: return@map
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
data class Data(
|
||||
val title: String?,
|
||||
val eps: Int?,
|
||||
val id: Int?,
|
||||
val epsId: Int?,
|
||||
)
|
||||
|
||||
data class Sources(
|
||||
@JsonProperty("Video") val video: String?,
|
||||
@JsonProperty("ThirdParty") val thirdParty: String?,
|
||||
)
|
||||
|
||||
data class Subtitle(
|
||||
@JsonProperty("src") val src: String?,
|
||||
@JsonProperty("label") val label: String?,
|
||||
)
|
||||
|
||||
data class Responses(
|
||||
@JsonProperty("data") val data: ArrayList<Media>? = arrayListOf(),
|
||||
)
|
||||
|
||||
data class Media(
|
||||
@JsonProperty("episodesCount") val episodesCount: Int?,
|
||||
@JsonProperty("thumbnail") val thumbnail: String?,
|
||||
@JsonProperty("id") val id: Int?,
|
||||
@JsonProperty("title") val title: String?,
|
||||
)
|
||||
|
||||
data class Episodes(
|
||||
@JsonProperty("id") val id: Int?,
|
||||
@JsonProperty("number") val number: Int?,
|
||||
@JsonProperty("sub") val sub: Int?,
|
||||
)
|
||||
|
||||
data class MediaDetail(
|
||||
@JsonProperty("description") val description: String?,
|
||||
@JsonProperty("releaseDate") val releaseDate: String?,
|
||||
@JsonProperty("status") val status: String?,
|
||||
@JsonProperty("type") val type: String?,
|
||||
@JsonProperty("country") val country: String?,
|
||||
@JsonProperty("episodes") val episodes: ArrayList<Episodes>? = arrayListOf(),
|
||||
@JsonProperty("thumbnail") val thumbnail: String?,
|
||||
@JsonProperty("id") val id: Int?,
|
||||
@JsonProperty("title") val title: String?,
|
||||
)
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
package com.hexated
|
||||
|
||||
import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
|
||||
import com.lagradost.cloudstream3.plugins.Plugin
|
||||
import android.content.Context
|
||||
|
||||
@CloudstreamPlugin
|
||||
class KisskhProviderPlugin: Plugin() {
|
||||
override fun load(context: Context) {
|
||||
// All providers should be added in this manner. Please don't edit the providers list directly.
|
||||
registerMainAPI(KisskhProvider())
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue