forked from recloudstream/cloudstream
fixed base64 for testing and AllMoviesForYouProvider dood extractor
This commit is contained in:
parent
bf18e657f6
commit
94f0f30580
5 changed files with 51 additions and 22 deletions
|
@ -198,6 +198,15 @@ abstract class MainAPI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Might need a different implementation for desktop*/
|
||||||
|
fun base64Decode(string: String): String {
|
||||||
|
return try {
|
||||||
|
String(android.util.Base64.decode(string, android.util.Base64.DEFAULT), Charsets.ISO_8859_1)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
String(Base64.getDecoder().decode(string))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ErrorLoadingException(message: String? = null) : Exception(message)
|
class ErrorLoadingException(message: String? = null) : Exception(message)
|
||||||
|
|
||||||
fun parseRating(ratingString: String?): Int? {
|
fun parseRating(ratingString: String?): Int? {
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
package com.lagradost.cloudstream3.animeproviders
|
package com.lagradost.cloudstream3.animeproviders
|
||||||
|
|
||||||
import com.lagradost.cloudstream3.*
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
import com.fasterxml.jackson.module.kotlin.readValue
|
import com.fasterxml.jackson.module.kotlin.readValue
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.*
|
||||||
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
||||||
import com.lagradost.cloudstream3.network.*
|
import com.lagradost.cloudstream3.network.*
|
||||||
|
import com.lagradost.cloudstream3.utils.ExtractorLink
|
||||||
import com.lagradost.cloudstream3.utils.getQualityFromName
|
import com.lagradost.cloudstream3.utils.getQualityFromName
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.ArrayList
|
|
||||||
|
|
||||||
class AnimePaheProvider : MainAPI() {
|
class AnimePaheProvider : MainAPI() {
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -434,7 +433,7 @@ class AnimePaheProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var returnValue = String(encodedUri.joinToString("").toByteArray(), Charsets.UTF_8)
|
var returnValue = String(encodedUri.joinToString("").toByteArray(), Charsets.UTF_8)
|
||||||
returnValue = String(android.util.Base64.decode(returnValue, android.util.Base64.DEFAULT), Charsets.ISO_8859_1)
|
returnValue = base64Decode(returnValue)
|
||||||
return returnValue.slice(16..returnValue.length - 17)
|
return returnValue.slice(16..returnValue.length - 17)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,7 @@ import com.lagradost.cloudstream3.*
|
||||||
import com.lagradost.cloudstream3.network.get
|
import com.lagradost.cloudstream3.network.get
|
||||||
import com.lagradost.cloudstream3.network.text
|
import com.lagradost.cloudstream3.network.text
|
||||||
import com.lagradost.cloudstream3.network.url
|
import com.lagradost.cloudstream3.network.url
|
||||||
import com.lagradost.cloudstream3.utils.ExtractorLink
|
import com.lagradost.cloudstream3.utils.*
|
||||||
import com.lagradost.cloudstream3.utils.Qualities
|
|
||||||
import com.lagradost.cloudstream3.utils.getPostForm
|
|
||||||
import com.lagradost.cloudstream3.utils.loadExtractor
|
|
||||||
import okio.Buffer
|
import okio.Buffer
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
|
@ -63,7 +60,8 @@ class AllMoviesForYouProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
document.select("div.OptionBx")?.forEach { element ->
|
document.select("div.OptionBx")?.forEach { element ->
|
||||||
val baseElement = element.selectFirst("> a.Button")
|
val baseElement = element.selectFirst("> a.Button")
|
||||||
if (element.selectFirst("> p.AAIco-dns")?.text() == "Streamhub") {
|
val elementText = element.selectFirst("> p.AAIco-dns")?.text()
|
||||||
|
if (elementText == "Streamhub" || elementText == "Dood") {
|
||||||
baseElement?.attr("href")?.let { href ->
|
baseElement?.attr("href")?.let { href ->
|
||||||
list.add(href)
|
list.add(href)
|
||||||
}
|
}
|
||||||
|
@ -108,7 +106,7 @@ class AllMoviesForYouProvider : MainAPI() {
|
||||||
if (episodes.isNotEmpty()) {
|
if (episodes.isNotEmpty()) {
|
||||||
episodes.forEach { episode ->
|
episodes.forEach { episode ->
|
||||||
val epNum = episode.selectFirst("> td > span.Num")?.text()?.toIntOrNull()
|
val epNum = episode.selectFirst("> td > span.Num")?.text()?.toIntOrNull()
|
||||||
val poster = episode.selectFirst("> td.MvTbImg > a > img")?.attr("src")
|
val poster = episode.selectFirst("> td.MvTbImg > a > img")?.attr("data-src")
|
||||||
val aName = episode.selectFirst("> td.MvTbTtl > a")
|
val aName = episode.selectFirst("> td.MvTbTtl > a")
|
||||||
val name = aName.text()
|
val name = aName.text()
|
||||||
val href = aName.attr("href")
|
val href = aName.attr("href")
|
||||||
|
@ -165,6 +163,7 @@ class AllMoviesForYouProvider : MainAPI() {
|
||||||
subtitleCallback: (SubtitleFile) -> Unit,
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
callback: (ExtractorLink) -> Unit
|
callback: (ExtractorLink) -> Unit
|
||||||
): Boolean {
|
): Boolean {
|
||||||
|
if (data == "about:blank") return false
|
||||||
if (data.startsWith("$mainUrl/episode/")) {
|
if (data.startsWith("$mainUrl/episode/")) {
|
||||||
val response = get(data).text
|
val response = get(data).text
|
||||||
getLink(Jsoup.parse(response))?.let { links ->
|
getLink(Jsoup.parse(response))?.let { links ->
|
||||||
|
@ -176,10 +175,11 @@ class AllMoviesForYouProvider : MainAPI() {
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
} else if (data.startsWith(mainUrl) && data != mainUrl) {
|
} else if (data.startsWith(mainUrl) && data != mainUrl) {
|
||||||
val realDataUrl = URLDecoder.decode(data, "application/x-www-form-urlencoded")
|
val realDataUrl = URLDecoder.decode(data, "UTF-8")
|
||||||
if (data.contains("trdownload")) {
|
if (data.contains("trdownload")) {
|
||||||
val request = get(data)
|
val request = get(data)
|
||||||
if (request.url.startsWith("https://streamhub.to/d/")) {
|
val requestUrl = request.url
|
||||||
|
if (requestUrl.startsWith("https://streamhub.to/d/")) {
|
||||||
val buffer = Buffer()
|
val buffer = Buffer()
|
||||||
val source = request.body?.source()
|
val source = request.body?.source()
|
||||||
var html = ""
|
var html = ""
|
||||||
|
@ -191,13 +191,22 @@ class AllMoviesForYouProvider : MainAPI() {
|
||||||
tries += 1
|
tries += 1
|
||||||
html += buffer.readUtf8()
|
html += buffer.readUtf8()
|
||||||
}
|
}
|
||||||
getPostForm(request.url,html)?.let { form ->
|
getPostForm(request.url, html)?.let { form ->
|
||||||
val postDocument = Jsoup.parse(form)
|
val postDocument = Jsoup.parse(form)
|
||||||
|
|
||||||
postDocument.selectFirst("a.downloadbtn")?.attr("href")?.let { url ->
|
postDocument.selectFirst("a.downloadbtn")?.attr("href")?.let { url ->
|
||||||
callback(ExtractorLink(this.name, this.name, url, mainUrl, Qualities.Unknown.value))
|
callback(ExtractorLink(this.name, this.name, url, mainUrl, Qualities.Unknown.value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (requestUrl.startsWith("https://dood")) {
|
||||||
|
for (extractor in extractorApis) {
|
||||||
|
if (requestUrl.startsWith(extractor.mainUrl)) {
|
||||||
|
extractor.getSafeUrl(requestUrl)?.forEach { link ->
|
||||||
|
callback(link)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
callback(ExtractorLink(this.name, this.name, realDataUrl, mainUrl, Qualities.Unknown.value))
|
callback(ExtractorLink(this.name, this.name, realDataUrl, mainUrl, Qualities.Unknown.value))
|
||||||
}
|
}
|
||||||
|
|
|
@ -264,7 +264,7 @@ class ThenosProvider : MainAPI() {
|
||||||
val isM3u8 = source.type != "video/mp4"
|
val isM3u8 = source.type != "video/mp4"
|
||||||
val token = get("https://token.noss.workers.dev/").text
|
val token = get("https://token.noss.workers.dev/").text
|
||||||
val authorization =
|
val authorization =
|
||||||
String(android.util.Base64.decode(token, android.util.Base64.DEFAULT), Charsets.ISO_8859_1)
|
base64Decode(token)
|
||||||
|
|
||||||
callback.invoke(
|
callback.invoke(
|
||||||
ExtractorLink(
|
ExtractorLink(
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.lagradost.cloudstream3
|
package com.lagradost.cloudstream3
|
||||||
|
|
||||||
|
import com.lagradost.cloudstream3.movieproviders.ThenosProvider
|
||||||
import com.lagradost.cloudstream3.mvvm.logError
|
import com.lagradost.cloudstream3.mvvm.logError
|
||||||
import com.lagradost.cloudstream3.utils.Qualities
|
import com.lagradost.cloudstream3.utils.Qualities
|
||||||
import com.lagradost.cloudstream3.utils.SubtitleHelper
|
import com.lagradost.cloudstream3.utils.SubtitleHelper
|
||||||
|
@ -39,7 +40,7 @@ class ProviderTests {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun test_single_provider(api: MainAPI) {
|
private fun testSingleProviderApi(api: MainAPI) : Boolean {
|
||||||
val searchQueries = listOf("over", "iron", "guy")
|
val searchQueries = listOf("over", "iron", "guy")
|
||||||
var correctResponses = 0
|
var correctResponses = 0
|
||||||
var searchResult: List<SearchResponse>? = null
|
var searchResult: List<SearchResponse>? = null
|
||||||
|
@ -62,8 +63,8 @@ class ProviderTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (correctResponses == 0 || searchResult == null) {
|
if (correctResponses == 0 || searchResult == null) {
|
||||||
println("Api ${api.name} did not return any valid search responses")
|
System.err.println("Api ${api.name} did not return any valid search responses")
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -119,16 +120,18 @@ class ProviderTests {
|
||||||
Assert.fail("Provider has not implemented .load")
|
Assert.fail("Provider has not implemented .load")
|
||||||
}
|
}
|
||||||
logError(e)
|
logError(e)
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun providers_exist() {
|
fun providersExist() {
|
||||||
Assert.assertTrue(getAllProviders().isNotEmpty())
|
Assert.assertTrue(getAllProviders().isNotEmpty())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun provider_correct_data() {
|
fun providerCorrectData() {
|
||||||
val isoNames = SubtitleHelper.languages.map { it.ISO_639_1 }
|
val isoNames = SubtitleHelper.languages.map { it.ISO_639_1 }
|
||||||
Assert.assertFalse("ISO does not contain any languages", isoNames.isNullOrEmpty())
|
Assert.assertFalse("ISO does not contain any languages", isoNames.isNullOrEmpty())
|
||||||
for (api in getAllProviders()) {
|
for (api in getAllProviders()) {
|
||||||
|
@ -140,7 +143,7 @@ class ProviderTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun provider_correct_homepage() {
|
fun providerCorrectHomepage() {
|
||||||
for (api in getAllProviders()) {
|
for (api in getAllProviders()) {
|
||||||
if (api.hasMainPage) {
|
if (api.hasMainPage) {
|
||||||
try {
|
try {
|
||||||
|
@ -167,12 +170,21 @@ class ProviderTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun provider_correct() {
|
fun testSingleProvider() {
|
||||||
|
testSingleProviderApi(ThenosProvider())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun providerCorrect() {
|
||||||
val providers = getAllProviders()
|
val providers = getAllProviders()
|
||||||
for ((index, api) in providers.withIndex()) {
|
for ((index, api) in providers.withIndex()) {
|
||||||
try {
|
try {
|
||||||
println("Trying $api (${index + 1}/${providers.size})")
|
println("Trying $api (${index + 1}/${providers.size})")
|
||||||
test_single_provider(api)
|
if(testSingleProviderApi(api)) {
|
||||||
|
println("Success $api (${index + 1}/${providers.size})")
|
||||||
|
} else {
|
||||||
|
System.err.println("Error $api (${index + 1}/${providers.size})")
|
||||||
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
logError(e)
|
logError(e)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue