mirror of
https://github.com/hexated/cloudstream-extensions-hexated.git
synced 2024-08-15 00:03:22 +00:00
[Time4tv] added DaddyHD Channels
This commit is contained in:
parent
99422ff76b
commit
771643a9d7
4 changed files with 79 additions and 32 deletions
|
@ -147,9 +147,9 @@ open class SoraStream : TmdbProvider() {
|
||||||
page: Int,
|
page: Int,
|
||||||
request: MainPageRequest
|
request: MainPageRequest
|
||||||
): HomePageResponse {
|
): HomePageResponse {
|
||||||
val adultQuery = if(settingsForProvider.enableAdult) "&page=" else "&without_keywords=190370|13059|226161|195669&page="
|
val adultQuery = if (settingsForProvider.enableAdult) "" else "&without_keywords=190370|13059|226161|195669"
|
||||||
val type = if (request.data.contains("/movie")) "movie" else "tv"
|
val type = if (request.data.contains("/movie")) "movie" else "tv"
|
||||||
val home = app.get("${request.data}$adultQuery$page")
|
val home = app.get("${request.data}$adultQuery&page=$page")
|
||||||
.parsedSafe<Results>()?.results
|
.parsedSafe<Results>()?.results
|
||||||
?.mapNotNull { media ->
|
?.mapNotNull { media ->
|
||||||
media.toSearchResponse(type)
|
media.toSearchResponse(type)
|
||||||
|
@ -180,9 +180,9 @@ open class SoraStream : TmdbProvider() {
|
||||||
val data = parseJson<Data>(url)
|
val data = parseJson<Data>(url)
|
||||||
val type = getType(data.type)
|
val type = getType(data.type)
|
||||||
val resUrl = if (type == TvType.Movie) {
|
val resUrl = if (type == TvType.Movie) {
|
||||||
"$tmdbAPI/movie/${data.id}?api_key=$apiKey&append_to_response=credits,external_ids,videos,recommendations"
|
"$tmdbAPI/movie/${data.id}?api_key=$apiKey&append_to_response=keywords,credits,external_ids,videos,recommendations"
|
||||||
} else {
|
} else {
|
||||||
"$tmdbAPI/tv/${data.id}?api_key=$apiKey&append_to_response=credits,external_ids,videos,recommendations"
|
"$tmdbAPI/tv/${data.id}?api_key=$apiKey&append_to_response=keywords,credits,external_ids,videos,recommendations"
|
||||||
}
|
}
|
||||||
val res = app.get(resUrl).parsedSafe<MediaDetail>()
|
val res = app.get(resUrl).parsedSafe<MediaDetail>()
|
||||||
?: throw ErrorLoadingException("Invalid Json Response")
|
?: throw ErrorLoadingException("Invalid Json Response")
|
||||||
|
@ -195,6 +195,8 @@ open class SoraStream : TmdbProvider() {
|
||||||
val rating = res.vote_average.toString().toRatingInt()
|
val rating = res.vote_average.toString().toRatingInt()
|
||||||
val genres = res.genres?.mapNotNull { it.name }
|
val genres = res.genres?.mapNotNull { it.name }
|
||||||
val isAnime = genres?.contains("Animation") == true && res.original_language == "ja"
|
val isAnime = genres?.contains("Animation") == true && res.original_language == "ja"
|
||||||
|
val keywords = res.keywords?.results?.mapNotNull { it.name }.orEmpty()
|
||||||
|
.ifEmpty { res.keywords?.keywords?.mapNotNull { it.name } }
|
||||||
|
|
||||||
val actors = res.credits?.cast?.mapNotNull { cast ->
|
val actors = res.credits?.cast?.mapNotNull { cast ->
|
||||||
ActorData(
|
ActorData(
|
||||||
|
@ -252,7 +254,7 @@ open class SoraStream : TmdbProvider() {
|
||||||
this.backgroundPosterUrl = bgPoster
|
this.backgroundPosterUrl = bgPoster
|
||||||
this.year = year
|
this.year = year
|
||||||
this.plot = res.overview
|
this.plot = res.overview
|
||||||
this.tags = genres
|
this.tags = if (isAnime) keywords else genres
|
||||||
this.rating = rating
|
this.rating = rating
|
||||||
this.showStatus = getStatus(res.status)
|
this.showStatus = getStatus(res.status)
|
||||||
this.recommendations = recommendations
|
this.recommendations = recommendations
|
||||||
|
@ -278,7 +280,7 @@ open class SoraStream : TmdbProvider() {
|
||||||
this.backgroundPosterUrl = bgPoster
|
this.backgroundPosterUrl = bgPoster
|
||||||
this.year = year
|
this.year = year
|
||||||
this.plot = res.overview
|
this.plot = res.overview
|
||||||
this.tags = genres
|
this.tags = if (isAnime) keywords else genres
|
||||||
this.rating = rating
|
this.rating = rating
|
||||||
this.recommendations = recommendations
|
this.recommendations = recommendations
|
||||||
this.actors = actors
|
this.actors = actors
|
||||||
|
@ -534,6 +536,16 @@ open class SoraStream : TmdbProvider() {
|
||||||
@JsonProperty("name") val name: String? = null,
|
@JsonProperty("name") val name: String? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
data class Keywords(
|
||||||
|
@JsonProperty("id") val id: Int? = null,
|
||||||
|
@JsonProperty("name") val name: String? = null,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class KeywordResults(
|
||||||
|
@JsonProperty("results") val results: ArrayList<Keywords>? = arrayListOf(),
|
||||||
|
@JsonProperty("keywords") val keywords: ArrayList<Keywords>? = arrayListOf(),
|
||||||
|
)
|
||||||
|
|
||||||
data class Seasons(
|
data class Seasons(
|
||||||
@JsonProperty("id") val id: Int? = null,
|
@JsonProperty("id") val id: Int? = null,
|
||||||
@JsonProperty("name") val name: String? = null,
|
@JsonProperty("name") val name: String? = null,
|
||||||
|
@ -602,6 +614,7 @@ open class SoraStream : TmdbProvider() {
|
||||||
@JsonProperty("original_language") val original_language: String? = null,
|
@JsonProperty("original_language") val original_language: String? = null,
|
||||||
@JsonProperty("status") val status: String? = null,
|
@JsonProperty("status") val status: String? = null,
|
||||||
@JsonProperty("genres") val genres: ArrayList<Genres>? = arrayListOf(),
|
@JsonProperty("genres") val genres: ArrayList<Genres>? = arrayListOf(),
|
||||||
|
@JsonProperty("keywords") val keywords: KeywordResults? = null,
|
||||||
@JsonProperty("seasons") val seasons: ArrayList<Seasons>? = arrayListOf(),
|
@JsonProperty("seasons") val seasons: ArrayList<Seasons>? = arrayListOf(),
|
||||||
@JsonProperty("videos") val videos: ResultsTrailer? = null,
|
@JsonProperty("videos") val videos: ResultsTrailer? = null,
|
||||||
@JsonProperty("external_ids") val external_ids: ExternalIds? = null,
|
@JsonProperty("external_ids") val external_ids: ExternalIds? = null,
|
||||||
|
@ -609,14 +622,6 @@ open class SoraStream : TmdbProvider() {
|
||||||
@JsonProperty("recommendations") val recommendations: ResultsRecommendations? = null,
|
@JsonProperty("recommendations") val recommendations: ResultsRecommendations? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
// data class PageProps(
|
|
||||||
// @JsonProperty("id") val id: String? = null,
|
|
||||||
// @JsonProperty("imdb") val imdbId: String? = null,
|
|
||||||
// @JsonProperty("result") val result: MediaDetail? = null,
|
|
||||||
// @JsonProperty("recommandations") val recommandations: ArrayList<Media>? = arrayListOf(),
|
|
||||||
// @JsonProperty("cast") val cast: ArrayList<Cast>? = arrayListOf(),
|
|
||||||
// )
|
|
||||||
|
|
||||||
data class EmbedJson(
|
data class EmbedJson(
|
||||||
@JsonProperty("type") val type: String? = null,
|
@JsonProperty("type") val type: String? = null,
|
||||||
@JsonProperty("link") val link: String? = null,
|
@JsonProperty("link") val link: String? = null,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// use an integer for version numbers
|
// use an integer for version numbers
|
||||||
version = 12
|
version = 13
|
||||||
|
|
||||||
|
|
||||||
cloudstream {
|
cloudstream {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import org.jsoup.nodes.Element
|
||||||
|
|
||||||
open class TimefourTv : MainAPI() {
|
open class TimefourTv : MainAPI() {
|
||||||
final override var mainUrl = "https://time4tv.stream"
|
final override var mainUrl = "https://time4tv.stream"
|
||||||
|
val daddyUrl = "https://daddyhd.com"
|
||||||
override var name = "Time4tv"
|
override var name = "Time4tv"
|
||||||
override val hasDownloadSupport = false
|
override val hasDownloadSupport = false
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
|
@ -25,8 +26,14 @@ open class TimefourTv : MainAPI() {
|
||||||
"$mainUrl/live-sports-streams" to "Live Sport Channels",
|
"$mainUrl/live-sports-streams" to "Live Sport Channels",
|
||||||
"$mainUrl/news-channels" to "News Channels",
|
"$mainUrl/news-channels" to "News Channels",
|
||||||
"$mainUrl/schedule.php" to "Schedule",
|
"$mainUrl/schedule.php" to "Schedule",
|
||||||
|
"$daddyUrl/24-7-channels.php" to "DaddyHD Channels"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private fun fixDetailLink(link: String?): String? {
|
||||||
|
if (link == null) return null
|
||||||
|
return if (link.startsWith("/")) "$daddyUrl$link" else link
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun getMainPage(
|
override suspend fun getMainPage(
|
||||||
page: Int,
|
page: Int,
|
||||||
request: MainPageRequest
|
request: MainPageRequest
|
||||||
|
@ -38,7 +45,7 @@ open class TimefourTv : MainAPI() {
|
||||||
val home = res.select("div.tab-content ul li").mapNotNull {
|
val home = res.select("div.tab-content ul li").mapNotNull {
|
||||||
it.toSearchResult()
|
it.toSearchResult()
|
||||||
}
|
}
|
||||||
if(home.isNotEmpty()) items.add(HomePageList(request.name, home, true))
|
if (home.isNotEmpty()) items.add(HomePageList(request.name, home, true))
|
||||||
}
|
}
|
||||||
if (request.name == "All Channels") {
|
if (request.name == "All Channels") {
|
||||||
val res = if (page == 1) {
|
val res = if (page == 1) {
|
||||||
|
@ -49,7 +56,15 @@ open class TimefourTv : MainAPI() {
|
||||||
val home = res.select("div.tab-content ul li").mapNotNull {
|
val home = res.select("div.tab-content ul li").mapNotNull {
|
||||||
it.toSearchResult()
|
it.toSearchResult()
|
||||||
}
|
}
|
||||||
if(home.isNotEmpty()) items.add(HomePageList(request.name, home, true))
|
if (home.isNotEmpty()) items.add(HomePageList(request.name, home, true))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nonPaged && request.name == "DaddyHD Channels") {
|
||||||
|
val res = app.get(request.data).document
|
||||||
|
val channelDaddy = res.select("div.grid-container div.grid-item").mapNotNull {
|
||||||
|
it.toSearchDaddy()
|
||||||
|
}
|
||||||
|
if (channelDaddy.isNotEmpty()) items.add(HomePageList(request.name, channelDaddy, true))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nonPaged && request.name == "Schedule") {
|
if (nonPaged && request.name == "Schedule") {
|
||||||
|
@ -57,12 +72,22 @@ open class TimefourTv : MainAPI() {
|
||||||
val schedule = res.select("div.search_p h1,div.search_p h2").mapNotNull {
|
val schedule = res.select("div.search_p h1,div.search_p h2").mapNotNull {
|
||||||
it.toSearchSchedule()
|
it.toSearchSchedule()
|
||||||
}
|
}
|
||||||
items.add(HomePageList(request.name, schedule, true))
|
if (schedule.isNotEmpty()) items.add(HomePageList(request.name, schedule, true))
|
||||||
}
|
}
|
||||||
|
|
||||||
return newHomePageResponse(items)
|
return newHomePageResponse(items)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun Element.toSearchDaddy(): LiveSearchResponse? {
|
||||||
|
return LiveSearchResponse(
|
||||||
|
this.select("strong").text() ?: return null,
|
||||||
|
fixDetailLink(this.select("a").attr("href")) ?: return null,
|
||||||
|
this@TimefourTv.name,
|
||||||
|
TvType.Live,
|
||||||
|
posterUrl = time4tvPoster
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun Element.toSearchSchedule(): LiveSearchResponse? {
|
private fun Element.toSearchSchedule(): LiveSearchResponse? {
|
||||||
return LiveSearchResponse(
|
return LiveSearchResponse(
|
||||||
this.text() ?: return null,
|
this.text() ?: return null,
|
||||||
|
@ -115,10 +140,13 @@ open class TimefourTv : MainAPI() {
|
||||||
if (!res.isSuccessful) return loadSchedule(url)
|
if (!res.isSuccessful) return loadSchedule(url)
|
||||||
|
|
||||||
val document = res.document
|
val document = res.document
|
||||||
val title = document.selectFirst("div.channelHeading h1")?.text() ?: return null
|
val title =
|
||||||
|
document.selectFirst("div.channelHeading h1")?.text() ?: document.selectFirst("title")
|
||||||
|
?.text()?.substringBefore("HD")?.trim() ?: return null
|
||||||
val poster =
|
val poster =
|
||||||
fixUrlNull(document.selectFirst("meta[property=\"og:image\"]")?.attr("content"))
|
fixUrlNull(document.selectFirst("meta[property=\"og:image\"]")?.attr("content")) ?: time4tvPoster
|
||||||
val description = document.selectFirst("div.tvText")?.text() ?: return null
|
val description = document.selectFirst("div.tvText")?.text()
|
||||||
|
?: document.selectFirst("meta[name=description]")?.attr("content") ?: return null
|
||||||
val episodes = document.selectFirst("div.playit")?.attr("onclick")?.substringAfter("open('")
|
val episodes = document.selectFirst("div.playit")?.attr("onclick")?.substringAfter("open('")
|
||||||
?.substringBefore("',")?.let { link ->
|
?.substringBefore("',")?.let { link ->
|
||||||
val doc = app.get(link).document.selectFirst("div.tv_palyer iframe")?.attr("src")
|
val doc = app.get(link).document.selectFirst("div.tv_palyer iframe")?.attr("src")
|
||||||
|
@ -140,7 +168,11 @@ open class TimefourTv : MainAPI() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} ?: throw ErrorLoadingException("Refresh page")
|
} ?: listOf(
|
||||||
|
Episode(
|
||||||
|
document.selectFirst("div#content iframe")?.attr("src") ?: return null, title
|
||||||
|
)
|
||||||
|
) ?: throw ErrorLoadingException("Refresh page")
|
||||||
return newTvSeriesLoadResponse(title, url, TvType.TvSeries, episodes) {
|
return newTvSeriesLoadResponse(title, url, TvType.TvSeries, episodes) {
|
||||||
this.posterUrl = poster
|
this.posterUrl = poster
|
||||||
this.plot = description
|
this.plot = description
|
||||||
|
@ -155,13 +187,13 @@ open class TimefourTv : MainAPI() {
|
||||||
): Boolean {
|
): Boolean {
|
||||||
|
|
||||||
val link = when {
|
val link = when {
|
||||||
data.contains("/channel") -> app.get(data).document.selectFirst("div.tv_palyer iframe")?.attr("src")
|
data.contains("/channel") -> app.get(data).document.selectFirst("div.tv_palyer iframe")
|
||||||
data.startsWith(mainUrl) -> {
|
?.attr("src")
|
||||||
app.get(data, allowRedirects = false).document.selectFirst("iframe")?.attr("src")
|
data.startsWith(mainUrl) -> app.get(
|
||||||
}
|
data,
|
||||||
else -> {
|
allowRedirects = false
|
||||||
data
|
).document.selectFirst("iframe")?.attr("src")
|
||||||
}
|
else -> data
|
||||||
} ?: throw ErrorLoadingException()
|
} ?: throw ErrorLoadingException()
|
||||||
getLink(fixUrl(link))?.let { m3uLink ->
|
getLink(fixUrl(link))?.let { m3uLink ->
|
||||||
val url = app.get(m3uLink, referer = "$mainServer/")
|
val url = app.get(m3uLink, referer = "$mainServer/")
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.hexated
|
||||||
import com.lagradost.cloudstream3.app
|
import com.lagradost.cloudstream3.app
|
||||||
import com.lagradost.cloudstream3.fixUrl
|
import com.lagradost.cloudstream3.fixUrl
|
||||||
import com.lagradost.cloudstream3.utils.getAndUnpack
|
import com.lagradost.cloudstream3.utils.getAndUnpack
|
||||||
|
import com.lagradost.nicehttp.NiceResponse
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
|
||||||
var mainServer: String? = null
|
var mainServer: String? = null
|
||||||
|
@ -71,6 +72,11 @@ object TimefourTvExtractor : TimefourTv() {
|
||||||
return getSportLink(url)
|
return getSportLink(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(url.contains("daddyhd")) {
|
||||||
|
mainServer = getBaseUrl(url)
|
||||||
|
return getFinalLink(app.get(url, referer = daddyUrl))
|
||||||
|
}
|
||||||
|
|
||||||
val (channel, iframe) = if (url.contains("width=") || url.contains("/link")) {
|
val (channel, iframe) = if (url.contains("width=") || url.contains("/link")) {
|
||||||
val doc = app.get(url, referer = "$mainUrl/").document
|
val doc = app.get(url, referer = "$mainUrl/").document
|
||||||
val tempIframe = doc.selectFirst("iframe")?.attr("src") ?: return null
|
val tempIframe = doc.selectFirst("iframe")?.attr("src") ?: return null
|
||||||
|
@ -105,15 +111,19 @@ object TimefourTvExtractor : TimefourTv() {
|
||||||
val docThird = app.get(fixUrl(iframeSecond), referer = "$refSecond/")
|
val docThird = app.get(fixUrl(iframeSecond), referer = "$refSecond/")
|
||||||
mainServer = getBaseUrl(iframeSecond)
|
mainServer = getBaseUrl(iframeSecond)
|
||||||
|
|
||||||
return Regex("""source:['|"](\S+.m3u8)['|"],""").find(docThird.text)?.groupValues?.getOrNull(
|
return getFinalLink(docThird)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getFinalLink(res: NiceResponse): String? {
|
||||||
|
return Regex("""source:['|"](\S+.m3u8)['|"],""").find(res.text)?.groupValues?.getOrNull(
|
||||||
1
|
1
|
||||||
) ?: run {
|
) ?: run {
|
||||||
val scriptData =
|
val scriptData =
|
||||||
docThird.document.selectFirst("div#player")?.nextElementSibling()?.data()
|
res.document.selectFirst("div#player")?.nextElementSibling()?.data()
|
||||||
?.substringAfterLast("return(")?.substringBefore(".join")
|
?.substringAfterLast("return(")?.substringBefore(".join")
|
||||||
scriptData?.removeSurrounding("[", "]")?.replace("\"", "")?.split(",")
|
scriptData?.removeSurrounding("[", "]")?.replace("\"", "")?.split(",")
|
||||||
?.joinToString("")
|
?.joinToString("")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue