mirror of
				https://github.com/recloudstream/cloudstream.git
				synced 2024-08-15 01:53:11 +00:00 
			
		
		
		
	api fix + VPN status + 1 frame issue resolved
This commit is contained in:
		
							parent
							
								
									f02793f62a
								
							
						
					
					
						commit
						08d557a82e
					
				
					 9 changed files with 98 additions and 19 deletions
				
			
		|  | @ -13,7 +13,7 @@ import java.util.* | ||||||
| 
 | 
 | ||||||
| const val USER_AGENT = | const val USER_AGENT = | ||||||
|     "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" |     "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" | ||||||
| val baseHeader = mapOf("User-Agent" to USER_AGENT) | //val baseHeader = mapOf("User-Agent" to USER_AGENT) | ||||||
| val mapper = JsonMapper.builder().addModule(KotlinModule()) | val mapper = JsonMapper.builder().addModule(KotlinModule()) | ||||||
|     .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).build()!! |     .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).build()!! | ||||||
| 
 | 
 | ||||||
|  | @ -119,6 +119,8 @@ abstract class MainAPI { | ||||||
|         TvType.ONA |         TvType.ONA | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|  |     open val vpnStatus = VPNStatus.None | ||||||
|  | 
 | ||||||
|     open fun getMainPage(): HomePageResponse? { |     open fun getMainPage(): HomePageResponse? { | ||||||
|         throw NotImplementedError() |         throw NotImplementedError() | ||||||
|     } |     } | ||||||
|  | @ -197,6 +199,12 @@ fun imdbUrlToIdNullable(url: String?): String? { | ||||||
|     return imdbUrlToId(url) |     return imdbUrlToId(url) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | enum class VPNStatus { | ||||||
|  |     None, | ||||||
|  |     MightBeNeeded, | ||||||
|  |     Torrent, | ||||||
|  | } | ||||||
|  | 
 | ||||||
| enum class ShowStatus { | enum class ShowStatus { | ||||||
|     Completed, |     Completed, | ||||||
|     Ongoing, |     Ongoing, | ||||||
|  |  | ||||||
|  | @ -10,6 +10,11 @@ class DoodToExtractor : DoodLaExtractor() { | ||||||
|         get() = "https://dood.to" |         get() = "https://dood.to" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | class DoodSoExtractor : DoodLaExtractor() { | ||||||
|  |     override val mainUrl: String | ||||||
|  |         get() = "https://dood.so" | ||||||
|  | } | ||||||
|  | 
 | ||||||
| open class DoodLaExtractor : ExtractorApi() { | open class DoodLaExtractor : ExtractorApi() { | ||||||
|     override val name: String |     override val name: String | ||||||
|         get() = "DoodStream" |         get() = "DoodStream" | ||||||
|  | @ -33,7 +38,16 @@ open class DoodLaExtractor : ExtractorApi() { | ||||||
|             val downloadResponse = khttp.get(downloadLink) |             val downloadResponse = khttp.get(downloadLink) | ||||||
|             Regex("onclick=\"window\\.open\\((['\"])(.*?)(['\"])").find(downloadResponse.text)?.groupValues?.get(2) |             Regex("onclick=\"window\\.open\\((['\"])(.*?)(['\"])").find(downloadResponse.text)?.groupValues?.get(2) | ||||||
|                 ?.let { trueLink -> |                 ?.let { trueLink -> | ||||||
|                     return listOf(ExtractorLink(trueLink, this.name, trueLink, mainUrl, Qualities.Unknown.value, false)) // links are valid in 8h |                     return listOf( | ||||||
|  |                         ExtractorLink( | ||||||
|  |                             trueLink, | ||||||
|  |                             this.name, | ||||||
|  |                             trueLink, | ||||||
|  |                             mainUrl, | ||||||
|  |                             Qualities.Unknown.value, | ||||||
|  |                             false | ||||||
|  |                         ) | ||||||
|  |                     ) // links are valid in 8h | ||||||
|                 } |                 } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,9 +1,12 @@ | ||||||
| package com.lagradost.cloudstream3.movieproviders | package com.lagradost.cloudstream3.movieproviders | ||||||
| 
 | 
 | ||||||
|  | import com.fasterxml.jackson.module.kotlin.readValue | ||||||
| import com.lagradost.cloudstream3.* | import com.lagradost.cloudstream3.* | ||||||
| import com.lagradost.cloudstream3.utils.ExtractorLink | import com.lagradost.cloudstream3.utils.ExtractorLink | ||||||
|  | import com.lagradost.cloudstream3.utils.Qualities | ||||||
| import com.lagradost.cloudstream3.utils.loadExtractor | import com.lagradost.cloudstream3.utils.loadExtractor | ||||||
| import org.jsoup.Jsoup | import org.jsoup.Jsoup | ||||||
|  | import org.jsoup.nodes.Document | ||||||
| 
 | 
 | ||||||
| class AllMoviesForYouProvider : MainAPI() { | class AllMoviesForYouProvider : MainAPI() { | ||||||
|     companion object { |     companion object { | ||||||
|  | @ -47,8 +50,21 @@ class AllMoviesForYouProvider : MainAPI() { | ||||||
|         return returnValue |         return returnValue | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private fun getLink(document: String): String? { |     private fun getLink(document: Document): List<String>? { | ||||||
|         return Regex("iframe src=\"(.*?)\"").find(document)?.groupValues?.get(1) |         val list = ArrayList<String>() | ||||||
|  |         Regex("iframe src=\"(.*?)\"").find(document.html())?.groupValues?.get(1)?.let { | ||||||
|  |             list.add(it) | ||||||
|  |         } | ||||||
|  |         document.select("div.OptionBx")?.forEach { element -> | ||||||
|  |             val baseElement = element.selectFirst("> a.Button") | ||||||
|  |             if (element.selectFirst("> p.AAIco-dns")?.text() == "Streamhub") { | ||||||
|  |                 baseElement?.attr("href")?.let { href -> | ||||||
|  |                     list.add(href) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return if (list.isEmpty()) null else list | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun load(url: String): LoadResponse { |     override fun load(url: String): LoadResponse { | ||||||
|  | @ -118,7 +134,7 @@ class AllMoviesForYouProvider : MainAPI() { | ||||||
|                 rating |                 rating | ||||||
|             ) |             ) | ||||||
|         } else { |         } else { | ||||||
|             val data = getLink(response.text) |             val data = getLink(document) | ||||||
|                 ?: throw ErrorLoadingException("No Links Found") |                 ?: throw ErrorLoadingException("No Links Found") | ||||||
| 
 | 
 | ||||||
|             return MovieLoadResponse( |             return MovieLoadResponse( | ||||||
|  | @ -126,7 +142,7 @@ class AllMoviesForYouProvider : MainAPI() { | ||||||
|                 url, |                 url, | ||||||
|                 this.name, |                 this.name, | ||||||
|                 type, |                 type, | ||||||
|                 data, |                 mapper.writeValueAsString(data), | ||||||
|                 backgroundPoster, |                 backgroundPoster, | ||||||
|                 year?.toIntOrNull(), |                 year?.toIntOrNull(), | ||||||
|                 descipt, |                 descipt, | ||||||
|  | @ -145,19 +161,31 @@ class AllMoviesForYouProvider : MainAPI() { | ||||||
|     ): Boolean { |     ): Boolean { | ||||||
|         if (data.startsWith("$mainUrl/episode/")) { |         if (data.startsWith("$mainUrl/episode/")) { | ||||||
|             val response = khttp.get(data) |             val response = khttp.get(data) | ||||||
|             val link = getLink(response.text) |             getLink(Jsoup.parse(response.text))?.let { links -> | ||||||
|             if (link == null || link == data) return false |                 for (link in links) { | ||||||
|             return loadLinks(link, isCasting, subtitleCallback, callback) |                     if (link == data) continue | ||||||
|         } |                     loadLinks(link, isCasting, subtitleCallback, callback) | ||||||
| 
 |  | ||||||
|         if (data.startsWith(mainUrl) && data != mainUrl) { |  | ||||||
|             val response = khttp.get(data.replace("&", "&")) |  | ||||||
|             Regex("<iframe.*?src=\"(.*?)\"").find(response.text)?.groupValues?.get(1)?.let { url -> |  | ||||||
|                 loadExtractor(url.trimStart(), data, callback) |  | ||||||
|                 } |                 } | ||||||
|                 return true |                 return true | ||||||
|             } |             } | ||||||
| 
 |  | ||||||
|             return false |             return false | ||||||
|  |         } else if (data.startsWith(mainUrl) && data != mainUrl) { | ||||||
|  |             val realDataUrl = data.replace("&", "&").replace("&", "&") | ||||||
|  |             if (data.contains("trdownload")) { | ||||||
|  |                 callback(ExtractorLink(this.name, this.name, realDataUrl, mainUrl, Qualities.Unknown.value)) | ||||||
|  |                 return true | ||||||
|  |             } | ||||||
|  |             val response = khttp.get(realDataUrl) | ||||||
|  |             Regex("<iframe.*?src=\"(.*?)\"").find(response.text)?.groupValues?.get(1)?.let { url -> | ||||||
|  |                 loadExtractor(url.trimStart(), realDataUrl, callback) | ||||||
|  |             } | ||||||
|  |             return true | ||||||
|  |         } else { | ||||||
|  |             val links = mapper.readValue<List<String>>(data) | ||||||
|  |             for (link in links) { | ||||||
|  |                 loadLinks(link, isCasting, subtitleCallback, callback) | ||||||
|  |             } | ||||||
|  |             return true | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -29,6 +29,9 @@ class TrailersToProvider : MainAPI() { | ||||||
|             TvType.TvSeries, |             TvType.TvSeries, | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|  |     override val vpnStatus: VPNStatus | ||||||
|  |         get() = VPNStatus.MightBeNeeded | ||||||
|  | 
 | ||||||
|     override fun getMainPage(): HomePageResponse? { |     override fun getMainPage(): HomePageResponse? { | ||||||
|         val response = khttp.get(mainUrl) |         val response = khttp.get(mainUrl) | ||||||
|         val document = Jsoup.parse(response.text) |         val document = Jsoup.parse(response.text) | ||||||
|  |  | ||||||
|  | @ -143,7 +143,7 @@ fun ResultEpisode.getWatchProgress(): Float { | ||||||
| 
 | 
 | ||||||
| class ResultFragment : Fragment() { | class ResultFragment : Fragment() { | ||||||
|     companion object { |     companion object { | ||||||
|         fun newInstance(url: String, apiName: String, startAction: Int = 0, startValue : Int = 0) = |         fun newInstance(url: String, apiName: String, startAction: Int = 0, startValue: Int = 0) = | ||||||
|             ResultFragment().apply { |             ResultFragment().apply { | ||||||
|                 arguments = Bundle().apply { |                 arguments = Bundle().apply { | ||||||
|                     putString("url", url) |                     putString("url", url) | ||||||
|  | @ -252,6 +252,7 @@ class ResultFragment : Fragment() { | ||||||
|     @SuppressLint("SetTextI18n") |     @SuppressLint("SetTextI18n") | ||||||
|     override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |     override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||||||
|         super.onViewCreated(view, savedInstanceState) |         super.onViewCreated(view, savedInstanceState) | ||||||
|  | 
 | ||||||
|         activity?.window?.decorView?.clearFocus() |         activity?.window?.decorView?.clearFocus() | ||||||
|         hideKeyboard() |         hideKeyboard() | ||||||
| 
 | 
 | ||||||
|  | @ -526,6 +527,7 @@ class ResultFragment : Fragment() { | ||||||
|             val isLoaded = when (episodeClick.action) { |             val isLoaded = when (episodeClick.action) { | ||||||
|                 ACTION_PLAY_EPISODE_IN_PLAYER -> true |                 ACTION_PLAY_EPISODE_IN_PLAYER -> true | ||||||
|                 ACTION_CLICK_DEFAULT -> true |                 ACTION_CLICK_DEFAULT -> true | ||||||
|  |                 ACTION_SHOW_TOAST -> true | ||||||
|                 ACTION_CHROME_CAST_EPISODE -> requireLinks(true) |                 ACTION_CHROME_CAST_EPISODE -> requireLinks(true) | ||||||
|                 ACTION_CHROME_CAST_MIRROR -> requireLinks(true) |                 ACTION_CHROME_CAST_MIRROR -> requireLinks(true) | ||||||
|                 else -> requireLinks(false) |                 else -> requireLinks(false) | ||||||
|  | @ -841,6 +843,13 @@ class ResultFragment : Fragment() { | ||||||
|                     if (d is LoadResponse) { |                     if (d is LoadResponse) { | ||||||
|                         updateVisStatus(2) |                         updateVisStatus(2) | ||||||
| 
 | 
 | ||||||
|  |                         result_vpn.text = when (api.vpnStatus) { | ||||||
|  |                             VPNStatus.MightBeNeeded -> getString(R.string.vpn_might_be_needed) | ||||||
|  |                             VPNStatus.Torrent -> getString(R.string.vpn_torrent) | ||||||
|  |                             else -> "" | ||||||
|  |                         } | ||||||
|  |                         result_vpn.visibility = if (api.vpnStatus == VPNStatus.None) GONE else VISIBLE | ||||||
|  | 
 | ||||||
|                         result_bookmark_button.text = "Watching" |                         result_bookmark_button.text = "Watching" | ||||||
| 
 | 
 | ||||||
|                         currentHeaderName = d.name |                         currentHeaderName = d.name | ||||||
|  |  | ||||||
|  | @ -72,8 +72,11 @@ val extractorApis: Array<ExtractorApi> = arrayOf( | ||||||
|     XStreamCdn(), |     XStreamCdn(), | ||||||
|     StreamSB(), |     StreamSB(), | ||||||
|     Streamhub(), |     Streamhub(), | ||||||
|     DoodLaExtractor(), | 
 | ||||||
|  |     // dood extractors | ||||||
|     DoodToExtractor(), |     DoodToExtractor(), | ||||||
|  |     DoodSoExtractor(), | ||||||
|  |     DoodLaExtractor(), | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| fun getExtractorApiFromName(name: String): ExtractorApi { | fun getExtractorApiFromName(name: String): ExtractorApi { | ||||||
|  |  | ||||||
|  | @ -10,6 +10,8 @@ | ||||||
|         tools:context=".ui.home.HomeFragment"> |         tools:context=".ui.home.HomeFragment"> | ||||||
| 
 | 
 | ||||||
|     <FrameLayout |     <FrameLayout | ||||||
|  |             android:visibility="visible" | ||||||
|  |             tools:visibility="gone" | ||||||
|             android:id="@+id/home_loading" |             android:id="@+id/home_loading" | ||||||
|             android:layout_width="match_parent" |             android:layout_width="match_parent" | ||||||
|             android:layout_height="match_parent"> |             android:layout_height="match_parent"> | ||||||
|  | @ -34,6 +36,7 @@ | ||||||
|     </FrameLayout> |     </FrameLayout> | ||||||
| 
 | 
 | ||||||
|     <LinearLayout |     <LinearLayout | ||||||
|  |             android:visibility="gone" | ||||||
|             tools:visibility="gone" |             tools:visibility="gone" | ||||||
|             android:id="@+id/home_loading_error" |             android:id="@+id/home_loading_error" | ||||||
|             android:orientation="vertical" |             android:orientation="vertical" | ||||||
|  | @ -71,6 +74,8 @@ | ||||||
|         /> |         /> | ||||||
|     </LinearLayout> |     </LinearLayout> | ||||||
|     <androidx.core.widget.NestedScrollView |     <androidx.core.widget.NestedScrollView | ||||||
|  |             tools:visibility="visible" | ||||||
|  |             android:visibility="gone" | ||||||
|             android:id="@+id/home_loaded" |             android:id="@+id/home_loaded" | ||||||
|             android:layout_width="match_parent" |             android:layout_width="match_parent" | ||||||
|             android:layout_height="match_parent"> |             android:layout_height="match_parent"> | ||||||
|  |  | ||||||
|  | @ -18,6 +18,7 @@ | ||||||
|             android:layout_width="50dp" android:layout_height="50dp"> |             android:layout_width="50dp" android:layout_height="50dp"> | ||||||
|     </ProgressBar> |     </ProgressBar> | ||||||
|     <LinearLayout |     <LinearLayout | ||||||
|  |             android:visibility="gone" | ||||||
|             tools:visibility="gone" |             tools:visibility="gone" | ||||||
|             android:id="@+id/result_loading_error" |             android:id="@+id/result_loading_error" | ||||||
|             android:orientation="vertical" |             android:orientation="vertical" | ||||||
|  | @ -265,7 +266,12 @@ | ||||||
|                         </ImageView> |                         </ImageView> | ||||||
|                     </LinearLayout> |                     </LinearLayout> | ||||||
|                 </GridLayout> |                 </GridLayout> | ||||||
| 
 |                 <TextView | ||||||
|  |                         android:id="@+id/result_vpn" | ||||||
|  |                         android:textSize="15sp" | ||||||
|  |                         tools:text="@string/vpn_torrent" | ||||||
|  |                         android:layout_width="match_parent" android:layout_height="wrap_content"> | ||||||
|  |                 </TextView> | ||||||
|                 <TextView |                 <TextView | ||||||
|                         android:layout_width="wrap_content" |                         android:layout_width="wrap_content" | ||||||
|                         android:layout_height="wrap_content" |                         android:layout_height="wrap_content" | ||||||
|  |  | ||||||
|  | @ -95,4 +95,7 @@ | ||||||
| 
 | 
 | ||||||
|     <string name="action_remove_watching">Remove</string> |     <string name="action_remove_watching">Remove</string> | ||||||
|     <string name="action_open_watching">More Info</string> |     <string name="action_open_watching">More Info</string> | ||||||
|  | 
 | ||||||
|  |     <string name="vpn_might_be_needed">A VPN might be needed for this provider to work correctly</string> | ||||||
|  |     <string name="vpn_torrent">This providers is a torrent, a VPN is recommended</string> | ||||||
| </resources> | </resources> | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue