mirror of
				https://github.com/recloudstream/cloudstream.git
				synced 2024-08-15 01:53:11 +00:00 
			
		
		
		
	added multimovie
This commit is contained in:
		
							parent
							
								
									58bed05a32
								
							
						
					
					
						commit
						7197970896
					
				
					 5 changed files with 114 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -10,6 +10,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature
 | 
			
		|||
import com.fasterxml.jackson.databind.json.JsonMapper
 | 
			
		||||
import com.fasterxml.jackson.module.kotlin.KotlinModule
 | 
			
		||||
import com.lagradost.cloudstream3.animeproviders.*
 | 
			
		||||
import com.lagradost.cloudstream3.metaproviders.CrossTmdbProvider
 | 
			
		||||
import com.lagradost.cloudstream3.movieproviders.*
 | 
			
		||||
import com.lagradost.cloudstream3.ui.player.SubtitleData
 | 
			
		||||
import com.lagradost.cloudstream3.utils.ExtractorLink
 | 
			
		||||
| 
						 | 
				
			
			@ -86,6 +87,8 @@ object APIHolder {
 | 
			
		|||
        AkwamProvider(),
 | 
			
		||||
        AnimePaheProvider(),
 | 
			
		||||
        NineAnimeProvider(),
 | 
			
		||||
 | 
			
		||||
        CrossTmdbProvider(),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    val restrictedApis = arrayListOf(
 | 
			
		||||
| 
						 | 
				
			
			@ -278,6 +281,8 @@ abstract class MainAPI {
 | 
			
		|||
    open val name = "NONE"
 | 
			
		||||
    open val mainUrl = "NONE"
 | 
			
		||||
 | 
			
		||||
    //open val uniqueId : Int by lazy { this.name.hashCode() } // in case of duplicate providers you can have a shared id
 | 
			
		||||
 | 
			
		||||
    open val lang = "en" // ISO_639_1 check SubtitleHelper
 | 
			
		||||
 | 
			
		||||
    /**If link is stored in the "data" string, so links can be instantly loaded*/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,104 @@
 | 
			
		|||
package com.lagradost.cloudstream3.metaproviders
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.annotation.JsonProperty
 | 
			
		||||
import com.lagradost.cloudstream3.*
 | 
			
		||||
import com.lagradost.cloudstream3.APIHolder.apis
 | 
			
		||||
import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull
 | 
			
		||||
import com.lagradost.cloudstream3.mvvm.logError
 | 
			
		||||
import com.lagradost.cloudstream3.utils.AppUtils.toJson
 | 
			
		||||
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
 | 
			
		||||
import com.lagradost.cloudstream3.utils.ExtractorLink
 | 
			
		||||
 | 
			
		||||
class CrossTmdbProvider : TmdbProvider() {
 | 
			
		||||
    override val name = "MultiMovie"
 | 
			
		||||
    override val apiName = "MultiMovie"
 | 
			
		||||
    override val lang = "en"
 | 
			
		||||
    override val useMetaLoadResponse = true
 | 
			
		||||
    override val usesWebView = true
 | 
			
		||||
 | 
			
		||||
    private fun filterName(name: String): String {
 | 
			
		||||
        return Regex("""[^a-zA-Z0-9-]""").replace(name, "")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private val validApis by lazy {
 | 
			
		||||
        apis.filter { it.lang == this.lang && it::class.java != this::class.java }
 | 
			
		||||
            //.distinctBy { it.uniqueId }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    data class CrossMetaData(
 | 
			
		||||
        @JsonProperty("isSuccess") val isSuccess: Boolean,
 | 
			
		||||
        @JsonProperty("movies") val movies: List<Pair<String, String>>? = null,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    override suspend fun loadLinks(
 | 
			
		||||
        data: String,
 | 
			
		||||
        isCasting: Boolean,
 | 
			
		||||
        subtitleCallback: (SubtitleFile) -> Unit,
 | 
			
		||||
        callback: (ExtractorLink) -> Unit
 | 
			
		||||
    ): Boolean {
 | 
			
		||||
        tryParseJson<CrossMetaData>(data)?.let { metaData ->
 | 
			
		||||
            if (!metaData.isSuccess) return false
 | 
			
		||||
            metaData.movies?.apmap { (apiName, data) ->
 | 
			
		||||
                getApiFromNameNull(apiName)?.let {
 | 
			
		||||
                    try {
 | 
			
		||||
                        it.loadLinks(data, isCasting, subtitleCallback, callback)
 | 
			
		||||
                    } catch (e: Exception) {
 | 
			
		||||
                        logError(e)
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return true
 | 
			
		||||
        }
 | 
			
		||||
        return false
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override suspend fun search(query: String): List<SearchResponse>? {
 | 
			
		||||
        return super.search(query)?.filterIsInstance<MovieSearchResponse>()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override suspend fun load(url: String): LoadResponse? {
 | 
			
		||||
        val base = super.load(url)?.apply {
 | 
			
		||||
            val matchName = filterName(this.name)
 | 
			
		||||
            when (this) {
 | 
			
		||||
                is MovieLoadResponse -> {
 | 
			
		||||
                    val data = validApis.apmap { api ->
 | 
			
		||||
                        try {
 | 
			
		||||
                            if (api.supportedTypes.contains(TvType.Movie)) { //|| api.supportedTypes.contains(TvType.AnimeMovie)
 | 
			
		||||
                                return@apmap api.search(this.name)?.first {
 | 
			
		||||
                                    if (filterName(it.name).equals(
 | 
			
		||||
                                            matchName,
 | 
			
		||||
                                            ignoreCase = true
 | 
			
		||||
                                        )
 | 
			
		||||
                                    ) {
 | 
			
		||||
                                        if (it is MovieSearchResponse)
 | 
			
		||||
                                            if (it.year != null && this.year != null && it.year != this.year) // if year exist then do a check
 | 
			
		||||
                                                return@first false
 | 
			
		||||
 | 
			
		||||
                                        return@first true
 | 
			
		||||
                                    }
 | 
			
		||||
                                    false
 | 
			
		||||
                                }?.let { search ->
 | 
			
		||||
                                    val response = api.load(search.url)
 | 
			
		||||
                                    if (response is MovieLoadResponse) {
 | 
			
		||||
                                        response
 | 
			
		||||
                                    } else {
 | 
			
		||||
                                        null
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            null
 | 
			
		||||
                        } catch (e: Exception) {
 | 
			
		||||
                            logError(e)
 | 
			
		||||
                            null
 | 
			
		||||
                        }
 | 
			
		||||
                    }.filterNotNull()
 | 
			
		||||
                    this.dataUrl =
 | 
			
		||||
                        CrossMetaData(true, data.map { it.apiName to it.dataUrl }).toJson()
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return base
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -251,7 +251,7 @@ open class TmdbProvider : MainAPI() {
 | 
			
		|||
        val found = idRegex.find(url)
 | 
			
		||||
 | 
			
		||||
        val isTvSeries = found?.groupValues?.getOrNull(1).equals("tv", ignoreCase = true)
 | 
			
		||||
        val id = found?.groupValues?.getOrNull(2)?.toIntOrNull() ?: return null
 | 
			
		||||
        val id = found?.groupValues?.getOrNull(2)?.toIntOrNull() ?: throw ErrorLoadingException("No id found")
 | 
			
		||||
 | 
			
		||||
        return if (useMetaLoadResponse) {
 | 
			
		||||
            return if (isTvSeries) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,6 +18,8 @@ class BflixProvider(providerUrl: String, providerName: String) : MainAPI() {
 | 
			
		|||
        TvType.TvSeries,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    //override val uniqueId: Int by lazy { "BflixProvider".hashCode() }
 | 
			
		||||
 | 
			
		||||
    override suspend fun getMainPage(): HomePageResponse {
 | 
			
		||||
        val items = ArrayList<HomePageList>()
 | 
			
		||||
        val soup = app.get("$mainUrl/home").document
 | 
			
		||||
| 
						 | 
				
			
			@ -323,6 +325,7 @@ class BflixProvider(providerUrl: String, providerName: String) : MainAPI() {
 | 
			
		|||
        callback: (ExtractorLink) -> Unit
 | 
			
		||||
    ): Boolean {
 | 
			
		||||
        val soup = app.get(data).document
 | 
			
		||||
 | 
			
		||||
        val movieid = encode(soup.selectFirst("div#watch").attr("data-id") ?: return false)
 | 
			
		||||
        val movieidencoded = encode(getVrf(movieid!!) ?: return false)
 | 
			
		||||
        Jsoup.parse(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -990,7 +990,7 @@ class ResultFragment : Fragment(), PanelsChildGestureRegionObserver.GestureRegio
 | 
			
		|||
                }
 | 
			
		||||
 | 
			
		||||
                ACTION_RELOAD_EPISODE -> {
 | 
			
		||||
                    viewModel.loadEpisode(episodeClick.data, false)
 | 
			
		||||
                    viewModel.loadEpisode(episodeClick.data, false, clearCache = true)
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                ACTION_DOWNLOAD_MIRROR -> {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue