forked from recloudstream/cloudstream
		
	added sflix mirror https://solarmovie.pe
This commit is contained in:
		
							parent
							
								
									c191d16b01
								
							
						
					
					
						commit
						d315b557ec
					
				
					 2 changed files with 76 additions and 59 deletions
				
			
		|  | @ -65,6 +65,7 @@ object APIHolder { | ||||||
| 
 | 
 | ||||||
|         SflixProvider("https://sflix.to", "Sflix"), |         SflixProvider("https://sflix.to", "Sflix"), | ||||||
|         SflixProvider("https://dopebox.to", "Dopebox"), |         SflixProvider("https://dopebox.to", "Dopebox"), | ||||||
|  |         SflixProvider("https://solarmovie.pe", "Solarmovie"), | ||||||
| 
 | 
 | ||||||
|         //TmdbProvider(), |         //TmdbProvider(), | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty | ||||||
| import com.lagradost.cloudstream3.* | import com.lagradost.cloudstream3.* | ||||||
| import com.lagradost.cloudstream3.LoadResponse.Companion.addActors | import com.lagradost.cloudstream3.LoadResponse.Companion.addActors | ||||||
| import com.lagradost.cloudstream3.LoadResponse.Companion.setDuration | import com.lagradost.cloudstream3.LoadResponse.Companion.setDuration | ||||||
|  | import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall | ||||||
| import com.lagradost.cloudstream3.network.WebViewResolver | import com.lagradost.cloudstream3.network.WebViewResolver | ||||||
| import com.lagradost.cloudstream3.utils.AppUtils.parseJson | import com.lagradost.cloudstream3.utils.AppUtils.parseJson | ||||||
| import com.lagradost.cloudstream3.utils.AppUtils.toJson | import com.lagradost.cloudstream3.utils.AppUtils.toJson | ||||||
|  | @ -99,9 +100,9 @@ class SflixProvider(providerUrl: String, providerName: String) : MainAPI() { | ||||||
|         val document = app.get(url).document |         val document = app.get(url).document | ||||||
| 
 | 
 | ||||||
|         val details = document.select("div.detail_page-watch") |         val details = document.select("div.detail_page-watch") | ||||||
|         val img = details.select("img.film-poster-img") |         val img = details?.select("img.film-poster-img") | ||||||
|         val posterUrl = img.attr("src") |         val posterUrl = img?.attr("src") | ||||||
|         val title = img.attr("title") |         val title = img?.attr("title") ?: throw ErrorLoadingException("No Title") | ||||||
| 
 | 
 | ||||||
|         /* |         /* | ||||||
|         val year = Regex("""[Rr]eleased:\s*(\d{4})""").find( |         val year = Regex("""[Rr]eleased:\s*(\d{4})""").find( | ||||||
|  | @ -110,7 +111,7 @@ class SflixProvider(providerUrl: String, providerName: String) : MainAPI() { | ||||||
|         val duration = Regex("""[Dd]uration:\s*(\d*)""").find( |         val duration = Regex("""[Dd]uration:\s*(\d*)""").find( | ||||||
|             document.select("div.elements").text() |             document.select("div.elements").text() | ||||||
|         )?.groupValues?.get(1)?.trim()?.plus(" min")*/ |         )?.groupValues?.get(1)?.trim()?.plus(" min")*/ | ||||||
|         var duration = document.selectFirst(".fs-item > .duration").text()?.trim() |         var duration = document.selectFirst(".fs-item > .duration")?.text()?.trim() | ||||||
|         var year: Int? = null |         var year: Int? = null | ||||||
|         var tags: List<String>? = null |         var tags: List<String>? = null | ||||||
|         var cast: List<String>? = null |         var cast: List<String>? = null | ||||||
|  | @ -133,7 +134,7 @@ class SflixProvider(providerUrl: String, providerName: String) : MainAPI() { | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         val plot = details.select("div.description").text().replace("Overview:", "").trim() |         val plot = details.select("div.description")?.text()?.replace("Overview:", "")?.trim() | ||||||
| 
 | 
 | ||||||
|         val isMovie = url.contains("/movie/") |         val isMovie = url.contains("/movie/") | ||||||
| 
 | 
 | ||||||
|  | @ -169,9 +170,16 @@ class SflixProvider(providerUrl: String, providerName: String) : MainAPI() { | ||||||
| 
 | 
 | ||||||
|             // Supported streams, they're identical |             // Supported streams, they're identical | ||||||
|             val sourceIds = Jsoup.parse(episodes).select("a").mapNotNull { element -> |             val sourceIds = Jsoup.parse(episodes).select("a").mapNotNull { element -> | ||||||
|                 val sourceId = element.attr("data-id") ?: return@mapNotNull null |                 var sourceId = element.attr("data-id") | ||||||
|  |                 if (sourceId.isNullOrEmpty()) | ||||||
|  |                     sourceId = element.attr("data-linkid") | ||||||
|  | 
 | ||||||
|                 if (element.select("span")?.text()?.trim()?.isValidServer() == true) { |                 if (element.select("span")?.text()?.trim()?.isValidServer() == true) { | ||||||
|                     "$url.$sourceId".replace("/movie/", "/watch-movie/") |                     if (sourceId.isNullOrEmpty()) { | ||||||
|  |                         fixUrlNull(element.attr("href")) | ||||||
|  |                     } else { | ||||||
|  |                         "$url.$sourceId".replace("/movie/", "/watch-movie/") | ||||||
|  |                     } | ||||||
|                 } else { |                 } else { | ||||||
|                     null |                     null | ||||||
|                 } |                 } | ||||||
|  | @ -189,41 +197,47 @@ class SflixProvider(providerUrl: String, providerName: String) : MainAPI() { | ||||||
|         } else { |         } else { | ||||||
|             val seasonsDocument = app.get("$mainUrl/ajax/v2/tv/seasons/$id").document |             val seasonsDocument = app.get("$mainUrl/ajax/v2/tv/seasons/$id").document | ||||||
|             val episodes = arrayListOf<TvSeriesEpisode>() |             val episodes = arrayListOf<TvSeriesEpisode>() | ||||||
|  |             var seasonItems = seasonsDocument.select("div.dropdown-menu.dropdown-menu-model > a") | ||||||
|  |             if (seasonItems.isNullOrEmpty()) | ||||||
|  |                 seasonItems = seasonsDocument.select("div.dropdown-menu > a.dropdown-item") | ||||||
|  |             seasonItems?.forEachIndexed { season, element -> | ||||||
|  |                 val seasonId = element.attr("data-id") | ||||||
|  |                 if (seasonId.isNullOrBlank()) return@forEachIndexed | ||||||
| 
 | 
 | ||||||
|             seasonsDocument.select("div.dropdown-menu.dropdown-menu-model > a") |                 var episode = 0 | ||||||
|                 .forEachIndexed { season, element -> |                 val seasonEpisodes = app.get("$mainUrl/ajax/v2/season/episodes/$seasonId").document | ||||||
|                     val seasonId = element.attr("data-id") |                 var seasonEpisodesItems = | ||||||
|                     if (seasonId.isNullOrBlank()) return@forEachIndexed |                     seasonEpisodes.select("div.flw-item.film_single-item.episode-item.eps-item") | ||||||
| 
 |                 if (seasonEpisodesItems.isNullOrEmpty()) { | ||||||
|                     var episode = 0 |                     seasonEpisodesItems = | ||||||
|                     app.get("$mainUrl/ajax/v2/season/episodes/$seasonId").document |                         seasonEpisodes.select("ul > li > a") | ||||||
|                         .select("div.flw-item.film_single-item.episode-item.eps-item") |  | ||||||
|                         .forEach { |  | ||||||
|                             val episodeImg = it.select("img") ?: return@forEach |  | ||||||
|                             val episodeTitle = episodeImg.attr("title") ?: return@forEach |  | ||||||
|                             val episodePosterUrl = episodeImg.attr("src") ?: return@forEach |  | ||||||
|                             val episodeData = it.attr("data-id") ?: return@forEach |  | ||||||
| 
 |  | ||||||
|                             episode++ |  | ||||||
| 
 |  | ||||||
|                             val episodeNum = |  | ||||||
|                                 (it.select("div.episode-number")?.text() |  | ||||||
|                                     ?: episodeTitle).let { str -> |  | ||||||
|                                     Regex("""\d+""").find(str)?.groupValues?.firstOrNull() |  | ||||||
|                                         ?.toIntOrNull() |  | ||||||
|                                 } ?: episode |  | ||||||
| 
 |  | ||||||
|                             episodes.add( |  | ||||||
|                                 TvSeriesEpisode( |  | ||||||
|                                     episodeTitle.removePrefix("Episode $episodeNum: "), |  | ||||||
|                                     season + 1, |  | ||||||
|                                     episodeNum, |  | ||||||
|                                     Pair(url, episodeData).toJson(), |  | ||||||
|                                     fixUrl(episodePosterUrl) |  | ||||||
|                                 ) |  | ||||||
|                             ) |  | ||||||
|                         } |  | ||||||
|                 } |                 } | ||||||
|  |                 seasonEpisodesItems.forEach { | ||||||
|  |                     val episodeImg = it?.select("img") | ||||||
|  |                     val episodeTitle = episodeImg?.attr("title") ?: it.ownText() | ||||||
|  |                     val episodePosterUrl = episodeImg?.attr("src") | ||||||
|  |                     val episodeData = it.attr("data-id") ?: return@forEach | ||||||
|  | 
 | ||||||
|  |                     episode++ | ||||||
|  | 
 | ||||||
|  |                     val episodeNum = | ||||||
|  |                         (it.select("div.episode-number")?.text() | ||||||
|  |                             ?: episodeTitle).let { str -> | ||||||
|  |                             Regex("""\d+""").find(str)?.groupValues?.firstOrNull() | ||||||
|  |                                 ?.toIntOrNull() | ||||||
|  |                         } ?: episode | ||||||
|  | 
 | ||||||
|  |                     episodes.add( | ||||||
|  |                         TvSeriesEpisode( | ||||||
|  |                             episodeTitle?.removePrefix("Episode $episodeNum: "), | ||||||
|  |                             season + 1, | ||||||
|  |                             episodeNum, | ||||||
|  |                             Pair(url, episodeData).toJson(), | ||||||
|  |                             fixUrlNull(episodePosterUrl) | ||||||
|  |                         ) | ||||||
|  |                     ) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|             return newTvSeriesLoadResponse(title, url, TvType.TvSeries, episodes) { |             return newTvSeriesLoadResponse(title, url, TvType.TvSeries, episodes) { | ||||||
|                 this.posterUrl = posterUrl |                 this.posterUrl = posterUrl | ||||||
|                 this.year = year |                 this.year = year | ||||||
|  | @ -277,29 +291,31 @@ class SflixProvider(providerUrl: String, providerName: String) : MainAPI() { | ||||||
|         } ?: tryParseJson<List<String>>(data))?.distinct() |         } ?: tryParseJson<List<String>>(data))?.distinct() | ||||||
| 
 | 
 | ||||||
|         urls?.apmap { url -> |         urls?.apmap { url -> | ||||||
|             val sources = app.get( |             suspendSafeApiCall { | ||||||
|                 url, |                 val sources = app.get( | ||||||
|                 interceptor = WebViewResolver( |                     url, | ||||||
|                     Regex("""/getSources"""), |                     interceptor = WebViewResolver( | ||||||
|                 ) |                         Regex("""/getSources"""), | ||||||
|             ).text |                     ) | ||||||
|  |                 ).text | ||||||
| 
 | 
 | ||||||
|             val mapped = parseJson<SourceObject>(sources) |                 val mapped = parseJson<SourceObject>(sources) | ||||||
| 
 | 
 | ||||||
|             mapped.tracks?.forEach { |                 mapped.tracks?.forEach { | ||||||
|                 it?.toSubtitleFile()?.let { subtitleFile -> |                     it?.toSubtitleFile()?.let { subtitleFile -> | ||||||
|                     subtitleCallback.invoke(subtitleFile) |                         subtitleCallback.invoke(subtitleFile) | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|             } |  | ||||||
| 
 | 
 | ||||||
|             listOf( |                 listOf( | ||||||
|                 mapped.sources to "", |                     mapped.sources to "", | ||||||
|                 mapped.sources1 to "source 2", |                     mapped.sources1 to "source 2", | ||||||
|                 mapped.sources2 to "source 3", |                     mapped.sources2 to "source 3", | ||||||
|                 mapped.sourcesBackup to "source backup" |                     mapped.sourcesBackup to "source backup" | ||||||
|             ).forEach { (sources, sourceName) -> |                 ).forEach { (sources, sourceName) -> | ||||||
|                 sources?.forEach { |                     sources?.forEach { | ||||||
|                     it?.toExtractorLink(this, sourceName)?.forEach(callback) |                         it?.toExtractorLink(this, sourceName)?.forEach(callback) | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue