mirror of
				https://github.com/recloudstream/cloudstream.git
				synced 2024-08-15 01:53:11 +00:00 
			
		
		
		
	fixed some warnings
This commit is contained in:
		
							parent
							
								
									509a0a6b90
								
							
						
					
					
						commit
						bf18e657f6
					
				
					 29 changed files with 235 additions and 283 deletions
				
			
		|  | @ -9,7 +9,6 @@ import com.lagradost.cloudstream3.utils.extractorApis | |||
| import org.jsoup.Jsoup | ||||
| import java.util.* | ||||
| 
 | ||||
| 
 | ||||
| class AnimeFlickProvider : MainAPI() { | ||||
|     companion object { | ||||
|         fun getType(t: String): TvType { | ||||
|  |  | |||
|  | @ -10,7 +10,6 @@ import com.lagradost.cloudstream3.utils.getQualityFromName | |||
| import org.jsoup.Jsoup | ||||
| import java.util.* | ||||
| 
 | ||||
| 
 | ||||
| class GogoanimeProvider : MainAPI() { | ||||
|     companion object { | ||||
|         fun getType(t: String): TvType { | ||||
|  |  | |||
|  | @ -4,7 +4,6 @@ import android.annotation.SuppressLint | |||
| import com.fasterxml.jackson.annotation.JsonProperty | ||||
| import com.fasterxml.jackson.module.kotlin.readValue | ||||
| import com.lagradost.cloudstream3.* | ||||
| import com.lagradost.cloudstream3.network.cookies | ||||
| import com.lagradost.cloudstream3.network.get | ||||
| import com.lagradost.cloudstream3.network.text | ||||
| import com.lagradost.cloudstream3.utils.ExtractorLink | ||||
|  | @ -16,8 +15,8 @@ import java.util.* | |||
| 
 | ||||
| class TenshiProvider : MainAPI() { | ||||
|     companion object { | ||||
|         var token: String? = null | ||||
|         var cookie: Map<String, String> = mapOf() | ||||
|         //var token: String? = null | ||||
|         //var cookie: Map<String, String> = mapOf() | ||||
| 
 | ||||
|         fun getType(t: String): TvType { | ||||
|             return if (t.contains("OVA") || t.contains("Special")) TvType.ONA | ||||
|  | @ -39,7 +38,7 @@ class TenshiProvider : MainAPI() { | |||
|     override val supportedTypes: Set<TvType> | ||||
|         get() = setOf(TvType.Anime, TvType.AnimeMovie, TvType.ONA) | ||||
| 
 | ||||
|     private fun loadToken(): Boolean { | ||||
|     /*private fun loadToken(): Boolean { | ||||
|         return try { | ||||
|             val response = get(mainUrl) | ||||
|             cookie = response.cookies | ||||
|  | @ -49,7 +48,7 @@ class TenshiProvider : MainAPI() { | |||
|         } catch (e: Exception) { | ||||
|             false | ||||
|         } | ||||
|     } | ||||
|     }*/ | ||||
| 
 | ||||
|     override fun getMainPage(): HomePageResponse { | ||||
|         val items = ArrayList<HomePageList>() | ||||
|  | @ -259,8 +258,7 @@ class TenshiProvider : MainAPI() { | |||
|                 null, | ||||
|                 it.attr("data-content").trim(), | ||||
|             ) | ||||
|         } | ||||
|             ?: ArrayList<AnimeEpisode>()) | ||||
|         }) | ||||
|         val status = when (document.selectFirst("li.status > .value")?.text()?.trim()) { | ||||
|             "Ongoing" -> ShowStatus.Ongoing | ||||
|             "Completed" -> ShowStatus.Completed | ||||
|  | @ -322,7 +320,7 @@ class TenshiProvider : MainAPI() { | |||
|                 headers = mapOf("Referer" to data) | ||||
|             ).text | ||||
| 
 | ||||
|             val match = Regex("""sources: (\[(?:.|\s)+?type: ['\"]video\/.*?['\"](?:.|\s)+?\])""").find(sourceHTML) | ||||
|             val match = Regex("""sources: (\[(?:.|\s)+?type: ['"]video/.*?['"](?:.|\s)+?])""").find(sourceHTML) | ||||
|             if (match != null) { | ||||
|                 val qualities = mapper.readValue<List<Quality>>( | ||||
|                     match.destructured.component1() | ||||
|  |  | |||
|  | @ -80,16 +80,16 @@ class WatchCartoonOnlineProvider : MainAPI() { | |||
|                 data = mapOf("catara" to query, "konuara" to "episodes") | ||||
|             ).text | ||||
|         document = Jsoup.parse(response) | ||||
|         items = document.select("#catlist-listview2 > ul > li").filter { it?.text() != null && !it?.text().toString().contains("Episode") } | ||||
|         items = document.select("#catlist-listview2 > ul > li").filter { it?.text() != null && !it.text().toString().contains("Episode") } | ||||
| 
 | ||||
| 
 | ||||
|         for (item in items) { | ||||
|             val titleHeader = item.selectFirst("a") | ||||
|             val title = titleHeader.text() | ||||
|             val href = fixUrl(titleHeader.attr("href")) | ||||
|             val isDubbed = title.contains("dubbed") | ||||
|             val set: EnumSet<DubStatus> = | ||||
|                 EnumSet.of(if (isDubbed) DubStatus.Dubbed else DubStatus.Subbed) | ||||
|             //val isDubbed = title.contains("dubbed") | ||||
|             //val set: EnumSet<DubStatus> = | ||||
|             //   EnumSet.of(if (isDubbed) DubStatus.Dubbed else DubStatus.Subbed) | ||||
|             returnValue.add( | ||||
|                 TvSeriesSearchResponse( | ||||
|                     title, | ||||
|  |  | |||
|  | @ -16,7 +16,7 @@ class MixDrop : ExtractorApi() { | |||
| 
 | ||||
|     override fun getUrl(url: String, referer: String?): List<ExtractorLink>? { | ||||
|         with(get(url)) { | ||||
|             getAndUnpack(this.text)?.let { unpackedText -> | ||||
|             getAndUnpack(this.text).let { unpackedText -> | ||||
|                 srcRegex.find(unpackedText)?.groupValues?.get(1)?.let { link -> | ||||
|                     return listOf( | ||||
|                         ExtractorLink( | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ class Mp4Upload : ExtractorApi() { | |||
| 
 | ||||
|     override fun getUrl(url: String, referer: String?): List<ExtractorLink>? { | ||||
|         with(get(url)) { | ||||
|             getAndUnpack(this.text)?.let { unpackedText -> | ||||
|             getAndUnpack(this.text).let { unpackedText -> | ||||
|                 srcRegex.find(unpackedText)?.groupValues?.get(1)?.let { link -> | ||||
|                     return listOf( | ||||
|                         ExtractorLink( | ||||
|  |  | |||
|  | @ -29,7 +29,7 @@ class MultiQuality : ExtractorApi() { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     override fun getUrl(url: String, referer: String?): List<ExtractorLink>? { | ||||
|     override fun getUrl(url: String, referer: String?): List<ExtractorLink> { | ||||
|         val extractedLinksList: MutableList<ExtractorLink> = mutableListOf() | ||||
|         with(get(url)) { | ||||
|             sourceRegex.findAll(this.text).forEach { sourceMatch -> | ||||
|  | @ -65,6 +65,5 @@ class MultiQuality : ExtractorApi() { | |||
|             } | ||||
|             return extractedLinksList | ||||
|         } | ||||
|         return null | ||||
|     } | ||||
| } | ||||
|  | @ -23,7 +23,7 @@ class SBPlay : ExtractorApi() { | |||
|         val response = get(url, referer = referer).text | ||||
|         val document = Jsoup.parse(response) | ||||
| 
 | ||||
|         val links = ArrayList<ExtractorLink>(); | ||||
|         val links = ArrayList<ExtractorLink>() | ||||
| 
 | ||||
|         val tree = document.select("table > tbody > tr > td > a") | ||||
|         for (item in tree) { | ||||
|  |  | |||
|  | @ -24,7 +24,7 @@ class StreamSB : ExtractorApi() { | |||
|         val extractedLinksList: MutableList<ExtractorLink> = mutableListOf() | ||||
|         val newUrl = url.replace("sbplay.org/embed-", "sbplay.org/play/").removeSuffix(".html") | ||||
|         with(get(newUrl, timeout = 10)) { | ||||
|             getAndUnpack(this.text)?.let { | ||||
|             getAndUnpack(this.text).let { | ||||
|                 sourceRegex.findAll(it).forEach { sourceMatch -> | ||||
|                     val extractedUrl = sourceMatch.groupValues[1] | ||||
|                     if (extractedUrl.contains(".m3u8")) { | ||||
|  |  | |||
|  | @ -293,7 +293,7 @@ class TrailersToProvider : MainAPI() { | |||
|                 Pair( | ||||
|                     subUrl, | ||||
|                     fixUrl( | ||||
|                         document?.selectFirst("content")?.attr("data-url") | ||||
|                         document.selectFirst("content")?.attr("data-url") | ||||
|                             ?: throw ErrorLoadingException("Link not found") | ||||
|                     ) | ||||
|                 ) | ||||
|  |  | |||
|  | @ -77,10 +77,10 @@ class VfFilmProvider : MainAPI() { | |||
| 
 | ||||
|     private fun getDirect(original: String): String {  // original data, https://vf-film.org/?trembed=1&trid=55313&trtype=1 for example | ||||
|         val response = get(original).text | ||||
|         val url = "iframe .*src=\\\"(.*?)\\\"".toRegex().find(response)?.groupValues?.get(1).toString()  // https://vudeo.net/embed-uweno86lzx8f.html for example | ||||
|         val url = "iframe .*src=\"(.*?)\"".toRegex().find(response)?.groupValues?.get(1).toString()  // https://vudeo.net/embed-uweno86lzx8f.html for example | ||||
|         val vudoResponse = get(url).text | ||||
|         val document = Jsoup.parse(vudoResponse) | ||||
|         val vudoUrl = Regex("sources: \\[\\\"(.*?)\\\"\\]").find(document.html())?.groupValues?.get(1).toString()  // direct mp4 link, https://m11.vudeo.net/2vp3ukyw2avjdohilpebtzuct42q5jwvpmpsez3xjs6d7fbs65dpuey2rbra/v.mp4 for exemple | ||||
|         val vudoUrl = Regex("sources: \\[\"(.*?)\"]").find(document.html())?.groupValues?.get(1).toString()  // direct mp4 link, https://m11.vudeo.net/2vp3ukyw2avjdohilpebtzuct42q5jwvpmpsez3xjs6d7fbs65dpuey2rbra/v.mp4 for exemple | ||||
|         return vudoUrl | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -95,7 +95,7 @@ class VidEmbedProvider : MainAPI() { | |||
|         val description = soup.selectFirst(".post-entry")?.text()?.trim() | ||||
|         var poster: String? = null | ||||
| 
 | ||||
|         val episodes = soup.select(".listing.items.lists > .video-block").withIndex().map { (index, li) -> | ||||
|         val episodes = soup.select(".listing.items.lists > .video-block").withIndex().map { (_, li) -> | ||||
|             val epTitle = if (li.selectFirst(".name") != null) | ||||
|                 if (li.selectFirst(".name").text().contains("Episode")) | ||||
|                     "Episode " + li.selectFirst(".name").text().split("Episode")[1].trim() | ||||
|  | @ -162,7 +162,7 @@ class VidEmbedProvider : MainAPI() { | |||
| 
 | ||||
|     // This loads the homepage, which is basically a collection of search results with labels. | ||||
|     // Optional function, but make sure to enable hasMainPage if you program this. | ||||
|     override fun getMainPage(): HomePageResponse? { | ||||
|     override fun getMainPage(): HomePageResponse { | ||||
|         val urls = listOf( | ||||
|             mainUrl, | ||||
|             "$mainUrl/movies", | ||||
|  | @ -262,8 +262,8 @@ class VidEmbedProvider : MainAPI() { | |||
| 
 | ||||
|                 // Having a referer is often required. It's a basic security check most providers have. | ||||
|                 // Try to replicate what your browser does. | ||||
|                 val html = get(it.second, headers = mapOf("referer" to iframeLink)).text | ||||
|                 sourceRegex.findAll(html).forEach { match -> | ||||
|                 val serverHtml = get(it.second, headers = mapOf("referer" to iframeLink)).text | ||||
|                 sourceRegex.findAll(serverHtml).forEach { match -> | ||||
|                     callback.invoke( | ||||
|                         ExtractorLink( | ||||
|                             this.name, | ||||
|  | @ -279,7 +279,7 @@ class VidEmbedProvider : MainAPI() { | |||
|                         ) | ||||
|                     ) | ||||
|                 } | ||||
|                 trackRegex.findAll(html).forEach { match -> | ||||
|                 trackRegex.findAll(serverHtml).forEach { match -> | ||||
|                     subtitleCallback.invoke( | ||||
|                         SubtitleFile( | ||||
|                             match.groupValues.getOrNull(2) ?: "Unknown", | ||||
|  |  | |||
|  | @ -5,7 +5,6 @@ import android.content.Context | |||
| import android.content.Intent | ||||
| import android.util.Log | ||||
| 
 | ||||
| 
 | ||||
| class VideoDownloadRestartReceiver : BroadcastReceiver() { | ||||
|     override fun onReceive(context: Context?, intent: Intent?) { | ||||
|         Log.i("Broadcast Listened", "Service tried to stop") | ||||
|  |  | |||
|  | @ -28,15 +28,12 @@ import com.lagradost.cloudstream3.sortUrls | |||
| import com.lagradost.cloudstream3.ui.result.ResultEpisode | ||||
| import com.lagradost.cloudstream3.utils.CastHelper.awaitLinks | ||||
| import com.lagradost.cloudstream3.utils.CastHelper.getMediaInfo | ||||
| import com.lagradost.cloudstream3.utils.Coroutines.main | ||||
| import com.lagradost.cloudstream3.utils.DataStore.toKotlinObject | ||||
| import com.lagradost.cloudstream3.utils.ExtractorLink | ||||
| import kotlinx.coroutines.Dispatchers | ||||
| import kotlinx.coroutines.withContext | ||||
| import org.json.JSONObject | ||||
| import kotlin.concurrent.thread | ||||
| 
 | ||||
| class SkipOpController(val view: ImageView) : UIController() { | ||||
| /*class SkipOpController(val view: ImageView) : UIController() { | ||||
|     init { | ||||
|         view.setImageResource(R.drawable.exo_controls_fastforward) | ||||
|         view.setOnClickListener { | ||||
|  | @ -47,12 +44,12 @@ class SkipOpController(val view: ImageView) : UIController() { | |||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| }*/ | ||||
| 
 | ||||
| private fun RemoteMediaClient.getItemIndex(): Int? { | ||||
|     return try { | ||||
|         val index = this.mediaQueue?.itemIds?.indexOf(this.currentItem?.itemId ?: 0) | ||||
|         if (index == null || index < 0) null else index | ||||
|         val index = this.mediaQueue.itemIds.indexOf(this.currentItem?.itemId ?: 0) | ||||
|         if (index < 0) null else index | ||||
|     } catch (e: Exception) { | ||||
|         null | ||||
|     } | ||||
|  | @ -136,7 +133,7 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi | |||
| 
 | ||||
|                         subtitleList.setOnItemClickListener { _, _, which, _ -> | ||||
|                             if (which == 0) { | ||||
|                                 remoteMediaClient.setActiveMediaTracks(longArrayOf()) // NO SUBS | ||||
|                                 remoteMediaClient?.setActiveMediaTracks(longArrayOf()) // NO SUBS | ||||
|                             } else { | ||||
|                                 val font = TextTrackStyle() | ||||
|                                 font.fontFamily = "Google Sans" //TODO FONT SETTINGS | ||||
|  | @ -147,10 +144,10 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi | |||
|                                 font.foregroundColor = Color.WHITE | ||||
|                                 font.fontScale = 1.05f | ||||
| 
 | ||||
|                                 remoteMediaClient.setTextTrackStyle(font) | ||||
|                                 remoteMediaClient?.setTextTrackStyle(font) | ||||
| 
 | ||||
|                                 remoteMediaClient.setActiveMediaTracks(longArrayOf(subTracks[which - 1].id)) | ||||
|                                     .setResultCallback { | ||||
|                                 remoteMediaClient?.setActiveMediaTracks(longArrayOf(subTracks[which - 1].id)) | ||||
|                                     ?.setResultCallback { | ||||
|                                         if (!it.status.isSuccess) { | ||||
|                                             Log.e( | ||||
|                                                 "CHROMECAST", "Failed with status code:" + | ||||
|  | @ -332,7 +329,9 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi | |||
|     } | ||||
| 
 | ||||
|     override fun onSessionConnected(castSession: CastSession?) { | ||||
|         super.onSessionConnected(castSession) | ||||
|         castSession?.let { | ||||
|             super.onSessionConnected(it) | ||||
|         } | ||||
|         remoteMediaClient?.queueSetRepeatMode(REPEAT_MODE_REPEAT_OFF, JSONObject()) | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -54,7 +54,7 @@ class DownloadChildFragment : Fragment() { | |||
|                         ?: return@mapNotNull null | ||||
|                     VisualDownloadChildCached(info.fileLength, info.totalBytes, it) | ||||
|                 } | ||||
|             } | ||||
|             }.sortedBy { it.data.episode + (it.data.season?: 0)*100000 } | ||||
|             if (eps.isEmpty()) { | ||||
|                 activity?.onBackPressed() | ||||
|                 return@main | ||||
|  |  | |||
|  | @ -102,10 +102,7 @@ class DownloadFragment : Fragment() { | |||
|                     } else { | ||||
|                         val folder = getFolderName(DOWNLOAD_EPISODE_CACHE, click.data.id.toString()) | ||||
|                         val navController = activity?.findNavController(R.id.nav_host_fragment) | ||||
|                         navController?.navigate(R.id.navigation_download_child, Bundle().apply { | ||||
|                             putString("folder", folder) | ||||
|                             putString("name", click.data.name) | ||||
|                         }) | ||||
|                         navController?.navigate(R.id.navigation_download_child, DownloadChildFragment.newInstance(click.data.name,folder)) | ||||
|                     } | ||||
|                 }, | ||||
|                 { downloadClickEvent -> | ||||
|  |  | |||
|  | @ -1,6 +1,5 @@ | |||
| package com.lagradost.cloudstream3.ui.download | ||||
| 
 | ||||
| import android.annotation.SuppressLint | ||||
| import android.view.LayoutInflater | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
|  |  | |||
|  | @ -13,7 +13,6 @@ import com.lagradost.cloudstream3.SearchResponse | |||
| import com.lagradost.cloudstream3.mvvm.Resource | ||||
| import com.lagradost.cloudstream3.ui.APIRepository | ||||
| import com.lagradost.cloudstream3.ui.APIRepository.Companion.noneApi | ||||
| import com.lagradost.cloudstream3.ui.APIRepository.Companion.noneRepo | ||||
| import com.lagradost.cloudstream3.ui.APIRepository.Companion.randomApi | ||||
| import com.lagradost.cloudstream3.ui.WatchType | ||||
| import com.lagradost.cloudstream3.utils.DOWNLOAD_HEADER_CACHE | ||||
|  |  | |||
|  | @ -33,7 +33,6 @@ import android.widget.* | |||
| import android.widget.Toast.LENGTH_SHORT | ||||
| import androidx.appcompat.app.AlertDialog | ||||
| import androidx.core.content.ContextCompat | ||||
| import androidx.core.net.toUri | ||||
| import androidx.core.view.isVisible | ||||
| import androidx.fragment.app.Fragment | ||||
| import androidx.lifecycle.ViewModelProvider | ||||
|  | @ -47,7 +46,6 @@ import com.fasterxml.jackson.module.kotlin.KotlinModule | |||
| import com.fasterxml.jackson.module.kotlin.readValue | ||||
| import com.google.android.exoplayer2.* | ||||
| import com.google.android.exoplayer2.C.TIME_UNSET | ||||
| import com.google.android.exoplayer2.PlaybackException.ERROR_CODE_AUDIO_TRACK_INIT_FAILED | ||||
| import com.google.android.exoplayer2.database.ExoDatabaseProvider | ||||
| import com.google.android.exoplayer2.source.DefaultMediaSourceFactory | ||||
| import com.google.android.exoplayer2.trackselection.DefaultTrackSelector | ||||
|  | @ -247,8 +245,6 @@ class PlayerFragment : Fragment() { | |||
|     private lateinit var playerData: PlayerData | ||||
|     private lateinit var uriData: UriData | ||||
|     private var isDownloadedFile = false | ||||
|     private var downloadId = 0 | ||||
|     private var isLoading = true | ||||
|     private var isShowing = true | ||||
|     private lateinit var exoPlayer: SimpleExoPlayer | ||||
| 
 | ||||
|  | @ -748,8 +744,6 @@ class PlayerFragment : Fragment() { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private var volumeObserver: SettingsContentObserver? = null | ||||
| 
 | ||||
|     companion object { | ||||
|         fun String.toSubtitleMimeType(): String { | ||||
|             return when { | ||||
|  | @ -764,7 +758,6 @@ class PlayerFragment : Fragment() { | |||
|             return Bundle().apply { | ||||
|                 //println(data) | ||||
|                 putString("data", mapper.writeValueAsString(data)) | ||||
|                 println("PUT START: " + startPos) | ||||
|                 if (startPos != null) { | ||||
|                     putLong(STATE_RESUME_POSITION, startPos) | ||||
|                 } | ||||
|  | @ -1042,88 +1035,89 @@ class PlayerFragment : Fragment() { | |||
|                     exoPlayer.play() | ||||
|             } | ||||
|         }*/ | ||||
|         activity?.let { act -> | ||||
|             if (act.isCastApiAvailable() && !isDownloadedFile) { | ||||
|                 try { | ||||
|                     CastButtonFactory.setUpMediaRouteButton(act, player_media_route_button) | ||||
|                     val castContext = CastContext.getSharedInstance(requireContext()) | ||||
| 
 | ||||
|         if (activity?.isCastApiAvailable() == true && !isDownloadedFile) { | ||||
|             try { | ||||
|                 CastButtonFactory.setUpMediaRouteButton(activity, player_media_route_button) | ||||
|                 val castContext = CastContext.getSharedInstance(requireContext()) | ||||
|                     if (castContext.castState != CastState.NO_DEVICES_AVAILABLE) player_media_route_button.visibility = | ||||
|                         VISIBLE | ||||
|                     castContext.addCastStateListener { state -> | ||||
|                         if (player_media_route_button != null) { | ||||
|                             player_media_route_button.isVisible = state != CastState.NO_DEVICES_AVAILABLE | ||||
| 
 | ||||
|                 if (castContext.castState != CastState.NO_DEVICES_AVAILABLE) player_media_route_button.visibility = VISIBLE | ||||
|                 castContext.addCastStateListener { state -> | ||||
|                     if (player_media_route_button != null) { | ||||
|                         player_media_route_button.isVisible = state != CastState.NO_DEVICES_AVAILABLE | ||||
|                             if (state == CastState.CONNECTED) { | ||||
|                                 if (!this::exoPlayer.isInitialized) return@addCastStateListener | ||||
|                                 val links = sortUrls(getUrls() ?: return@addCastStateListener) | ||||
|                                 val epData = getEpisode() ?: return@addCastStateListener | ||||
| 
 | ||||
|                         if (state == CastState.CONNECTED) { | ||||
|                             if (!this::exoPlayer.isInitialized) return@addCastStateListener | ||||
|                             val links = sortUrls(getUrls() ?: return@addCastStateListener) | ||||
|                             val epData = getEpisode() ?: return@addCastStateListener | ||||
|                                 val index = links.indexOf(getCurrentUrl()) | ||||
|                                 activity?.getCastSession()?.startCast( | ||||
|                                     apiName, | ||||
|                                     currentIsMovie ?: return@addCastStateListener, | ||||
|                                     currentHeaderName, | ||||
|                                     currentPoster, | ||||
|                                     epData.index, | ||||
|                                     episodes, | ||||
|                                     links, | ||||
|                                     context?.getSubs(supportsDownloadedFiles = false) ?: emptyList(), | ||||
|                                     index, | ||||
|                                     exoPlayer.currentPosition | ||||
|                                 ) | ||||
| 
 | ||||
|                             val index = links.indexOf(getCurrentUrl()) | ||||
|                             activity?.getCastSession()?.startCast( | ||||
|                                 apiName, | ||||
|                                 currentIsMovie ?: return@addCastStateListener, | ||||
|                                 currentHeaderName, | ||||
|                                 currentPoster, | ||||
|                                 epData.index, | ||||
|                                 episodes, | ||||
|                                 links, | ||||
|                                 context?.getSubs(supportsDownloadedFiles = false) ?: emptyList(), | ||||
|                                 index, | ||||
|                                 exoPlayer.currentPosition | ||||
|                             ) | ||||
| 
 | ||||
|                             /* | ||||
|                             val customData = | ||||
|                                 links.map { JSONObject().put("name", it.name) } | ||||
|                             val jsonArray = JSONArray() | ||||
|                             for (item in customData) { | ||||
|                                 jsonArray.put(item) | ||||
|                             } | ||||
| 
 | ||||
|                             val mediaItems = links.map { | ||||
|                                 val movieMetadata = MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE) | ||||
| 
 | ||||
|                                 movieMetadata.putString(MediaMetadata.KEY_SUBTITLE, | ||||
|                                     epData.name ?: "Episode ${epData.episode}") | ||||
| 
 | ||||
|                                 if (currentHeaderName != null) | ||||
|                                     movieMetadata.putString(MediaMetadata.KEY_TITLE, currentHeaderName) | ||||
| 
 | ||||
|                                 val srcPoster = epData.poster ?: currentPoster | ||||
|                                 if (srcPoster != null) { | ||||
|                                     movieMetadata.addImage(WebImage(Uri.parse(srcPoster))) | ||||
|                                 /* | ||||
|                                 val customData = | ||||
|                                     links.map { JSONObject().put("name", it.name) } | ||||
|                                 val jsonArray = JSONArray() | ||||
|                                 for (item in customData) { | ||||
|                                     jsonArray.put(item) | ||||
|                                 } | ||||
| 
 | ||||
|                                 MediaQueueItem.Builder( | ||||
|                                     MediaInfo.Builder(it.url) | ||||
|                                         .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED) | ||||
|                                         .setContentType(MimeTypes.VIDEO_UNKNOWN) | ||||
|                                 val mediaItems = links.map { | ||||
|                                     val movieMetadata = MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE) | ||||
| 
 | ||||
|                                         .setCustomData(JSONObject().put("data", jsonArray)) | ||||
|                                         .setMetadata(movieMetadata) | ||||
|                                     movieMetadata.putString(MediaMetadata.KEY_SUBTITLE, | ||||
|                                         epData.name ?: "Episode ${epData.episode}") | ||||
| 
 | ||||
|                                     if (currentHeaderName != null) | ||||
|                                         movieMetadata.putString(MediaMetadata.KEY_TITLE, currentHeaderName) | ||||
| 
 | ||||
|                                     val srcPoster = epData.poster ?: currentPoster | ||||
|                                     if (srcPoster != null) { | ||||
|                                         movieMetadata.addImage(WebImage(Uri.parse(srcPoster))) | ||||
|                                     } | ||||
| 
 | ||||
|                                     MediaQueueItem.Builder( | ||||
|                                         MediaInfo.Builder(it.url) | ||||
|                                             .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED) | ||||
|                                             .setContentType(MimeTypes.VIDEO_UNKNOWN) | ||||
| 
 | ||||
|                                             .setCustomData(JSONObject().put("data", jsonArray)) | ||||
|                                             .setMetadata(movieMetadata) | ||||
|                                             .build() | ||||
|                                     ) | ||||
|                                         .build() | ||||
|                                 ) | ||||
|                                     .build() | ||||
|                             }.toTypedArray() | ||||
|                                 }.toTypedArray() | ||||
| 
 | ||||
|                             val castPlayer = CastPlayer(castContext) | ||||
|                             castPlayer.loadItems( | ||||
|                                 mediaItems, | ||||
|                                 if (index > 0) index else 0, | ||||
|                                 exoPlayer.currentPosition, | ||||
|                                 MediaStatus.REPEAT_MODE_REPEAT_SINGLE | ||||
|                             )*/ | ||||
|                             //  activity?.popCurrentPage(isInPlayer = true, isInExpandedView = false, isInResults = false) | ||||
|                             safeReleasePlayer() | ||||
|                             activity?.popCurrentPage() | ||||
|                                 val castPlayer = CastPlayer(castContext) | ||||
|                                 castPlayer.loadItems( | ||||
|                                     mediaItems, | ||||
|                                     if (index > 0) index else 0, | ||||
|                                     exoPlayer.currentPosition, | ||||
|                                     MediaStatus.REPEAT_MODE_REPEAT_SINGLE | ||||
|                                 )*/ | ||||
|                                 //  activity?.popCurrentPage(isInPlayer = true, isInExpandedView = false, isInResults = false) | ||||
|                                 safeReleasePlayer() | ||||
|                                 activity?.popCurrentPage() | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } catch (e: Exception) { | ||||
|                     logError(e) | ||||
|                 } | ||||
|             } catch (e : Exception) { | ||||
|                 logError(e) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         isDownloadedFile = false | ||||
|         arguments?.getString("uriData")?.let { | ||||
|             uriData = mapper.readValue(it) | ||||
|  | @ -1159,7 +1153,7 @@ class PlayerFragment : Fragment() { | |||
| 
 | ||||
|         activity?.let { | ||||
|             it.contentResolver?.registerContentObserver( | ||||
|                 android.provider.Settings.System.CONTENT_URI, true, SettingsContentObserver( | ||||
|                 Settings.System.CONTENT_URI, true, SettingsContentObserver( | ||||
|                     Handler( | ||||
|                         Looper.getMainLooper() | ||||
|                     ), it | ||||
|  | @ -1172,13 +1166,13 @@ class PlayerFragment : Fragment() { | |||
| 
 | ||||
|             observeDirectly(viewModel.episodes) { _episodes -> | ||||
|                 episodes = _episodes | ||||
|                 if (isLoading) { | ||||
|                     /*if (playerData.episodeIndex > 0 && playerData.episodeIndex < episodes.size) { | ||||
|                 /*if (isLoading) { | ||||
|                     if (playerData.episodeIndex > 0 && playerData.episodeIndex < episodes.size) { | ||||
| 
 | ||||
|                     } else { | ||||
|                         // WHAT THE FUCK DID YOU DO | ||||
|                     }*/ | ||||
|                 } | ||||
|                     } | ||||
|                 }*/ | ||||
|             } | ||||
| 
 | ||||
|             observe(viewModel.apiName) { | ||||
|  | @ -1485,7 +1479,7 @@ class PlayerFragment : Fragment() { | |||
|                 requireContext().setKey(RESIZE_MODE_KEY, resizeMode) | ||||
|                 player_view.resizeMode = resizeModes[resizeMode].first | ||||
|                 activity?.let { act -> | ||||
|                     showToast(act, resizeModes[resizeMode].second, Toast.LENGTH_SHORT); | ||||
|                     showToast(act, resizeModes[resizeMode].second, LENGTH_SHORT) | ||||
|                 } | ||||
|                 //exoPlayer.videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING | ||||
|             } | ||||
|  | @ -1508,18 +1502,6 @@ class PlayerFragment : Fragment() { | |||
|         // initPlayer() | ||||
|     } | ||||
| 
 | ||||
|     private fun getRendererIndex(trackIndex: Int): Int? { | ||||
|         if (!this::exoPlayer.isInitialized) return null | ||||
| 
 | ||||
|         for (renderIndex in 0 until exoPlayer.rendererCount) { | ||||
|             if (exoPlayer.getRendererType(renderIndex) == renderIndex) { | ||||
|                 return renderIndex | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return null | ||||
|     } | ||||
| 
 | ||||
|     private fun getCurrentUrl(): ExtractorLink? { | ||||
|         val urls = getUrls() ?: return null | ||||
|         for (i in urls) { | ||||
|  | @ -2067,7 +2049,11 @@ class PlayerFragment : Fragment() { | |||
|                             } | ||||
|                         } | ||||
|                         PlaybackException.ERROR_CODE_REMOTE_ERROR, PlaybackException.ERROR_CODE_IO_BAD_HTTP_STATUS, PlaybackException.ERROR_CODE_TIMEOUT, PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED, PlaybackException.ERROR_CODE_IO_INVALID_HTTP_CONTENT_TYPE -> { | ||||
|                             showToast(activity, "${getString(R.string.remote_error)}\n$errorName ($code)\n$msg", LENGTH_SHORT) | ||||
|                             showToast( | ||||
|                                 activity, | ||||
|                                 "${getString(R.string.remote_error)}\n$errorName ($code)\n$msg", | ||||
|                                 LENGTH_SHORT | ||||
|                             ) | ||||
|                         } | ||||
|                         PlaybackException.ERROR_CODE_DECODING_FAILED, PlaybackErrorEvent.ERROR_AUDIO_TRACK_INIT_FAILED, PlaybackErrorEvent.ERROR_AUDIO_TRACK_OTHER, PlaybackException.ERROR_CODE_AUDIO_TRACK_WRITE_FAILED, PlaybackException.ERROR_CODE_DECODER_INIT_FAILED, PlaybackException.ERROR_CODE_DECODER_QUERY_FAILED -> { | ||||
|                             showToast( | ||||
|  |  | |||
|  | @ -280,7 +280,7 @@ class ResultViewModel : ViewModel() { | |||
|                         if (dataList != null) { // TODO dub and sub at the same time | ||||
|                             val episodes = ArrayList<ResultEpisode>() | ||||
|                             for ((index, i) in dataList.withIndex()) { | ||||
|                                 val episode = i.episode ?: (index + 1); | ||||
|                                 val episode = i.episode ?: (index + 1) | ||||
|                                 episodes.add( | ||||
|                                     context.buildResultEpisode( | ||||
|                                         filterName(i.name), | ||||
|  |  | |||
|  | @ -72,7 +72,7 @@ object CastHelper { | |||
|         if (pending == null) return | ||||
|         main { | ||||
|             val res = withContext(Dispatchers.IO) { pending.await() } | ||||
|             when (res.status?.statusCode) { | ||||
|             when (res.status.statusCode) { | ||||
|                 CastStatusCodes.FAILED -> { | ||||
|                     callback.invoke(true) | ||||
|                     println("FAILED AND LOAD NEXT") | ||||
|  |  | |||
|  | @ -10,7 +10,6 @@ import com.lagradost.cloudstream3.utils.DataStore.getKey | |||
| import com.lagradost.cloudstream3.utils.DataStore.removeKey | ||||
| import com.lagradost.cloudstream3.utils.VideoDownloadManager.WORK_KEY_INFO | ||||
| import com.lagradost.cloudstream3.utils.VideoDownloadManager.WORK_KEY_PACKAGE | ||||
| import com.lagradost.cloudstream3.utils.VideoDownloadManager.createNotification | ||||
| import com.lagradost.cloudstream3.utils.VideoDownloadManager.downloadCheck | ||||
| import com.lagradost.cloudstream3.utils.VideoDownloadManager.downloadEpisode | ||||
| import com.lagradost.cloudstream3.utils.VideoDownloadManager.downloadFromResume | ||||
|  |  | |||
|  | @ -1,9 +1,5 @@ | |||
| package com.lagradost.cloudstream3.utils | ||||
| 
 | ||||
| import com.lagradost.cloudstream3.mvvm.logError | ||||
| import java.lang.Exception | ||||
| import java.lang.StringBuilder | ||||
| import java.util.HashMap | ||||
| import java.util.regex.Pattern | ||||
| import kotlin.math.pow | ||||
| 
 | ||||
|  |  | |||
|  | @ -85,7 +85,7 @@ class M3u8Helper { | |||
| 
 | ||||
|             for (match in QUALITY_REGEX.findAll(response)) { | ||||
|                 var (quality, m3u8Link, m3u8Link2) = match.destructured | ||||
|                 if (m3u8Link.isNullOrEmpty()) m3u8Link = m3u8Link2 | ||||
|                 if (m3u8Link.isEmpty()) m3u8Link = m3u8Link2 | ||||
|                 if (absoluteExtensionDetermination(m3u8Link) == "m3u8") { | ||||
|                     if (isNotCompleteUrl(m3u8Link)) { | ||||
|                         m3u8Link = "$m3u8Parent/$m3u8Link" | ||||
|  | @ -138,7 +138,7 @@ class M3u8Helper { | |||
|         if (secondSelection != null) { | ||||
|             val m3u8Response = get(secondSelection.streamUrl, headers = headers).text | ||||
| 
 | ||||
|             var encryptionUri: String? = null | ||||
|             var encryptionUri: String? | ||||
|             var encryptionIv = byteArrayOf() | ||||
|             var encryptionData = byteArrayOf() | ||||
| 
 | ||||
|  |  | |||
|  | @ -2,7 +2,6 @@ package com.lagradost.cloudstream3.utils | |||
| 
 | ||||
| import android.app.Dialog | ||||
| import android.content.Context | ||||
| import android.view.View | ||||
| import android.widget.* | ||||
| import androidx.appcompat.app.AlertDialog | ||||
| import androidx.core.view.isVisible | ||||
|  | @ -10,9 +9,7 @@ import androidx.core.view.marginLeft | |||
| import androidx.core.view.marginRight | ||||
| import androidx.core.view.marginTop | ||||
| import com.google.android.material.bottomsheet.BottomSheetDialog | ||||
| import com.lagradost.cloudstream3.MainActivity.Companion.updateLocale | ||||
| import com.lagradost.cloudstream3.R | ||||
| import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showDialog | ||||
| 
 | ||||
| object SingleSelectionHelper { | ||||
|     fun Context.showDialog( | ||||
|  |  | |||
|  | @ -16,7 +16,7 @@ object SubtitleHelper { | |||
|         val ISO_639_6: String, | ||||
|     ) | ||||
| 
 | ||||
|     fun createISO() { | ||||
|     /*fun createISO() { | ||||
|         val url = "https://infogalactic.com/info/List_of_ISO_639-1_codes" | ||||
|         val response = get(url).text | ||||
|         val document = Jsoup.parse(response) | ||||
|  | @ -40,7 +40,7 @@ object SubtitleHelper { | |||
|         } | ||||
|         text += ")" | ||||
|         println("ISO CREATED:\n$text") | ||||
|     } | ||||
|     }*/ | ||||
| 
 | ||||
|     /** lang -> ISO_639_1*/ | ||||
|     fun fromLanguageToTwoLetters(input: String): String? { | ||||
|  |  | |||
|  | @ -661,10 +661,9 @@ object VideoDownloadManager { | |||
| 
 | ||||
|         val contentLength = try { | ||||
|             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // fuck android | ||||
|                 connection.contentLengthLong ?: 0L | ||||
|                 connection.contentLengthLong | ||||
|             } else { | ||||
|                 connection.getHeaderField("content-length").toLongOrNull() ?: connection.contentLength?.toLong() | ||||
|                 ?: 0L | ||||
|                 connection.getHeaderField("content-length").toLongOrNull() ?: connection.contentLength.toLong() | ||||
|             } | ||||
|         } catch (e: Exception) { | ||||
|             logError(e) | ||||
|  |  | |||
|  | @ -1,17 +0,0 @@ | |||
| package com.lagradost.cloudstream3 | ||||
| 
 | ||||
| import org.junit.Test | ||||
| 
 | ||||
| import org.junit.Assert.* | ||||
| 
 | ||||
| /** | ||||
|  * Example local unit test, which will execute on the development machine (host). | ||||
|  * | ||||
|  * See [testing documentation](http://d.android.com/tools/testing). | ||||
|  */ | ||||
| class ExampleUnitTest { | ||||
|     @Test | ||||
|     fun addition_isCorrect() { | ||||
|         assertEquals(4, 2 + 2) | ||||
|     } | ||||
| } | ||||
|  | @ -13,6 +13,115 @@ class ProviderTests { | |||
|         return allApis | ||||
|     } | ||||
| 
 | ||||
|     private fun loadLinks(api: MainAPI, url: String?): Boolean { | ||||
|         Assert.assertNotNull("Api ${api.name} has invalid url on episode", url) | ||||
|         if (url == null) return true | ||||
|         var linksLoaded = 0 | ||||
|         try { | ||||
|             val success = api.loadLinks(url, false, {}) { link -> | ||||
|                 Assert.assertTrue( | ||||
|                     "Api ${api.name} returns link with invalid Quality", | ||||
|                     Qualities.values().map { it.value }.contains(link.quality) | ||||
|                 ) | ||||
|                 Assert.assertTrue("Api ${api.name} returns link with invalid url", link.url.length > 4) | ||||
|                 linksLoaded++ | ||||
|             } | ||||
|             if (success) { | ||||
|                 return linksLoaded > 0 | ||||
|             } | ||||
|             Assert.assertTrue("Api ${api.name} has returns false on .loadLinks", success) | ||||
|         } catch (e: Exception) { | ||||
|             if (e.cause is NotImplementedError) { | ||||
|                 Assert.fail("Provider has not implemented .loadLinks") | ||||
|             } | ||||
|             logError(e) | ||||
|         } | ||||
|         return true | ||||
|     } | ||||
| 
 | ||||
|     private fun test_single_provider(api: MainAPI) { | ||||
|         val searchQueries = listOf("over", "iron", "guy") | ||||
|         var correctResponses = 0 | ||||
|         var searchResult: List<SearchResponse>? = null | ||||
|         for (query in searchQueries) { | ||||
|             val response = try { | ||||
|                 api.search(query) | ||||
|             } catch (e: Exception) { | ||||
|                 if (e.cause is NotImplementedError) { | ||||
|                     Assert.fail("Provider has not implemented .search") | ||||
|                 } | ||||
|                 logError(e) | ||||
|                 null | ||||
|             } | ||||
|             if (!response.isNullOrEmpty()) { | ||||
|                 correctResponses++ | ||||
|                 if (searchResult == null) { | ||||
|                     searchResult = response | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (correctResponses == 0 || searchResult == null) { | ||||
|             println("Api ${api.name} did not return any valid search responses") | ||||
|             return | ||||
|         } | ||||
| 
 | ||||
|         try { | ||||
|             var validResults = false | ||||
|             for (result in searchResult) { | ||||
|                 Assert.assertEquals("Invalid apiName on response on ${api.name}", result.apiName, api.name) | ||||
|                 val load = api.load(result.url) ?: continue | ||||
|                 Assert.assertEquals("Invalid apiName on load on ${api.name}", load.apiName, result.apiName) | ||||
|                 Assert.assertTrue( | ||||
|                     "Api ${api.name} on load does not contain any of the supportedTypes", | ||||
|                     api.supportedTypes.contains(load.type) | ||||
|                 ) | ||||
|                 when (load) { | ||||
|                     is AnimeLoadResponse -> { | ||||
|                         val gotNoEpisodes = | ||||
|                             load.dubEpisodes.isNullOrEmpty() && load.subEpisodes.isNullOrEmpty() | ||||
|                         if (gotNoEpisodes) { | ||||
|                             println("Api ${api.name} got no episodes on ${load.url}") | ||||
|                             continue | ||||
|                         } | ||||
| 
 | ||||
|                         val url = (load.dubEpisodes ?: load.subEpisodes)?.first()?.url | ||||
|                         validResults = loadLinks(api, url) | ||||
|                         if (!validResults) continue | ||||
|                     } | ||||
|                     is MovieLoadResponse -> { | ||||
|                         val gotNoEpisodes = load.dataUrl.isBlank() | ||||
|                         if (gotNoEpisodes) { | ||||
|                             println("Api ${api.name} got no movie on ${load.url}") | ||||
|                             continue | ||||
|                         } | ||||
| 
 | ||||
|                         validResults = loadLinks(api, load.dataUrl) | ||||
|                         if (!validResults) continue | ||||
|                     } | ||||
|                     is TvSeriesLoadResponse -> { | ||||
|                         val gotNoEpisodes = load.episodes.isEmpty() | ||||
|                         if (gotNoEpisodes) { | ||||
|                             println("Api ${api.name} got no episodes on ${load.url}") | ||||
|                             continue | ||||
|                         } | ||||
| 
 | ||||
|                         validResults = loadLinks(api, load.episodes.first().data) | ||||
|                         if (!validResults) continue | ||||
|                     } | ||||
|                 } | ||||
|                 break | ||||
|             } | ||||
| 
 | ||||
|             Assert.assertTrue("Api ${api.name} did not load on any}", validResults) | ||||
|         } catch (e: Exception) { | ||||
|             if (e.cause is NotImplementedError) { | ||||
|                 Assert.fail("Provider has not implemented .load") | ||||
|             } | ||||
|             logError(e) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     fun providers_exist() { | ||||
|         Assert.assertTrue(getAllProviders().isNotEmpty()) | ||||
|  | @ -23,7 +132,7 @@ class ProviderTests { | |||
|         val isoNames = SubtitleHelper.languages.map { it.ISO_639_1 } | ||||
|         Assert.assertFalse("ISO does not contain any languages", isoNames.isNullOrEmpty()) | ||||
|         for (api in getAllProviders()) { | ||||
|             Assert.assertTrue("Api does not contain a mainurl", api.mainUrl != "NONE") | ||||
|             Assert.assertTrue("Api does not contain a mainUrl", api.mainUrl != "NONE") | ||||
|             Assert.assertTrue("Api does not contain a name", api.name != "NONE") | ||||
|             Assert.assertTrue("Api ${api.name} does not contain a valid language code", isoNames.contains(api.lang)) | ||||
|             Assert.assertTrue("Api ${api.name} does not contain any supported types", api.supportedTypes.isNotEmpty()) | ||||
|  | @ -57,118 +166,13 @@ class ProviderTests { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private fun loadLinks(api: MainAPI, url: String?): Boolean { | ||||
|         Assert.assertNotNull("Api ${api.name} has invalid url on episode", url) | ||||
|         if (url == null) return true | ||||
|         var linksLoaded = 0 | ||||
|         try { | ||||
|             val success = api.loadLinks(url, false, {}) { link -> | ||||
|                 Assert.assertTrue( | ||||
|                     "Api ${api.name} returns link with invalid Quality", | ||||
|                     Qualities.values().map { it.value }.contains(link.quality) | ||||
|                 ) | ||||
|                 Assert.assertTrue("Api ${api.name} returns link with invalid url", link.url.length > 4) | ||||
|                 linksLoaded++ | ||||
|             } | ||||
|             if (success) { | ||||
|                 return linksLoaded > 0 | ||||
|             } | ||||
|             Assert.assertTrue("Api ${api.name} has returns false on .loadLinks", success) | ||||
|         } catch (e: Exception) { | ||||
|             if (e.cause is NotImplementedError) { | ||||
|                 Assert.fail("Provider has not implemented .loadLinks") | ||||
|             } | ||||
|             logError(e) | ||||
|         } | ||||
|         return true | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     fun provider_correct() { | ||||
|         val searchQueries = listOf("over", "iron", "guy") | ||||
|         val providers = getAllProviders() | ||||
|         for ((index, api) in providers.withIndex()) { | ||||
|             try { | ||||
|                 println("Trying $api (${index + 1}/${providers.size})") | ||||
|                 var correctResponses = 0 | ||||
|                 var searchResult: List<SearchResponse>? = null | ||||
|                 for (query in searchQueries) { | ||||
|                     val response = try { | ||||
|                         api.search(query) | ||||
|                     } catch (e: Exception) { | ||||
|                         if (e.cause is NotImplementedError) { | ||||
|                             Assert.fail("Provider has not implemented .search") | ||||
|                         } | ||||
|                         logError(e) | ||||
|                         null | ||||
|                     } | ||||
|                     if (!response.isNullOrEmpty()) { | ||||
|                         correctResponses++ | ||||
|                         if (searchResult == null) { | ||||
|                             searchResult = response | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 if (correctResponses == 0 || searchResult == null) { | ||||
|                     println("Api ${api.name} did not return any valid search responses") | ||||
|                     continue | ||||
|                 } | ||||
| 
 | ||||
|                 try { | ||||
|                     var validResults = false | ||||
|                     for (result in searchResult) { | ||||
|                         Assert.assertEquals("Invalid apiName on response on ${api.name}", result.apiName, api.name) | ||||
|                         val load = api.load(result.url) ?: continue | ||||
|                         Assert.assertEquals("Invalid apiName on load on ${api.name}", load.apiName, result.apiName) | ||||
|                         Assert.assertTrue( | ||||
|                             "Api ${api.name} on load does not contain any of the supportedTypes", | ||||
|                             api.supportedTypes.contains(load.type) | ||||
|                         ) | ||||
|                         when (load) { | ||||
|                             is AnimeLoadResponse -> { | ||||
|                                 val gotNoEpisodes = | ||||
|                                     load.dubEpisodes.isNullOrEmpty() && load.subEpisodes.isNullOrEmpty() | ||||
|                                 if (gotNoEpisodes) { | ||||
|                                     println("Api ${api.name} got no episodes on ${load.url}") | ||||
|                                     continue | ||||
|                                 } | ||||
| 
 | ||||
|                                 val url = (load.dubEpisodes ?: load.subEpisodes)?.first()?.url | ||||
|                                 validResults = loadLinks(api, url) | ||||
|                                 if (!validResults) continue | ||||
|                             } | ||||
|                             is MovieLoadResponse -> { | ||||
|                                 val gotNoEpisodes = load.dataUrl.isBlank() | ||||
|                                 if (gotNoEpisodes) { | ||||
|                                     println("Api ${api.name} got no movie on ${load.url}") | ||||
|                                     continue | ||||
|                                 } | ||||
| 
 | ||||
|                                 validResults = loadLinks(api, load.dataUrl) | ||||
|                                 if (!validResults) continue | ||||
|                             } | ||||
|                             is TvSeriesLoadResponse -> { | ||||
|                                 val gotNoEpisodes = load.episodes.isEmpty() | ||||
|                                 if (gotNoEpisodes) { | ||||
|                                     println("Api ${api.name} got no episodes on ${load.url}") | ||||
|                                     continue | ||||
|                                 } | ||||
| 
 | ||||
|                                 validResults = loadLinks(api, load.episodes.first().data) | ||||
|                                 if (!validResults) continue | ||||
|                             } | ||||
|                         } | ||||
|                         break | ||||
|                     } | ||||
| 
 | ||||
|                     Assert.assertTrue("Api ${api.name} did not load on any}", validResults) | ||||
|                 } catch (e: Exception) { | ||||
|                     if (e.cause is NotImplementedError) { | ||||
|                         Assert.fail("Provider has not implemented .load") | ||||
|                     } | ||||
|                     logError(e) | ||||
|                 } | ||||
|                 test_single_provider(api) | ||||
|             } catch (e: Exception) { | ||||
|                 logError(e) | ||||
|             } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue