From 109e1b9f17025fa7757fbdf1dc923e1181dc8116 Mon Sep 17 00:00:00 2001 From: Blatzar <46196380+Blatzar@users.noreply.github.com> Date: Mon, 2 May 2022 18:58:27 +0200 Subject: [PATCH] Switched to NiceHttp Used !! as it was easier (with 10000 providers) + visible errors --- app/build.gradle | 15 +- .../lagradost/cloudstream3/MainActivity.kt | 3 +- .../animeproviders/AnimeFlickProvider.kt | 18 +- .../animeproviders/AnimePaheProvider.kt | 10 +- .../animeproviders/AnimeWorldProvider.kt | 4 +- .../animeproviders/AnimeflvProvider.kt | 91 ++-- .../animeproviders/AnimekisaProvider.kt | 80 ++-- .../animeproviders/DubbedAnimeProvider.kt | 32 +- .../animeproviders/GogoanimeProvider.kt | 27 +- .../animeproviders/KawaiifuProvider.kt | 70 +-- .../animeproviders/MonoschinosProvider.kt | 34 +- .../animeproviders/NineAnimeProvider.kt | 40 +- .../animeproviders/TenshiProvider.kt | 46 +- .../WatchCartoonOnlineProvider.kt | 16 +- .../animeproviders/WcoProvider.kt | 18 +- .../animeproviders/ZoroProvider.kt | 12 +- .../cloudstream3/extractors/WcoStream.kt | 2 +- .../movieproviders/AllMoviesForYouProvider.kt | 18 +- .../movieproviders/BflixProvider.kt | 42 +- .../movieproviders/CinecalidadProvider.kt | 30 +- .../movieproviders/CuevanaProvider.kt | 32 +- .../movieproviders/DoramasYTProvider.kt | 34 +- .../movieproviders/EgyBestProvider.kt | 8 +- .../EntrePeliculasySeriesProvider.kt | 22 +- .../movieproviders/FilmanProvider.kt | 10 +- .../movieproviders/HDMProvider.kt | 12 +- .../movieproviders/IHaveNoTvProvider.kt | 26 +- .../movieproviders/KdramaHoodProvider.kt | 35 +- .../movieproviders/LookMovieProvider.kt | 12 +- .../movieproviders/MeloMovieProvider.kt | 14 +- .../movieproviders/MyCimaProvider.kt | 4 +- .../movieproviders/NginxProvider.kt | 10 +- .../movieproviders/PeliSmartProvider.kt | 20 +- .../movieproviders/PelisflixProvider.kt | 24 +- .../movieproviders/PelisplusHDProvider.kt | 16 +- .../PelisplusProviderTemplate.kt | 18 +- .../movieproviders/SeriesflixProvider.kt | 24 +- .../movieproviders/SflixProvider.kt | 42 +- .../movieproviders/SoaptwoDayProvider.kt | 55 ++- .../StreamingcommunityProvider.kt | 12 +- .../movieproviders/TantiFilmProvider.kt | 62 ++- .../movieproviders/TheFlixToProvider.kt | 6 +- .../movieproviders/VMoveeProvider.kt | 16 +- .../movieproviders/VfFilmProvider.kt | 20 +- .../movieproviders/VfSerieProvider.kt | 22 +- .../VidstreamProviderTemplate.kt | 20 +- .../movieproviders/french-stream.kt | 56 +-- .../cloudstream3/network/DdosGuardKiller.kt | 11 +- .../cloudstream3/network/Requests.kt | 449 ------------------ .../cloudstream3/network/RequestsHelper.kt | 68 +++ .../cloudstream3/network/WebViewResolver.kt | 38 +- .../torrentproviders/NyaaProvider.kt | 6 +- .../ui/settings/SettingsFragment.kt | 1 + .../cloudstream3/utils/FillerEpisodeCheck.kt | 4 +- .../lagradost/cloudstream3/utils/GlideApp.kt | 3 +- .../lagradost/cloudstream3/utils/SyncUtil.kt | 2 +- 56 files changed, 728 insertions(+), 1094 deletions(-) delete mode 100644 app/src/main/java/com/lagradost/cloudstream3/network/Requests.kt create mode 100644 app/src/main/java/com/lagradost/cloudstream3/network/RequestsHelper.kt diff --git a/app/build.gradle b/app/build.gradle index 74551e17..fc3665e1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -105,16 +105,16 @@ dependencies { androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' //implementation "io.karn:khttp-android:0.1.2" //okhttp instead - implementation 'org.jsoup:jsoup:1.13.1' - implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.12.3" +// implementation 'org.jsoup:jsoup:1.13.1' +// implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.12.3" implementation "com.google.android.material:material:1.5.0" implementation "androidx.preference:preference-ktx:1.2.0" - implementation 'com.github.bumptech.glide:glide:4.13.0' - kapt 'com.github.bumptech.glide:compiler:4.13.0' - implementation 'com.github.bumptech.glide:okhttp3-integration:4.12.0' + implementation 'com.github.bumptech.glide:glide:4.13.1' + kapt 'com.github.bumptech.glide:compiler:4.13.1' + implementation 'com.github.bumptech.glide:okhttp3-integration:4.13.0' implementation 'jp.wasabeef:glide-transformations:4.3.0' @@ -154,8 +154,9 @@ dependencies { implementation "androidx.work:work-runtime-ktx:2.7.1" // Networking - implementation "com.squareup.okhttp3:okhttp:4.9.2" - implementation "com.squareup.okhttp3:okhttp-dnsoverhttps:4.9.1" +// implementation "com.squareup.okhttp3:okhttp:4.9.2" +// implementation "com.squareup.okhttp3:okhttp-dnsoverhttps:4.9.1" + implementation 'com.github.Blatzar:NiceHttp:0.1.8' // Util to skip the URI file fuckery 🙏 implementation "com.github.tachiyomiorg:unifile:17bec43" diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt index 5d82e1a4..4b5913e9 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt @@ -36,7 +36,7 @@ import com.lagradost.cloudstream3.CommonActivity.showToast import com.lagradost.cloudstream3.CommonActivity.updateLocale import com.lagradost.cloudstream3.movieproviders.NginxProvider import com.lagradost.cloudstream3.mvvm.logError -import com.lagradost.cloudstream3.network.Requests +import com.lagradost.cloudstream3.network.initClient import com.lagradost.cloudstream3.receivers.VideoDownloadRestartReceiver import com.lagradost.cloudstream3.syncproviders.OAuth2API.Companion.OAuth2Apis import com.lagradost.cloudstream3.syncproviders.OAuth2API.Companion.OAuth2accountApis @@ -65,6 +65,7 @@ import com.lagradost.cloudstream3.utils.UIHelper.getResourceColor import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard import com.lagradost.cloudstream3.utils.UIHelper.navigate import com.lagradost.cloudstream3.utils.UIHelper.requestRW +import com.lagradost.nicehttp.Requests import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.fragment_result_swipe.* import kotlinx.coroutines.Dispatchers diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeFlickProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeFlickProvider.kt index 65cb6193..9b172e16 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeFlickProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeFlickProvider.kt @@ -32,10 +32,10 @@ class AnimeFlickProvider : MainAPI() { val html = app.get(link).text val doc = Jsoup.parse(html) - return doc.select(".row.mt-2").map { - val href = mainUrl + it.selectFirst("a").attr("href") - val title = it.selectFirst("h5 > a").text() - val poster = mainUrl + it.selectFirst("img").attr("src").replace("70x110", "225x320") + return doc.select(".row.mt-2").mapNotNull { + val href = mainUrl + it.selectFirst("a")?.attr("href") + val title = it.selectFirst("h5 > a")?.text() ?: return@mapNotNull null + val poster = mainUrl + it.selectFirst("img")?.attr("src")?.replace("70x110", "225x320") AnimeSearchResponse( title, href, @@ -52,19 +52,19 @@ class AnimeFlickProvider : MainAPI() { val html = app.get(url).text val doc = Jsoup.parse(html) - val poster = mainUrl + doc.selectFirst("img.rounded").attr("src") - val title = doc.selectFirst("h2.title").text() + val poster = mainUrl + doc.selectFirst("img.rounded")?.attr("src") + val title = doc.selectFirst("h2.title")!!.text() val yearText = doc.selectFirst(".trending-year")?.text() val year = if (yearText != null) Regex("""(\d{4})""").find(yearText)?.destructured?.component1() ?.toIntOrNull() else null - val description = doc.selectFirst("p").text() + val description = doc.selectFirst("p")?.text() val genres = doc.select("a[href*=\"genre-\"]").map { it.text() } val episodes = doc.select("#collapseOne .block-space > .row > div:nth-child(2)").map { - val name = it.selectFirst("a").text() - val link = mainUrl + it.selectFirst("a").attr("href") + val name = it.selectFirst("a")?.text() + val link = mainUrl + it.selectFirst("a")?.attr("href") Episode(link, name) }.reversed() diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimePaheProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimePaheProvider.kt index 4dd0e752..2cc790ca 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimePaheProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimePaheProvider.kt @@ -7,10 +7,10 @@ import com.lagradost.cloudstream3.LoadResponse.Companion.addAniListId import com.lagradost.cloudstream3.LoadResponse.Companion.addMalId import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall -import com.lagradost.cloudstream3.network.AppResponse import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.JsUnpacker import com.lagradost.cloudstream3.utils.getQualityFromName +import com.lagradost.nicehttp.NiceResponse import org.jsoup.Jsoup import kotlin.math.pow @@ -242,7 +242,7 @@ class AnimePaheProvider : MainAPI() { val doc = Jsoup.parse(html) val japTitle = doc.selectFirst("h2.japanese")?.text() - val poster = doc.selectFirst(".anime-poster a").attr("href") + val poster = doc.selectFirst(".anime-poster a")?.attr("href") val tvType = doc.selectFirst("""a[href*="/anime/type/"]""")?.text() @@ -263,7 +263,7 @@ class AnimePaheProvider : MainAPI() { "completed" -> ShowStatus.Completed else -> null } - val synopsis = doc.selectFirst(".anime-synopsis").text() + val synopsis = doc.selectFirst(".anime-synopsis")?.text() var anilistId: Int? = null var malId: Int? = null @@ -431,7 +431,7 @@ class AnimePaheProvider : MainAPI() { } var responseCode = 302 - var adflyContent: AppResponse? = null + var adflyContent: NiceResponse? = null var tries = 0 while (responseCode != 200 && tries < 20) { @@ -481,7 +481,7 @@ class AnimePaheProvider : MainAPI() { val decrypted = decrypt(fullString, key, v1.toInt(), v2.toInt()) val uri = KWIK_D_URL.find(decrypted)!!.destructured.component1() val tok = KWIK_D_TOKEN.find(decrypted)!!.destructured.component1() - var content: AppResponse? = null + var content: NiceResponse? = null var code = 419 var tries = 0 diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeWorldProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeWorldProvider.kt index a7b4851c..d02afa86 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeWorldProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeWorldProvider.kt @@ -6,10 +6,10 @@ import com.lagradost.cloudstream3.LoadResponse.Companion.addAniListId import com.lagradost.cloudstream3.LoadResponse.Companion.addMalId import com.lagradost.cloudstream3.LoadResponse.Companion.addRating import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer -import com.lagradost.cloudstream3.network.AppResponse import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.Qualities +import com.lagradost.nicehttp.NiceResponse import org.jsoup.nodes.Element class AnimeWorldProvider : MainAPI() { @@ -29,7 +29,7 @@ class AnimeWorldProvider : MainAPI() { private val cookieRegex = Regex("$cookieName=(.+?)(\\s?);") private val cookies = mutableMapOf(cookieName to "") - private suspend fun request(url: String): AppResponse { + private suspend fun request(url: String): NiceResponse { val response = app.get(url, cookies = cookies) return cookieRegex.find(response.text)?.let { val verify = it.groups[1]?.value ?: throw ErrorLoadingException("Can't bypass protection") diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeflvProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeflvProvider.kt index e197d79f..7e88ce75 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeflvProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeflvProvider.kt @@ -7,19 +7,21 @@ import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.loadExtractor import java.util.* -class AnimeflvnetProvider:MainAPI() { +class AnimeflvnetProvider : MainAPI() { companion object { fun getType(t: String): TvType { return if (t.contains("OVA") || t.contains("Especial")) TvType.OVA else if (t.contains("Película")) TvType.AnimeMovie else TvType.Anime } + fun getDubStatus(title: String): DubStatus { return if (title.contains("Latino") || title.contains("Castellano")) DubStatus.Dubbed else DubStatus.Subbed } } + override var mainUrl = "https://www3.animeflv.net" override var name = "Animeflv.net" override val lang = "es" @@ -42,13 +44,14 @@ class AnimeflvnetProvider:MainAPI() { items.add( HomePageList( "Últimos episodios", - app.get(mainUrl).document.select("main.Main ul.ListEpisodios li").map { - val title = it.selectFirst("strong.Title").text() - val poster = it.selectFirst("span img").attr("src") + app.get(mainUrl).document.select("main.Main ul.ListEpisodios li").mapNotNull { + val title = it.selectFirst("strong.Title")?.text() ?: return@mapNotNull null + val poster = it.selectFirst("span img")?.attr("src") ?: return@mapNotNull null val epRegex = Regex("(-(\\d+)\$)") - val url = it.selectFirst("a").attr("href").replace(epRegex,"") - .replace("ver/","anime/") - val epNum = it.selectFirst("span.Capi").text().replace("Episodio ","").toIntOrNull() + val url = it.selectFirst("a")?.attr("href")?.replace(epRegex, "") + ?.replace("ver/", "anime/") ?: return@mapNotNull null + val epNum = + it.selectFirst("span.Capi")?.text()?.replace("Episodio ", "")?.toIntOrNull() newAnimeSearchResponse(title, url) { this.posterUrl = fixUrl(poster) addDubStatus(getDubStatus(title), epNum) @@ -58,10 +61,13 @@ class AnimeflvnetProvider:MainAPI() { for ((url, name) in urls) { try { val doc = app.get(url).document - val home = doc.select("ul.ListAnimes li article").map { - val title = it.selectFirst("h3.Title").text() - val poster = it.selectFirst("figure img").attr("src") - newAnimeSearchResponse(title, fixUrl(it.selectFirst("a").attr("href"))) { + val home = doc.select("ul.ListAnimes li article").mapNotNull { + val title = it.selectFirst("h3.Title")?.text() ?: return@mapNotNull null + val poster = it.selectFirst("figure img")?.attr("src") ?: return@mapNotNull null + newAnimeSearchResponse( + title, + fixUrl(it.selectFirst("a")?.attr("href") ?: return@mapNotNull null) + ) { this.posterUrl = fixUrl(poster) addDubStatus(MonoschinosProvider.getDubStatus(title)) } @@ -76,7 +82,7 @@ class AnimeflvnetProvider:MainAPI() { return HomePageResponse(items) } - data class SearchObject ( + data class SearchObject( @JsonProperty("id") val id: String, @JsonProperty("title") val title: String, @JsonProperty("type") val type: String, @@ -85,33 +91,36 @@ class AnimeflvnetProvider:MainAPI() { ) override suspend fun search(query: String): List { - val response = app.post("https://www3.animeflv.net/api/animes/search", - data = mapOf(Pair("value",query)) + val response = app.post( + "https://www3.animeflv.net/api/animes/search", + data = mapOf(Pair("value", query)) ).text val json = parseJson>(response) - return json.map { searchr -> + return json.map { searchr -> val title = searchr.title val href = "$mainUrl/anime/${searchr.slug}" val image = "$mainUrl/uploads/animes/covers/${searchr.id}.jpg" - AnimeSearchResponse( - title, - href, - this.name, - TvType.Anime, - fixUrl(image), - null, - if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of(DubStatus.Dubbed) else EnumSet.of(DubStatus.Subbed), - ) + AnimeSearchResponse( + title, + href, + this.name, + TvType.Anime, + fixUrl(image), + null, + if (title.contains("Latino") || title.contains("Castellano")) EnumSet.of(DubStatus.Dubbed) else EnumSet.of( + DubStatus.Subbed + ), + ) } } override suspend fun load(url: String): LoadResponse { val doc = app.get(url).document val episodes = ArrayList() - val title = doc.selectFirst("h1.Title").text() - val poster = doc.selectFirst("div.AnimeCover div.Image figure img").attr("src") - val description = doc.selectFirst("div.Description p").text() - val type = doc.selectFirst("span.Type").text() + val title = doc.selectFirst("h1.Title")!!.text() + val poster = doc.selectFirst("div.AnimeCover div.Image figure img")?.attr("src")!! + val description = doc.selectFirst("div.Description p")?.text() + val type = doc.selectFirst("span.Type")?.text() ?: "" val status = when (doc.selectFirst("p.AnmStts span")?.text()) { "En emision" -> ShowStatus.Ongoing "Finalizado" -> ShowStatus.Completed @@ -126,15 +135,16 @@ class AnimeflvnetProvider:MainAPI() { data.split("],").forEach { val epNum = it.removePrefix("[").substringBefore(",") // val epthumbid = it.removePrefix("[").substringAfter(",").substringBefore("]") - val animeid = doc.selectFirst("div.Strs.RateIt").attr("data-id") + val animeid = doc.selectFirst("div.Strs.RateIt")?.attr("data-id") val epthumb = "https://cdn.animeflv.net/screenshots/$animeid/$epNum/th_3.jpg" - val link = url.replace("/anime/","/ver/")+"-$epNum" - episodes.add( Episode( - link, - null, - posterUrl = epthumb, - episode = epNum.toIntOrNull() - ) + val link = url.replace("/anime/", "/ver/") + "-$epNum" + episodes.add( + Episode( + link, + null, + posterUrl = epthumb, + episode = epNum.toIntOrNull() + ) ) } } @@ -147,6 +157,7 @@ class AnimeflvnetProvider:MainAPI() { tags = genre } } + override suspend fun loadLinks( data: String, isCasting: Boolean, @@ -154,11 +165,13 @@ class AnimeflvnetProvider:MainAPI() { callback: (ExtractorLink) -> Unit ): Boolean { app.get(data).document.select("script").apmap { script -> - if (script.data().contains("var videos = {") || script.data().contains("var anime_id =") || script.data().contains("server")) { + if (script.data().contains("var videos = {") || script.data() + .contains("var anime_id =") || script.data().contains("server") + ) { val videos = script.data().replace("\\/", "/") fetchUrls(videos).map { - it.replace("https://embedsb.com/e/","https://watchsb.com/e/") - .replace("https://ok.ru","http://ok.ru") + it.replace("https://embedsb.com/e/", "https://watchsb.com/e/") + .replace("https://ok.ru", "http://ok.ru") }.apmap { loadExtractor(it, data, callback) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimekisaProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimekisaProvider.kt index 3a3cb0d7..c70cf86b 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimekisaProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimekisaProvider.kt @@ -2,6 +2,9 @@ package com.lagradost.cloudstream3.animeproviders import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.mvvm.normalSafeApiCall +import com.lagradost.cloudstream3.mvvm.safeApiCall +import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall import com.lagradost.cloudstream3.utils.AppUtils.parseJson import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.loadExtractor @@ -31,23 +34,20 @@ class AnimekisaProvider : MainAPI() { Pair("$mainUrl/ajax/list/views?type=day", "Trending now"), Pair("$mainUrl/ajax/list/views?type=week", "Trending by week"), Pair("$mainUrl/ajax/list/views?type=month", "Trending by month"), + ) - ) - - val items = ArrayList() - - for ((url, name) in urls) { - try { + val items = urls.mapNotNull { + suspendSafeApiCall { val home = Jsoup.parse( parseJson( app.get( - url + it.first ).text ).html - ).select("div.flw-item").map { - val title = it.selectFirst("h3.title a").text() - val link = it.selectFirst("a").attr("href") - val poster = it.selectFirst("img.lazyload").attr("data-src") + ).select("div.flw-item").mapNotNull secondMap@ { + val title = it.selectFirst("h3.title a")?.text() ?: return@secondMap null + val link = it.selectFirst("a")?.attr("href") ?: return@secondMap null + val poster = it.selectFirst("img.lazyload")?.attr("data-src") AnimeSearchResponse( title, link, @@ -60,52 +60,50 @@ class AnimekisaProvider : MainAPI() { ) else EnumSet.of(DubStatus.Subbed), ) } - - items.add(HomePageList(name, home)) - } catch (e: Exception) { - e.printStackTrace() + HomePageList(name, home) } } - if (items.size <= 0) throw ErrorLoadingException() + if (items.isEmpty()) throw ErrorLoadingException() return HomePageResponse(items) } override suspend fun search(query: String): List { - return app.get("$mainUrl/search/?keyword=$query").document.select("div.flw-item").map { - val title = it.selectFirst("h3 a").text() - val url = it.selectFirst("a.film-poster-ahref").attr("href") - .replace("watch/", "anime/").replace( - Regex("(-episode-(\\d+)\\/\$|-episode-(\\d+)\$|-episode-full|-episode-.*-.(\\/|))"), - "" + return app.get("$mainUrl/search/?keyword=$query").document.select("div.flw-item") + .mapNotNull { + val title = it.selectFirst("h3 a")?.text() ?: "" + val url = it.selectFirst("a.film-poster-ahref")?.attr("href") + ?.replace("watch/", "anime/")?.replace( + Regex("(-episode-(\\d+)\\/\$|-episode-(\\d+)\$|-episode-full|-episode-.*-.(\\/|))"), + "" + ) ?: return@mapNotNull null + val poster = it.selectFirst(".film-poster img")?.attr("data-src") + AnimeSearchResponse( + title, + url, + this.name, + TvType.Anime, + poster, + null, + if (title.contains("(DUB)") || title.contains("(Dub)")) EnumSet.of( + DubStatus.Dubbed + ) else EnumSet.of(DubStatus.Subbed), ) - val poster = it.selectFirst(".film-poster img").attr("data-src") - AnimeSearchResponse( - title, - url, - this.name, - TvType.Anime, - poster, - null, - if (title.contains("(DUB)") || title.contains("(Dub)")) EnumSet.of( - DubStatus.Dubbed - ) else EnumSet.of(DubStatus.Subbed), - ) - }.toList() + }.toList() } override suspend fun load(url: String): LoadResponse { val doc = app.get(url, timeout = 120).document - val poster = doc.selectFirst(".mb-2 img").attr("src") - ?: doc.selectFirst("head meta[property=og:image]").attr("content") - val title = doc.selectFirst("h1.heading-name a").text() - val description = doc.selectFirst("div.description p").text().trim() + val poster = doc.selectFirst(".mb-2 img")?.attr("src") + ?: doc.selectFirst("head meta[property=og:image]")?.attr("content") + val title = doc.selectFirst("h1.heading-name a")!!.text() + val description = doc.selectFirst("div.description p")?.text()?.trim() val genres = doc.select("div.row-line a").map { it.text() } val test = if (doc.selectFirst("div.dp-i-c-right").toString() .contains("Airing") ) ShowStatus.Ongoing else ShowStatus.Completed - val episodes = doc.select("div.tab-content ul li.nav-item").map { - val link = it.selectFirst("a").attr("href") + val episodes = doc.select("div.tab-content ul li.nav-item").mapNotNull { + val link = it.selectFirst("a")?.attr("href") ?: return@mapNotNull null Episode(link) } val type = if (doc.selectFirst(".dp-i-stats").toString() diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/DubbedAnimeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/DubbedAnimeProvider.kt index 6b6301e7..1219e3f4 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/DubbedAnimeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/DubbedAnimeProvider.kt @@ -57,9 +57,9 @@ class DubbedAnimeProvider : MainAPI() { private suspend fun parseDocumentTrending(url: String): List { val response = app.get(url).text val document = Jsoup.parse(response) - return document.select("li > a").map { + return document.select("li > a").mapNotNull { val href = fixUrl(it.attr("href")) - val title = it.selectFirst("> div > div.cittx").text() + val title = it.selectFirst("> div > div.cittx")?.text() ?: return@mapNotNull null val poster = fixUrlNull(it.selectFirst("> div > div.imghddde > img")?.attr("src")) AnimeSearchResponse( title, @@ -79,10 +79,11 @@ class DubbedAnimeProvider : MainAPI() { ): List { val response = app.get(url).text val document = Jsoup.parse(response) - return document.select("a.grid__link").map { + return document.select("a.grid__link").mapNotNull { val href = fixUrl(it.attr("href")) - val title = it.selectFirst("> div.gridtitlek").text() - val poster = fixUrl(it.selectFirst("> img.grid__img").attr("src")) + val title = it.selectFirst("> div.gridtitlek")?.text() ?: return@mapNotNull null + val poster = + fixUrl(it.selectFirst("> img.grid__img")?.attr("src") ?: return@mapNotNull null) AnimeSearchResponse( title, if (trimEpisode) href.removeRange(href.lastIndexOf('/'), href.length) else href, @@ -135,9 +136,9 @@ class DubbedAnimeProvider : MainAPI() { val document = Jsoup.parse(response) val items = document.select("div.grid__item > a") if (items.isEmpty()) return emptyList() - return items.map { i -> + return items.mapNotNull { i -> val href = fixUrl(i.attr("href")) - val title = i.selectFirst("div.gridtitlek").text() + val title = i.selectFirst("div.gridtitlek")?.text() ?: return@mapNotNull null val img = fixUrlNull(i.selectFirst("img.grid__img")?.attr("src")) if (getIsMovie(href)) { @@ -164,11 +165,11 @@ class DubbedAnimeProvider : MainAPI() { val document = Jsoup.parse(response) val items = document.select("div.resultinner > a.resulta") if (items.isEmpty()) return ArrayList() - return items.map { i -> + return items.mapNotNull { i -> val innerDiv = i.selectFirst("> div.result") val href = fixUrl(i.attr("href")) - val img = fixUrl(innerDiv.selectFirst("> div.imgkz > img").attr("src")) - val title = innerDiv.selectFirst("> div.titleresults").text() + val img = fixUrl(innerDiv?.selectFirst("> div.imgkz > img")?.attr("src") ?: return@mapNotNull null) + val title = innerDiv.selectFirst("> div.titleresults")?.text() ?: return@mapNotNull null if (getIsMovie(href)) { MovieSearchResponse( @@ -244,12 +245,13 @@ class DubbedAnimeProvider : MainAPI() { } else { val response = app.get(url).text val document = Jsoup.parse(response) - val title = document.selectFirst("h4").text() + val title = document.selectFirst("h4")!!.text() val descriptHeader = document.selectFirst("div.animeDescript") - val descript = descriptHeader.selectFirst("> p").text() - val year = descriptHeader.selectFirst("> div.distatsx > div.sroverd").text() - .replace("Released: ", "") - .toIntOrNull() + val descript = descriptHeader?.selectFirst("> p")?.text() + val year = descriptHeader?.selectFirst("> div.distatsx > div.sroverd") + ?.text() + ?.replace("Released: ", "") + ?.toIntOrNull() val episodes = document.select("a.epibloks").map { val epTitle = it.selectFirst("> div.inwel > span.isgrxx")?.text() diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt index 2f35b564..a04e9e5a 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt @@ -116,7 +116,8 @@ class GogoanimeProvider : MainAPI() { val encryptRequestData = if (isUsingAdaptiveData) { // Only fetch the document if necessary val realDocument = document ?: app.get(iframeUrl).document - val dataEncrypted = realDocument.select("script[data-name='episode']").attr("data-value") + val dataEncrypted = + realDocument.select("script[data-name='episode']").attr("data-value") val headers = cryptoHandler(dataEncrypted, foundIv, foundKey, false) "id=$encryptedId&alias=$id&" + headers.substringAfter("&") } else { @@ -246,17 +247,17 @@ class GogoanimeProvider : MainAPI() { val html = app.get(link).text val doc = Jsoup.parse(html) - val episodes = doc.select(""".last_episodes li""").map { + val episodes = doc.select(""".last_episodes li""").mapNotNull { AnimeSearchResponse( - it.selectFirst(".name").text().replace(" (Dub)", ""), - fixUrl(it.selectFirst(".name > a").attr("href")), + it.selectFirst(".name")?.text()?.replace(" (Dub)", "") ?: return@mapNotNull null, + fixUrl(it.selectFirst(".name > a")?.attr("href") ?: return@mapNotNull null), this.name, TvType.Anime, - it.selectFirst("img").attr("src"), + it.selectFirst("img")?.attr("src"), it.selectFirst(".released")?.text()?.split(":")?.getOrNull(1)?.trim() ?.toIntOrNull(), - if (it.selectFirst(".name").text() - .contains("Dub") + if (it.selectFirst(".name")?.text() + ?.contains("Dub") == true ) EnumSet.of(DubStatus.Dubbed) else EnumSet.of( DubStatus.Subbed ), @@ -282,8 +283,8 @@ class GogoanimeProvider : MainAPI() { val doc = Jsoup.parse(html) val animeBody = doc.selectFirst(".anime_info_body_bg") - val title = animeBody.selectFirst("h1").text() - val poster = animeBody.selectFirst("img").attr("src") + val title = animeBody?.selectFirst("h1")!!.text() + val poster = animeBody.selectFirst("img")?.attr("src") var description: String? = null val genre = ArrayList() var year: Int? = null @@ -292,7 +293,7 @@ class GogoanimeProvider : MainAPI() { var type: String? = null animeBody.select("p.type").forEach { pType -> - when (pType.selectFirst("span").text().trim()) { + when (pType.selectFirst("span")?.text()?.trim()) { "Plot Summary:" -> { description = pType.text().replace("Plot Summary:", "").trim() } @@ -316,13 +317,13 @@ class GogoanimeProvider : MainAPI() { } } - val animeId = doc.selectFirst("#movie_id").attr("value") + val animeId = doc.selectFirst("#movie_id")!!.attr("value") val params = mapOf("ep_start" to "0", "ep_end" to "2000", "id" to animeId) val episodes = app.get(episodeloadApi, params = params).document.select("a").map { Episode( fixUrl(it.attr("href").trim()), - "Episode " + it.selectFirst(".name").text().replace("EP", "").trim() + "Episode " + it.selectFirst(".name")?.text()?.replace("EP", "")?.trim() ) }.reversed() @@ -357,7 +358,7 @@ class GogoanimeProvider : MainAPI() { private suspend fun extractVideos(uri: String, callback: (ExtractorLink) -> Unit) { val doc = app.get(uri).document - val iframe = fixUrlNull(doc.selectFirst("div.play-video > iframe").attr("src")) ?: return + val iframe = fixUrlNull(doc.selectFirst("div.play-video > iframe")?.attr("src")) ?: return argamap( { diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/KawaiifuProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/KawaiifuProvider.kt index a3327645..f1930306 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/KawaiifuProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/KawaiifuProvider.kt @@ -20,31 +20,35 @@ class KawaiifuProvider : MainAPI() { val soup = Jsoup.parse(resp) - items.add(HomePageList("Latest Updates", soup.select(".today-update .item").map { - val title = it.selectFirst("img").attr("alt") + items.add(HomePageList("Latest Updates", soup.select(".today-update .item").mapNotNull { + val title = it.selectFirst("img")?.attr("alt") AnimeSearchResponse( - title, - it.selectFirst("a").attr("href"), + title ?: return@mapNotNull null, + it.selectFirst("a")?.attr("href") ?: return@mapNotNull null, this.name, TvType.Anime, - it.selectFirst("img").attr("src"), - it.selectFirst("h4 > a").attr("href").split("-").last().toIntOrNull(), - if (title.contains("(DUB)")) EnumSet.of(DubStatus.Dubbed) else EnumSet.of(DubStatus.Subbed), + it.selectFirst("img")?.attr("src"), + it.selectFirst("h4 > a")?.attr("href")?.split("-")?.last()?.toIntOrNull(), + if (title.contains("(DUB)")) EnumSet.of(DubStatus.Dubbed) else EnumSet.of( + DubStatus.Subbed + ), ) })) for (section in soup.select(".section")) { try { - val title = section.selectFirst(".title").text() - val anime = section.select(".list-film > .item").map { ani -> - val animTitle = ani.selectFirst("img").attr("alt") + val title = section.selectFirst(".title")!!.text() + val anime = section.select(".list-film > .item").mapNotNull { ani -> + val animTitle = ani.selectFirst("img")?.attr("alt") AnimeSearchResponse( - animTitle, - ani.selectFirst("a").attr("href"), + animTitle ?: return@mapNotNull null, + ani.selectFirst("a")?.attr("href") ?: return@mapNotNull null, this.name, TvType.Anime, - ani.selectFirst("img").attr("src"), - ani.selectFirst(".vl-chil-date").text().toIntOrNull(), - if (animTitle.contains("(DUB)")) EnumSet.of(DubStatus.Dubbed) else EnumSet.of(DubStatus.Subbed), + ani.selectFirst("img")?.attr("src"), + ani.selectFirst(".vl-chil-date")?.text()?.toIntOrNull(), + if (animTitle.contains("(DUB)")) EnumSet.of(DubStatus.Dubbed) else EnumSet.of( + DubStatus.Subbed + ), ) } items.add(HomePageList(title, anime)) @@ -63,11 +67,11 @@ class KawaiifuProvider : MainAPI() { val html = app.get(link).text val soup = Jsoup.parse(html) - return ArrayList(soup.select(".item").map { - val year = it.selectFirst("h4 > a").attr("href").split("-").last().toIntOrNull() - val title = it.selectFirst("img").attr("alt") - val poster = it.selectFirst("img").attr("src") - val uri = it.selectFirst("a").attr("href") + return ArrayList(soup.select(".item").mapNotNull { + val year = it.selectFirst("h4 > a")?.attr("href")?.split("-")?.last()?.toIntOrNull() + val title = it.selectFirst("img")?.attr("alt") ?: return@mapNotNull null + val poster = it.selectFirst("img")?.attr("src") + val uri = it.selectFirst("a")?.attr("href") ?: return@mapNotNull null AnimeSearchResponse( title, uri, @@ -84,22 +88,26 @@ class KawaiifuProvider : MainAPI() { val html = app.get(url).text val soup = Jsoup.parse(html) - val title = soup.selectFirst(".title").text() + val title = soup.selectFirst(".title")!!.text() val tags = soup.select(".table a[href*=\"/tag/\"]").map { tag -> tag.text() } val description = soup.select(".sub-desc p") - .filter { it.select("strong").isEmpty() && it.select("iframe").isEmpty() }.joinToString("\n") { it.text() } + .filter { it.select("strong").isEmpty() && it.select("iframe").isEmpty() } + .joinToString("\n") { it.text() } val year = url.split("/").filter { it.contains("-") }[0].split("-")[1].toIntOrNull() - val episodesLink = soup.selectFirst("a[href*=\".html-episode\"]").attr("href") ?: throw ErrorLoadingException("Error getting episode list") + val episodesLink = soup.selectFirst("a[href*=\".html-episode\"]")?.attr("href") + ?: throw ErrorLoadingException("Error getting episode list") val episodes = Jsoup.parse( app.get(episodesLink).text - ).selectFirst(".list-ep").select("li").map { + ).selectFirst(".list-ep")?.select("li")?.map { Episode( - it.selectFirst("a").attr("href"), - if (it.text().trim().toIntOrNull() != null) "Episode ${it.text().trim()}" else it.text().trim() + it.selectFirst("a")!!.attr("href"), + if (it.text().trim().toIntOrNull() != null) "Episode ${ + it.text().trim() + }" else it.text().trim() ) } - val poster = soup.selectFirst("a.thumb > img").attr("src") + val poster = soup.selectFirst("a.thumb > img")?.attr("src") return newAnimeLoadResponse(title, url, TvType.Anime) { this.year = year @@ -119,11 +127,13 @@ class KawaiifuProvider : MainAPI() { val htmlSource = app.get(data).text val soupa = Jsoup.parse(htmlSource) - val episodeNum = if (data.contains("ep=")) data.split("ep=")[1].split("&")[0].toIntOrNull() else null + val episodeNum = + if (data.contains("ep=")) data.split("ep=")[1].split("&")[0].toIntOrNull() else null val servers = soupa.select(".list-server").map { - val serverName = it.selectFirst(".server-name").text() - val episodes = it.select(".list-ep > li > a").map { episode -> Pair(episode.attr("href"), episode.text()) } + val serverName = it.selectFirst(".server-name")!!.text() + val episodes = it.select(".list-ep > li > a") + .map { episode -> Pair(episode.attr("href"), episode.text()) } val episode = if (episodeNum == null) episodes[0] else episodes.mapNotNull { ep -> if ((if (ep.first.contains("ep=")) ep.first.split("ep=")[1].split("&")[0].toIntOrNull() else null) == episodeNum) { ep diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/MonoschinosProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/MonoschinosProvider.kt index 4823e682..3681e6f0 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/MonoschinosProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/MonoschinosProvider.kt @@ -50,12 +50,12 @@ class MonoschinosProvider : MainAPI() { HomePageList( "Capítulos actualizados", app.get(mainUrl, timeout = 120).document.select(".col-6").map { - val title = it.selectFirst("p.animetitles").text() - val poster = it.selectFirst(".animeimghv").attr("data-src") + val title = it.selectFirst("p.animetitles")!!.text() + val poster = it.selectFirst(".animeimghv")!!.attr("data-src") val epRegex = Regex("episodio-(\\d+)") - val url = it.selectFirst("a").attr("href").replace("ver/", "anime/") + val url = it.selectFirst("a")?.attr("href")!!.replace("ver/", "anime/") .replace(epRegex, "sub-espanol") - val epNum = it.selectFirst(".positioning h5").text().toIntOrNull() + val epNum = it.selectFirst(".positioning h5")?.text()?.toIntOrNull() newAnimeSearchResponse(title, url) { this.posterUrl = fixUrl(poster) addDubStatus(getDubStatus(title), epNum) @@ -66,9 +66,9 @@ class MonoschinosProvider : MainAPI() { for (i in urls) { try { val home = app.get(i.first, timeout = 120).document.select(".col-6").map { - val title = it.selectFirst(".seristitles").text() - val poster = it.selectFirst("img.animemainimg").attr("src") - newAnimeSearchResponse(title, fixUrl(it.selectFirst("a").attr("href"))) { + val title = it.selectFirst(".seristitles")!!.text() + val poster = it.selectFirst("img.animemainimg")!!.attr("src") + newAnimeSearchResponse(title, fixUrl(it.selectFirst("a")!!.attr("href"))) { this.posterUrl = fixUrl(poster) addDubStatus(getDubStatus(title)) } @@ -87,9 +87,9 @@ class MonoschinosProvider : MainAPI() { override suspend fun search(query: String): ArrayList { val search = app.get("$mainUrl/buscar?q=$query", timeout = 120).document.select(".col-6").map { - val title = it.selectFirst(".seristitles").text() - val href = fixUrl(it.selectFirst("a").attr("href")) - val image = it.selectFirst("img.animemainimg").attr("src") + val title = it.selectFirst(".seristitles")!!.text() + val href = fixUrl(it.selectFirst("a")!!.attr("href")) + val image = it.selectFirst("img.animemainimg")!!.attr("src") AnimeSearchResponse( title, href, @@ -107,10 +107,10 @@ class MonoschinosProvider : MainAPI() { override suspend fun load(url: String): LoadResponse { val doc = app.get(url, timeout = 120).document - val poster = doc.selectFirst(".chapterpic img").attr("src") - val title = doc.selectFirst(".chapterdetails h1").text() - val type = doc.selectFirst("div.chapterdetls2").text() - val description = doc.selectFirst("p.textComplete").text().replace("Ver menos", "") + val poster = doc.selectFirst(".chapterpic img")!!.attr("src") + val title = doc.selectFirst(".chapterdetails h1")!!.text() + val type = doc.selectFirst("div.chapterdetls2")!!.text() + val description = doc.selectFirst("p.textComplete")!!.text().replace("Ver menos", "") val genres = doc.select(".breadcrumb-item a").map { it.text() } val status = when (doc.selectFirst("button.btn1")?.text()) { "Estreno" -> ShowStatus.Ongoing @@ -118,9 +118,9 @@ class MonoschinosProvider : MainAPI() { else -> null } val episodes = doc.select("div.col-item").map { - val name = it.selectFirst("p.animetitles").text() - val link = it.selectFirst("a").attr("href") - val epThumb = it.selectFirst(".animeimghv").attr("data-src") + val name = it.selectFirst("p.animetitles")!!.text() + val link = it.selectFirst("a")!!.attr("href") + val epThumb = it.selectFirst(".animeimghv")!!.attr("data-src") Episode(link, name, posterUrl = epThumb) } return newAnimeLoadResponse(title, url, getType(type)) { diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/NineAnimeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/NineAnimeProvider.kt index e80dbc87..e32b6c92 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/NineAnimeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/NineAnimeProvider.kt @@ -45,11 +45,11 @@ class NineAnimeProvider : MainAPI() { val home = Jsoup.parse( app.get( url - ).mapped().html + ).parsed().html ).select("ul.anime-list li").map { - val title = it.selectFirst("a.name").text() - val link = it.selectFirst("a").attr("href") - val poster = it.selectFirst("a.poster img").attr("src") + val title = it.selectFirst("a.name")!!.text() + val link = it.selectFirst("a")!!.attr("href") + val poster = it.selectFirst("a.poster img")!!.attr("src") newAnimeSearchResponse(title, link) { this.posterUrl = poster @@ -173,11 +173,11 @@ class NineAnimeProvider : MainAPI() { val url = "$mainUrl/filter?sort=title%3Aasc&keyword=$query" return app.get(url).document.select("ul.anime-list li").mapNotNull { - val title = it.selectFirst("a.name").text() + val title = it.selectFirst("a.name")!!.text() val href = - fixUrlNull(it.selectFirst("a").attr("href"))?.replace(Regex("(\\?ep=(\\d+)\$)"), "") + fixUrlNull(it.selectFirst("a")!!.attr("href"))?.replace(Regex("(\\?ep=(\\d+)\$)"), "") ?: return@mapNotNull null - val image = it.selectFirst("a.poster img").attr("src") + val image = it.selectFirst("a.poster img")!!.attr("src") AnimeSearchResponse( title, href, @@ -199,26 +199,26 @@ class NineAnimeProvider : MainAPI() { override suspend fun load(url: String): LoadResponse? { val validUrl = url.replace("https://9anime.to", mainUrl) val doc = app.get(validUrl).document - val animeid = doc.selectFirst("div.player-wrapper.watchpage").attr("data-id") ?: return null + val animeid = doc.selectFirst("div.player-wrapper.watchpage")!!.attr("data-id") ?: return null val animeidencoded = encode(getVrf(animeid) ?: return null) - val poster = doc.selectFirst("aside.main div.thumb div img").attr("src") - val title = doc.selectFirst(".info .title").text() - val description = doc.selectFirst("div.info p").text().replace("Ver menos", "").trim() + val poster = doc.selectFirst("aside.main div.thumb div img")!!.attr("src") + val title = doc.selectFirst(".info .title")!!.text() + val description = doc.selectFirst("div.info p")!!.text().replace("Ver menos", "").trim() val episodes = Jsoup.parse( app.get( "$mainUrl/ajax/anime/servers?ep=1&id=${animeid}&vrf=$animeidencoded&ep=8&episode=&token=" - ).mapped().html - )?.select("ul.episodes li a")?.mapNotNull { + ).parsed().html + ).select("ul.episodes li a").mapNotNull { val link = it?.attr("href") ?: return@mapNotNull null val name = "Episode ${it.text()}" Episode(link, name) - } ?: return null + } val recommendations = doc.select("div.container aside.main section div.body ul.anime-list li") - ?.mapNotNull { element -> - val recTitle = element.select("a.name")?.text() ?: return@mapNotNull null - val image = element.select("a.poster img")?.attr("src") + .mapNotNull { element -> + val recTitle = element.select("a.name").text() ?: return@mapNotNull null + val image = element.select("a.poster img").attr("src") val recUrl = fixUrl(element.select("a").attr("href")) newAnimeSearchResponse(recTitle, recUrl) { this.posterUrl = image @@ -226,7 +226,7 @@ class NineAnimeProvider : MainAPI() { } } - val infodoc = doc.selectFirst("div.info .meta .col1").text() + val infodoc = doc.selectFirst("div.info .meta .col1")!!.text() val tvType = if (infodoc.contains("Movie")) TvType.AnimeMovie else TvType.Anime val status = if (infodoc.contains("Completed")) ShowStatus.Completed @@ -264,13 +264,13 @@ class NineAnimeProvider : MainAPI() { ): Boolean { val document = app.get(data).document val animeid = - document.selectFirst("div.player-wrapper.watchpage").attr("data-id") ?: return false + document.selectFirst("div.player-wrapper.watchpage")!!.attr("data-id") ?: return false val animeidencoded = encode(getVrf(animeid) ?: return false) Jsoup.parse( app.get( "$mainUrl/ajax/anime/servers?&id=${animeid}&vrf=$animeidencoded&episode=&token=" - ).mapped().html + ).parsed().html ).select("div.body").map { element -> val jsonregex = Regex("(\\{.+\\}.*$data)") val servers = jsonregex.find(element.toString())?.value?.replace( diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/TenshiProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/TenshiProvider.kt index da479c0e..f1ad18b6 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/TenshiProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/TenshiProvider.kt @@ -47,6 +47,7 @@ class TenshiProvider : MainAPI() { override suspend fun getMainPage(): HomePageResponse { val items = ArrayList() val soup = app.get(mainUrl, interceptor = ddosGuardKiller).document + println(soup) for (section in soup.select("#content > section")) { try { if (section.attr("id") == "toplist-tabs") { @@ -58,11 +59,11 @@ class TenshiProvider : MainAPI() { } val anime = top.select("li > a").map { AnimeSearchResponse( - it.selectFirst(".thumb-title").text(), + it.selectFirst(".thumb-title")!!.text(), fixUrl(it.attr("href")), this.name, TvType.Anime, - it.selectFirst("img").attr("src"), + it.selectFirst("img")!!.attr("src"), null, EnumSet.of(DubStatus.Subbed), ) @@ -70,14 +71,14 @@ class TenshiProvider : MainAPI() { items.add(HomePageList(title, anime)) } } else { - val title = section.selectFirst("h2").text() + val title = section.selectFirst("h2")!!.text() val anime = section.select("li > a").map { AnimeSearchResponse( it.selectFirst(".thumb-title")?.text() ?: "", fixUrl(it.attr("href")), this.name, TvType.Anime, - it.selectFirst("img").attr("src"), + it.selectFirst("img")!!.attr("src"), null, EnumSet.of(DubStatus.Subbed), ) @@ -104,7 +105,7 @@ class TenshiProvider : MainAPI() { val items = soup.select("ul.thumb > li > a") return items.map { val href = fixUrl(it.attr("href")) - val img = fixUrl(it.selectFirst("img").attr("src")) + val img = fixUrl(it.selectFirst("img")!!.attr("src")) val title = it.attr("title") if (getIsMovie(href, true)) { MovieSearchResponse( @@ -225,10 +226,10 @@ class TenshiProvider : MainAPI() { interceptor = ddosGuardKiller ).document - val canonicalTitle = document.selectFirst("header.entry-header > h1.mb-3").text().trim() + val canonicalTitle = document.selectFirst("header.entry-header > h1.mb-3")!!.text().trim() val episodeNodes = document.select("li[class*=\"episode\"] > a").toMutableList() val totalEpisodePages = if (document.select(".pagination").size > 0) - document.select(".pagination .page-item a.page-link:not([rel])").last().text() + document.select(".pagination .page-item a.page-link:not([rel])").last()!!.text() .toIntOrNull() else 1 @@ -283,7 +284,7 @@ class TenshiProvider : MainAPI() { ?.trim() val pattern = Regex("(\\d{4})") - val yearText = document.selectFirst("li.release-date .value").text() + val yearText = document.selectFirst("li.release-date .value")!!.text() year = pattern.find(yearText)?.groupValues?.get(1)?.toIntOrNull() addEpisodes(DubStatus.Subbed, episodes) @@ -310,7 +311,6 @@ class TenshiProvider : MainAPI() { @JsonProperty("size") val size: Int ) - val sources = ArrayList() for (source in soup.select("""[aria-labelledby="mirror-dropdown"] > li > a.dropdown-item""")) { val release = source.text().replace("/", "").trim() val sourceHTML = app.get( @@ -330,24 +330,24 @@ class TenshiProvider : MainAPI() { .replace(",}", "}") .replace(",]", "]") ) - sources.addAll(qualities.map { - ExtractorLink( - this.name, - "${this.name} $release", - fixUrl(it.src), - this.mainUrl, - getQualityFromName("${it.size}"), - headers = getHeaders( - mapOf(), - null, - ddosGuardKiller.savedCookiesMap.get(URI(this.mainUrl).host) ?: mapOf() - ).toMap() + qualities.forEach { + callback.invoke( + ExtractorLink( + this.name, + "${this.name} $release", + fixUrl(it.src), + this.mainUrl, + getQualityFromName("${it.size}"), + headers = getHeaders(emptyMap(), + ddosGuardKiller.savedCookiesMap[URI(this.mainUrl).host] + ?: emptyMap() + ).toMap() + ) ) - }) + } } } - sources.forEach(callback) return true } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WatchCartoonOnlineProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WatchCartoonOnlineProvider.kt index 9e43ac84..940ad97c 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WatchCartoonOnlineProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WatchCartoonOnlineProvider.kt @@ -38,11 +38,11 @@ class WatchCartoonOnlineProvider : MainAPI() { for (item in items) { val header = item.selectFirst("> div.iccerceve") - val titleHeader = header.selectFirst("> div.aramadabaslik > a") - val title = titleHeader.text() + val titleHeader = header!!.selectFirst("> div.aramadabaslik > a") + val title = titleHeader!!.text() val href = fixUrl(titleHeader.attr("href")) - val poster = fixUrl(header.selectFirst("> a > img").attr("src")) - val genreText = item.selectFirst("div.cerceve-tur-ve-genre").ownText() + val poster = fixUrl(header.selectFirst("> a > img")!!.attr("src")) + val genreText = item.selectFirst("div.cerceve-tur-ve-genre")!!.ownText() if (genreText.contains("cartoon")) { returnValue.add(TvSeriesSearchResponse(title, href, this.name, TvType.Cartoon, poster, null, null)) } else { @@ -76,7 +76,7 @@ class WatchCartoonOnlineProvider : MainAPI() { for (item in items) { val titleHeader = item.selectFirst("a") - val title = titleHeader.text() + val title = titleHeader!!.text() val href = fixUrl(titleHeader.attr("href")) //val isDubbed = title.contains("dubbed") //val set: EnumSet = @@ -103,9 +103,9 @@ class WatchCartoonOnlineProvider : MainAPI() { val document = Jsoup.parse(response) return if (!isMovie) { - val title = document.selectFirst("td.vsbaslik > h2").text() + val title = document.selectFirst("td.vsbaslik > h2")!!.text() val poster = fixUrlNull(document.selectFirst("div#cat-img-desc > div > img")?.attr("src")) - val plot = document.selectFirst("div.iltext").text() + val plot = document.selectFirst("div.iltext")!!.text() val genres = document.select("div#cat-genre > div.wcobtn > a").map { it.text() } val episodes = document.select("div#catlist-listview > ul > li > a").reversed().map { val text = it.text() @@ -152,7 +152,7 @@ class WatchCartoonOnlineProvider : MainAPI() { val title = document.selectFirst(".iltext .Apple-style-span")?.text().toString() val b = document.select(".iltext b") val description = if (b.isNotEmpty()) { - b.last().html().split("
")[0] + b.last()!!.html().split("
")[0] } else null TvSeriesLoadResponse( diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt index ca4af0c6..a6763c70 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt @@ -50,15 +50,15 @@ class WcoProvider : MainAPI() { val results = document.select("div.flw-item").map { val filmPoster = it.selectFirst("> div.film-poster") val filmDetail = it.selectFirst("> div.film-detail") - val nameHeader = filmDetail.selectFirst("> h3.film-name > a") - val title = nameHeader.text().replace(" (Dub)", "") + val nameHeader = filmDetail!!.selectFirst("> h3.film-name > a") + val title = nameHeader!!.text().replace(" (Dub)", "") val href = nameHeader.attr("href").replace("/watch/", "/anime/") .replace(Regex("-episode-.*"), "/") val isDub = - filmPoster.selectFirst("> div.film-poster-quality")?.text()?.contains("DUB") + filmPoster!!.selectFirst("> div.film-poster-quality")?.text()?.contains("DUB") ?: false - val poster = filmPoster.selectFirst("> img").attr("data-src") + val poster = filmPoster.selectFirst("> img")!!.attr("data-src") val set: EnumSet = EnumSet.of(if (isDub) DubStatus.Dubbed else DubStatus.Subbed) AnimeSearchResponse(title, href, this.name, TvType.Anime, poster, null, set) @@ -83,15 +83,15 @@ class WcoProvider : MainAPI() { val items = soup.select(".film_list-wrap > .flw-item") if (items.isEmpty()) return ArrayList() return items.map { i -> - val href = fixAnimeLink(i.selectFirst("a").attr("href")) - val img = fixUrl(i.selectFirst("img").attr("data-src")) - val title = i.selectFirst("img").attr("title") + val href = fixAnimeLink(i.selectFirst("a")!!.attr("href")) + val img = fixUrl(i.selectFirst("img")!!.attr("data-src")) + val title = i.selectFirst("img")!!.attr("title") val isDub = !i.select(".pick.film-poster-quality").isEmpty() val year = - i.selectFirst(".film-detail.film-detail-fix > div > span:nth-child(1)").text() + i.selectFirst(".film-detail.film-detail-fix > div > span:nth-child(1)")!!.text() .toIntOrNull() val type = - i.selectFirst(".film-detail.film-detail-fix > div > span:nth-child(3)").text() + i.selectFirst(".film-detail.film-detail-fix > div > span:nth-child(3)")!!.text() if (getType(type) == TvType.AnimeMovie) { MovieSearchResponse( diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ZoroProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ZoroProvider.kt index de947e19..24751a36 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ZoroProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ZoroProvider.kt @@ -8,11 +8,11 @@ import com.lagradost.cloudstream3.LoadResponse.Companion.addAniListId import com.lagradost.cloudstream3.LoadResponse.Companion.addMalId import com.lagradost.cloudstream3.movieproviders.SflixProvider.Companion.extractRabbitStream import com.lagradost.cloudstream3.movieproviders.SflixProvider.Companion.runSflixExtractorVerifierJob -import com.lagradost.cloudstream3.network.Requests.Companion.await import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson import com.lagradost.cloudstream3.utils.Coroutines.ioSafe import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.loadExtractor +import com.lagradost.nicehttp.Requests.Companion.await import okhttp3.Interceptor import org.jsoup.Jsoup import org.jsoup.nodes.Element @@ -141,7 +141,7 @@ class ZoroProvider : MainAPI() { return document.select(".flw-item").map { val title = it.selectFirst(".film-detail > .film-name > a")?.attr("title").toString() val filmPoster = it.selectFirst(".film-poster") - val poster = filmPoster.selectFirst("img")?.attr("data-src") + val poster = filmPoster!!.selectFirst("img")?.attr("data-src") val episodes = filmPoster.selectFirst("div.rtl > div.tick-eps")?.text()?.let { eps -> // current episode / max episode @@ -154,7 +154,7 @@ class ZoroProvider : MainAPI() { val tvType = getType(it.selectFirst(".film-detail > .fd-infor > .fdi-item")?.text().toString()) - val href = fixUrl(it.selectFirst(".film-name a").attr("href")) + val href = fixUrl(it.selectFirst(".film-name a")!!.attr("href")) newAnimeSearchResponse(title, href, tvType) { this.posterUrl = poster @@ -327,11 +327,11 @@ class ZoroProvider : MainAPI() { val servers: List> = Jsoup.parse( app.get("$mainUrl/ajax/v2/episode/servers?episodeId=" + data.split("=")[1]) - .mapped().html + .parsed().html ).select(".server-item[data-type][data-id]").map { Pair( if (it.attr("data-type") == "sub") DubStatus.Subbed else DubStatus.Dubbed, - it.attr("data-id")!! + it.attr("data-id") ) } @@ -344,7 +344,7 @@ class ZoroProvider : MainAPI() { "$mainUrl/ajax/v2/episode/sources?id=${it.second}" val extractorLink = app.get( link, - ).mapped().link + ).parsed().link val hasLoadedExtractorLink = loadExtractor(extractorLink, "https://rapid-cloud.ru/", callback) diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/WcoStream.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/WcoStream.kt index 7861fbf3..78ddcc24 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/extractors/WcoStream.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/WcoStream.kt @@ -77,7 +77,7 @@ open class WcoStream : ExtractorApi() { @JsonProperty("media") val media: Media ) - val mapped = app.get(apiLink, headers = mapOf("Referer" to referrer)).mapped() + val mapped = app.get(apiLink, headers = mapOf("Referer" to referrer)).parsed() val sources = mutableListOf() if (mapped.success) { diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AllMoviesForYouProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AllMoviesForYouProvider.kt index b17855f9..9434f7bc 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AllMoviesForYouProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/AllMoviesForYouProvider.kt @@ -37,14 +37,14 @@ class AllMoviesForYouProvider : MainAPI() { for ((name, element) in urls) { try { val home = soup.select(element).map { - val title = it.selectFirst("h2.title").text() - val link = it.selectFirst("a").attr("href") + val title = it.selectFirst("h2.title")!!.text() + val link = it.selectFirst("a")!!.attr("href") TvSeriesSearchResponse( title, link, this.name, TvType.Movie, - fixUrl(it.selectFirst("figure img").attr("data-src")), + fixUrl(it.selectFirst("figure img")!!.attr("data-src")), null, null, ) @@ -66,8 +66,8 @@ class AllMoviesForYouProvider : MainAPI() { val items = document.select("ul.MovieList > li > article > a") return items.map { item -> val href = item.attr("href") - val title = item.selectFirst("> h2.Title").text() - val img = fixUrl(item.selectFirst("> div.Image > figure > img").attr("data-src")) + val title = item.selectFirst("> h2.Title")!!.text() + val img = fixUrl(item.selectFirst("> div.Image > figure > img")!!.attr("data-src")) val type = getType(href) if (type == TvType.Movie) { MovieSearchResponse(title, href, this.name, type, img, null) @@ -108,12 +108,12 @@ class AllMoviesForYouProvider : MainAPI() { val document = app.get(url).document - val title = document.selectFirst("h1.Title").text() - val descipt = document.selectFirst("div.Description > p").text() + val title = document.selectFirst("h1.Title")!!.text() + val descipt = document.selectFirst("div.Description > p")!!.text() val rating = document.selectFirst("div.Vote > div.post-ratings > span")?.text()?.toRatingInt() val year = document.selectFirst("span.Date")?.text() - val duration = document.selectFirst("span.Time").text() + val duration = document.selectFirst("span.Time")!!.text() val backgroundPoster = fixUrlNull(document.selectFirst("div.Image > figure > img")?.attr("data-src")) @@ -140,7 +140,7 @@ class AllMoviesForYouProvider : MainAPI() { val epNum = episode.selectFirst("> td > span.Num")?.text()?.toIntOrNull() val poster = episode.selectFirst("> td.MvTbImg > a > img")?.attr("data-src") val aName = episode.selectFirst("> td.MvTbTtl > a") - val name = aName.text() + val name = aName!!.text() val href = aName.attr("href") val date = episode.selectFirst("> td.MvTbTtl > span")?.text() diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/BflixProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/BflixProvider.kt index 39e750fc..b660db0b 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/BflixProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/BflixProvider.kt @@ -32,16 +32,16 @@ open class BflixProvider : MainAPI() { ) for ((name, element) in testa) try { val test = soup.select(element).map { - val title = it.selectFirst("h3 a").text() - val link = fixUrl(it.selectFirst("a").attr("href")) - val qualityInfo = it.selectFirst("div.quality").text() + val title = it.selectFirst("h3 a")!!.text() + val link = fixUrl(it.selectFirst("a")!!.attr("href")) + val qualityInfo = it.selectFirst("div.quality")!!.text() val quality = getQualityFromString(qualityInfo) TvSeriesSearchResponse( title, link, this.name, if (link.contains("/movie/")) TvType.Movie else TvType.TvSeries, - it.selectFirst("a.poster img").attr("src"), + it.selectFirst("a.poster img")!!.attr("src"), null, null, quality = quality @@ -167,11 +167,11 @@ open class BflixProvider : MainAPI() { val document = Jsoup.parse(html) return document.select(".filmlist div.item").map { - val title = it.selectFirst("h3 a").text() - val href = fixUrl(it.selectFirst("a").attr("href")) - val image = it.selectFirst("a.poster img").attr("src") + val title = it.selectFirst("h3 a")!!.text() + val href = fixUrl(it.selectFirst("a")!!.attr("href")) + val image = it.selectFirst("a.poster img")!!.attr("src") val isMovie = href.contains("/movie/") - val qualityInfo = it.selectFirst("div.quality").text() + val qualityInfo = it.selectFirst("div.quality")!!.text() val quality = getQualityFromString(qualityInfo) if (isMovie) { @@ -205,33 +205,33 @@ open class BflixProvider : MainAPI() { override suspend fun load(url: String): LoadResponse? { val soup = app.get(url).document - val movieid = soup.selectFirst("div#watch").attr("data-id") + val movieid = soup.selectFirst("div#watch")!!.attr("data-id") val movieidencoded = encode(getVrf(movieid) ?: return null) - val title = soup.selectFirst("div.info h1").text() + val title = soup.selectFirst("div.info h1")!!.text() val description = soup.selectFirst(".info .desc")?.text()?.trim() val poster: String? = try { - soup.selectFirst("img.poster").attr("src") + soup.selectFirst("img.poster")!!.attr("src") } catch (e: Exception) { - soup.selectFirst(".info .poster img").attr("src") + soup.selectFirst(".info .poster img")!!.attr("src") } val tags = soup.select("div.info .meta div:contains(Genre) a").map { it.text() } val episodes = Jsoup.parse( app.get( "$mainUrl/ajax/film/servers?id=$movieid&vrf=$movieidencoded" - ).mapped().html + ).parsed().html ).select("div.episode").map { val a = it.selectFirst("a") - val href = fixUrl(a.attr("href")) - val extraData = a.attr("data-kname")?.let { str -> + val href = fixUrl(a!!.attr("href")) + val extraData = a.attr("data-kname").let { str -> str.split("-").mapNotNull { subStr -> subStr.toIntOrNull() } } - val isValid = extraData?.size == 2 - val episode = if (isValid) extraData?.getOrNull(1) else null - val season = if (isValid) extraData?.getOrNull(0) else null + val isValid = extraData.size == 2 + val episode = if (isValid) extraData.getOrNull(1) else null + val season = if (isValid) extraData.getOrNull(0) else null - val eptitle = it.selectFirst(".episode a span.name").text() - val secondtitle = it.selectFirst(".episode a span").text() + val eptitle = it.selectFirst(".episode a span.name")!!.text() + val secondtitle = it.selectFirst(".episode a span")!!.text() .replace(Regex("(Episode (\\d+):|Episode (\\d+)-|Episode (\\d+))"),"") ?: "" Episode( href, @@ -329,7 +329,7 @@ open class BflixProvider : MainAPI() { ): Boolean { val soup = app.get(data).document - val movieid = encode(soup.selectFirst("div#watch").attr("data-id") ?: return false) + val movieid = encode(soup.selectFirst("div#watch")?.attr("data-id") ?: return false) val movieidencoded = encode(getVrf(movieid!!) ?: return false) Jsoup.parse( parseJson( diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/CinecalidadProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/CinecalidadProvider.kt index c3a98bc9..c650ba49 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/CinecalidadProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/CinecalidadProvider.kt @@ -31,14 +31,14 @@ class CinecalidadProvider:MainAPI() { try { val soup = app.get(url).document val home = soup.select(".item.movies").map { - val title = it.selectFirst("div.in_title").text() - val link = it.selectFirst("a").attr("href") + val title = it.selectFirst("div.in_title")!!.text() + val link = it.selectFirst("a")!!.attr("href") TvSeriesSearchResponse( title, link, this.name, if (link.contains("/ver-pelicula/")) TvType.Movie else TvType.TvSeries, - it.selectFirst(".poster.custom img").attr("data-src"), + it.selectFirst(".poster.custom img")!!.attr("data-src"), null, null, ) @@ -59,9 +59,9 @@ class CinecalidadProvider:MainAPI() { val document = app.get(url).document return document.select("article").map { - val title = it.selectFirst("div.in_title").text() - val href = it.selectFirst("a").attr("href") - val image = it.selectFirst(".poster.custom img").attr("data-src") + val title = it.selectFirst("div.in_title")!!.text() + val href = it.selectFirst("a")!!.attr("href") + val image = it.selectFirst(".poster.custom img")!!.attr("data-src") val isMovie = href.contains("/ver-pelicula/") if (isMovie) { @@ -91,14 +91,14 @@ class CinecalidadProvider:MainAPI() { override suspend fun load(url: String): LoadResponse? { val soup = app.get(url, timeout = 120).document - val title = soup.selectFirst(".single_left h1").text() + val title = soup.selectFirst(".single_left h1")!!.text() val description = soup.selectFirst("div.single_left table tbody tr td p")?.text()?.trim() - val poster: String? = soup.selectFirst(".alignnone").attr("data-src") + val poster: String? = soup.selectFirst(".alignnone")!!.attr("data-src") val episodes = soup.select("div.se-c div.se-a ul.episodios li").map { li -> - val href = li.selectFirst("a").attr("href") - val epThumb = li.selectFirst("img.lazy").attr("data-src") - val name = li.selectFirst(".episodiotitle a").text() - val seasonid = li.selectFirst(".numerando").text().replace(Regex("(S|E)"),"").let { str -> + val href = li.selectFirst("a")!!.attr("href") + val epThumb = li.selectFirst("img.lazy")!!.attr("data-src") + val name = li.selectFirst(".episodiotitle a")!!.text() + val seasonid = li.selectFirst(".numerando")!!.text().replace(Regex("(S|E)"),"").let { str -> str.split("-").mapNotNull { subStr -> subStr.toIntOrNull() } } val isValid = seasonid.size == 2 @@ -182,7 +182,7 @@ class CinecalidadProvider:MainAPI() { "Sec-Fetch-Site" to "same-origin", "Sec-Fetch-User" to "?1", ), - allowRedirects = false).response.headers.values("location").apmap { extractedurl -> + allowRedirects = false).okhttpResponse.headers.values("location").apmap { extractedurl -> if (extractedurl.contains("cinestart")) { loadExtractor(extractedurl, mainUrl, callback) } @@ -221,7 +221,7 @@ class CinecalidadProvider:MainAPI() { "Sec-Fetch-Site" to "same-origin", "Sec-Fetch-User" to "?1", ), - allowRedirects = false).response.headers.values("location").apmap { extractedurl -> + allowRedirects = false).okhttpResponse.headers.values("location").apmap { extractedurl -> if (extractedurl.contains("cinestart")) { loadExtractor(extractedurl, mainUrl, callback) } @@ -238,7 +238,7 @@ class CinecalidadProvider:MainAPI() { val validsub = docsub.text if (validsub.contains("Subtítulo") || validsub.contains("Forzados")) { val langregex = Regex("(Subtítulo.*\$|Forzados.*\$)") - val langdoc = linksub.selectFirst("div.titulo h3").text() + val langdoc = linksub.selectFirst("div.titulo h3")!!.text() val reallang = langregex.find(langdoc)?.destructured?.component1() linksub.select("a.link").apmap { val sublink = if (data.contains("serie") || data.contains("episodio")) "${data}${it.attr("href")}" diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/CuevanaProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/CuevanaProvider.kt index dadf02df..0703a124 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/CuevanaProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/CuevanaProvider.kt @@ -30,9 +30,9 @@ class CuevanaProvider : MainAPI() { "Series", app.get("$mainUrl/serie", timeout = 120).document.select("section.home-series li") .map { - val title = it.selectFirst("h2.Title").text() - val poster = it.selectFirst("img.lazy").attr("data-src") - val url = it.selectFirst("a").attr("href") + val title = it.selectFirst("h2.Title")!!.text() + val poster = it.selectFirst("img.lazy")!!.attr("data-src") + val url = it.selectFirst("a")!!.attr("href") TvSeriesSearchResponse( title, url, @@ -48,14 +48,14 @@ class CuevanaProvider : MainAPI() { try { val soup = app.get(url).document val home = soup.select("section li.xxx.TPostMv").map { - val title = it.selectFirst("h2.Title").text() - val link = it.selectFirst("a").attr("href") + val title = it.selectFirst("h2.Title")!!.text() + val link = it.selectFirst("a")!!.attr("href") TvSeriesSearchResponse( title, link, this.name, if (link.contains("/pelicula/")) TvType.Movie else TvType.TvSeries, - it.selectFirst("img.lazy").attr("data-src"), + it.selectFirst("img.lazy")!!.attr("data-src"), null, null, ) @@ -76,9 +76,9 @@ class CuevanaProvider : MainAPI() { val document = app.get(url).document return document.select("li.xxx.TPostMv").map { - val title = it.selectFirst("h2.Title").text() - val href = it.selectFirst("a").attr("href") - val image = it.selectFirst("img.lazy").attr("data-src") + val title = it.selectFirst("h2.Title")!!.text() + val href = it.selectFirst("a")!!.attr("href") + val image = it.selectFirst("img.lazy")!!.attr("data-src") val isSerie = href.contains("/serie/") if (isSerie) { @@ -106,9 +106,9 @@ class CuevanaProvider : MainAPI() { override suspend fun load(url: String): LoadResponse? { val soup = app.get(url, timeout = 120).document - val title = soup.selectFirst("h1.Title").text() + val title = soup.selectFirst("h1.Title")!!.text() val description = soup.selectFirst(".Description p")?.text()?.trim() - val poster: String? = soup.selectFirst(".movtv-info div.Image img").attr("data-src") + val poster: String? = soup.selectFirst(".movtv-info div.Image img")!!.attr("data-src") val year1 = soup.selectFirst("footer p.meta").toString() val yearRegex = Regex("(\\d+)") val yearf = @@ -117,9 +117,9 @@ class CuevanaProvider : MainAPI() { val episodes = soup.select(".all-episodes li.TPostMv article").map { li -> val href = li.select("a").attr("href") val epThumb = - li.selectFirst("div.Image img").attr("data-src") ?: li.selectFirst("img.lazy") + li.selectFirst("div.Image img")?.attr("data-src") ?: li.selectFirst("img.lazy")!! .attr("data-srcc") - val seasonid = li.selectFirst("span.Year").text().let { str -> + val seasonid = li.selectFirst("span.Year")!!.text().let { str -> str.split("x").mapNotNull { subStr -> subStr.toIntOrNull() } } val isValid = seasonid.size == 2 @@ -255,7 +255,7 @@ class CuevanaProvider : MainAPI() { "Sec-Fetch-Site" to "same-origin", ), data = mapOf(Pair("url", tomkey)) - ).response.headers.values("location").apmap { loc -> + ).okhttpResponse.headers.values("location").apmap { loc -> if (loc.contains("goto_ddh.php")) { val gotoregex = Regex("(\\/\\/api.cuevana3.me\\/ir\\/goto_ddh.php\\?h=[a-zA-Z0-9]{0,8}[a-zA-Z0-9_-]+)") @@ -280,7 +280,7 @@ class CuevanaProvider : MainAPI() { "Sec-Fetch-Site" to "same-origin", ), data = mapOf(Pair("url", gotolink)) - ).response.headers.values("location").apmap { golink -> + ).okhttpResponse.headers.values("location").apmap { golink -> loadExtractor(golink, data, callback) } } @@ -310,7 +310,7 @@ class CuevanaProvider : MainAPI() { "Sec-Fetch-User" to "?1", ), data = mapOf(Pair("h", inlink)) - ).response.headers.values("location").apmap { link -> + ).okhttpResponse.headers.values("location").apmap { link -> loadExtractor(link, data, callback) } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DoramasYTProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DoramasYTProvider.kt index 03c39617..6d2bde57 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DoramasYTProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DoramasYTProvider.kt @@ -52,12 +52,12 @@ class DoramasYTProvider : MainAPI() { HomePageList( "Capítulos actualizados", app.get(mainUrl, timeout = 120).document.select(".col-6").map { - val title = it.selectFirst("p").text() - val poster = it.selectFirst(".chapter img").attr("src") + val title = it.selectFirst("p")!!.text() + val poster = it.selectFirst(".chapter img")!!.attr("src") val epRegex = Regex("episodio-(\\d+)") - val url = it.selectFirst("a").attr("href").replace("ver/", "dorama/") + val url = it.selectFirst("a")!!.attr("href").replace("ver/", "dorama/") .replace(epRegex, "sub-espanol") - val epNum = it.selectFirst("h3").text().toIntOrNull() + val epNum = it.selectFirst("h3")!!.text().toIntOrNull() newAnimeSearchResponse(title,url) { this.posterUrl = fixUrl(poster) addDubStatus(getDubStatus(title), epNum) @@ -68,9 +68,9 @@ class DoramasYTProvider : MainAPI() { for (i in urls) { try { val home = app.get(i.first, timeout = 120).document.select(".col-6").map { - val title = it.selectFirst(".animedtls p").text() - val poster = it.selectFirst(".anithumb img").attr("src") - newAnimeSearchResponse(title, fixUrl(it.selectFirst("a").attr("href"))) { + val title = it.selectFirst(".animedtls p")!!.text() + val poster = it.selectFirst(".anithumb img")!!.attr("src") + newAnimeSearchResponse(title, fixUrl(it.selectFirst("a")!!.attr("href"))) { this.posterUrl = fixUrl(poster) addDubStatus(getDubStatus(title)) } @@ -88,9 +88,9 @@ class DoramasYTProvider : MainAPI() { override suspend fun search(query: String): List { return app.get("$mainUrl/buscar?q=$query", timeout = 120).document.select(".col-6").map { - val title = it.selectFirst(".animedtls p").text() - val href = it.selectFirst("a").attr("href") - val image = it.selectFirst(".animes img").attr("src") + val title = it.selectFirst(".animedtls p")!!.text() + val href = it.selectFirst("a")!!.attr("href") + val image = it.selectFirst(".animes img")!!.attr("src") AnimeSearchResponse( title, href, @@ -107,10 +107,10 @@ class DoramasYTProvider : MainAPI() { override suspend fun load(url: String): LoadResponse { val doc = app.get(url, timeout = 120).document - val poster = doc.selectFirst("div.flimimg img.img1").attr("src") - val title = doc.selectFirst("h1").text() - val type = doc.selectFirst("h4").text() - val description = doc.selectFirst("p.textComplete").text().replace("Ver menos", "") + val poster = doc.selectFirst("div.flimimg img.img1")!!.attr("src") + val title = doc.selectFirst("h1")!!.text() + val type = doc.selectFirst("h4")!!.text() + val description = doc.selectFirst("p.textComplete")!!.text().replace("Ver menos", "") val genres = doc.select(".nobel a").map { it.text() } val status = when (doc.selectFirst(".state h6")?.text()) { "Estreno" -> ShowStatus.Ongoing @@ -118,9 +118,9 @@ class DoramasYTProvider : MainAPI() { else -> null } val episodes = doc.select(".heromain .col-item").map { - val name = it.selectFirst(".dtlsflim p").text() - val link = it.selectFirst("a").attr("href") - val epThumb = it.selectFirst(".flimimg img.img1").attr("src") + val name = it.selectFirst(".dtlsflim p")!!.text() + val link = it.selectFirst("a")!!.attr("href") + val epThumb = it.selectFirst(".flimimg img.img1")!!.attr("src") Episode(link, name, posterUrl = epThumb) } return newAnimeLoadResponse(title, url, getType(type)) { diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/EgyBestProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/EgyBestProvider.kt index 41266a81..47081258 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/EgyBestProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/EgyBestProvider.kt @@ -46,7 +46,7 @@ class EgyBestProvider : MainAPI() { val pages = arrayListOf() doc.select("#mainLoad div.mbox").apmap { val name = it.select(".bdb.pda > strong").text() - if (it.select(".movie").first().attr("href").contains("season-(.....)|ep-(.....)".toRegex())) return@apmap + if (it.select(".movie").first()?.attr("href")?.contains("season-(.....)|ep-(.....)".toRegex()) == true) return@apmap val list = arrayListOf() it.select(".movie").map { element -> list.add(element.toSearchResponse()!!) @@ -87,16 +87,16 @@ class EgyBestProvider : MainAPI() { it.text().contains("النوع") }?.select("a")?.map { it.text() } - val actors = doc.select("div.cast_list .cast_item")?.mapNotNull { + val actors = doc.select("div.cast_list .cast_item").mapNotNull { val name = it.selectFirst("div > a > img")?.attr("alt") ?: return@mapNotNull null val image = it.selectFirst("div > a > img")?.attr("src") ?: return@mapNotNull null - val roleString = it.selectFirst("div > span").text() + val roleString = it.selectFirst("div > span")!!.text() val mainActor = Actor(name, image) ActorData(actor = mainActor, roleString = roleString) } return if (isMovie) { - val recommendations = doc.select(".movies_small .movie")?.mapNotNull { element -> + val recommendations = doc.select(".movies_small .movie").mapNotNull { element -> element.toSearchResponse() } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/EntrePeliculasySeriesProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/EntrePeliculasySeriesProvider.kt index 3d33d39e..8ad342b8 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/EntrePeliculasySeriesProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/EntrePeliculasySeriesProvider.kt @@ -30,14 +30,14 @@ class EntrepeliculasyseriesProvider:MainAPI() { try { val soup = app.get(url).document val home = soup.select("ul.list-movie li").map { - val title = it.selectFirst("a.link-title h2").text() - val link = it.selectFirst("a").attr("href") + val title = it.selectFirst("a.link-title h2")!!.text() + val link = it.selectFirst("a")!!.attr("href") TvSeriesSearchResponse( title, link, this.name, if (link.contains("/pelicula/")) TvType.Movie else TvType.TvSeries, - it.selectFirst("a.poster img").attr("src"), + it.selectFirst("a.poster img")!!.attr("src"), null, null, ) @@ -58,9 +58,9 @@ class EntrepeliculasyseriesProvider:MainAPI() { val document = app.get(url).document return document.select("li.xxx.TPostMv").map { - val title = it.selectFirst("h2.Title").text() - val href = it.selectFirst("a").attr("href") - val image = it.selectFirst("img.lazy").attr("data-src") + val title = it.selectFirst("h2.Title")!!.text() + val href = it.selectFirst("a")!!.attr("href") + val image = it.selectFirst("img.lazy")!!.attr("data-src") val isMovie = href.contains("/pelicula/") if (isMovie) { @@ -90,13 +90,13 @@ class EntrepeliculasyseriesProvider:MainAPI() { override suspend fun load(url: String): LoadResponse? { val soup = app.get(url, timeout = 120).document - val title = soup.selectFirst("h1.title-post").text() + val title = soup.selectFirst("h1.title-post")!!.text() val description = soup.selectFirst("p.text-content:nth-child(3)")?.text()?.trim() - val poster: String? = soup.selectFirst("article.TPost img.lazy").attr("data-src") + val poster: String? = soup.selectFirst("article.TPost img.lazy")!!.attr("data-src") val episodes = soup.select(".TPostMv article").map { li -> val href = (li.select("a") ?: li.select(".C a") ?: li.select("article a")).attr("href") - val epThumb = li.selectFirst("div.Image img").attr("data-src") - val seasonid = li.selectFirst("span.Year").text().let { str -> + val epThumb = li.selectFirst("div.Image img")!!.attr("data-src") + val seasonid = li.selectFirst("span.Year")!!.text().let { str -> str.split("x").mapNotNull { subStr -> subStr.toIntOrNull() } } val isValid = seasonid.size == 2 @@ -169,7 +169,7 @@ class EntrepeliculasyseriesProvider:MainAPI() { //params = mapOf(Pair("h", postkey)), data = mapOf(Pair("h", postkey)), allowRedirects = false - ).response.headers.values("location").apmap { + ).okhttpResponse.headers.values("location").apmap { loadExtractor(it, data, callback) } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/FilmanProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/FilmanProvider.kt index 62c25dbe..14fa5d6f 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/FilmanProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/FilmanProvider.kt @@ -24,7 +24,7 @@ class FilmanProvider : MainAPI() { val lists = document.select(".item-list,.series-list") val categories = ArrayList() for (l in lists) { - val title = l.parent().select("h3").text() + val title = l.parent()!!.select("h3").text() val items = l.select(".poster").map { i -> val name = i.select("a[href]").attr("title") val href = i.select("a[href]").attr("href") @@ -63,8 +63,8 @@ class FilmanProvider : MainAPI() { fun getVideos(type: TvType, items: Elements): List { return items.map { i -> val href = i.attr("href") - val img = i.selectFirst("> img").attr("src").replace("/thumb/", "/big/") - val name = i.selectFirst(".title").text() + val img = i.selectFirst("> img")!!.attr("src").replace("/thumb/", "/big/") + val name = i.selectFirst(".title")!!.text() if (type === TvType.TvSeries) { TvSeriesSearchResponse( name, @@ -95,7 +95,7 @@ class FilmanProvider : MainAPI() { if (episodesElements.isEmpty()) { return MovieLoadResponse(title, url, name, TvType.Movie, data, posterUrl, year, plot) } - title = document.selectFirst(".info").parent().select("h2").text() + title = document.selectFirst(".info")?.parent()?.select("h2")?.text() ?: "" val episodes = episodesElements.mapNotNull { episode -> val e = episode.text() val regex = Regex("""\[s(\d{1,3})e(\d{1,3})]""").find(e) ?: return@mapNotNull null @@ -130,7 +130,7 @@ class FilmanProvider : MainAPI() { app.get(data).document.select("#links").first() else Jsoup.parse(data) - document.select(".link-to-video")?.apmap { item -> + document?.select(".link-to-video")?.apmap { item -> val decoded = base64Decode(item.select("a").attr("data-iframe")) val link = mapper.readValue(decoded).src loadExtractor(link, null, callback) diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/HDMProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/HDMProvider.kt index 23657f40..cd08293e 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/HDMProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/HDMProvider.kt @@ -23,9 +23,9 @@ class HDMProvider : MainAPI() { return items.map { i -> val href = i.attr("href") - val data = i.selectFirst("> div.item") - val img = data.selectFirst("> img").attr("src") - val name = data.selectFirst("> div.movie-details").text() + val data = i.selectFirst("> div.item")!! + val img = data.selectFirst("> img")!!.attr("src") + val name = data.selectFirst("> div.movie-details")!!.text() MovieSearchResponse(name, href, this.name, TvType.Movie, img, null) } } @@ -57,9 +57,9 @@ class HDMProvider : MainAPI() { val response = app.get(url).text val document = Jsoup.parse(response) val title = document.selectFirst("h2.movieTitle")?.text() ?: throw ErrorLoadingException("No Data Found") - val poster = document.selectFirst("div.post-thumbnail > img").attr("src") - val descript = document.selectFirst("div.synopsis > p").text() - val year = document.select("div.movieInfoAll > div.row > div.col-md-6")?.get(1)?.selectFirst("> p > a")?.text() + val poster = document.selectFirst("div.post-thumbnail > img")!!.attr("src") + val descript = document.selectFirst("div.synopsis > p")!!.text() + val year = document.select("div.movieInfoAll > div.row > div.col-md-6").getOrNull(1)?.selectFirst("> p > a")?.text() ?.toIntOrNull() val data = "src/player/\\?v=(.*?)\"".toRegex().find(response)?.groupValues?.get(1) ?: return null diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/IHaveNoTvProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/IHaveNoTvProvider.kt index 1632a7ae..b6d224d7 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/IHaveNoTvProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/IHaveNoTvProvider.kt @@ -56,10 +56,10 @@ class IHaveNoTvProvider : MainAPI() { res.selectFirst("a[href][title]") } val year = Regex("""•?\s+(\d{4})\s+•""").find( - res.selectFirst(".episodeMeta").text() + res.selectFirst(".episodeMeta")!!.text() )?.destructured?.component1()?.toIntOrNull() - val title = aTag.attr("title") + val title = aTag!!.attr("title") val href = fixUrl(aTag.attr("href")) searchResults[href] = TvSeriesSearchResponse( title, @@ -98,11 +98,11 @@ class IHaveNoTvProvider : MainAPI() { } val year = Regex("""•?\s+(\d{4})\s+•""").find( - res.selectFirst(".episodeMeta").text() + res.selectFirst(".episodeMeta")!!.text() )?.destructured?.component1() ?.toIntOrNull() - val title = aTag.attr("title") + val title = aTag!!.attr("title") val href = fixUrl(aTag.attr("href")) searchResults[href] = TvSeriesSearchResponse( title, @@ -126,7 +126,7 @@ class IHaveNoTvProvider : MainAPI() { val container = soup.selectFirst(".container-fluid h1")?.parent() val title = if (isSeries) { container?.selectFirst("h1")?.text()?.split("•")?.firstOrNull().toString() - } else soup.selectFirst(".videoDetails").selectFirst("strong")?.text().toString() + } else soup.selectFirst(".videoDetails")!!.selectFirst("strong")?.text().toString() val description = if (isSeries) { container?.selectFirst("p")?.text() } else { @@ -138,11 +138,11 @@ class IHaveNoTvProvider : MainAPI() { val episodes = if (isSeries) { container?.select(".episode")?.map { ep -> - val thumb = ep.selectFirst("img").attr("src") + val thumb = ep.selectFirst("img")!!.attr("src") - val epLink = fixUrl(ep.selectFirst("a[title]").attr("href")) + val epLink = fixUrl(ep.selectFirst("a[title]")!!.attr("href")) val (season, epNum) = if (ep.selectFirst(".episodeMeta > strong") != null && - ep.selectFirst(".episodeMeta > strong").html().contains("S") + ep.selectFirst(".episodeMeta > strong")!!.html().contains("S") ) { val split = ep.selectFirst(".episodeMeta > strong")?.text()?.split("E") Pair( @@ -152,14 +152,14 @@ class IHaveNoTvProvider : MainAPI() { } else Pair(null, null) year = Regex("""•?\s+(\d{4})\s+•""").find( - ep.selectFirst(".episodeMeta").text() + ep.selectFirst(".episodeMeta")!!.text() )?.destructured?.component1()?.toIntOrNull() categories.addAll( ep.select(".episodeMeta > a[href*=\"/category/\"]").map { it.text().trim() }) newEpisode(epLink) { - this.name = ep.selectFirst("a[title]").attr("title") + this.name = ep.selectFirst("a[title]")!!.attr("title") this.season = season this.episode = epNum this.posterUrl = thumb @@ -173,13 +173,13 @@ class IHaveNoTvProvider : MainAPI() { this.name, TvType.Movie, url, - soup.selectFirst("[rel=\"image_src\"]").attr("href"), + soup.selectFirst("[rel=\"image_src\"]")!!.attr("href"), Regex("""•?\s+(\d{4})\s+•""").find( - soup.selectFirst(".videoDetails").text() + soup.selectFirst(".videoDetails")!!.text() )?.destructured?.component1()?.toIntOrNull(), description, null, - soup.selectFirst(".videoDetails").select("a[href*=\"/category/\"]") + soup.selectFirst(".videoDetails")!!.select("a[href*=\"/category/\"]") .map { it.text().trim() } )) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/KdramaHoodProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/KdramaHoodProvider.kt index e3bec4ae..8785d5a4 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/KdramaHoodProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/KdramaHoodProvider.kt @@ -33,17 +33,14 @@ class KdramaHoodProvider : MainAPI() { // Hardcoded homepage cause of site implementation // Recently added val recentlyInner = doc.selectFirst("div.peliculas") - val recentlyAddedTitle = recentlyInner.selectFirst("h1")?.text() ?: "Recently Added" - val recentlyAdded = recentlyInner.select("div.item_2.items > div.fit.item")?.mapNotNull { - if (it == null) { - return@mapNotNull null - } + val recentlyAddedTitle = recentlyInner!!.selectFirst("h1")?.text() ?: "Recently Added" + val recentlyAdded = recentlyInner.select("div.item_2.items > div.fit.item").mapNotNull { val innerA = it.select("div.image > a") ?: return@mapNotNull null val link = fixUrlNull(innerA.attr("href")) ?: return@mapNotNull null - val image = fixUrlNull(innerA.select("img")?.attr("src")) + val image = fixUrlNull(innerA.select("img").attr("src")) val innerData = it.selectFirst("div.data") - val title = innerData.selectFirst("h1")?.text() ?: return@mapNotNull null + val title = innerData!!.selectFirst("h1")?.text() ?: return@mapNotNull null val year = try { val yearText = innerData.selectFirst("span.titulo_o") ?.text()?.takeLast(11)?.trim()?.take(4) ?: "" @@ -61,7 +58,7 @@ class KdramaHoodProvider : MainAPI() { posterUrl = image, year = year ) - }?.distinctBy { it.url } ?: listOf() + }.distinctBy { it.url } ?: listOf() home.add(HomePageList(recentlyAddedTitle, recentlyAdded)) return HomePageResponse(home.filter { it.list.isNotEmpty() }) } @@ -102,15 +99,15 @@ class KdramaHoodProvider : MainAPI() { val title = inner?.selectFirst("h1")?.text() ?: "" val poster = fixUrlNull(doc.selectFirst("meta[property=og:image]")?.attr("content")) ?: "" //Log.i(this.name, "Result => (poster) ${poster}") - val info = inner.selectFirst("div#info") - val descript = inner?.selectFirst("div.contenidotv > div > p")?.text() + val info = inner!!.selectFirst("div#info") + val descript = inner.selectFirst("div.contenidotv > div > p")?.text() val year = try { val startLink = "https://kdramahood.com/drama-release-year/" var res: Int? = null - info.select("div.metadatac")?.forEach { + info?.select("div.metadatac")?.forEach { if (res != null) { return@forEach } if (it == null) { return@forEach } - val yearLink = it.select("a")?.attr("href") ?: return@forEach + val yearLink = it.select("a").attr("href") ?: return@forEach if (yearLink.startsWith(startLink)) { res = yearLink.substring(startLink.length).replace("/", "").toIntOrNull() } @@ -118,13 +115,13 @@ class KdramaHoodProvider : MainAPI() { res } catch (e: Exception) { null } - val recs = doc.select("div.sidebartv > div.tvitemrel")?.mapNotNull { + val recs = doc.select("div.sidebartv > div.tvitemrel").mapNotNull { val a = it?.select("a") ?: return@mapNotNull null val aUrl = fixUrlNull(a.attr("href")) ?: return@mapNotNull null val aImg = a.select("img") - val aCover = fixUrlNull(aImg?.attr("src")) ?: fixUrlNull(aImg?.attr("data-src")) + val aCover = fixUrlNull(aImg.attr("src")) ?: fixUrlNull(aImg.attr("data-src")) val aNameYear = a.select("div.datatvrel") ?: return@mapNotNull null - val aName = aNameYear.select("h4")?.text() ?: aImg?.attr("alt") ?: return@mapNotNull null + val aName = aNameYear.select("h4").text() ?: aImg.attr("alt") ?: return@mapNotNull null val aYear = aName.trim().takeLast(5).removeSuffix(")").toIntOrNull() MovieSearchResponse( url = aUrl, @@ -137,7 +134,7 @@ class KdramaHoodProvider : MainAPI() { } // Episodes Links - val episodeList = inner?.select("ul.episodios > li")?.mapNotNull { ep -> + val episodeList = inner.select("ul.episodios > li")?.mapNotNull { ep -> //Log.i(this.name, "Result => (ep) ${ep}") val listOfLinks = mutableListOf() val count = ep.select("div.numerando")?.text()?.toIntOrNull() ?: 0 @@ -181,10 +178,10 @@ class KdramaHoodProvider : MainAPI() { posterUrl = poster, date = null ) - } ?: listOf() + } //If there's only 1 episode, consider it a movie. - if (episodeList.size == 1) { + if (episodeList?.size == 1) { return MovieLoadResponse( name = title, url = url, @@ -202,7 +199,7 @@ class KdramaHoodProvider : MainAPI() { url = url, apiName = this.name, type = TvType.AsianDrama, - episodes = episodeList.reversed(), + episodes = episodeList?.reversed() ?: emptyList(), posterUrl = poster, year = year, plot = descript, diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/LookMovieProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/LookMovieProvider.kt index 82ce3562..9559f563 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/LookMovieProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/LookMovieProvider.kt @@ -118,10 +118,10 @@ class LookMovieProvider : MainAPI() { val items = document.select("div.flex-wrap-movielist > div.movie-item-style-1") return items.map { item -> val titleHolder = item.selectFirst("> div.mv-item-infor > h6 > a") - val href = fixUrl(titleHolder.attr("href")) + val href = fixUrl(titleHolder!!.attr("href")) val name = titleHolder.text() val posterHolder = item.selectFirst("> div.image__placeholder > a") - val poster = posterHolder.selectFirst("> img")?.attr("data-src") + val poster = posterHolder!!.selectFirst("> img")?.attr("data-src") val year = posterHolder.selectFirst("> p.year")?.text()?.toIntOrNull() if (isMovie) { MovieSearchResponse( @@ -199,17 +199,17 @@ class LookMovieProvider : MainAPI() { val isMovie = url.contains("/movies/") val watchHeader = document.selectFirst("div.watch-heading") - val nameHeader = watchHeader.selectFirst("> h1.bd-hd") - val year = nameHeader.selectFirst("> span")?.text()?.toIntOrNull() + val nameHeader = watchHeader!!.selectFirst("> h1.bd-hd") + val year = nameHeader!!.selectFirst("> span")?.text()?.toIntOrNull() val title = nameHeader.ownText() val rating = - parseRating(watchHeader.selectFirst("> div.movie-rate > div.rate > p > span").text()) + parseRating(watchHeader.selectFirst("> div.movie-rate > div.rate > p > span")!!.text()) val imgElement = document.selectFirst("div.movie-img > p.movie__poster") val img = imgElement?.attr("style") var poster = if (img.isNullOrEmpty()) null else "url\\((.*?)\\)".toRegex() .find(img)?.groupValues?.get(1) if (poster.isNullOrEmpty()) poster = imgElement?.attr("data-background-image") - val descript = document.selectFirst("p.description-short").text() + val descript = document.selectFirst("p.description-short")!!.text() val id = "${if (isMovie) "id_movie" else "id_show"}:(.*?),".toRegex() .find(response)?.groupValues?.get(1) ?.replace(" ", "") diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/MeloMovieProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/MeloMovieProvider.kt index 18bcbb88..7bccfe09 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/MeloMovieProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/MeloMovieProvider.kt @@ -88,11 +88,11 @@ class MeloMovieProvider : MainAPI() { private fun serializeData(element: Element): List { val eps = element.select("> tbody > tr") - val parsed = eps.map { + val parsed = eps.mapNotNull { try { val tds = it.select("> td") val name = tds[if (tds.size == 5) 1 else 0].text() - val url = fixUrl(tds.last().selectFirst("> a").attr("data-lnk").replace(" ", "%20")) + val url = fixUrl(tds.last()!!.selectFirst("> a")!!.attr("data-lnk").replace(" ", "%20")) MeloMovieLink(name, url) } catch (e: Exception) { MeloMovieLink("", "") @@ -133,13 +133,13 @@ class MeloMovieProvider : MainAPI() { val imdbUrl = findUsingRegex("var imdb = \"(.*?)\"") val document = Jsoup.parse(response) - val poster = document.selectFirst("img.img-fluid").attr("src") + val poster = document.selectFirst("img.img-fluid")!!.attr("src") val type = findUsingRegex("var posttype = ([0-9]*)")?.toInt() ?: return null val titleInfo = document.selectFirst("div.movie_detail_title > div > div > h1") - val title = titleInfo.ownText() + val title = titleInfo!!.ownText() val year = titleInfo.selectFirst("> a")?.text()?.replace("(", "")?.replace(")", "")?.toIntOrNull() - val plot = document.selectFirst("div.col-lg-12 > p").text() + val plot = document.selectFirst("div.col-lg-12 > p")!!.text() if (type == 1) { // MOVIE val serialize = document.selectFirst("table.accordion__list") @@ -161,12 +161,12 @@ class MeloMovieProvider : MainAPI() { ?: throw ErrorLoadingException("No episodes found") for (s in seasons) { val season = - s.selectFirst("> div.card-header > button > span").text() + s.selectFirst("> div.card-header > button > span")!!.text() .replace("Season: ", "").toIntOrNull() val localEpisodes = s.select("> div.collapse > div > div > div.accordion__card") for (e in localEpisodes) { val episode = - e.selectFirst("> div.card-header > button > span").text() + e.selectFirst("> div.card-header > button > span")!!.text() .replace("Episode: ", "").toIntOrNull() val links = e.selectFirst("> div.collapse > div > table.accordion__list") ?: continue diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/MyCimaProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/MyCimaProvider.kt index 3a41706b..36c5b00d 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/MyCimaProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/MyCimaProvider.kt @@ -153,7 +153,7 @@ class MyCimaProvider : MainAPI() { if (moreButton.isNotEmpty()) { val n = doc.select("div.Seasons--Episodes div.Episodes--Seasons--Episodes a").size val totals = - doc.select("div.Episodes--Seasons--Episodes a").first().text().getIntFromText() + doc.select("div.Episodes--Seasons--Episodes a").first()!!.text().getIntFromText() val mEPS = arrayListOf( n, n + 40, @@ -229,7 +229,7 @@ class MyCimaProvider : MainAPI() { val n = seasonsite.select("div.Seasons--Episodes div.Episodes--Seasons--Episodes a").size val totals = - seasonsite.select("div.Episodes--Seasons--Episodes a").first().text() + seasonsite.select("div.Episodes--Seasons--Episodes a").first()!!.text() .getIntFromText() val mEPS = arrayListOf( n, diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/NginxProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/NginxProvider.kt index 589a039f..fd2a27c8 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/NginxProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/NginxProvider.kt @@ -37,13 +37,13 @@ class NginxProvider : MainAPI() { val isMovie = !nfoUrl.contains("tvshow.nfo") - val title = metadataDocument.selectFirst("title").text() + val title = metadataDocument.selectFirst("title")!!.text() - val description = metadataDocument.selectFirst("plot").text() + val description = metadataDocument.selectFirst("plot")!!.text() if (isMovie) { - val poster = metadataDocument.selectFirst("thumb").text() - val trailer = metadataDocument.select("trailer")?.mapNotNull { + val poster = metadataDocument.selectFirst("thumb")!!.text() + val trailer = metadataDocument.select("trailer").mapNotNull { it?.text()?.replace( "plugin://plugin.video.youtube/play/?video_id=", "https://www.youtube.com/watch?v=" @@ -125,7 +125,7 @@ class NginxProvider : MainAPI() { val epNum = nfoDocument.selectFirst("episode")?.text()?.toIntOrNull() val poster = seasonString + episode.attr("href").replace(".nfo", "-thumb.jpg") - val name = nfoDocument.selectFirst("title").text() + val name = nfoDocument.selectFirst("title")!!.text() // val seasonInt = nfoDocument.selectFirst("season").text().toIntOrNull() val date = nfoDocument.selectFirst("aired")?.text() val plot = nfoDocument.selectFirst("plot")?.text() diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PeliSmartProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PeliSmartProvider.kt index 09a02c3c..d29c4b58 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PeliSmartProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PeliSmartProvider.kt @@ -29,14 +29,14 @@ class PeliSmartProvider: MainAPI() { try { val soup = app.get(url).document val home = soup.select(".description-off").map { - val title = it.selectFirst("h3.entry-title a").text() - val link = it.selectFirst("a").attr("href") + val title = it.selectFirst("h3.entry-title a")!!.text() + val link = it.selectFirst("a")!!.attr("href") TvSeriesSearchResponse( title, link, this.name, if (link.contains("pelicula")) TvType.Movie else TvType.TvSeries, - it.selectFirst("div img").attr("src"), + it.selectFirst("div img")!!.attr("src"), null, null, ) @@ -57,9 +57,9 @@ class PeliSmartProvider: MainAPI() { val document = app.get(url).document return document.select(".description-off").map { - val title = it.selectFirst("h3.entry-title a").text() - val href = it.selectFirst("a").attr("href") - val image = it.selectFirst("div img").attr("src") + val title = it.selectFirst("h3.entry-title a")!!.text() + val href = it.selectFirst("a")!!.attr("href") + val image = it.selectFirst("div img")!!.attr("src") val isMovie = href.contains("pelicula") if (isMovie) { @@ -88,13 +88,13 @@ class PeliSmartProvider: MainAPI() { override suspend fun load(url: String): LoadResponse? { val soup = app.get(url, timeout = 120).document - val title = soup.selectFirst(".wpb_wrapper h1").text() + val title = soup.selectFirst(".wpb_wrapper h1")!!.text() val description = soup.selectFirst("div.wpb_wrapper p")?.text()?.trim() - val poster: String? = soup.selectFirst(".vc_single_image-img").attr("src") + val poster: String? = soup.selectFirst(".vc_single_image-img")!!.attr("src") val episodes = soup.select("div.vc_tta-panel-body div a").map { li -> - val href = li.selectFirst("a").attr("href") + val href = li.selectFirst("a")!!.attr("href") val preregex = Regex("(\\d+)\\. ") - val name = li.selectFirst("a").text().replace(preregex,"") + val name = li.selectFirst("a")!!.text().replace(preregex,"") val regextest = Regex("(temporada-(\\d+)-capitulo-(\\d+)|temporada-(\\d+)-episodio-(\\d+))") val test = regextest.find(href)?.destructured?.component1()?.replace(Regex("(temporada-|-)"),"") val seasonid = test.let { str -> diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisflixProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisflixProvider.kt index 56317f28..f635573c 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisflixProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisflixProvider.kt @@ -28,14 +28,14 @@ class PelisflixProvider : MainAPI() { try { val soup = app.get(i.first).document val home = soup.select("article.TPost.B").map { - val title = it.selectFirst("h2.title").text() - val link = it.selectFirst("a").attr("href") + val title = it.selectFirst("h2.title")!!.text() + val link = it.selectFirst("a")!!.attr("href") TvSeriesSearchResponse( title, link, this.name, TvType.Movie, - it.selectFirst("figure img").attr("data-src"), + it.selectFirst("figure img")!!.attr("data-src"), null, null, ) @@ -54,9 +54,9 @@ class PelisflixProvider : MainAPI() { val url = "$mainUrl/?s=$query" val doc = app.get(url).document return doc.select("article.TPost.B").map { - val href = it.selectFirst("a").attr("href") - val poster = it.selectFirst("figure img").attr("data-src") - val name = it.selectFirst("h2.title").text() + val href = it.selectFirst("a")!!.attr("href") + val poster = it.selectFirst("figure img")!!.attr("data-src") + val name = it.selectFirst("h2.title")!!.text() val isMovie = href.contains("/pelicula/") if (isMovie) { MovieSearchResponse( @@ -86,24 +86,24 @@ class PelisflixProvider : MainAPI() { val document = app.get(url).document - val title = document.selectFirst("h1.Title").text() + val title = document.selectFirst("h1.Title")!!.text() val descRegex = Regex("(.Recuerda.*Pelisflix.+)") val descRegex2 = Regex("(Actualmente.*.)") val descRegex3 = Regex("(.*Director:.*)") val descRegex4 = Regex("(.*Actores:.*)") val descRegex5 = Regex("(Ver.*(\\)|)((\\d+).))") - val descipt = document.selectFirst("div.Description").text().replace(descRegex, "") + val descipt = document.selectFirst("div.Description")!!.text().replace(descRegex, "") .replace(descRegex2, "").replace(descRegex3, "") .replace(descRegex4, "").replace(descRegex5, "") val desc2Regex = Regex("(G(e|é)nero:.*..)") - val descipt2 = document.selectFirst("div.Description").text().replace(desc2Regex, "") + val descipt2 = document.selectFirst("div.Description")!!.text().replace(desc2Regex, "") val rating = document.selectFirst("div.rating-content button.like-mov span.vot_cl")?.text() ?.toFloatOrNull() ?.times(0)?.toInt() val year = document.selectFirst("span.Date")?.text() val duration = - if (type == TvType.Movie) document.selectFirst(".Container .Container span.Time") + if (type == TvType.Movie) document.selectFirst(".Container .Container span.Time")!! .text() else null val postercss = document.selectFirst("head").toString() val posterRegex = @@ -137,7 +137,7 @@ class PelisflixProvider : MainAPI() { val epNum = episode.selectFirst("> td > span.Num")?.text()?.toIntOrNull() val epthumb = episode.selectFirst("img")?.attr("src") val aName = episode.selectFirst("> td.MvTbTtl > a") - val name = aName.text() + val name = aName!!.text() val href = aName.attr("href") val date = episode.selectFirst("> td.MvTbTtl > span")?.text() episodeList.add( @@ -220,7 +220,7 @@ class PelisflixProvider : MainAPI() { params = mapOf(Pair("h", postkey)), data = mapOf(Pair("h", postkey)), allowRedirects = false - ).response.headers.values("location").apmap { link -> + ).okhttpResponse.headers.values("location").apmap { link -> val url1 = link.replace("#bu", "") loadExtractor(url1, data, callback) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisplusHDProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisplusHDProvider.kt index fb14456f..3aef6b4f 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisplusHDProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisplusHDProvider.kt @@ -67,9 +67,9 @@ class PelisplusHDProvider:MainAPI() { val document = app.get(url).document return document.select("a.Posters-link").map { - val title = it.selectFirst(".listing-content p").text() - val href = it.selectFirst("a").attr("href") - val image = it.selectFirst(".Posters-img").attr("src") + val title = it.selectFirst(".listing-content p")!!.text() + val href = it.selectFirst("a")!!.attr("href") + val image = it.selectFirst(".Posters-img")!!.attr("src") val isMovie = href.contains("/pelicula/") if (isMovie) { @@ -98,12 +98,12 @@ class PelisplusHDProvider:MainAPI() { override suspend fun load(url: String): LoadResponse? { val soup = app.get(url, timeout = 120).document - val title = soup.selectFirst(".m-b-5").text() + val title = soup.selectFirst(".m-b-5")!!.text() val description = soup.selectFirst("div.text-large")?.text()?.trim() - val poster: String? = soup.selectFirst(".img-fluid").attr("src") + val poster: String? = soup.selectFirst(".img-fluid")!!.attr("src") val episodes = soup.select("div.tab-pane .btn").map { li -> - val href = li.selectFirst("a").attr("href") - val name = li.selectFirst(".btn-primary.btn-block").text() + val href = li.selectFirst("a")!!.attr("href") + val name = li.selectFirst(".btn-primary.btn-block")!!.text() val seasonid = href.replace("/capitulo/","-") .replace(Regex("$mainUrl/.*/.*/temporada/"),"").let { str -> str.split("-").mapNotNull { subStr -> subStr.toIntOrNull() } @@ -119,7 +119,7 @@ class PelisplusHDProvider:MainAPI() { ) } - val year = soup.selectFirst(".p-r-15 .text-semibold").text().toIntOrNull() + val year = soup.selectFirst(".p-r-15 .text-semibold")!!.text().toIntOrNull() val tvType = if (url.contains("/pelicula/")) TvType.Movie else TvType.TvSeries val tags = soup.select(".p-h-15.text-center a span.font-size-18.text-info.text-semibold") .map { it?.text()?.trim().toString().replace(", ","") } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisplusProviderTemplate.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisplusProviderTemplate.kt index 0b40c12d..a9fd90a0 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisplusProviderTemplate.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/PelisplusProviderTemplate.kt @@ -44,11 +44,11 @@ open class PelisplusProviderTemplate : MainAPI() { return ArrayList(soup.select(".listing.items > .video-block").map { li -> // Selects the href in - val href = fixUrl(li.selectFirst("a").attr("href")) - val poster = fixUrl(li.selectFirst("img").attr("src")) + val href = fixUrl(li.selectFirst("a")!!.attr("href")) + val poster = fixUrl(li.selectFirst("img")!!.attr("src")) // .text() selects all the text in the element, be careful about doing this while too high up in the html hierarchy - val title = cleanName(li.selectFirst(".name").text()) + val title = cleanName(li.selectFirst(".name")!!.text()) // Use get(0) and toIntOrNull() to prevent any possible crashes, [0] or toInt() will error the search on unexpected values. val year = li.selectFirst(".date")?.text()?.split("-")?.get(0)?.toIntOrNull() @@ -73,13 +73,13 @@ open class PelisplusProviderTemplate : MainAPI() { val html = app.get(url).text val soup = Jsoup.parse(html) - val title = cleanName(soup.selectFirst("h1,h2,h3").text()) + val title = cleanName(soup.selectFirst("h1,h2,h3")!!.text()) val description = soup.selectFirst(".post-entry")?.text()?.trim() - val poster = soup.selectFirst("head meta[property=og:image]").attr("content") + val poster = soup.selectFirst("head meta[property=og:image]")!!.attr("content") var year : Int? = null val episodes = soup.select(".listing.items.lists > .video-block").map { li -> - val href = fixUrl(li.selectFirst("a").attr("href")) + val href = fixUrl(li.selectFirst("a")!!.attr("href")) val regexseason = Regex("(-[Tt]emporada-(\\d+)-[Cc]apitulo-(\\d+))") val aaa = regexseason.find(href)?.destructured?.component1()?.replace(Regex("(-[Tt]emporada-|[Cc]apitulo-)"),"") val seasonid = aaa.let { str -> @@ -88,14 +88,14 @@ open class PelisplusProviderTemplate : MainAPI() { val isValid = seasonid?.size == 2 val episode = if (isValid) seasonid?.getOrNull(1) else null val season = if (isValid) seasonid?.getOrNull(0) else null - val epThumb = fixUrl(li.selectFirst("img").attr("src")) - val epDate = li.selectFirst(".meta > .date").text() + val epThumb = fixUrl(li.selectFirst("img")!!.attr("src")) + val epDate = li.selectFirst(".meta > .date")!!.text() if(year == null) { year = epDate?.split("-")?.get(0)?.toIntOrNull() } - newEpisode(li.selectFirst("a").attr("href")) { + newEpisode(li.selectFirst("a")!!.attr("href")) { this.season = season this.episode = episode this.posterUrl = epThumb diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SeriesflixProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SeriesflixProvider.kt index ac44697b..94683604 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SeriesflixProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SeriesflixProvider.kt @@ -29,14 +29,14 @@ class SeriesflixProvider : MainAPI() { try { val soup = app.get(i.first).document val home = soup.select("article.TPost.B").map { - val title = it.selectFirst("h2.title").text() - val link = it.selectFirst("a").attr("href") + val title = it.selectFirst("h2.title")!!.text() + val link = it.selectFirst("a")!!.attr("href") TvSeriesSearchResponse( title, link, this.name, TvType.Movie, - it.selectFirst("figure img").attr("src"), + it.selectFirst("figure img")!!.attr("src"), null, null, ) @@ -55,9 +55,9 @@ class SeriesflixProvider : MainAPI() { val url = "$mainUrl/?s=$query" val doc = app.get(url).document return doc.select("article.TPost.B").map { - val href = it.selectFirst("a").attr("href") - val poster = it.selectFirst("figure img").attr("src") - val name = it.selectFirst("h2.title").text() + val href = it.selectFirst("a")!!.attr("href") + val poster = it.selectFirst("figure img")!!.attr("src") + val name = it.selectFirst("h2.title")!!.text() val isMovie = href.contains("/movies/") if (isMovie) { MovieSearchResponse( @@ -88,15 +88,15 @@ class SeriesflixProvider : MainAPI() { val document = app.get(url).document - val title = document.selectFirst("h1.Title").text() + val title = document.selectFirst("h1.Title")!!.text() val descRegex = Regex("(Recuerda.*Seriesflix.)") - val descipt = document.selectFirst("div.Description > p").text().replace(descRegex, "") + val descipt = document.selectFirst("div.Description > p")!!.text().replace(descRegex, "") val rating = document.selectFirst("div.Vote > div.post-ratings > span")?.text()?.toRatingInt() val year = document.selectFirst("span.Date")?.text() // ?: does not work val duration = try { - document.selectFirst("span.Time").text() + document.selectFirst("span.Time")!!.text() } catch (e: Exception) { null } @@ -133,8 +133,8 @@ class SeriesflixProvider : MainAPI() { val epNum = episode.selectFirst("> td > span.Num")?.text()?.toIntOrNull() val epthumb = episode.selectFirst("img")?.attr("src") val aName = episode.selectFirst("> td.MvTbTtl > a") - val name = aName.text() - val href = aName.attr("href") + val name = aName!!.text() + val href = aName!!.attr("href") val date = episode.selectFirst("> td.MvTbTtl > span")?.text() episodeList.add( newEpisode(href) { @@ -215,7 +215,7 @@ class SeriesflixProvider : MainAPI() { params = mapOf(Pair("h", postkey)), data = mapOf(Pair("h", postkey)), allowRedirects = false - ).response.headers.values("location").apmap { link -> + ).okhttpResponse.headers.values("location").apmap { link -> val url1 = link.replace("#bu", "") loadExtractor(url1, data, callback) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SflixProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SflixProvider.kt index c6a29ec6..2c293741 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SflixProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SflixProvider.kt @@ -10,13 +10,13 @@ import com.lagradost.cloudstream3.LoadResponse.Companion.addDuration import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer import com.lagradost.cloudstream3.animeproviders.ZoroProvider import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall -import com.lagradost.cloudstream3.network.AppResponse import com.lagradost.cloudstream3.utils.AppUtils.parseJson import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson import com.lagradost.cloudstream3.utils.Coroutines.ioSafe import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.M3u8Helper import com.lagradost.cloudstream3.utils.getQualityFromName +import com.lagradost.nicehttp.NiceResponse import kotlinx.coroutines.delay import org.jsoup.Jsoup import org.jsoup.nodes.Element @@ -82,7 +82,7 @@ open class SflixProvider : MainAPI() { val metaInfo = it.select("div.fd-infor > span.fdi-item") // val rating = metaInfo[0].text() - val quality = getQualityFromString(metaInfo?.getOrNull(1)?.text()) + val quality = getQualityFromString(metaInfo.getOrNull(1)?.text()) if (isMovie) { MovieSearchResponse( @@ -113,9 +113,9 @@ open class SflixProvider : MainAPI() { val document = app.get(url).document val details = document.select("div.detail_page-watch") - val img = details?.select("img.film-poster-img") - val posterUrl = img?.attr("src") - val title = img?.attr("title") ?: throw ErrorLoadingException("No Title") + val img = details.select("img.film-poster-img") + val posterUrl = img.attr("src") + val title = img.attr("title") ?: throw ErrorLoadingException("No Title") /* val year = Regex("""[Rr]eleased:\s*(\d{4})""").find( @@ -132,7 +132,7 @@ open class SflixProvider : MainAPI() { val rating = document.selectFirst(".fs-item > .imdb")?.text()?.trim() ?.removePrefix("IMDB:")?.toRatingInt() - document.select("div.elements > .row > div > .row-line")?.forEach { element -> + document.select("div.elements > .row > div > .row-line").forEach { element -> val type = element?.select(".type")?.text() ?: return@forEach when { type.contains("Released") -> { @@ -141,17 +141,17 @@ open class SflixProvider : MainAPI() { )?.groupValues?.firstOrNull()?.toIntOrNull() } type.contains("Genre") -> { - tags = element.select("a")?.mapNotNull { it.text() } + tags = element.select("a").mapNotNull { it.text() } } type.contains("Cast") -> { - cast = element.select("a")?.mapNotNull { it.text() } + cast = element.select("a").mapNotNull { it.text() } } type.contains("Duration") -> { - duration = duration ?: element.ownText()?.trim() + duration = duration ?: element.ownText().trim() } } } - 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/") @@ -164,12 +164,12 @@ open class SflixProvider : MainAPI() { else dataId val recommendations = - document.select("div.film_list-wrap > div.flw-item")?.mapNotNull { element -> + document.select("div.film_list-wrap > div.flw-item").mapNotNull { element -> val titleHeader = element.select("div.film-detail > .film-name > a") ?: return@mapNotNull null val recUrl = fixUrlNull(titleHeader.attr("href")) ?: return@mapNotNull null val recTitle = titleHeader.text() ?: return@mapNotNull null - val poster = element.select("div.film-poster > img")?.attr("data-src") + val poster = element.select("div.film-poster > img").attr("data-src") MovieSearchResponse( recTitle, recUrl, @@ -191,7 +191,7 @@ open class SflixProvider : MainAPI() { if (sourceId.isNullOrEmpty()) sourceId = element.attr("data-linkid") - if (element.select("span")?.text()?.trim()?.isValidServer() == true) { + if (element.select("span").text().trim().isValidServer()) { if (sourceId.isNullOrEmpty()) { fixUrlNull(element.attr("href")) } else { @@ -222,7 +222,7 @@ open class SflixProvider : MainAPI() { 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 -> + seasonItems.forEachIndexed { season, element -> val seasonId = element.attr("data-id") if (seasonId.isNullOrBlank()) return@forEachIndexed @@ -243,7 +243,7 @@ open class SflixProvider : MainAPI() { episode++ val episodeNum = - (it.select("div.episode-number")?.text() + (it.select("div.episode-number").text() ?: episodeTitle).let { str -> Regex("""\d+""").find(str)?.groupValues?.firstOrNull() ?.toIntOrNull() @@ -314,7 +314,7 @@ open class SflixProvider : MainAPI() { // Supported streams, they're identical app.get(episodesUrl).document.select("a").mapNotNull { element -> val id = element?.attr("data-id") ?: return@mapNotNull null - if (element.select("span")?.text()?.trim()?.isValidServer() == true) { + if (element.select("span").text().trim().isValidServer()) { "$prefix.$id".replace("/tv/", "/watch-tv/") } else { null @@ -334,7 +334,7 @@ open class SflixProvider : MainAPI() { val serverId = url.substringAfterLast(".") val iframeLink = - app.get("${this.mainUrl}/ajax/get_link/$serverId").mapped().link + app.get("${this.mainUrl}/ajax/get_link/$serverId").parsed().link ?: return@suspendSafeApiCall // Some smarter ws11 or w10 selection might be required in the future. @@ -354,7 +354,7 @@ open class SflixProvider : MainAPI() { private fun Element.toSearchResult(): SearchResponse { val inner = this.selectFirst("div.film-poster") - val img = inner.select("img") + val img = inner!!.select("img") val title = img.attr("title") val posterUrl = img.attr("data-src") ?: img.attr("src") val href = fixUrl(inner.select("a").attr("href")) @@ -454,11 +454,11 @@ open class SflixProvider : MainAPI() { * @return the data and if it is new. * */ private suspend fun getUpdatedData( - response: AppResponse, + response: NiceResponse, data: PollingData, baseUrl: String ): Pair { - if (!response.response.isSuccessful) { + if (!response.okhttpResponse.isSuccessful) { return negotiateNewSid(baseUrl)?.let { it to true } ?: data to false @@ -688,7 +688,7 @@ open class SflixProvider : MainAPI() { // "Cache-Control" to "no-cache", "TE" to "trailers" ) - ).mapped() + ).parsed() mapped.tracks?.forEach { track -> track?.toSubtitleFile()?.let { subtitleFile -> diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SoaptwoDayProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SoaptwoDayProvider.kt index 7c600cbe..3a7519f8 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SoaptwoDayProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SoaptwoDayProvider.kt @@ -28,14 +28,14 @@ class SoaptwoDayProvider:MainAPI() { try { val soup = app.get(url).document val home = soup.select("div.container div.row div.col-sm-12.col-lg-12 div.row div.col-sm-12.col-lg-12 .col-xs-6").map { - val title = it.selectFirst("h5 a").text() - val link = it.selectFirst("a").attr("href") + val title = it.selectFirst("h5 a")!!.text() + val link = it.selectFirst("a")!!.attr("href") TvSeriesSearchResponse( title, link, this.name, TvType.TvSeries, - fixUrl(it.selectFirst("img").attr("src")), + fixUrl(it.selectFirst("img")!!.attr("src")), null, null, ) @@ -52,9 +52,9 @@ class SoaptwoDayProvider:MainAPI() { override suspend fun search(query: String): List { val doc = app.get("$mainUrl/search/keyword/$query").document return doc.select("div.container div.row div.col-sm-12.col-lg-12 div.row div.col-sm-12.col-lg-12 .col-xs-6").map { - val title = it.selectFirst("h5 a").text() - val image = fixUrl(it.selectFirst("img").attr("src")) - val href = fixUrl(it.selectFirst("a").attr("href")) + val title = it.selectFirst("h5 a")!!.text() + val image = fixUrl(it.selectFirst("img")!!.attr("src")) + val href = fixUrl(it.selectFirst("a")!!.attr("href")) TvSeriesSearchResponse( title, href, @@ -80,34 +80,33 @@ class SoaptwoDayProvider:MainAPI() { data = link ) } - val otherInfoBody = soup.select("div.col-sm-8 div.panel-body")?.toString() + val otherInfoBody = soup.select("div.col-sm-8 div.panel-body").toString() //Fetch casts - val casts = otherInfoBody?.substringAfter("Stars : ") - ?.substringBefore("Genre : ")?.let { - Jsoup.parse(it)?.select("a") - }?.mapNotNull { - val castName = it?.text() ?: return@mapNotNull null - ActorData( - Actor( - name = castName + val casts = otherInfoBody.substringAfter("Stars : ") + .substringBefore("Genre : ").let { + Jsoup.parse(it).select("a") + }.mapNotNull { + val castName = it?.text() ?: return@mapNotNull null + ActorData( + Actor( + name = castName + ) ) - ) - } + } //Fetch year - val year = otherInfoBody?.substringAfter("

Release :

") - ?.substringBefore("Release : ") + .substringBefore(" year string: $it") - Jsoup.parse(it)?.select("p")?.get(1) + Jsoup.parse(it).select("p")[1] }?.text()?.take(4)?.toIntOrNull() //Fetch genres - val genre = otherInfoBody?.substringAfter("

Genre :

") - ?.substringBefore("

Release :

")?.let { + val genre = otherInfoBody.substringAfter("

Genre :

") + .substringBefore("

Release :

").let { //Log.i(this.name, "Result => genre string: $it") - Jsoup.parse(it)?.select("a") - }?.mapNotNull { it?.text()?.trim() ?: return@mapNotNull null } + Jsoup.parse(it).select("a") + }.mapNotNull { it?.text()?.trim() ?: return@mapNotNull null } - val tvType = if (episodes.isEmpty()) TvType.Movie else TvType.TvSeries - return when (tvType) { + return when (val tvType = if (episodes.isEmpty()) TvType.Movie else TvType.TvSeries) { TvType.TvSeries -> { TvSeriesLoadResponse( title, @@ -177,9 +176,9 @@ class SoaptwoDayProvider:MainAPI() { val doc = app.get(data).document val idplayer = doc.selectFirst("#divU")?.text() val idplayer2 = doc.selectFirst("#divP")?.text() - val movieid = doc.selectFirst("div.row input#hId").attr("value") + val movieid = doc.selectFirst("div.row input#hId")!!.attr("value") val tvType = try { - doc.selectFirst(".col-md-5 > div:nth-child(1) > div:nth-child(1) > img").attr("src") ?: "" + doc.selectFirst(".col-md-5 > div:nth-child(1) > div:nth-child(1) > img")!!.attr("src") ?: "" } catch (e: Exception) { "" } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/StreamingcommunityProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/StreamingcommunityProvider.kt index 8785aad0..284756d7 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/StreamingcommunityProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/StreamingcommunityProvider.kt @@ -224,7 +224,7 @@ class StreamingcommunityProvider : MainAPI() { val document = app.get(url).document val films = - document.selectFirst("the-search-page").attr("records-json").replace(""", """"""") + document.selectFirst("the-search-page")!!.attr("records-json").replace(""", """"""") val searchresults = parseJson>(films) return searchresults.map { result -> @@ -289,7 +289,7 @@ class StreamingcommunityProvider : MainAPI() { val year = datajs.releaseDate.substringBefore("-") - val correlatijs = document.selectFirst("slider-title").attr("titles-json") + val correlatijs = document.selectFirst("slider-title")!!.attr("titles-json") val listacorr = mutableListOf() val correlatidata = parseJson>(correlatijs) val number : Int = if (correlatidata.size<=15) {correlatidata.size} else correlatidata.size-15 @@ -332,7 +332,7 @@ class StreamingcommunityProvider : MainAPI() { val episodeList = arrayListOf() val episodes = - Html.fromHtml(document.selectFirst("season-select").attr("seasons")).toString() + Html.fromHtml(document.selectFirst("season-select")!!.attr("seasons")).toString() val jsonEpisodes = parseJson>(episodes) jsonEpisodes.map { seasons -> @@ -365,7 +365,7 @@ class StreamingcommunityProvider : MainAPI() { return newTvSeriesLoadResponse(name, url, type, episodeList) { this.posterUrl = poster this.year = year.filter { it.isDigit() }.toInt() - this.plot = document.selectFirst("div.plot-wrap > p").text() + this.plot = document.selectFirst("div.plot-wrap > p")!!.text() this.duration = datajs.runtime?.toInt() this.rating = (datajs.votes[0].average.toFloatOrNull()?.times(1000))?.toInt() this.tags = datajs.genres.map { it.name } @@ -377,14 +377,14 @@ class StreamingcommunityProvider : MainAPI() { } else { return newMovieLoadResponse( - document.selectFirst("div > div > h1").text(), + document.selectFirst("div > div > h1")!!.text(), document.select("a.play-hitzone").attr("href"), type, document.select("a.play-hitzone").attr("href") ) { posterUrl = fixUrlNull(poster) this.year = year.filter { it.isDigit() }.toInt() - this.plot = document.selectFirst("p.plot").text() + this.plot = document.selectFirst("p.plot")!!.text() this.rating = datajs.votes[0].average.toFloatOrNull()?.times(1000)?.toInt() this.tags = datajs.genres.map { it.name } this.duration = datajs.runtime?.toInt() diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TantiFilmProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TantiFilmProvider.kt index 28838062..20ae662b 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TantiFilmProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TantiFilmProvider.kt @@ -27,14 +27,14 @@ class TantifilmProvider : MainAPI() { try { val soup = app.get(url).document val home = soup.select("div.media3").map { - val title = it.selectFirst("p").text().substringBefore("(") - val link = it.selectFirst("a").attr("href") + val title = it.selectFirst("p")!!.text().substringBefore("(") + val link = it.selectFirst("a")!!.attr("href") TvSeriesSearchResponse( title, link, this.name, TvType.Movie, - it.selectFirst("img").attr("src"), + it.selectFirst("img")!!.attr("src"), null, null, ) @@ -54,9 +54,9 @@ class TantifilmProvider : MainAPI() { val url = "$mainUrl/search/$queryformatted" val doc = app.get(url).document return doc.select("div.film.film-2").map { - val href = it.selectFirst("a").attr("href") - val poster = it.selectFirst("img").attr("src") - val name = it.selectFirst("a").text().substringBefore("(") + val href = it.selectFirst("a")!!.attr("href") + val poster = it.selectFirst("img")!!.attr("src") + val name = it.selectFirst("a")!!.text().substringBefore("(") MovieSearchResponse( name, href, @@ -72,30 +72,30 @@ class TantifilmProvider : MainAPI() { override suspend fun load(url: String): LoadResponse { val document = app.get(url).document - val type = if (document.selectFirst("div.category-film").text().contains("Serie") + val type = if (document.selectFirst("div.category-film")!!.text().contains("Serie") .not() ) TvType.Movie else TvType.TvSeries - val title = document.selectFirst("div.title-film-left").text().substringBefore("(") + val title = document.selectFirst("div.title-film-left")!!.text().substringBefore("(") val descipt = document.select("div.content-left-film > p").map { it.text() } val rating = - document.selectFirst("div.star-rating.star-rating-f > span > span") - .attr("data-rateit-value")?.toFloatOrNull() + document.selectFirst("div.star-rating.star-rating-f > span > span")!! + .attr("data-rateit-value").toFloatOrNull() ?.times(2857)?.toInt()?.let { minOf(it, 10000) } - var year = document.selectFirst("div.title-film-left").text().substringAfter("(") + var year = document.selectFirst("div.title-film-left")!!.text().substringAfter("(") .filter { it.isDigit() } - if (year.length > 4) { - year = year.dropLast(4) + year = if (year.length > 4) { + year.dropLast(4) } else { - year = year + year } // ?: does not wor - val poster = document.selectFirst("div.image-right-film > img").attr("src") + val poster = document.selectFirst("div.image-right-film > img")!!.attr("src") val recomm = document.select("div.mediaWrap.mediaWrapAlt.recomended_videos").map { - val href = it.selectFirst("a").attr("href") - val poster = it.selectFirst("img").attr("src") - val name = it.selectFirst("a").attr("title").substringBeforeLast("(") + val href = it.selectFirst("a")!!.attr("href") + val poster = it.selectFirst("img")!!.attr("src") + val name = it.selectFirst("a")!!.attr("title").substringBeforeLast("(") MovieSearchResponse( name, href, @@ -111,10 +111,10 @@ class TantifilmProvider : MainAPI() { if (type == TvType.TvSeries) { val list = ArrayList>() - val urlvideocontainer = document.selectFirst("iframe").attr("src") + val urlvideocontainer = document.selectFirst("iframe")!!.attr("src") val videocontainer = app.get(urlvideocontainer).document videocontainer.select("nav.nav1 > select > option").forEach { element -> - val season = element.text()?.toIntOrNull() + val season = element.text().toIntOrNull() val href = element.attr("value") if (season != null && season > 0 && !href.isNullOrBlank()) { list.add(Pair(season, fixUrl(href))) @@ -130,7 +130,7 @@ class TantifilmProvider : MainAPI() { if (episodes.isNotEmpty()) { episodes.forEach { episode -> val href = episode.attr("value") - val epNum = episode.text()?.toIntOrNull() + val epNum = episode.text().toIntOrNull() episodeList.add( Episode( href, @@ -149,7 +149,7 @@ class TantifilmProvider : MainAPI() { type, episodeList, fixUrlNull(poster), - year?.toIntOrNull(), + year.toIntOrNull(), descipt[0], null, rating, @@ -159,23 +159,21 @@ class TantifilmProvider : MainAPI() { recomm ) } else { - val url2 = document.selectFirst("iframe").attr("src") + val url2 = document.selectFirst("iframe")!!.attr("src") val actorpagelink = document.select("div.content-left-film > p:nth-child(2) > a").attr("href") val actorpagelink2 = document.select("div.content-left-film > p > a").attr("href") - val Linkactor: String = if (actorpagelink.isNotEmpty()) { - actorpagelink - } else { + val Linkactor: String = actorpagelink.ifEmpty { actorpagelink2 } val actors: List? = if (Linkactor.isNotEmpty()) { val actorpage = app.get(Linkactor + "cast/").document - actorpage.select("article.membro-cast")?.filter { + actorpage.select("article.membro-cast").filter { it.selectFirst("img") ?.attr("src") != "https://www.filmtv.it/imgbank/DUMMY/no_portrait.jpg" - }?.mapNotNull { it -> - val name = it.selectFirst("div.info > h3").text() + }.mapNotNull { + val name = it.selectFirst("div.info > h3")!!.text() val image = it.selectFirst("img")?.attr("src") val roleString: String = if (it.selectFirst("h2")?.text() == "Regia") { "Regia" @@ -196,7 +194,7 @@ class TantifilmProvider : MainAPI() { null } val tags: List? = if (descipt.size == 2) { - descipt[0].let { mutableListOf(it.substringBefore(" ")) } + mutableListOf(descipt[0].substringBefore(" ")) } else { null } @@ -212,7 +210,7 @@ class TantifilmProvider : MainAPI() { url2 ) { posterUrl = fixUrlNull(poster) - this.year = year?.toIntOrNull() + this.year = year.toIntOrNull() this.plot = plot this.rating = rating this.recommendations = recomm @@ -235,7 +233,7 @@ class TantifilmProvider : MainAPI() { doc.select("option").map { fixUrl(it.attr("value")) }.filter { it.contains("label") } iframe.forEach { id -> val doc2 = app.get(id).document - val id2 = app.get(doc2.selectFirst("iframe").attr("src")).url + val id2 = app.get(doc2.selectFirst("iframe")!!.attr("src")).url loadExtractor(id2, data, callback) } return true diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TheFlixToProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TheFlixToProvider.kt index 5a4c17ca..81bd5757 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TheFlixToProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TheFlixToProvider.kt @@ -98,7 +98,7 @@ class TheFlixToProvider : MainAPI() { override suspend fun getMainPage(): HomePageResponse { val items = ArrayList() val doc = app.get(mainUrl).document - val scriptText = doc.selectFirst("script[type=application/json]").data() + val scriptText = doc.selectFirst("script[type=application/json]")!!.data() if (scriptText.contains("moviesListTrending")) { val json = parseJson(scriptText) val homePageProps = json.props.pageProps @@ -181,7 +181,7 @@ class TheFlixToProvider : MainAPI() { ) urls.apmap { url -> val doc = app.get(url).document - val scriptText = doc.selectFirst("script[type=application/json]").data() + val scriptText = doc.selectFirst("script[type=application/json]")!!.data() if (scriptText.contains("pageProps")) { val json = parseJson(scriptText) val searchPageProps = json.props.pageProps.mainList @@ -397,7 +397,7 @@ class TheFlixToProvider : MainAPI() { private suspend fun getLoadMan(url: String): LoadMain { val og = app.get(url, cookies = latestCookies) val soup = og.document - val script = soup.selectFirst("script[type=application/json]").data() + val script = soup.selectFirst("script[type=application/json]")!!.data() return parseJson(script) } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VMoveeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VMoveeProvider.kt index 0e878ad3..9f847fad 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VMoveeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VMoveeProvider.kt @@ -24,15 +24,15 @@ class VMoveeProvider : MainAPI() { val details = item.selectFirst("> div.details") val imgHolder = item.selectFirst("> div.image > div.thumbnail > a") // val href = imgHolder.attr("href") - val poster = imgHolder.selectFirst("> img").attr("data-lazy-src") - val isTV = imgHolder.selectFirst("> span").text() == "TV" + val poster = imgHolder!!.selectFirst("> img")!!.attr("data-lazy-src") + val isTV = imgHolder.selectFirst("> span")!!.text() == "TV" if (isTV) continue // no TV support yet - val titleHolder = details.selectFirst("> div.title > a") - val title = titleHolder.text() + val titleHolder = details!!.selectFirst("> div.title > a") + val title = titleHolder!!.text() val href = titleHolder.attr("href") val meta = details.selectFirst("> div.meta") - val year = meta.selectFirst("> span.year").text().toIntOrNull() + val year = meta!!.selectFirst("> span.year")!!.text().toIntOrNull() // val rating = parseRating(meta.selectFirst("> span.rating").text().replace("IMDb ", "")) // val descript = details.selectFirst("> div.contenido").text() returnValue.add( @@ -114,10 +114,10 @@ class VMoveeProvider : MainAPI() { val sheader = document.selectFirst("div.sheader") - val poster = sheader.selectFirst("> div.poster > img").attr("data-lazy-src") + val poster = sheader!!.selectFirst("> div.poster > img")!!.attr("data-lazy-src") val data = sheader.selectFirst("> div.data") - val title = data.selectFirst("> h1").text() - val descript = document.selectFirst("div#info > div").text() + val title = data!!.selectFirst("> h1")!!.text() + val descript = document.selectFirst("div#info > div")!!.text() val id = document.select("div.starstruck").attr("data-id") return MovieLoadResponse(title, url, this.name, TvType.Movie, id, poster, null, descript, null, null) diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VfFilmProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VfFilmProvider.kt index 72cad36d..51335f6b 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VfFilmProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VfFilmProvider.kt @@ -27,12 +27,12 @@ class VfFilmProvider : MainAPI() { for (item in items) { val href = item.attr("href") - val poster = item.selectFirst("> div.Image > figure > img").attr("src") + val poster = item.selectFirst("> div.Image > figure > img")!!.attr("src") .replace("//image", "https://image") - val name = item.selectFirst("> h3.Title").text() + val name = item.selectFirst("> h3.Title")!!.text() - val year = item.selectFirst("> span.Year").text()?.toIntOrNull() + val year = item.selectFirst("> span.Year")!!.text().toIntOrNull() returnValue.add(MovieSearchResponse(name, href, this.name, TvType.Movie, poster, year)) } @@ -73,25 +73,25 @@ class VfFilmProvider : MainAPI() { override suspend fun load(url: String): LoadResponse { val response = app.get(url).text val document = Jsoup.parse(response) - val title = document?.selectFirst("div.SubTitle")?.text() + val title = document.selectFirst("div.SubTitle")?.text() ?: throw ErrorLoadingException("Service might be unavailable") - val year = document.select("span.Date").text()?.toIntOrNull() + val year = document.select("span.Date").text().toIntOrNull() - val rating = document.select("span.AAIco-star").text() +// val rating = document.select("span.AAIco-star").text() - val duration = document.select("span.Time").text()?.toIntOrNull() + val duration = document.select("span.Time").text().toIntOrNull() - val poster = document.selectFirst("div.Image > figure > img").attr("src") + val poster = document.selectFirst("div.Image > figure > img")!!.attr("src") .replace("//image", "https://image") - val descript = document.selectFirst("div.Description > p").text() + val descript = document.selectFirst("div.Description > p")!!.text() val players = document.select("ul.TPlayerNv > li") var number_player = 0 var found = false for (player in players) { - if (player.selectFirst("> span").text() == "Vudeo") { + if (player.selectFirst("> span")!!.text() == "Vudeo") { found = true break } else { diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VfSerieProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VfSerieProvider.kt index f7eeee6f..654406d8 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VfSerieProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VfSerieProvider.kt @@ -28,15 +28,15 @@ class VfSerieProvider : MainAPI() { for (item in items) { val href = item.attr("href") - val poster = item.selectFirst("> div.Image > figure > img").attr("src") + val poster = item.selectFirst("> div.Image > figure > img")!!.attr("src") .replace("//image", "https://image") if (poster == "$mainUrl/wp-content/themes/toroplay/img/cnt/noimg-thumbnail.png") { // if the poster is missing (the item is just a redirect to something like https://vf-serie.org/series-tv/) continue } - val name = item.selectFirst("> h3.Title").text() + val name = item.selectFirst("> h3.Title")!!.text() - val year = item.selectFirst("> span.Year").text()?.toIntOrNull() + val year = item.selectFirst("> span.Year")!!.text().toIntOrNull() returnValue.add( TvSeriesSearchResponse( @@ -74,12 +74,12 @@ class VfSerieProvider : MainAPI() { val response = app.get(data).text val document = Jsoup.parse(response) val players = document.select("ul.TPlayerNv > li") - val trembedUrl = document.selectFirst("div.TPlayerTb > iframe").attr("src") + val trembedUrl = document.selectFirst("div.TPlayerTb > iframe")!!.attr("src") var numberPlayer = Regex(".*trembed=(.*?)&").find(trembedUrl)?.groupValues?.get(1)!! .toInt() // the starting trembed number of the first player website, some start at 0 other at 1 var found = false for (player in players) { - if (player.selectFirst("> span").text() == "Vudeo") { + if (player.selectFirst("> span")!!.text() == "Vudeo") { found = true break } else { @@ -110,21 +110,21 @@ class VfSerieProvider : MainAPI() { val response = app.get(url).text val document = Jsoup.parse(response) val title = - document?.selectFirst(".Title")?.text()?.replace("Regarder Serie ", "") + document.selectFirst(".Title")?.text()?.replace("Regarder Serie ", "") ?.replace(" En Streaming", "") ?: throw ErrorLoadingException("Service might be unavailable") - val year = document.select("span.Date").text()?.toIntOrNull() - val rating = document.select("span.AAIco-star").text()?.toIntOrNull() + val year = document.select("span.Date").text().toIntOrNull() + val rating = document.select("span.AAIco-star").text().toIntOrNull() //val duration = document.select("span.Time").text()?.toIntOrNull() val backgroundPoster = - document.selectFirst("div.Image > figure > img").attr("src") + document.selectFirst("div.Image > figure > img")!!.attr("src") .replace("//image", "https://image") - val descript = document.selectFirst("div.Description > p").text() + val descript = document.selectFirst("div.Description > p")!!.text() val list = ArrayList() @@ -149,7 +149,7 @@ class VfSerieProvider : MainAPI() { ?.replace("//image", "https://image") val aName = episode.selectFirst("> td.MvTbTtl > a") val date = episode.selectFirst("> td.MvTbTtl > span")?.text()?.toString() - val name = aName.text() + val name = aName!!.text() val href = aName.attr("href") episodeList.add( newEpisode(href) { diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidstreamProviderTemplate.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidstreamProviderTemplate.kt index aba3cf31..52b43037 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidstreamProviderTemplate.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/VidstreamProviderTemplate.kt @@ -104,11 +104,11 @@ open class VidstreamProviderTemplate : MainAPI() { return ArrayList(soup.select(".listing.items > .video-block").map { li -> // Selects the href in
- val href = fixUrl(li.selectFirst("a").attr("href")) + val href = fixUrl(li.selectFirst("a")!!.attr("href")) val poster = li.selectFirst("img")?.attr("src") // .text() selects all the text in the element, be careful about doing this while too high up in the html hierarchy - val title = li.selectFirst(".name").text() + val title = li.selectFirst(".name")!!.text() // Use get(0) and toIntOrNull() to prevent any possible crashes, [0] or toInt() will error the search on unexpected values. val year = li.selectFirst(".date")?.text()?.split("-")?.get(0)?.toIntOrNull() @@ -133,7 +133,7 @@ open class VidstreamProviderTemplate : MainAPI() { val html = app.get(url).text val soup = Jsoup.parse(html) - var title = soup.selectFirst("h1,h2,h3").text() + var title = soup.selectFirst("h1,h2,h3")!!.text() title = if (!title.contains("Episode")) title else title.split("Episode")[0].trim() val description = soup.selectFirst(".post-entry")?.text()?.trim() @@ -143,13 +143,13 @@ open class VidstreamProviderTemplate : MainAPI() { 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() + if (li.selectFirst(".name")!!.text().contains("Episode")) + "Episode " + li.selectFirst(".name")!!.text().split("Episode")[1].trim() else - li.selectFirst(".name").text() + li.selectFirst(".name")!!.text() else "" val epThumb = li.selectFirst("img")?.attr("src") - val epDate = li.selectFirst(".meta > .date").text() + val epDate = li.selectFirst(".meta > .date")!!.text() if (poster == null) { poster = li.selectFirst("img")?.attr("onerror")?.split("=")?.get(1) @@ -159,9 +159,9 @@ open class VidstreamProviderTemplate : MainAPI() { val epNum = Regex("""Episode (\d+)""").find(epTitle)?.destructured?.component1() ?.toIntOrNull() if (year == null) { - year = epDate?.split("-")?.get(0)?.toIntOrNull() + year = epDate.split("-")[0].toIntOrNull() } - newEpisode(li.selectFirst("a").attr("href")) { + newEpisode(li.selectFirst("a")!!.attr("href")) { this.episode = epNum this.posterUrl = epThumb addDate(epDate) @@ -215,7 +215,7 @@ open class VidstreamProviderTemplate : MainAPI() { urls.apmap { url -> val response = app.get(url, timeout = 20).text val document = Jsoup.parse(response) - document.select("div.main-inner")?.forEach { inner -> + document.select("div.main-inner").forEach { inner -> // Always trim your text unless you want the risk of spaces at the start or end. val title = inner.select(".widget-title").text().trim() val elements = inner.select(".video-block").map { diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/french-stream.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/french-stream.kt index c5a40286..e3146a96 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/french-stream.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/french-stream.kt @@ -20,9 +20,9 @@ class FrenchStreamProvider : MainAPI() { val soup = app.post(link).document return soup.select("div.short-in.nl").map { li -> - val href = fixUrl(li.selectFirst("a.short-poster").attr("href")) + val href = fixUrl(li.selectFirst("a.short-poster")!!.attr("href")) val poster = li.selectFirst("img")?.attr("src") - val title = li.selectFirst("> a.short-poster").text().toString().replace(". ", "") + val title = li.selectFirst("> a.short-poster")!!.text().toString().replace(". ", "") val year = li.selectFirst(".date")?.text()?.split("-")?.get(0)?.toIntOrNull() if (title.contains( "saison", @@ -54,24 +54,24 @@ class FrenchStreamProvider : MainAPI() { override suspend fun load(url: String): LoadResponse { val soup = app.get(url).document - val title = soup.selectFirst("h1#s-title").text().toString() + val title = soup.selectFirst("h1#s-title")!!.text().toString() val isMovie = !title.contains("saison", ignoreCase = true) val description = - soup.selectFirst("div.fdesc").text().toString() + soup.selectFirst("div.fdesc")!!.text().toString() .split("streaming", ignoreCase = true)[1].replace(" : ", "") var poster = fixUrlNull(soup.selectFirst("div.fposter > img")?.attr("src")) val listEpisode = soup.select("div.elink") if (isMovie) { - val tags = soup.select("ul.flist-col > li")?.getOrNull(1) + val tags = soup.select("ul.flist-col > li").getOrNull(1) val tagsList = tags?.select("a") ?.mapNotNull { // all the tags like action, thriller ...; unused variable it?.text() } return newMovieLoadResponse(title,url,TvType.Movie,url) { this.posterUrl = poster - addRating(soup.select("div.fr-count > div")?.text()) - this.year = soup.select("ul.flist-col > li")?.getOrNull(2)?.text()?.toIntOrNull() + addRating(soup.select("div.fr-count > div").text()) + this.year = soup.select("ul.flist-col > li").getOrNull(2)?.text()?.toIntOrNull() this.tags = tagsList this.plot = description addTrailer(soup.selectFirst("div.fleft > span > a")?.attr("href")) @@ -91,17 +91,16 @@ class FrenchStreamProvider : MainAPI() { val episodes = episodeList.select("a").map { a -> val epNum = a.text().split("Episode")[1].trim().toIntOrNull() - val epTitle = if (a.text()?.toString() != null) - if (a.text().contains("Episode")) { - val type = if ("honey" in a.attr("id")) { - "VF" - } else { - "VOSTFR" - } - "Episode " + epNum?.toString() + " en " + type + val epTitle = if (a.text().contains("Episode")) { + val type = if ("honey" in a.attr("id")) { + "VF" } else { - a.text() - } else "" + "VOSTFR" + } + "Episode " + epNum?.toString() + " en " + type + } else { + a.text() + } if (poster == null) { poster = a.selectFirst("div.fposter > img")?.attr("src") } @@ -133,13 +132,14 @@ class FrenchStreamProvider : MainAPI() { episodeNumber: String, is_vf_available: Boolean, ): String { - if (episodeNumber == "1") { + return if (episodeNumber == "1") { if (is_vf_available) { // 1 translate differently if vf is available or not - return "FGHIJK" - } else { return "episode033" } - } - else { - return "episode" + (episodeNumber.toInt() + 32).toString() + "FGHIJK" + } else { + "episode033" + } + } else { + "episode" + (episodeNumber.toInt() + 32).toString() } } @@ -173,7 +173,7 @@ class FrenchStreamProvider : MainAPI() { val serversvf =// French version servers soup.select("div#$wantedEpisode > div.selink > ul.btnss $div> li") .mapNotNull { li -> // list of all french version servers - val serverUrl = fixUrl(li.selectFirst("a").attr("href")) + val serverUrl = fixUrl(li.selectFirst("a")!!.attr("href")) // val litext = li.text() if (serverUrl.isNotBlank()) { if (li.text().replace(" ", "").replace(" ", "").isNotBlank()) { @@ -208,7 +208,7 @@ class FrenchStreamProvider : MainAPI() { .mapNotNull { a -> val serverurl = fixUrlNull(a.attr("href")) ?: return@mapNotNull null val parent = a.parents()[2] - val element = parent.selectFirst("a").text().plus(" ") + val element = parent.selectFirst("a")!!.text().plus(" ") if (a.text().replace(" ", "").isNotBlank()) { Pair(element.plus(a.text()), fixUrl(serverurl)) } else { @@ -239,14 +239,14 @@ class FrenchStreamProvider : MainAPI() { val returnList = docs.mapNotNull { val epList = it.selectFirst("> div.sect-c.floats.clearfix") ?: return@mapNotNull null val title = - it.selectFirst("> div.sect-t.fx-row.icon-r > div.st-left > a.st-capt").text() + it.selectFirst("> div.sect-t.fx-row.icon-r > div.st-left > a.st-capt")!!.text() val list = epList.select("> div.short") val isMovieType = title.contains("Films") // if truen type is Movie val currentList = list.map { head -> val hrefItem = head.selectFirst("> div.short-in.nl > a") - val href = fixUrl(hrefItem.attr("href")) + val href = fixUrl(hrefItem!!.attr("href")) val img = hrefItem.selectFirst("> img") - val posterUrl = img.attr("src") + val posterUrl = img!!.attr("src") val name = img.attr("> div.short-title").toString() return@map if (isMovieType) MovieSearchResponse( name, diff --git a/app/src/main/java/com/lagradost/cloudstream3/network/DdosGuardKiller.kt b/app/src/main/java/com/lagradost/cloudstream3/network/DdosGuardKiller.kt index 0d51f6cc..d5271e10 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/network/DdosGuardKiller.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/network/DdosGuardKiller.kt @@ -1,9 +1,13 @@ package com.lagradost.cloudstream3.network import androidx.annotation.AnyThread +import com.lagradost.cloudstream3.USER_AGENT import com.lagradost.cloudstream3.app -import com.lagradost.cloudstream3.network.Requests.Companion.await +import com.lagradost.nicehttp.Requests.Companion.await +import com.lagradost.nicehttp.getCookies import kotlinx.coroutines.runBlocking +import okhttp3.Headers +import okhttp3.Headers.Companion.toHeaders import okhttp3.Interceptor import okhttp3.Request import okhttp3.Response @@ -13,14 +17,13 @@ import okhttp3.Response * If false it will only try to get cookies when a request returns 403 * */ // As seen in https://github.com/anime-dl/anime-downloader/blob/master/anime_downloader/sites/erairaws.py - @AnyThread class DdosGuardKiller(private val alwaysBypass: Boolean) : Interceptor { val savedCookiesMap = mutableMapOf>() private var ddosBypassPath: String? = null - override fun intercept(chain: Interceptor.Chain): Response = runBlocking { + override fun intercept(chain: Interceptor.Chain): Response = runBlocking { val request = chain.request() if (alwaysBypass) return@runBlocking bypassDdosGuard(request) @@ -46,7 +49,7 @@ class DdosGuardKiller(private val alwaysBypass: Boolean) : Interceptor { } } - val headers = getHeaders(request.headers.toMap(), null, cookies + request.cookies) + val headers = getHeaders(request.headers.toMap(), cookies + request.cookies) return app.baseClient.newCall( request.newBuilder() .headers(headers) diff --git a/app/src/main/java/com/lagradost/cloudstream3/network/Requests.kt b/app/src/main/java/com/lagradost/cloudstream3/network/Requests.kt deleted file mode 100644 index 292531fa..00000000 --- a/app/src/main/java/com/lagradost/cloudstream3/network/Requests.kt +++ /dev/null @@ -1,449 +0,0 @@ -package com.lagradost.cloudstream3.network - -import android.annotation.SuppressLint -import android.content.Context -import android.util.Log -import androidx.preference.PreferenceManager -import com.fasterxml.jackson.module.kotlin.readValue -import com.lagradost.cloudstream3.R -import com.lagradost.cloudstream3.USER_AGENT -import com.lagradost.cloudstream3.app -import com.lagradost.cloudstream3.mapper -import kotlinx.coroutines.CancellableContinuation -import kotlinx.coroutines.CompletionHandler -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.suspendCancellableCoroutine -import okhttp3.* -import okhttp3.Headers.Companion.toHeaders -import okhttp3.MediaType.Companion.toMediaTypeOrNull -import okhttp3.RequestBody.Companion.toRequestBody -import org.jsoup.Jsoup -import org.jsoup.nodes.Document -import java.io.File -import java.io.IOException -import java.net.URI -import java.security.SecureRandom -import java.security.cert.X509Certificate -import java.util.concurrent.TimeUnit -import javax.net.ssl.SSLContext -import javax.net.ssl.TrustManager -import javax.net.ssl.X509TrustManager -import kotlin.coroutines.resumeWithException - - -class Session( - client: OkHttpClient = app.baseClient -) : Requests() { - init { - this.baseClient = client - .newBuilder() - .cookieJar(CustomCookieJar()) - .build() - } - - inner class CustomCookieJar : CookieJar { - private var cookies = mapOf() - - override fun loadForRequest(url: HttpUrl): List { - return this.cookies.values.toList() - } - - override fun saveFromResponse(url: HttpUrl, cookies: List) { - this.cookies += cookies.map { it.name to it } - } - } -} - -private const val DEFAULT_TIME = 10 -private val DEFAULT_TIME_UNIT = TimeUnit.MINUTES -private const val DEFAULT_USER_AGENT = USER_AGENT -private val DEFAULT_HEADERS = mapOf("user-agent" to DEFAULT_USER_AGENT) -private val DEFAULT_DATA: Map = mapOf() -private val DEFAULT_COOKIES: Map = mapOf() -private val DEFAULT_REFERER: String? = null - -/** WARNING! CAN ONLY BE READ ONCE */ -val Response.text: String - get() { - return this.body?.string() ?: "" - } - -val Response.url: String - get() { - return this.request.url.toString() - } - - -fun Headers.getCookies(cookieKey: String): Map { - val cookieList = - this.filter { it.first.equals(cookieKey, ignoreCase = true) } - .getOrNull(0)?.second?.split(";") - return cookieList?.associate { - val split = it.split("=") - (split.getOrNull(0)?.trim() ?: "") to (split.getOrNull(1)?.trim() ?: "") - }?.filter { it.key.isNotBlank() && it.value.isNotBlank() } ?: mapOf() -} - -val Response.cookies: Map - get() { - return this.headers.getCookies("set-cookie") - } - -val Request.cookies: Map - get() { - return this.headers.getCookies("Cookie") - } - -class AppResponse( - val response: Response -) { - /** Lazy, initialized on use. */ - val text by lazy { response.text } - val url by lazy { response.url } - val cookies by lazy { response.cookies } - val body by lazy { response.body } - val code = response.code - val headers = response.headers - val document: Document by lazy { Jsoup.parse(text) } - - /** Same as using mapper.readValue() */ - inline fun mapped(): T { - return mapper.readValue(this.text) - } -} - -private fun getData(data: Any?): RequestBody { - return when (data) { - null -> FormBody.Builder().build() - is Map<*, *> -> { - val builder = FormBody.Builder() - data.forEach { - if (it.key is String && it.value is String) - builder.add(it.key as String, it.value as String) - } - builder.build() - } - else -> - data.toString().toRequestBody("text/plain;charset=UTF-8".toMediaTypeOrNull()) - } -} - -// https://github.com, id=test -> https://github.com?id=test -private fun appendUri(uri: String, appendQuery: String): String { - val oldUri = URI(uri) - return URI( - oldUri.scheme, - oldUri.authority, - oldUri.path, - if (oldUri.query == null) appendQuery else oldUri.query + "&" + appendQuery, - oldUri.fragment - ).toString() -} - -// Can probably be done recursively -private fun addParamsToUrl(url: String, params: Map): String { - var appendedUrl = url - params.forEach { - it.value?.let { value -> - appendedUrl = appendUri(appendedUrl, "${it.key}=${value}") - } - } - return appendedUrl -} - -private fun getCache(cacheTime: Int, cacheUnit: TimeUnit): CacheControl { - return CacheControl.Builder().maxStale(cacheTime, cacheUnit).build() -} - -/** - * Referer > Set headers > Set cookies > Default headers > Default Cookies - */ -fun getHeaders( - headers: Map, - referer: String?, - cookie: Map -): Headers { - val refererMap = (referer ?: DEFAULT_REFERER)?.let { mapOf("referer" to it) } ?: mapOf() - val cookieHeaders = (DEFAULT_COOKIES + cookie) - val cookieMap = - if (cookieHeaders.isNotEmpty()) mapOf( - "Cookie" to cookieHeaders.entries.joinToString(" ") { - "${it.key}=${it.value};" - }) else mapOf() - val tempHeaders = (DEFAULT_HEADERS + headers + cookieMap + refererMap) - return tempHeaders.toHeaders() -} - -fun postRequestCreator( - url: String, - headers: Map = emptyMap(), - referer: String? = null, - params: Map = emptyMap(), - cookies: Map = emptyMap(), - data: Any? = DEFAULT_DATA, - cacheTime: Int = DEFAULT_TIME, - cacheUnit: TimeUnit = DEFAULT_TIME_UNIT -): Request { - return Request.Builder() - .url(addParamsToUrl(url, params)) - .cacheControl(getCache(cacheTime, cacheUnit)) - .headers(getHeaders(headers, referer, cookies)) - .post(getData(data)) - .build() -} - -fun getRequestCreator( - url: String, - headers: Map = emptyMap(), - referer: String? = null, - params: Map = emptyMap(), - cookies: Map = emptyMap(), - cacheTime: Int = DEFAULT_TIME, - cacheUnit: TimeUnit = DEFAULT_TIME_UNIT -): Request { - return Request.Builder() - .url(addParamsToUrl(url, params)) - .cacheControl(getCache(cacheTime, cacheUnit)) - .headers(getHeaders(headers, referer, cookies)) - .build() -} - -fun putRequestCreator( - url: String, - headers: Map, - referer: String?, - params: Map, - cookies: Map, - data: Map, - cacheTime: Int, - cacheUnit: TimeUnit -): Request { - return Request.Builder() - .url(addParamsToUrl(url, params)) - .cacheControl(getCache(cacheTime, cacheUnit)) - .headers(getHeaders(headers, referer, cookies)) - .put(getData(data)) - .build() -} - -fun optionsRequestCreator( - url: String, - headers: Map, - referer: String?, - params: Map, - cookies: Map, - data: Map, - cacheTime: Int, - cacheUnit: TimeUnit -): Request { - return Request.Builder() - .url(addParamsToUrl(url, params)) - .cacheControl(getCache(cacheTime, cacheUnit)) - .headers(getHeaders(headers, referer, cookies)) - .method("OPTIONS", getData(data)) - .build() -} - -// https://stackoverflow.com/a/59322754 -// Issues with Akwam otherwise -fun OkHttpClient.Builder.ignoreAllSSLErrors(): OkHttpClient.Builder { - val naiveTrustManager = @SuppressLint("CustomX509TrustManager") - object : X509TrustManager { - override fun getAcceptedIssuers(): Array = arrayOf() - override fun checkClientTrusted(certs: Array, authType: String) = Unit - override fun checkServerTrusted(certs: Array, authType: String) = Unit - } - - val insecureSocketFactory = SSLContext.getInstance("TLSv1.2").apply { - val trustAllCerts = arrayOf(naiveTrustManager) - init(null, trustAllCerts, SecureRandom()) - }.socketFactory - - sslSocketFactory(insecureSocketFactory, naiveTrustManager) - hostnameVerifier { _, _ -> true } - return this -} - - -open class Requests { - var baseClient = OkHttpClient() - - fun initClient(context: Context): OkHttpClient { - val settingsManager = PreferenceManager.getDefaultSharedPreferences(context) - val dns = settingsManager.getInt(context.getString(R.string.dns_pref), 0) - baseClient = OkHttpClient.Builder() - .followRedirects(true) - .followSslRedirects(true) - .ignoreAllSSLErrors() - .cache( - // Note that you need to add a ResponseInterceptor to make this 100% active. - // The server response dictates if and when stuff should be cached. - Cache( - directory = File(context.cacheDir, "http_cache"), - maxSize = 50L * 1024L * 1024L // 50 MiB - ) - ).apply { - when (dns) { - 1 -> addGoogleDns() - 2 -> addCloudFlareDns() -// 3 -> addOpenDns() - 4 -> addAdGuardDns() - } - } - // Needs to be build as otherwise the other builders will change this object - .build() - return baseClient - } - - class ContinuationCallback( - private val call: Call, - private val continuation: CancellableContinuation - ) : Callback, CompletionHandler { - - @ExperimentalCoroutinesApi - override fun onResponse(call: Call, response: Response) { - continuation.resume(response, null) - } - - override fun onFailure(call: Call, e: IOException) { - if (!call.isCanceled()) { - continuation.resumeWithException(e) - } - } - - override fun invoke(cause: Throwable?) { - try { - call.cancel() - } catch (_: Throwable) { - } - } - } - - companion object { - suspend inline fun Call.await(): Response { - return suspendCancellableCoroutine { continuation -> - val callback = ContinuationCallback(this, continuation) - enqueue(callback) - continuation.invokeOnCancellation(callback) - } - } - } - - suspend fun get( - url: String, - headers: Map = emptyMap(), - referer: String? = null, - params: Map = emptyMap(), - cookies: Map = emptyMap(), - allowRedirects: Boolean = true, - cacheTime: Int = DEFAULT_TIME, - cacheUnit: TimeUnit = DEFAULT_TIME_UNIT, - timeout: Long = 0L, - interceptor: Interceptor? = null, - ): AppResponse { - Log.i("GET", url) - val client = baseClient - .newBuilder() - .followRedirects(allowRedirects) - .followSslRedirects(allowRedirects) - .callTimeout(timeout, TimeUnit.SECONDS) - if (timeout > 0) - client - .connectTimeout(timeout, TimeUnit.SECONDS) - .readTimeout(timeout, TimeUnit.SECONDS) - - if (interceptor != null) client.addInterceptor(interceptor) - val request = - getRequestCreator(url, headers, referer, params, cookies, cacheTime, cacheUnit) - val response = client.build().newCall(request).await() - return AppResponse(response) - } - - fun executeRequest(request: Request): AppResponse { - return AppResponse(baseClient.newCall(request).execute()) - } - - suspend fun post( - url: String, - headers: Map = mapOf(), - referer: String? = null, - params: Map = mapOf(), - cookies: Map = mapOf(), - data: Any? = DEFAULT_DATA, - allowRedirects: Boolean = true, - cacheTime: Int = DEFAULT_TIME, - cacheUnit: TimeUnit = DEFAULT_TIME_UNIT, - timeout: Long = 0L, - ): AppResponse { - Log.i("POST", url) - val client = baseClient - .newBuilder() - .followRedirects(allowRedirects) - .followSslRedirects(allowRedirects) - .callTimeout(timeout, TimeUnit.SECONDS) - .build() - val request = - postRequestCreator(url, headers, referer, params, cookies, data, cacheTime, cacheUnit) - val response = client.newCall(request).await() - return AppResponse(response) - } - - suspend fun options( - url: String, - headers: Map = mapOf(), - referer: String? = null, - params: Map = mapOf(), - cookies: Map = mapOf(), - data: Map = DEFAULT_DATA, - allowRedirects: Boolean = true, - cacheTime: Int = DEFAULT_TIME, - cacheUnit: TimeUnit = DEFAULT_TIME_UNIT, - timeout: Long = 0L - ): AppResponse { - Log.i("OPTIONS", url) - val client = baseClient - .newBuilder() - .followRedirects(allowRedirects) - .followSslRedirects(allowRedirects) - .callTimeout(timeout, TimeUnit.SECONDS) - .build() - val request = - optionsRequestCreator( - url, - headers, - referer, - params, - cookies, - data, - cacheTime, - cacheUnit - ) - val response = client.newCall(request).await() - return AppResponse(response) - } - - suspend fun put( - url: String, - headers: Map = mapOf(), - referer: String? = null, - params: Map = mapOf(), - cookies: Map = mapOf(), - data: Map = DEFAULT_DATA, - allowRedirects: Boolean = true, - cacheTime: Int = DEFAULT_TIME, - cacheUnit: TimeUnit = DEFAULT_TIME_UNIT, - timeout: Long = 0L - ): AppResponse { - Log.i("PUT", url) - val client = baseClient - .newBuilder() - .followRedirects(allowRedirects) - .followSslRedirects(allowRedirects) - .callTimeout(timeout, TimeUnit.SECONDS) - .build() - val request = - putRequestCreator(url, headers, referer, params, cookies, data, cacheTime, cacheUnit) - val response = client.newCall(request).await() - return AppResponse(response) - } -} diff --git a/app/src/main/java/com/lagradost/cloudstream3/network/RequestsHelper.kt b/app/src/main/java/com/lagradost/cloudstream3/network/RequestsHelper.kt new file mode 100644 index 00000000..c961a117 --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/network/RequestsHelper.kt @@ -0,0 +1,68 @@ +package com.lagradost.cloudstream3.network + +import android.content.Context +import androidx.preference.PreferenceManager +import com.lagradost.cloudstream3.R +import com.lagradost.cloudstream3.USER_AGENT +import com.lagradost.nicehttp.Requests +import com.lagradost.nicehttp.getCookies +import com.lagradost.nicehttp.ignoreAllSSLErrors +import okhttp3.Cache +import okhttp3.Headers +import okhttp3.Headers.Companion.toHeaders +import okhttp3.OkHttpClient +import okhttp3.Request +import java.io.File +import java.util.concurrent.TimeUnit + + +fun Requests.initClient(context: Context): OkHttpClient { + val settingsManager = PreferenceManager.getDefaultSharedPreferences(context) + val dns = settingsManager.getInt(context.getString(R.string.dns_pref), 0) + baseClient = OkHttpClient.Builder() + .followRedirects(true) + .followSslRedirects(true) + .ignoreAllSSLErrors() + .cache( + // Note that you need to add a ResponseInterceptor to make this 100% active. + // The server response dictates if and when stuff should be cached. + Cache( + directory = File(context.cacheDir, "http_cache"), + maxSize = 50L * 1024L * 1024L // 50 MiB + ) + ).apply { + when (dns) { + 1 -> addGoogleDns() + 2 -> addCloudFlareDns() +// 3 -> addOpenDns() + 4 -> addAdGuardDns() + } + } + // Needs to be build as otherwise the other builders will change this object + .build() + return baseClient +} + +val Request.cookies: Map + get() { + return this.headers.getCookies("Cookie") + } + +private val DEFAULT_HEADERS = mapOf("user-agent" to USER_AGENT) + +/** + * Set headers > Set cookies > Default headers > Default Cookies + * TODO REMOVE AND REPLACE WITH NICEHTTP + */ +fun getHeaders( + headers: Map, + cookie: Map +): Headers { + val cookieMap = + if (cookie.isNotEmpty()) mapOf( + "Cookie" to cookie.entries.joinToString(" ") { + "${it.key}=${it.value};" + }) else mapOf() + val tempHeaders = (DEFAULT_HEADERS + headers + cookieMap) + return tempHeaders.toHeaders() +} \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/network/WebViewResolver.kt b/app/src/main/java/com/lagradost/cloudstream3/network/WebViewResolver.kt index 2b55f90d..e021bdbe 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/network/WebViewResolver.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/network/WebViewResolver.kt @@ -8,6 +8,7 @@ import com.lagradost.cloudstream3.USER_AGENT import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.utils.Coroutines.main +import com.lagradost.nicehttp.requestCreator import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking import okhttp3.Interceptor @@ -155,12 +156,12 @@ class WebViewResolver(val interceptUrl: Regex, val additionalUrls: List = request.method == "GET" -> app.get( webViewUrl, headers = request.requestHeaders - ).response.toWebResourceResponse() + ).okhttpResponse.toWebResourceResponse() request.method == "POST" -> app.post( webViewUrl, headers = request.requestHeaders - ).response.toWebResourceResponse() + ).okhttpResponse.toWebResourceResponse() else -> return@runBlocking super.shouldInterceptRequest( view, request @@ -206,28 +207,17 @@ class WebViewResolver(val interceptUrl: Regex, val additionalUrls: List = fun WebResourceRequest.toRequest(): Request { val webViewUrl = this.url.toString() - return when (this.method) { - "POST" -> postRequestCreator( - webViewUrl, - this.requestHeaders, - null, - emptyMap(), - emptyMap(), - emptyMap(), - 10, - TimeUnit.MINUTES - ) -// "GET", - else -> getRequestCreator( - webViewUrl, - this.requestHeaders, - null, - emptyMap(), - emptyMap(), - 10, - TimeUnit.MINUTES - ) - } + return requestCreator( + this.method, + webViewUrl, + this.requestHeaders, + null, + emptyMap(), + emptyMap(), + null, + 10, + TimeUnit.MINUTES + ) } fun Response.toWebResourceResponse(): WebResourceResponse { diff --git a/app/src/main/java/com/lagradost/cloudstream3/torrentproviders/NyaaProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/torrentproviders/NyaaProvider.kt index dbccd89a..2bd1aaa8 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/torrentproviders/NyaaProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/torrentproviders/NyaaProvider.kt @@ -26,7 +26,7 @@ class NyaaProvider : MainAPI() { if (tds.size < 2) continue val type = tds[0].select("> a").attr("title") val titleHeader = tds[1].select("> a").last() - val href = titleHeader.attr("href") + val href = titleHeader!!.attr("href") val title = titleHeader.text() if (title.contains("[Batch]") || !type.contains("Anime")) continue returnValues.add(TorrentSearchResponse(title, fixUrl(href), this.name, TvType.Torrent, null)) @@ -38,8 +38,8 @@ class NyaaProvider : MainAPI() { override suspend fun load(url: String): LoadResponse { val response = app.get(url).text val document = Jsoup.parse(response) - val title = document.selectFirst("h3.panel-title").text() - val description = document.selectFirst("div#torrent-description").text() + val title = document.selectFirst("h3.panel-title")!!.text() + val description = document.selectFirst("div#torrent-description")!!.text() val downloadLinks = document.select("div.panel-footer > a") val magnet = downloadLinks[1].attr("href") val torrent = downloadLinks[0].attr("href") diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsFragment.kt index 0876c974..f4eb11a5 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/SettingsFragment.kt @@ -33,6 +33,7 @@ import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.mvvm.normalSafeApiCall +import com.lagradost.cloudstream3.network.initClient import com.lagradost.cloudstream3.syncproviders.AccountManager import com.lagradost.cloudstream3.syncproviders.OAuth2API import com.lagradost.cloudstream3.syncproviders.OAuth2API.Companion.aniListApi diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/FillerEpisodeCheck.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/FillerEpisodeCheck.kt index d0fdd88b..911d58e7 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/FillerEpisodeCheck.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/FillerEpisodeCheck.kt @@ -84,8 +84,8 @@ object FillerEpisodeCheck { val documented = Jsoup.parse(result) ?: return null val hashMap = HashMap() documented.select("table.EpisodeList > tbody > tr").forEach { - val type = it.selectFirst("td.Type > span").text() == "Filler" - val episodeNumber = it.selectFirst("td.Number").text().toIntOrNull() + val type = it.selectFirst("td.Type > span")?.text() == "Filler" + val episodeNumber = it.selectFirst("td.Number")?.text()?.toIntOrNull() if (episodeNumber != null) { hashMap[episodeNumber] = type } diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/GlideApp.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/GlideApp.kt index 0fdfb922..e173b7a7 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/GlideApp.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/GlideApp.kt @@ -13,7 +13,8 @@ import com.bumptech.glide.module.AppGlideModule import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.signature.ObjectKey import com.lagradost.cloudstream3.network.DdosGuardKiller -import com.lagradost.cloudstream3.network.Requests +import com.lagradost.cloudstream3.network.initClient +import com.lagradost.nicehttp.Requests import java.io.InputStream @GlideModule diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/SyncUtil.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/SyncUtil.kt index 4f9e294e..b5a34b86 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/SyncUtil.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/SyncUtil.kt @@ -79,7 +79,7 @@ object SyncUtil { suspend fun getUrlsFromId(id: String, type: String = "anilist") : List { val url = "https://raw.githubusercontent.com/MALSync/MAL-Sync-Backup/master/data/$type/anime/$id.json" - val response = app.get(url, cacheTime = 1, cacheUnit = TimeUnit.DAYS).mapped() + val response = app.get(url, cacheTime = 1, cacheUnit = TimeUnit.DAYS).parsed() val pages = response.pages ?: return emptyList() return pages.gogoanime.values.union(pages.nineanime.values).union(pages.twistmoe.values).mapNotNull { it.url } }