[Time4tv] added DaddyHD Channels

This commit is contained in:
hexated 2023-01-01 21:03:35 +07:00
parent 99422ff76b
commit 771643a9d7
4 changed files with 79 additions and 32 deletions

View file

@ -147,9 +147,9 @@ open class SoraStream : TmdbProvider() {
page: Int,
request: MainPageRequest
): 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 home = app.get("${request.data}$adultQuery$page")
val home = app.get("${request.data}$adultQuery&page=$page")
.parsedSafe<Results>()?.results
?.mapNotNull { media ->
media.toSearchResponse(type)
@ -180,9 +180,9 @@ open class SoraStream : TmdbProvider() {
val data = parseJson<Data>(url)
val type = getType(data.type)
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 {
"$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>()
?: throw ErrorLoadingException("Invalid Json Response")
@ -195,6 +195,8 @@ open class SoraStream : TmdbProvider() {
val rating = res.vote_average.toString().toRatingInt()
val genres = res.genres?.mapNotNull { it.name }
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 ->
ActorData(
@ -252,7 +254,7 @@ open class SoraStream : TmdbProvider() {
this.backgroundPosterUrl = bgPoster
this.year = year
this.plot = res.overview
this.tags = genres
this.tags = if (isAnime) keywords else genres
this.rating = rating
this.showStatus = getStatus(res.status)
this.recommendations = recommendations
@ -278,7 +280,7 @@ open class SoraStream : TmdbProvider() {
this.backgroundPosterUrl = bgPoster
this.year = year
this.plot = res.overview
this.tags = genres
this.tags = if (isAnime) keywords else genres
this.rating = rating
this.recommendations = recommendations
this.actors = actors
@ -534,6 +536,16 @@ open class SoraStream : TmdbProvider() {
@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(
@JsonProperty("id") val id: Int? = null,
@JsonProperty("name") val name: String? = null,
@ -602,6 +614,7 @@ open class SoraStream : TmdbProvider() {
@JsonProperty("original_language") val original_language: String? = null,
@JsonProperty("status") val status: String? = null,
@JsonProperty("genres") val genres: ArrayList<Genres>? = arrayListOf(),
@JsonProperty("keywords") val keywords: KeywordResults? = null,
@JsonProperty("seasons") val seasons: ArrayList<Seasons>? = arrayListOf(),
@JsonProperty("videos") val videos: ResultsTrailer? = null,
@JsonProperty("external_ids") val external_ids: ExternalIds? = null,
@ -609,14 +622,6 @@ open class SoraStream : TmdbProvider() {
@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(
@JsonProperty("type") val type: String? = null,
@JsonProperty("link") val link: String? = null,

View file

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

View file

@ -9,6 +9,7 @@ import org.jsoup.nodes.Element
open class TimefourTv : MainAPI() {
final override var mainUrl = "https://time4tv.stream"
val daddyUrl = "https://daddyhd.com"
override var name = "Time4tv"
override val hasDownloadSupport = false
override val hasMainPage = true
@ -25,8 +26,14 @@ open class TimefourTv : MainAPI() {
"$mainUrl/live-sports-streams" to "Live Sport Channels",
"$mainUrl/news-channels" to "News Channels",
"$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(
page: Int,
request: MainPageRequest
@ -38,7 +45,7 @@ open class TimefourTv : MainAPI() {
val home = res.select("div.tab-content ul li").mapNotNull {
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") {
val res = if (page == 1) {
@ -49,7 +56,15 @@ open class TimefourTv : MainAPI() {
val home = res.select("div.tab-content ul li").mapNotNull {
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") {
@ -57,12 +72,22 @@ open class TimefourTv : MainAPI() {
val schedule = res.select("div.search_p h1,div.search_p h2").mapNotNull {
it.toSearchSchedule()
}
items.add(HomePageList(request.name, schedule, true))
if (schedule.isNotEmpty()) items.add(HomePageList(request.name, schedule, true))
}
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? {
return LiveSearchResponse(
this.text() ?: return null,
@ -115,10 +140,13 @@ open class TimefourTv : MainAPI() {
if (!res.isSuccessful) return loadSchedule(url)
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 =
fixUrlNull(document.selectFirst("meta[property=\"og:image\"]")?.attr("content"))
val description = document.selectFirst("div.tvText")?.text() ?: return null
fixUrlNull(document.selectFirst("meta[property=\"og:image\"]")?.attr("content")) ?: time4tvPoster
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('")
?.substringBefore("',")?.let { link ->
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) {
this.posterUrl = poster
this.plot = description
@ -155,13 +187,13 @@ open class TimefourTv : MainAPI() {
): Boolean {
val link = when {
data.contains("/channel") -> app.get(data).document.selectFirst("div.tv_palyer iframe")?.attr("src")
data.startsWith(mainUrl) -> {
app.get(data, allowRedirects = false).document.selectFirst("iframe")?.attr("src")
}
else -> {
data
}
data.contains("/channel") -> app.get(data).document.selectFirst("div.tv_palyer iframe")
?.attr("src")
data.startsWith(mainUrl) -> app.get(
data,
allowRedirects = false
).document.selectFirst("iframe")?.attr("src")
else -> data
} ?: throw ErrorLoadingException()
getLink(fixUrl(link))?.let { m3uLink ->
val url = app.get(m3uLink, referer = "$mainServer/")

View file

@ -3,6 +3,7 @@ package com.hexated
import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.fixUrl
import com.lagradost.cloudstream3.utils.getAndUnpack
import com.lagradost.nicehttp.NiceResponse
import java.net.URI
var mainServer: String? = null
@ -71,6 +72,11 @@ object TimefourTvExtractor : TimefourTv() {
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 doc = app.get(url, referer = "$mainUrl/").document
val tempIframe = doc.selectFirst("iframe")?.attr("src") ?: return null
@ -105,15 +111,19 @@ object TimefourTvExtractor : TimefourTv() {
val docThird = app.get(fixUrl(iframeSecond), referer = "$refSecond/")
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
) ?: run {
val scriptData =
docThird.document.selectFirst("div#player")?.nextElementSibling()?.data()
res.document.selectFirst("div#player")?.nextElementSibling()?.data()
?.substringAfterLast("return(")?.substringBefore(".join")
scriptData?.removeSurrounding("[", "]")?.replace("\"", "")?.split(",")
?.joinToString("")
}
}
}