mirror of
				https://github.com/recloudstream/cloudstream.git
				synced 2024-08-15 01:53:11 +00:00 
			
		
		
		
	
							parent
							
								
									ff7b875b09
								
							
						
					
					
						commit
						cc7bf8534c
					
				
					 5 changed files with 288 additions and 183 deletions
				
			
		|  | @ -100,6 +100,7 @@ object APIHolder { | |||
|             OpenVidsProvider(),        | ||||
|             IdlixProvider(), | ||||
|             MultiplexProvider(), | ||||
|             VidSrcProvider(), | ||||
| 
 | ||||
|             // Metadata providers | ||||
|             //TmdbProvider(), | ||||
|  |  | |||
|  | @ -50,12 +50,12 @@ class MonoschinosProvider : MainAPI() { | |||
|             HomePageList( | ||||
|                 "Capítulos actualizados", | ||||
|                 app.get(mainUrl, timeout = 120).document.select(".col-6").map { | ||||
|                     val title = it.selectFirst("p.animetitles")!!.text() | ||||
|                     val title = it.selectFirst("p.animetitles")?.text() ?: it.selectFirst(".animetitles")?.text() ?: "" | ||||
|                     val poster = it.selectFirst(".animeimghv")!!.attr("data-src") | ||||
|                     val epRegex = Regex("episodio-(\\d+)") | ||||
|                     val url = it.selectFirst("a")?.attr("href")!!.replace("ver/", "anime/") | ||||
|                         .replace(epRegex, "sub-espanol") | ||||
|                     val epNum = it.selectFirst(".positioning h5")?.text()?.toIntOrNull() | ||||
|                     val epNum = (it.selectFirst(".positioning h5")?.text() ?: it.selectFirst("div.positioning p")?.text())?.toIntOrNull() | ||||
|                     newAnimeSearchResponse(title, url) { | ||||
|                         this.posterUrl = fixUrl(poster) | ||||
|                         addDubStatus(getDubStatus(title), epNum) | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ package com.lagradost.cloudstream3.movieproviders | |||
| import com.fasterxml.jackson.annotation.JsonProperty | ||||
| import com.lagradost.cloudstream3.* | ||||
| import com.lagradost.cloudstream3.LoadResponse.Companion.addActors | ||||
| import com.lagradost.cloudstream3.network.cookies | ||||
| import com.lagradost.cloudstream3.utils.AppUtils.parseJson | ||||
| import com.lagradost.cloudstream3.utils.ExtractorLink | ||||
| import com.lagradost.cloudstream3.utils.getQualityFromName | ||||
|  | @ -22,6 +23,8 @@ class TheFlixToProvider : MainAPI() { | |||
|         TvType.TvSeries, | ||||
|     ) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     data class HomeJson( | ||||
|         @JsonProperty("props") val props: HomeProps = HomeProps(), | ||||
|     ) | ||||
|  | @ -92,9 +95,54 @@ class TheFlixToProvider : MainAPI() { | |||
|         @JsonProperty("conversionDate") val conversionDate: String? = null, | ||||
|         @JsonProperty("id") val id: Int? = null, | ||||
|         @JsonProperty("available") val available: Boolean? = null, | ||||
|         @JsonProperty("videos"           ) val videos           : ArrayList<String>? = arrayListOf(), | ||||
|     ) | ||||
| 
 | ||||
| 
 | ||||
|     private suspend fun getCookies(): Map<String, String> { | ||||
|         //  val cookieResponse = app.post( | ||||
|         //      "https://theflix.to:5679/authorization/session/continue?contentUsageType=Viewing", | ||||
|         //    headers = mapOf( | ||||
|         //          "Host" to "theflix.to:5679", | ||||
|         //          "User-Agent" to "Mozilla/5.0 (Windows NT 10.0; rv:91.0) Gecko/20100101 Firefox/91.0", | ||||
|         //          "Accept" to "application/json, text/plain," | ||||
|         //          "Accept-Language" to "en-US,en;q=0.5", | ||||
|         //          "Content-Type" to "application/json;charset=utf-8", | ||||
|         //          "Content-Length" to "35", | ||||
|         //          "Origin" to "https://theflix.to", | ||||
|         //          "DNT" to "1", | ||||
|         //          "Connection" to "keep-alive", | ||||
|         //          "Referer" to "https://theflix.to/", | ||||
|         //          "Sec-Fetch-Dest" to "empty", | ||||
|         //          "Sec-Fetch-Mode" to "cors", | ||||
|         //          "Sec-Fetch-Site" to "same-site",)).okhttpResponse.headers.values("Set-Cookie") | ||||
| 
 | ||||
|         val cookies = app.post( | ||||
|             "$mainUrl:5679/authorization/session/continue?contentUsageType=Viewing", | ||||
|             headers = mapOf( | ||||
|                 "Host" to "theflix.to:5679", | ||||
|                 "User-Agent" to USER_AGENT, | ||||
|                 "Accept" to "application/json, text/plain, */*", | ||||
|                 "Accept-Language" to "en-US,en;q=0.5", | ||||
|                 "Content-Type" to "application/json;charset=utf-8", | ||||
|                 "Content-Length" to "35", | ||||
|                 "Origin" to mainUrl, | ||||
|                 "DNT" to "1", | ||||
|                 "Connection" to "keep-alive", | ||||
|                 "Referer" to mainUrl, | ||||
|                 "Sec-Fetch-Dest" to "empty", | ||||
|                 "Sec-Fetch-Mode" to "cors", | ||||
|                 "Sec-Fetch-Site" to "same-site",) | ||||
|         ).cookies | ||||
|         /* val cookieRegex = Regex("(theflix\\..*?id\\=[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)") | ||||
|        val findcookie = cookieRegex.findAll(cookieResponse.toString()).map { it.value }.toList() | ||||
|        val cookiesstring = findcookie.toString().replace(", ","; ").replace("[","").replace("]","") | ||||
|        val cookiesmap = mapOf("Cookie" to cookiesstring) */ | ||||
|         latestCookies = cookies | ||||
|         return latestCookies | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     override suspend fun getMainPage(): HomePageResponse { | ||||
|         val items = ArrayList<HomePageList>() | ||||
|         val doc = app.get(mainUrl).document | ||||
|  | @ -131,7 +179,7 @@ class TheFlixToProvider : MainAPI() { | |||
|                         if (type?.contains("TV") == true) TvType.TvSeries else TvType.Movie | ||||
|                     val link = | ||||
|                         if (typeinfo == TvType.Movie) "$mainUrl/movie/${info.id}-${cleanTitle(title)}" | ||||
|                         else "$mainUrl/tv-show/${info.id}-${cleanTitle(title)}/season-1/episode-1" | ||||
|                         else "$mainUrl/tv-show/${info.id}-${cleanTitle(title).replace("?","")}/season-1/episode-1" | ||||
|                     TvSeriesSearchResponse( | ||||
|                         title, | ||||
|                         link, | ||||
|  | @ -226,67 +274,53 @@ class TheFlixToProvider : MainAPI() { | |||
|         } | ||||
|         return search | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     data class LoadMain ( | ||||
|         @JsonProperty("props") val props: LoadProps = LoadProps(), | ||||
|         @JsonProperty("page") var page: String? = null, | ||||
|         //@JsonProperty("query") val query: Query? = Query(), | ||||
|         @JsonProperty("props"         ) val props         : LoadProps?         = LoadProps(), | ||||
|         @JsonProperty("page"          ) val page          : String?        = null, | ||||
|         @JsonProperty("buildId"       ) val buildId       : String?        = null, | ||||
|         @JsonProperty("runtimeConfig" ) val runtimeConfig : RuntimeConfig? = RuntimeConfig(), | ||||
|         @JsonProperty("isFallback"    ) val isFallback    : Boolean?       = null, | ||||
|         @JsonProperty("gssp"          ) val gssp          : Boolean?       = null, | ||||
|         @JsonProperty("customServer"  ) val customServer  : Boolean?       = null, | ||||
|         @JsonProperty("appGip"        ) val appGip        : Boolean?       = null | ||||
|     ) | ||||
| 
 | ||||
|     data class RuntimeConfig( | ||||
|         @JsonProperty("AddThisService") val AddThisService: AddThisService? = AddThisService(), | ||||
|         //@JsonProperty("Application") val Application: Application? = Application(), | ||||
|         //@JsonProperty("Content") val Content: Content? = Content(), | ||||
|         //@JsonProperty("GtmService") val GtmService: GtmService? = GtmService(), | ||||
|         //@JsonProperty("IptvChannels") val IptvChannels: IptvChannels? = IptvChannels(), | ||||
|         //@JsonProperty("Notifications") val Notifications: Notifications? = Notifications(), | ||||
|         //@JsonProperty("Payments") val Payments: Payments? = Payments(), | ||||
|         //@JsonProperty("Redux") val Redux: Redux? = Redux(), | ||||
|         //@JsonProperty("Search") val Search: Search? = Search(), | ||||
|         @JsonProperty("Services") val Services: Services? = Services(), | ||||
|         //@JsonProperty("Sitemap") val Sitemap: Sitemap? = Sitemap(), | ||||
|         //@JsonProperty("Support") val Support: Support? = Support(), | ||||
|         @JsonProperty("Videos") val Videos: Videos? = Videos() | ||||
|     ) | ||||
| 
 | ||||
| 
 | ||||
|     data class Server( | ||||
|         @JsonProperty("Url") var Url: String? = null | ||||
|     ) | ||||
| 
 | ||||
|     data class Services( | ||||
| 
 | ||||
|         @JsonProperty("Server") val Server: Server? = Server(), | ||||
|         @JsonProperty("TmdbServer") val TmdbServer: Server? = Server() | ||||
| 
 | ||||
|     ) | ||||
| 
 | ||||
|     data class AddThisService( | ||||
|         @JsonProperty("PublicId") val PublicId: String? = null | ||||
|     ) | ||||
| 
 | ||||
|     data class LoadProps ( | ||||
|         @JsonProperty("pageProps") val pageProps: LoadPageProps = LoadPageProps(), | ||||
|         @JsonProperty("pageProps" ) val pageProps : LoadPageProps? = LoadPageProps(), | ||||
|         @JsonProperty("__N_SSP"   ) val _NSSP     : Boolean?   = null | ||||
|     ) | ||||
| 
 | ||||
|     data class LoadPageProps ( | ||||
|         @JsonProperty("selectedTv"          ) val selectedTv          : TheFlixMetadata?          = TheFlixMetadata(), | ||||
|         @JsonProperty("movie") val movie: TheFlixMetadata? = TheFlixMetadata(), | ||||
|         @JsonProperty("videoUrl") val videoUrl: String? = null, | ||||
|         @JsonProperty("recommendationsList" ) val recommendationsList : RecommendationsList? = RecommendationsList(), | ||||
|         @JsonProperty("basePageSegments"    ) val basePageSegments    : ArrayList<String>?    = arrayListOf() | ||||
|     ) | ||||
| 
 | ||||
|     data class Genres( | ||||
|         @JsonProperty("name") val name: String, | ||||
|         @JsonProperty("id") val id: Int? = null | ||||
|     data class TheFlixMetadata ( | ||||
|         @JsonProperty("episodeRuntime"   ) val episodeRuntime   : Int?               = null, | ||||
|         @JsonProperty("name"             ) val name             : String?            = null, | ||||
|         @JsonProperty("numberOfSeasons"  ) val numberOfSeasons  : Int?               = null, | ||||
|         @JsonProperty("numberOfEpisodes" ) val numberOfEpisodes : Int?               = null, | ||||
|         @JsonProperty("originalLanguage" ) val originalLanguage : String?            = null, | ||||
|         @JsonProperty("popularity"       ) val popularity       : Double?            = null, | ||||
|         @JsonProperty("status"           ) val status           : String?            = null, | ||||
|         @JsonProperty("voteAverage"      ) val voteAverage      : Double?            = null, | ||||
|         @JsonProperty("voteCount"        ) val voteCount        : Int?               = null, | ||||
|         @JsonProperty("cast"             ) val cast             : String?            = null, | ||||
|         @JsonProperty("director"         ) val director         : String?            = null, | ||||
|         @JsonProperty("overview"         ) val overview         : String?            = null, | ||||
|         @JsonProperty("posterUrl"        ) val posterUrl        : String?            = null, | ||||
|         @JsonProperty("releaseDate"      ) val releaseDate      : String?            = null, | ||||
|         @JsonProperty("createdAt"        ) val createdAt        : String?            = null, | ||||
|         @JsonProperty("updatedAt"        ) val updatedAt        : String?            = null, | ||||
|         @JsonProperty("id"               ) val id               : Int?               = null, | ||||
|         @JsonProperty("available"        ) val available        : Boolean?           = null, | ||||
|         @JsonProperty("genres"           ) val genres           : ArrayList<Genres>?  = arrayListOf(), | ||||
|         @JsonProperty("seasons"          ) val seasons          : ArrayList<Seasons>? = arrayListOf(), | ||||
|         @JsonProperty("videos"           ) val videos           : ArrayList<String>? = arrayListOf(), | ||||
|         @JsonProperty("runtime"          ) val runtime          : Int?              = null, | ||||
|     ) | ||||
| 
 | ||||
|     data class Seasons( | ||||
|         @JsonProperty("name") val name: String? = null, | ||||
|         @JsonProperty("numberOfEpisodes") val numberOfEpisodes: Int? = null, | ||||
|  | @ -297,7 +331,7 @@ class TheFlixToProvider : MainAPI() { | |||
|         @JsonProperty("createdAt") val createdAt: String? = null, | ||||
|         @JsonProperty("updatedAt") val updatedAt: String? = null, | ||||
|         @JsonProperty("id") val id: Int? = null, | ||||
|         @JsonProperty("episodes") val episodes: ArrayList<Episodes> = arrayListOf() | ||||
|         @JsonProperty("episodes") val episodes: ArrayList<Episodes>? = arrayListOf() | ||||
|     ) | ||||
| 
 | ||||
|     data class Episodes( | ||||
|  | @ -311,17 +345,50 @@ class TheFlixToProvider : MainAPI() { | |||
|         @JsonProperty("createdAt") val createdAt: String? = null, | ||||
|         @JsonProperty("updatedAt") val updatedAt: String? = null, | ||||
|         @JsonProperty("id") val id: Int? = null, | ||||
|         @JsonProperty("videos") val videos: ArrayList<Videos> = arrayListOf() | ||||
|         @JsonProperty("videos") val videos: ArrayList<String>? = arrayListOf() | ||||
|     ) | ||||
| 
 | ||||
|     data class Videos( | ||||
|         @JsonProperty("language") val language: String? = null, | ||||
| 
 | ||||
|     data class Genres ( | ||||
|         @JsonProperty("name" ) val name : String? = null, | ||||
|         @JsonProperty("id"   ) val id   : Int?    = null | ||||
|     ) | ||||
| 
 | ||||
|     data class RuntimeConfig ( | ||||
|         @JsonProperty("AddThisService" ) val AddThisService : RuntimeConfigData? = RuntimeConfigData(), | ||||
|         @JsonProperty("Application"    ) val Application    : RuntimeConfigData?    = RuntimeConfigData(), | ||||
|         @JsonProperty("GtmService"     ) val GtmService     : RuntimeConfigData?     = RuntimeConfigData(), | ||||
|         @JsonProperty("Services"       ) val Services       : RuntimeConfigData?       = RuntimeConfigData(), | ||||
|     ) | ||||
| 
 | ||||
|     data class RuntimeConfigData( | ||||
|         @JsonProperty("PublicId" ) val PublicId : String? = null, | ||||
|         @JsonProperty("ContentUsageType"              ) val ContentUsageType              : String?  = null, | ||||
|         @JsonProperty("IsDevelopmentMode"             ) val IsDevelopmentMode             : Boolean? = null, | ||||
|         @JsonProperty("IsDevelopmentOrProductionMode" ) val IsDevelopmentOrProductionMode : Boolean? = null, | ||||
|         @JsonProperty("IsProductionMode"              ) val IsProductionMode              : Boolean? = null, | ||||
|         @JsonProperty("IsStagingMode"                 ) val IsStagingMode                 : Boolean? = null, | ||||
|         @JsonProperty("IsTestMode"                    ) val IsTestMode                    : Boolean? = null, | ||||
|         @JsonProperty("Mode"                          ) val Mode                          : String?  = null, | ||||
|         @JsonProperty("Name"                          ) val Name                          : String?  = null, | ||||
|         @JsonProperty("Url"                           ) val Url                           : String?  = null, | ||||
|         @JsonProperty("UseFilterInfoInUrl"            ) val UseFilterInfoInUrl            : Boolean? = null, | ||||
|         @JsonProperty("TrackingId" ) val TrackingId : String? = null, | ||||
|         @JsonProperty("Server"     ) val Server     : Server?     = Server(), | ||||
|         @JsonProperty("TmdbServer" ) val TmdbServer : TmdbServer? = TmdbServer(), | ||||
|     ) | ||||
| 
 | ||||
|     data class TmdbServer ( | ||||
|         @JsonProperty("Url" ) val Url : String? = null | ||||
|     ) | ||||
| 
 | ||||
| 
 | ||||
|     data class Server ( | ||||
|         @JsonProperty("Url" ) val Url : String? = null | ||||
|     ) | ||||
| 
 | ||||
|     data class RecommendationsList ( | ||||
|         @JsonProperty("docs") val docs: ArrayList<LoadDocs> = arrayListOf(), | ||||
|         @JsonProperty("docs"  ) val docs  : ArrayList<Docs> = arrayListOf(), | ||||
|         @JsonProperty("total" ) val total : Int?            = null, | ||||
|         @JsonProperty("page"  ) val page  : Int?            = null, | ||||
|         @JsonProperty("limit" ) val limit : Int?            = null, | ||||
|  | @ -329,52 +396,6 @@ class TheFlixToProvider : MainAPI() { | |||
|         @JsonProperty("type"  ) val type  : String?         = null, | ||||
|     ) | ||||
| 
 | ||||
|     data class LoadDocs( | ||||
|         @JsonProperty("name") val name: String = String(), | ||||
|         @JsonProperty("originalLanguage") val originalLanguage: String? = null, | ||||
|         @JsonProperty("popularity") val popularity: Double? = null, | ||||
|         @JsonProperty("runtime") val runtime: Int? = null, | ||||
|         @JsonProperty("status") val status: String? = null, | ||||
|         @JsonProperty("voteAverage") val voteAverage: Double? = null, | ||||
|         @JsonProperty("voteCount") val voteCount: Int? = null, | ||||
|         @JsonProperty("cast") val cast: String? = null, | ||||
|         @JsonProperty("director") val director: String? = null, | ||||
|         @JsonProperty("overview") val overview: String? = null, | ||||
|         @JsonProperty("posterUrl") val posterUrl: String? = null, | ||||
|         @JsonProperty("releaseDate") val releaseDate: String? = null, | ||||
|         @JsonProperty("createdAt") val createdAt: String? = null, | ||||
|         @JsonProperty("updatedAt") val updatedAt: String? = null, | ||||
|         @JsonProperty("id") val id: Int? = null, | ||||
|         @JsonProperty("available") val available: Boolean? = null, | ||||
|     ) | ||||
| 
 | ||||
| 
 | ||||
|     data class TheFlixMetadata( | ||||
|         @JsonProperty("episodeRuntime") val episodeRuntime: Int? = null, | ||||
|         @JsonProperty("name") val name: String = String(), | ||||
|         @JsonProperty("originalLanguage") val originalLanguage: String? = null, | ||||
|         @JsonProperty("popularity") val popularity: Double? = null, | ||||
|         @JsonProperty("runtime") val runtime: Int? = null, | ||||
|         @JsonProperty("numberOfSeasons") val numberOfSeasons: Int? = null, | ||||
|         @JsonProperty("numberOfEpisodes") val numberOfEpisodes: Int? = null, | ||||
|         @JsonProperty("status") val status: String? = null, | ||||
|         @JsonProperty("voteAverage") val voteAverage: Double? = null, | ||||
|         @JsonProperty("voteCount") val voteCount: Int? = null, | ||||
|         @JsonProperty("cast") val cast: String? = null, | ||||
|         @JsonProperty("director") val director: String? = null, | ||||
|         @JsonProperty("overview") val overview: String? = null, | ||||
|         @JsonProperty("posterUrl") val posterUrl: String? = null, | ||||
|         @JsonProperty("releaseDate") val releaseDate: String? = null, | ||||
|         @JsonProperty("conversionDate") val conversionDate: String? = null, | ||||
|         @JsonProperty("createdAt") val createdAt: String? = null, | ||||
|         @JsonProperty("updatedAt") val updatedAt: String? = null, | ||||
|         @JsonProperty("id") val id: Int? = null, | ||||
|         @JsonProperty("available") val available: Boolean? = null, | ||||
|         @JsonProperty("genres") val genres: ArrayList<Genres> = arrayListOf(), | ||||
|         @JsonProperty("videos") val videos: ArrayList<Videos> = arrayListOf(), | ||||
|         @JsonProperty("seasons") val seasons: ArrayList<Seasons> = arrayListOf() | ||||
|     ) | ||||
| 
 | ||||
|     private fun cleanTitle(title: String): String { | ||||
|         val dotTitle = title.substringBefore("/season") | ||||
|         if (dotTitle.contains(Regex("\\..\\."))) { //For titles containing more than two dots (S.W.A.T.) | ||||
|  | @ -395,60 +416,21 @@ class TheFlixToProvider : MainAPI() { | |||
|     } | ||||
| 
 | ||||
|     private suspend fun getLoadMan(url: String): LoadMain { | ||||
|         val og = app.get(url, cookies = latestCookies) | ||||
|         getCookies() | ||||
|         val og = app.get(url, headers = latestCookies) | ||||
|         val soup = og.document | ||||
|         val script = soup.selectFirst("script[type=application/json]")!!.data() | ||||
|         return parseJson(script) | ||||
|     } | ||||
| 
 | ||||
|     // I legit cant figure this out | ||||
|     private suspend fun getLoadMainRetry(url: String): LoadMain { | ||||
|         val first = getLoadMan(url) | ||||
|         val notFound = "/404" | ||||
|         if (first.page == notFound) { | ||||
|             first.runtimeConfig?.Services?.TmdbServer?.Url?.let { authUrl -> | ||||
|                 val optionsUrl = "$authUrl/authorization/session/continue?contentUsageType=Viewing" | ||||
|                 val options = app.options( | ||||
|                     optionsUrl, | ||||
|                     headers = mapOf( | ||||
|                         "User-Agent" to USER_AGENT, | ||||
|                         "Access-Control-Request-Method" to "POST", | ||||
|                         "Access-Control-Request-Headers" to "content-type", | ||||
|                         "Origin" to url, | ||||
|                         "Referer" to mainUrl, | ||||
|                     ) | ||||
|                 ) | ||||
|                 //{"affiliateCode":"","pathname":"/movie/696806-the-adam-project"} | ||||
|                 val data = mapOf("affiliateCode" to "", "pathname" to url.removePrefix(mainUrl)) | ||||
|                 val resp = app.post( | ||||
|                     optionsUrl, headers = mapOf( | ||||
|                         "User-Agent" to USER_AGENT, | ||||
|                         "Content-Type" to "application/json;charset=UTF-8", | ||||
|                         "Accept" to "application/json, text/plain, */*", | ||||
|                         "Origin" to url, | ||||
|                         "Referer" to mainUrl, | ||||
|                     ), data = data | ||||
|                 ) | ||||
| 
 | ||||
|                 latestCookies = resp.cookies | ||||
|                 val newData = getLoadMan(url) | ||||
|                 if (newData.page == notFound) { | ||||
|                     throw ErrorLoadingException("404 Not found") | ||||
|                 } | ||||
|                 return newData | ||||
|             } | ||||
|         } | ||||
|         return first | ||||
|     } | ||||
| 
 | ||||
|     override suspend fun load(url: String): LoadResponse? { | ||||
|         val tvtype = if (url.contains("movie")) TvType.Movie else TvType.TvSeries | ||||
|         val json = getLoadMainRetry(url) | ||||
|         val json = getLoadMan(url) | ||||
|         val episodes = ArrayList<Episode>() | ||||
|         val isMovie = tvtype == TvType.Movie | ||||
|         val pageMain = json.props.pageProps | ||||
|         val pageMain = json.props?.pageProps | ||||
| 
 | ||||
|         val metadata: TheFlixMetadata? = if (isMovie) pageMain.movie else pageMain.selectedTv | ||||
|         val metadata: TheFlixMetadata? = if (isMovie) pageMain?.movie else pageMain?.selectedTv | ||||
| 
 | ||||
|         val available = metadata?.available | ||||
| 
 | ||||
|  | @ -463,9 +445,9 @@ class TheFlixToProvider : MainAPI() { | |||
|         val description = metadata.overview | ||||
| 
 | ||||
|         if (!isMovie) { | ||||
|             metadata.seasons.map { seasons -> | ||||
|             metadata.seasons?.map { seasons -> | ||||
|                 val seasonPoster = seasons.posterUrl ?: metadata.posterUrl | ||||
|                 seasons.episodes.forEach { epi -> | ||||
|                 seasons.episodes?.forEach { epi -> | ||||
|                     val episodenu = epi.episodeNumber | ||||
|                     val seasonum = epi.seasonNumber | ||||
|                     val title = epi.name | ||||
|  | @ -474,7 +456,7 @@ class TheFlixToProvider : MainAPI() { | |||
|                     val ratinginfo = (epi.voteAverage)?.times(10)?.toInt() | ||||
|                     val rating = if (ratinginfo?.equals(0) == true) null else ratinginfo | ||||
|                     val eps = Episode( | ||||
|                         "$mainUrl/tv-show/$movieId-${cleanTitle(movietitle)}/season-$seasonum/episode-$episodenu", | ||||
|                         "$mainUrl/tv-show/$movieId-${cleanTitle(movietitle!!)}/season-$seasonum/episode-$episodenu", | ||||
|                         title, | ||||
|                         seasonum, | ||||
|                         episodenu, | ||||
|  | @ -482,7 +464,7 @@ class TheFlixToProvider : MainAPI() { | |||
|                         posterUrl = seasonPoster, | ||||
|                         rating = rating, | ||||
|                     ) | ||||
|                     if (test.isNotEmpty()) { | ||||
|                     if (test!!.isNotEmpty()) { | ||||
|                         episodes.add(eps) | ||||
|                     } else { | ||||
|                         //Nothing, will prevent seasons/episodes with no videos to be added | ||||
|  | @ -492,9 +474,9 @@ class TheFlixToProvider : MainAPI() { | |||
|         } | ||||
|         val rating = metadata.voteAverage?.toFloat()?.times(1000)?.toInt() | ||||
| 
 | ||||
|         val tags = metadata.genres.map { it.name } | ||||
|         val tags = metadata.genres?.mapNotNull { it.name } | ||||
| 
 | ||||
|         val recommendationsitem = pageMain.recommendationsList?.docs?.map { loadDocs -> | ||||
|         val recommendationsitem = pageMain?.recommendationsList?.docs?.map { loadDocs -> | ||||
|             val title = loadDocs.name | ||||
|             val posterrec = loadDocs.posterUrl | ||||
|             val link = if (isMovie) "$mainUrl/movie/${loadDocs.id}-${cleanTitle(title)}" | ||||
|  | @ -516,7 +498,7 @@ class TheFlixToProvider : MainAPI() { | |||
| 
 | ||||
|         return when (tvtype) { | ||||
|             TvType.TvSeries -> { | ||||
|                 return newTvSeriesLoadResponse(movietitle, url, TvType.TvSeries, episodes) { | ||||
|                 return newTvSeriesLoadResponse(movietitle!!, url, TvType.TvSeries, episodes) { | ||||
|                     this.posterUrl = poster | ||||
|                     this.year = year?.toIntOrNull() | ||||
|                     this.plot = description | ||||
|  | @ -529,7 +511,7 @@ class TheFlixToProvider : MainAPI() { | |||
|                 } | ||||
|             } | ||||
|             TvType.Movie -> { | ||||
|                 newMovieLoadResponse(movietitle, url, TvType.Movie, url) { | ||||
|                 newMovieLoadResponse(movietitle!!, url, TvType.Movie, url) { | ||||
|                     this.year = year?.toIntOrNull() | ||||
|                     this.posterUrl = poster | ||||
|                     this.plot = description | ||||
|  | @ -546,27 +528,76 @@ class TheFlixToProvider : MainAPI() { | |||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     data class VideoData ( | ||||
|         @JsonProperty("url"           ) val url           : String?        = null, | ||||
|         @JsonProperty("id"            ) val id            : String?        = null, | ||||
|         @JsonProperty("type"          ) val type          : String?        = null, | ||||
|     ) | ||||
| 
 | ||||
| 
 | ||||
|     override suspend fun loadLinks( | ||||
|         data: String, | ||||
|         isCasting: Boolean, | ||||
|         subtitleCallback: (SubtitleFile) -> Unit, | ||||
|         callback: (ExtractorLink) -> Unit | ||||
|     ): Boolean { | ||||
|         val json = getLoadMainRetry(data) | ||||
|         val extractedLink = json.props.pageProps.videoUrl | ||||
|         val json = getLoadMan(data) | ||||
|         val authhost = json.runtimeConfig?.Services?.Server?.Url | ||||
|         val isMovie = data.contains("/movie/") | ||||
|         val qualityReg = Regex("(\\d+p)") | ||||
|         if (extractedLink != null) { | ||||
|             val quality = qualityReg.find(extractedLink)?.value ?: "" | ||||
|         if (isMovie){ | ||||
|             json.props?.pageProps?.movie?.videos?.apmap { id -> | ||||
|                 val jsonmovie = app.get("$authhost/movies/videos/$id/request-access?contentUsageType=Viewing", | ||||
|                     headers = latestCookies).parsedSafe<VideoData>() ?: return@apmap false | ||||
|                 val extractedlink = jsonmovie.url | ||||
|                 if (!extractedlink.isNullOrEmpty()) { | ||||
|                     val quality = qualityReg.find(extractedlink)?.value ?: "" | ||||
|                     callback( | ||||
|                         ExtractorLink( | ||||
|                             name, | ||||
|                     "$name $quality", | ||||
|                     extractedLink, | ||||
|                             name, | ||||
|                             extractedlink, | ||||
|                             "", | ||||
|                             getQualityFromName(quality), | ||||
|                             false | ||||
|                         ) | ||||
|                     ) | ||||
|                 } else null | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             val dataRegex = Regex("(season-(\\d+)\\/episode-(\\d+))") | ||||
|             val cleandatainfo = dataRegex.find(data)?.value?.replace(Regex("(season-|episode-)"),"")?.replace("/","x") | ||||
|             val tesatt = cleandatainfo.let { str -> | ||||
|                 str?.split("x")?.mapNotNull { subStr -> subStr.toIntOrNull() } | ||||
|             } | ||||
|             val epID = tesatt?.getOrNull(1) | ||||
|             val seasonid = tesatt?.getOrNull(0) | ||||
|             json.props?.pageProps?.selectedTv?.seasons?.map { | ||||
|                 it.episodes?.map { | ||||
|                     val epsInfo = Triple(it.seasonNumber, it.episodeNumber, it.videos) | ||||
|                     if (epsInfo.first == seasonid && epsInfo.second == epID) { | ||||
|                         epsInfo.third?.apmap { id -> | ||||
|                             val jsonserie = app.get("$authhost/tv/videos/$id/request-access?contentUsageType=Viewing", headers = latestCookies).parsedSafe<VideoData>() ?: return@apmap false | ||||
|                             val extractedlink = jsonserie.url | ||||
|                             if (!extractedlink.isNullOrEmpty()) { | ||||
|                                 val quality = qualityReg.find(extractedlink)?.value ?: "" | ||||
|                                 callback( | ||||
|                                     ExtractorLink( | ||||
|                                         name, | ||||
|                                         name, | ||||
|                                         extractedlink, | ||||
|                                         "", | ||||
|                                         getQualityFromName(quality), | ||||
|                                         false | ||||
|                                     ) | ||||
|                                 ) | ||||
|                             } else null | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return true | ||||
|     } | ||||
|  |  | |||
|  | @ -0,0 +1,73 @@ | |||
| package com.lagradost.cloudstream3.movieproviders | ||||
| 
 | ||||
| import com.lagradost.cloudstream3.* | ||||
| import com.lagradost.cloudstream3.metaproviders.TmdbLink | ||||
| import com.lagradost.cloudstream3.metaproviders.TmdbProvider | ||||
| import com.lagradost.cloudstream3.utils.AppUtils.parseJson | ||||
| import com.lagradost.cloudstream3.utils.ExtractorLink | ||||
| import com.lagradost.cloudstream3.utils.M3u8Helper.Companion.generateM3u8 | ||||
| import com.lagradost.cloudstream3.utils.loadExtractor | ||||
| 
 | ||||
| class VidSrcProvider : TmdbProvider() { | ||||
|     override val apiName = "VidSrc" | ||||
|     override var name = "VidSrc" | ||||
|     override var mainUrl = "https://v2.vidsrc.me" | ||||
|     override val useMetaLoadResponse = true | ||||
|     override val instantLinkLoading = false | ||||
|     override val supportedTypes = setOf( | ||||
|         TvType.Movie, | ||||
|         TvType.TvSeries, | ||||
|     ) | ||||
| 
 | ||||
|     override suspend fun loadLinks( | ||||
|         data: String, | ||||
|         isCasting: Boolean, | ||||
|         subtitleCallback: (SubtitleFile) -> Unit, | ||||
|         callback: (ExtractorLink) -> Unit | ||||
|     ): Boolean { | ||||
|         val mappedData = parseJson<TmdbLink>(data) | ||||
|         val (id, site) = if (mappedData.imdbID != null) listOf( | ||||
|             mappedData.imdbID, | ||||
|             "imdb" | ||||
|         ) else listOf(mappedData.tmdbID.toString(), "tmdb") | ||||
|         val isMovie = mappedData.episode == null && mappedData.season == null | ||||
|         val embedUrl = if (isMovie) { | ||||
|             if(site == "imdb") "$mainUrl/embed/$id" else | ||||
|                 "$mainUrl/embed/$id" | ||||
|         } else { | ||||
|             val suffix = "$id/${mappedData.season ?: 1}-${mappedData.episode ?: 1}" | ||||
|             if (site == "imdb") "$mainUrl/embed/$suffix" else | ||||
|                 "$mainUrl/embed/$suffix" | ||||
|         } | ||||
|         val iframedoc = app.get(embedUrl).document | ||||
| 
 | ||||
|         val serverslist = iframedoc.select("div#sources.button_content div#content div#list div").map { | ||||
|             val datahash = it.attr("data-hash") | ||||
|             if (datahash.isNotBlank()) { | ||||
|                 val links = try { | ||||
|                     app.get("$mainUrl/src/$datahash", referer = "https://source.vidsrc.me/").url | ||||
|                 } catch (e: Exception) { | ||||
|                     "" | ||||
|                 } | ||||
|                 links | ||||
|             } else "" | ||||
|         } | ||||
| 
 | ||||
|         serverslist.apmap { server -> | ||||
|             val linkfixed = server.replace("https://vidsrc.xyz/","https://embedsito.com/") | ||||
|             if (linkfixed.contains("/pro")) { | ||||
|                 val srcresponse = app.get(server, referer = mainUrl).text | ||||
|                 val m3u8Regex = Regex("((https:|http:)\\/\\/.*\\.m3u8)") | ||||
|                 val srcm3u8 = m3u8Regex.find(srcresponse)?.value ?: return@apmap false | ||||
|                 generateM3u8( | ||||
|                     name, | ||||
|                     srcm3u8, | ||||
|                     mainUrl | ||||
|                 ).forEach(callback) | ||||
|             } else | ||||
|                 loadExtractor(linkfixed, embedUrl, callback) | ||||
|         } | ||||
| 
 | ||||
|         return true | ||||
|     } | ||||
| } | ||||
|  | @ -472,7 +472,7 @@ | |||
|     "TheFlixToProvider": { | ||||
|         "language": "en", | ||||
|         "name": "TheFlix.to", | ||||
|         "status": 0, | ||||
|         "status": 1, | ||||
|         "url": "https://theflix.to" | ||||
|     }, | ||||
|     "TrailersTwoProvider": { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue