This commit is contained in:
parent
b41c963dda
commit
f19b930678
6 changed files with 223 additions and 65 deletions
|
@ -1,7 +1,7 @@
|
||||||
ext {
|
ext {
|
||||||
extName = 'Anitube'
|
extName = 'Anitube'
|
||||||
extClass = '.Anitube'
|
extClass = '.Anitube'
|
||||||
extVersionCode = 16
|
extVersionCode = 17
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
apply from: "$rootDir/common.gradle"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package eu.kanade.tachiyomi.animeextension.pt.anitube
|
package eu.kanade.tachiyomi.animeextension.pt.anitube
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import androidx.preference.EditTextPreference
|
||||||
import androidx.preference.ListPreference
|
import androidx.preference.ListPreference
|
||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
import eu.kanade.tachiyomi.animeextension.pt.anitube.extractors.AnitubeExtractor
|
import eu.kanade.tachiyomi.animeextension.pt.anitube.extractors.AnitubeExtractor
|
||||||
|
@ -188,7 +189,7 @@ class Anitube : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================ Video Links =============================
|
// ============================ Video Links =============================
|
||||||
private val extractor by lazy { AnitubeExtractor(headers, client) }
|
private val extractor by lazy { AnitubeExtractor(headers, client, preferences) }
|
||||||
|
|
||||||
override fun videoListParse(response: Response) = extractor.getVideoList(response)
|
override fun videoListParse(response: Response) = extractor.getVideoList(response)
|
||||||
override fun videoListSelector() = throw UnsupportedOperationException()
|
override fun videoListSelector() = throw UnsupportedOperationException()
|
||||||
|
@ -210,7 +211,22 @@ class Anitube : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||||
val entry = entryValues[index] as String
|
val entry = entryValues[index] as String
|
||||||
preferences.edit().putString(key, entry).commit()
|
preferences.edit().putString(key, entry).commit()
|
||||||
}
|
}
|
||||||
}.let(screen::addPreference)
|
}.also(screen::addPreference)
|
||||||
|
|
||||||
|
// Auth Code
|
||||||
|
EditTextPreference(screen.context).apply {
|
||||||
|
key = PREF_AUTHCODE_KEY
|
||||||
|
title = "Auth Code"
|
||||||
|
setDefaultValue(PREF_AUTHCODE_DEFAULT)
|
||||||
|
summary = PREF_AUTHCODE_SUMMARY
|
||||||
|
|
||||||
|
setOnPreferenceChangeListener { _, newValue ->
|
||||||
|
runCatching {
|
||||||
|
val value = (newValue as String).trim().ifBlank { PREF_AUTHCODE_DEFAULT }
|
||||||
|
preferences.edit().putString(key, value).commit()
|
||||||
|
}.getOrDefault(false)
|
||||||
|
}
|
||||||
|
}.also(screen::addPreference)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================= Utilities ==============================
|
// ============================= Utilities ==============================
|
||||||
|
@ -264,6 +280,9 @@ class Anitube : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||||
|
|
||||||
private const val ACCEPT_LANGUAGE = "pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7"
|
private const val ACCEPT_LANGUAGE = "pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7"
|
||||||
|
|
||||||
|
private const val PREF_AUTHCODE_KEY = "authcode"
|
||||||
|
private const val PREF_AUTHCODE_SUMMARY = "Código de Autenticação"
|
||||||
|
private const val PREF_AUTHCODE_DEFAULT = ""
|
||||||
private const val PREF_QUALITY_KEY = "preferred_quality"
|
private const val PREF_QUALITY_KEY = "preferred_quality"
|
||||||
private const val PREF_QUALITY_TITLE = "Qualidade preferida"
|
private const val PREF_QUALITY_TITLE = "Qualidade preferida"
|
||||||
private const val PREF_QUALITY_DEFAULT = "HD"
|
private const val PREF_QUALITY_DEFAULT = "HD"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package eu.kanade.tachiyomi.animeextension.pt.anitube.extractors
|
package eu.kanade.tachiyomi.animeextension.pt.anitube.extractors
|
||||||
|
|
||||||
|
import android.content.SharedPreferences
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import eu.kanade.tachiyomi.animesource.model.Video
|
import eu.kanade.tachiyomi.animesource.model.Video
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
|
@ -9,35 +10,83 @@ import okhttp3.FormBody
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import java.util.Calendar
|
|
||||||
import java.util.Date
|
|
||||||
|
|
||||||
class AnitubeExtractor(private val headers: Headers, private val client: OkHttpClient) {
|
class AnitubeExtractor(
|
||||||
|
private val headers: Headers,
|
||||||
|
private val client: OkHttpClient,
|
||||||
|
private val preferences: SharedPreferences,
|
||||||
|
) {
|
||||||
|
|
||||||
private var authCodeCache: String = ""
|
private fun getAdsUrl(
|
||||||
private var authCodeDate: Date = Calendar.getInstance().getTime()
|
serverUrl: String,
|
||||||
|
thumbUrl: String,
|
||||||
private fun getAuthCode(serverUrl: String, thumbUrl: String): String {
|
link: String,
|
||||||
val duration = Calendar.getInstance().getTime().time - authCodeDate.time
|
linkHeaders: Headers,
|
||||||
|
): String {
|
||||||
// check the authCode in cache for 1 hour
|
|
||||||
if (authCodeCache.isNotBlank() && duration < 60 * 60 * 1000) {
|
|
||||||
Log.d("AnitubeExtractor", "Using authCode from cache")
|
|
||||||
return authCodeCache
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.d("AnitubeExtractor", "Fetching new authCode")
|
|
||||||
val videoName = serverUrl.split('/').last()
|
val videoName = serverUrl.split('/').last()
|
||||||
|
|
||||||
|
val docLink = client.newCall(GET(link, headers = linkHeaders)).execute().asJsoup()
|
||||||
|
|
||||||
|
val refresh = docLink.selectFirst("meta[http-equiv=refresh]")?.attr("content")
|
||||||
|
|
||||||
|
if (!refresh.isNullOrBlank()) {
|
||||||
|
val newLink = refresh.substringAfter("=")
|
||||||
|
val newHeaders = linkHeaders.newBuilder().set("Referer", link).build()
|
||||||
|
Log.d("AnitubeExtractor", "Following link redirection to $newLink")
|
||||||
|
|
||||||
|
return getAdsUrl(serverUrl, thumbUrl, newLink, newHeaders)
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d("AnitubeExtractor", "Fetching ADS URL")
|
||||||
|
|
||||||
|
val newHeaders = linkHeaders.newBuilder().set("Referer", link).build()
|
||||||
|
|
||||||
|
try {
|
||||||
val adsUrl =
|
val adsUrl =
|
||||||
client.newCall(GET("$SITE_URL/playerricas.php?name=apphd/$videoName&img=$thumbUrl&url=$serverUrl"))
|
client.newCall(
|
||||||
|
GET(
|
||||||
|
"$SITE_URL/playerricas.php?name=apphd/$videoName&img=$thumbUrl&url=$serverUrl",
|
||||||
|
headers = newHeaders,
|
||||||
|
),
|
||||||
|
)
|
||||||
.execute()
|
.execute()
|
||||||
.body.string()
|
.body.string()
|
||||||
.substringAfter("ADS_URL")
|
.substringAfter("ADS_URL")
|
||||||
.substringAfter('"')
|
.substringAfter('"')
|
||||||
.substringBefore('"')
|
.substringBefore('"')
|
||||||
|
|
||||||
|
if (adsUrl.startsWith("http")) {
|
||||||
Log.d("AnitubeExtractor", "ADS URL: $adsUrl")
|
Log.d("AnitubeExtractor", "ADS URL: $adsUrl")
|
||||||
|
return adsUrl
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try default url
|
||||||
|
Log.e("AnitubeExtractor", "Failed to get the ADS URL, trying the default")
|
||||||
|
return "https://www.popads.net/js/adblock.js"
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getAuthCode(serverUrl: String, thumbUrl: String, link: String): String {
|
||||||
|
var authCode = preferences.getString(PREF_AUTHCODE_KEY, "")!!
|
||||||
|
|
||||||
|
if (authCode.isNotBlank()) {
|
||||||
|
Log.d("AnitubeExtractor", "AuthCode found in preferences")
|
||||||
|
|
||||||
|
val isSuccessful = client.newCall(GET("${serverUrl}$authCode", headers = headers))
|
||||||
|
.execute().isSuccessful
|
||||||
|
|
||||||
|
if (isSuccessful) {
|
||||||
|
Log.d("AnitubeExtractor", "AuthCode is OK")
|
||||||
|
return authCode
|
||||||
|
}
|
||||||
|
Log.d("AnitubeExtractor", "AuthCode is invalid")
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d("AnitubeExtractor", "Fetching new authCode")
|
||||||
|
|
||||||
|
val adsUrl = getAdsUrl(serverUrl, thumbUrl, link, headers)
|
||||||
|
|
||||||
val adsContent = client.newCall(GET(adsUrl)).execute().body.string()
|
val adsContent = client.newCall(GET(adsUrl)).execute().body.string()
|
||||||
|
|
||||||
val body = FormBody.Builder()
|
val body = FormBody.Builder()
|
||||||
|
@ -66,11 +115,15 @@ class AnitubeExtractor(private val headers: Headers, private val client: OkHttpC
|
||||||
.substringBefore('"')
|
.substringBefore('"')
|
||||||
|
|
||||||
if (publicidade.isBlank()) {
|
if (publicidade.isBlank()) {
|
||||||
Log.e("AnitubeExtractor", "Failed to fetch \"publicidade\" code")
|
Log.e(
|
||||||
return ""
|
"AnitubeExtractor",
|
||||||
|
"Failed to fetch \"publicidade\" code, the current response: $publicidade",
|
||||||
|
)
|
||||||
|
|
||||||
|
throw Exception("Por favor, abra o vídeo uma vez no navegador para liberar o IP")
|
||||||
}
|
}
|
||||||
|
|
||||||
authCodeCache =
|
authCode =
|
||||||
client.newCall(
|
client.newCall(
|
||||||
GET(
|
GET(
|
||||||
"$ADS_URL/?token=$publicidade",
|
"$ADS_URL/?token=$publicidade",
|
||||||
|
@ -83,13 +136,17 @@ class AnitubeExtractor(private val headers: Headers, private val client: OkHttpC
|
||||||
.substringAfter('"')
|
.substringAfter('"')
|
||||||
.substringBefore('"')
|
.substringBefore('"')
|
||||||
|
|
||||||
if (authCodeCache.isBlank()) {
|
if (authCode.startsWith("?")) {
|
||||||
Log.e("AnitubeExtractor", "Failed to fetch auth code")
|
|
||||||
} else {
|
|
||||||
Log.d("AnitubeExtractor", "Auth code fetched successfully")
|
Log.d("AnitubeExtractor", "Auth code fetched successfully")
|
||||||
|
preferences.edit().putString(PREF_AUTHCODE_KEY, authCode).commit()
|
||||||
|
} else {
|
||||||
|
Log.e(
|
||||||
|
"AnitubeExtractor",
|
||||||
|
"Failed to fetch auth code, the current response: $authCode",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return authCodeCache
|
return authCode
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getVideoList(response: Response): List<Video> {
|
fun getVideoList(response: Response): List<Video> {
|
||||||
|
@ -110,7 +167,9 @@ class AnitubeExtractor(private val headers: Headers, private val client: OkHttpC
|
||||||
}
|
}
|
||||||
} + listOf("appfullhd")
|
} + listOf("appfullhd")
|
||||||
|
|
||||||
val authCode = getAuthCode(serverUrl, thumbUrl)
|
val firstLink = doc.selectFirst("div.video_container > a, div.playerContainer > a")!!.attr("href")
|
||||||
|
|
||||||
|
val authCode = getAuthCode(serverUrl, thumbUrl, firstLink)
|
||||||
|
|
||||||
return qualities.mapIndexed { index, quality ->
|
return qualities.mapIndexed { index, quality ->
|
||||||
val path = paths[index]
|
val path = paths[index]
|
||||||
|
@ -120,7 +179,8 @@ class AnitubeExtractor(private val headers: Headers, private val client: OkHttpC
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val ADS_URL = "https://ads.anitube.vip"
|
private const val PREF_AUTHCODE_KEY = "authcode"
|
||||||
val SITE_URL = "https://www.anitube.vip"
|
private const val ADS_URL = "https://ads.anitube.vip"
|
||||||
|
private const val SITE_URL = "https://www.anitube.vip"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
ext {
|
ext {
|
||||||
extName = 'Hinata Soul'
|
extName = 'Hinata Soul'
|
||||||
extClass = '.HinataSoul'
|
extClass = '.HinataSoul'
|
||||||
extVersionCode = 6
|
extVersionCode = 7
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
apply from: "$rootDir/common.gradle"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package eu.kanade.tachiyomi.animeextension.pt.hinatasoul
|
package eu.kanade.tachiyomi.animeextension.pt.hinatasoul
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import androidx.preference.EditTextPreference
|
||||||
import androidx.preference.ListPreference
|
import androidx.preference.ListPreference
|
||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
import eu.kanade.tachiyomi.animeextension.pt.hinatasoul.extractors.HinataSoulExtractor
|
import eu.kanade.tachiyomi.animeextension.pt.hinatasoul.extractors.HinataSoulExtractor
|
||||||
|
@ -162,7 +163,7 @@ class HinataSoul : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================ Video Links =============================
|
// ============================ Video Links =============================
|
||||||
private val extractor by lazy { HinataSoulExtractor(headers, client) }
|
private val extractor by lazy { HinataSoulExtractor(headers, client, preferences) }
|
||||||
|
|
||||||
override fun videoListParse(response: Response) = extractor.getVideoList(response)
|
override fun videoListParse(response: Response) = extractor.getVideoList(response)
|
||||||
|
|
||||||
|
@ -186,6 +187,21 @@ class HinataSoul : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||||
preferences.edit().putString(key, entry).commit()
|
preferences.edit().putString(key, entry).commit()
|
||||||
}
|
}
|
||||||
}.also(screen::addPreference)
|
}.also(screen::addPreference)
|
||||||
|
|
||||||
|
// Auth Code
|
||||||
|
EditTextPreference(screen.context).apply {
|
||||||
|
key = PREF_AUTHCODE_KEY
|
||||||
|
title = "Auth Code"
|
||||||
|
setDefaultValue(PREF_AUTHCODE_DEFAULT)
|
||||||
|
summary = PREF_AUTHCODE_SUMMARY
|
||||||
|
|
||||||
|
setOnPreferenceChangeListener { _, newValue ->
|
||||||
|
runCatching {
|
||||||
|
val value = (newValue as String).trim().ifBlank { PREF_AUTHCODE_DEFAULT }
|
||||||
|
preferences.edit().putString(key, value).commit()
|
||||||
|
}.getOrDefault(false)
|
||||||
|
}
|
||||||
|
}.also(screen::addPreference)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================= Utilities ==============================
|
// ============================= Utilities ==============================
|
||||||
|
@ -241,6 +257,9 @@ class HinataSoul : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
||||||
|
|
||||||
const val PREFIX_SEARCH = "slug:"
|
const val PREFIX_SEARCH = "slug:"
|
||||||
|
|
||||||
|
private const val PREF_AUTHCODE_KEY = "authcode"
|
||||||
|
private const val PREF_AUTHCODE_SUMMARY = "Código de Autenticação"
|
||||||
|
private const val PREF_AUTHCODE_DEFAULT = ""
|
||||||
private const val PREF_QUALITY_KEY = "preferred_quality"
|
private const val PREF_QUALITY_KEY = "preferred_quality"
|
||||||
private const val PREF_QUALITY_TITLE = "Qualidade preferida"
|
private const val PREF_QUALITY_TITLE = "Qualidade preferida"
|
||||||
private const val PREF_QUALITY_DEFAULT = "FULLHD"
|
private const val PREF_QUALITY_DEFAULT = "FULLHD"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package eu.kanade.tachiyomi.animeextension.pt.hinatasoul.extractors
|
package eu.kanade.tachiyomi.animeextension.pt.hinatasoul.extractors
|
||||||
|
|
||||||
|
import android.content.SharedPreferences
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import eu.kanade.tachiyomi.animesource.model.Video
|
import eu.kanade.tachiyomi.animesource.model.Video
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
|
@ -9,35 +10,83 @@ import okhttp3.FormBody
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import java.util.Calendar
|
|
||||||
import java.util.Date
|
|
||||||
|
|
||||||
class HinataSoulExtractor(private val headers: Headers, private val client: OkHttpClient) {
|
class HinataSoulExtractor(
|
||||||
|
private val headers: Headers,
|
||||||
|
private val client: OkHttpClient,
|
||||||
|
private val preferences: SharedPreferences,
|
||||||
|
) {
|
||||||
|
|
||||||
private var authCodeCache: String = ""
|
private fun getAdsUrl(
|
||||||
private var authCodeDate: Date = Calendar.getInstance().getTime()
|
serverUrl: String,
|
||||||
|
thumbUrl: String,
|
||||||
private fun getAuthCode(serverUrl: String, thumbUrl: String): String {
|
link: String,
|
||||||
val duration = Calendar.getInstance().getTime().time - authCodeDate.time
|
linkHeaders: Headers,
|
||||||
|
): String {
|
||||||
// check the authCode in cache for 1 hour
|
|
||||||
if (authCodeCache.isNotBlank() && duration < 60 * 60 * 1000) {
|
|
||||||
Log.d("HinataSoulExtractor", "Using authCode from cache")
|
|
||||||
return authCodeCache
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.d("HinataSoulExtractor", "Fetching new authCode")
|
|
||||||
val videoName = serverUrl.split('/').last()
|
val videoName = serverUrl.split('/').last()
|
||||||
|
|
||||||
|
val docLink = client.newCall(GET(link, headers = linkHeaders)).execute().asJsoup()
|
||||||
|
|
||||||
|
val refresh = docLink.selectFirst("meta[http-equiv=refresh]")?.attr("content")
|
||||||
|
|
||||||
|
if (!refresh.isNullOrBlank()) {
|
||||||
|
val newLink = refresh.substringAfter("=")
|
||||||
|
val newHeaders = linkHeaders.newBuilder().set("Referer", link).build()
|
||||||
|
Log.d("HinataSoulExtractor", "Following link redirection to $newLink")
|
||||||
|
|
||||||
|
return getAdsUrl(serverUrl, thumbUrl, newLink, newHeaders)
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d("HinataSoulExtractor", "Fetching ADS URL")
|
||||||
|
|
||||||
|
val newHeaders = linkHeaders.newBuilder().set("Referer", link).build()
|
||||||
|
|
||||||
|
try {
|
||||||
val adsUrl =
|
val adsUrl =
|
||||||
client.newCall(GET("$SITE_URL/playerricas.php?name=apphd/$videoName&img=$thumbUrl&url=$serverUrl"))
|
client.newCall(
|
||||||
|
GET(
|
||||||
|
"$SITE_URL/playerricas.php?name=apphd/$videoName&img=$thumbUrl&url=$serverUrl",
|
||||||
|
headers = newHeaders,
|
||||||
|
),
|
||||||
|
)
|
||||||
.execute()
|
.execute()
|
||||||
.body.string()
|
.body.string()
|
||||||
.substringAfter("ADS_URL")
|
.substringAfter("ADS_URL")
|
||||||
.substringAfter('"')
|
.substringAfter('"')
|
||||||
.substringBefore('"')
|
.substringBefore('"')
|
||||||
|
|
||||||
|
if (adsUrl.startsWith("http")) {
|
||||||
Log.d("HinataSoulExtractor", "ADS URL: $adsUrl")
|
Log.d("HinataSoulExtractor", "ADS URL: $adsUrl")
|
||||||
|
return adsUrl
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try default url
|
||||||
|
Log.e("HinataSoulExtractor", "Failed to get the ADS URL, trying the default")
|
||||||
|
return "https://www.popads.net/js/adblock.js"
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getAuthCode(serverUrl: String, thumbUrl: String, link: String): String {
|
||||||
|
var authCode = preferences.getString(PREF_AUTHCODE_KEY, "")!!
|
||||||
|
|
||||||
|
if (authCode.isNotBlank()) {
|
||||||
|
Log.d("HinataSoulExtractor", "AuthCode found in preferences")
|
||||||
|
|
||||||
|
val isSuccessful = client.newCall(GET("${serverUrl}$authCode", headers = headers))
|
||||||
|
.execute().isSuccessful
|
||||||
|
|
||||||
|
if (isSuccessful) {
|
||||||
|
Log.d("HinataSoulExtractor", "AuthCode is OK")
|
||||||
|
return authCode
|
||||||
|
}
|
||||||
|
Log.d("HinataSoulExtractor", "AuthCode is invalid")
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d("HinataSoulExtractor", "Fetching new authCode")
|
||||||
|
|
||||||
|
val adsUrl = getAdsUrl(serverUrl, thumbUrl, link, headers)
|
||||||
|
|
||||||
val adsContent = client.newCall(GET(adsUrl)).execute().body.string()
|
val adsContent = client.newCall(GET(adsUrl)).execute().body.string()
|
||||||
|
|
||||||
val body = FormBody.Builder()
|
val body = FormBody.Builder()
|
||||||
|
@ -66,11 +115,15 @@ class HinataSoulExtractor(private val headers: Headers, private val client: OkHt
|
||||||
.substringBefore('"')
|
.substringBefore('"')
|
||||||
|
|
||||||
if (publicidade.isBlank()) {
|
if (publicidade.isBlank()) {
|
||||||
Log.e("HinataSoulExtractor", "Failed to fetch \"publicidade\" code")
|
Log.e(
|
||||||
return ""
|
"HinataSoulExtractor",
|
||||||
|
"Failed to fetch \"publicidade\" code, the current response: $publicidade",
|
||||||
|
)
|
||||||
|
|
||||||
|
throw Exception("Por favor, abra o vídeo uma vez no navegador para liberar o IP")
|
||||||
}
|
}
|
||||||
|
|
||||||
authCodeCache =
|
authCode =
|
||||||
client.newCall(
|
client.newCall(
|
||||||
GET(
|
GET(
|
||||||
"$ADS_URL/?token=$publicidade",
|
"$ADS_URL/?token=$publicidade",
|
||||||
|
@ -83,13 +136,17 @@ class HinataSoulExtractor(private val headers: Headers, private val client: OkHt
|
||||||
.substringAfter('"')
|
.substringAfter('"')
|
||||||
.substringBefore('"')
|
.substringBefore('"')
|
||||||
|
|
||||||
if (authCodeCache.isBlank()) {
|
if (authCode.startsWith("?")) {
|
||||||
Log.e("HinataSoulExtractor", "Failed to fetch auth code")
|
|
||||||
} else {
|
|
||||||
Log.d("HinataSoulExtractor", "Auth code fetched successfully")
|
Log.d("HinataSoulExtractor", "Auth code fetched successfully")
|
||||||
|
preferences.edit().putString(PREF_AUTHCODE_KEY, authCode).commit()
|
||||||
|
} else {
|
||||||
|
Log.e(
|
||||||
|
"HinataSoulExtractor",
|
||||||
|
"Failed to fetch auth code, the current response: $authCode",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return authCodeCache
|
return authCode
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getVideoList(response: Response): List<Video> {
|
fun getVideoList(response: Response): List<Video> {
|
||||||
|
@ -110,7 +167,9 @@ class HinataSoulExtractor(private val headers: Headers, private val client: OkHt
|
||||||
}
|
}
|
||||||
} + listOf("appfullhd")
|
} + listOf("appfullhd")
|
||||||
|
|
||||||
val authCode = getAuthCode(serverUrl, thumbUrl)
|
val firstLink = doc.selectFirst("div.video_container > a, div.playerContainer > a")!!.attr("href")
|
||||||
|
|
||||||
|
val authCode = getAuthCode(serverUrl, thumbUrl, firstLink)
|
||||||
|
|
||||||
return qualities.mapIndexed { index, quality ->
|
return qualities.mapIndexed { index, quality ->
|
||||||
val path = paths[index]
|
val path = paths[index]
|
||||||
|
@ -120,7 +179,8 @@ class HinataSoulExtractor(private val headers: Headers, private val client: OkHt
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val ADS_URL = "https://ads.anitube.vip"
|
private const val PREF_AUTHCODE_KEY = "authcode"
|
||||||
val SITE_URL = "https://www.anitube.vip"
|
private const val ADS_URL = "https://ads.anitube.vip"
|
||||||
|
private const val SITE_URL = "https://www.anitube.vip"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue