minor crash fixes + suspended stuff

This commit is contained in:
reduplicated 2022-08-20 19:39:04 +02:00
parent cb11cd13e6
commit 051ca7a68d
8 changed files with 99 additions and 111 deletions

View file

@ -40,10 +40,7 @@ class DownloaderTestImpl private constructor(builder: OkHttpClient.Builder) : Do
throw ReCaptchaException("reCaptcha Challenge requested", url)
}
val body = response.body
var responseBodyToReturn: String? = null
if (body != null) {
responseBodyToReturn = body.string()
}
val responseBodyToReturn: String = body.string()
val latestUrl = response.request.url.toString()
return Response(
response.code, response.message, response.headers.toMultimap(),

View file

@ -88,7 +88,8 @@ object APIHolder {
}
private fun getLoadResponseIdFromUrl(url: String, apiName: String): Int {
return url.replace(getApiFromNameNull(apiName)?.mainUrl ?: "", "").replace("/", "").hashCode()
return url.replace(getApiFromNameNull(apiName)?.mainUrl ?: "", "").replace("/", "")
.hashCode()
}
fun LoadResponse.getId(): Int {
@ -109,39 +110,43 @@ object APIHolder {
// Try document.select("script[src*=https://www.google.com/recaptcha/api.js?render=]").attr("src").substringAfter("render=")
// To get the key
suspend fun getCaptchaToken(url: String, key: String, referer: String? = null): String? {
val uri = Uri.parse(url)
val domain = encodeToString(
(uri.scheme + "://" + uri.host + ":443").encodeToByteArray(),
0
).replace("\n", "").replace("=", ".")
try {
val uri = Uri.parse(url)
val domain = encodeToString(
(uri.scheme + "://" + uri.host + ":443").encodeToByteArray(),
0
).replace("\n", "").replace("=", ".")
val vToken =
app.get(
"https://www.google.com/recaptcha/api.js?render=$key",
referer = referer,
cacheTime = 0
)
.text
.substringAfter("releases/")
.substringBefore("/")
val recapToken =
app.get("https://www.google.com/recaptcha/api2/anchor?ar=1&hl=en&size=invisible&cb=cs3&k=$key&co=$domain&v=$vToken")
.document
.selectFirst("#recaptcha-token")?.attr("value")
if (recapToken != null) {
return app.post(
"https://www.google.com/recaptcha/api2/reload?k=$key",
data = mapOf(
"v" to vToken,
"k" to key,
"c" to recapToken,
"co" to domain,
"sa" to "",
"reason" to "q"
), cacheTime = 0
).text
.substringAfter("rresp\",\"")
.substringBefore("\"")
val vToken =
app.get(
"https://www.google.com/recaptcha/api.js?render=$key",
referer = referer,
cacheTime = 0
)
.text
.substringAfter("releases/")
.substringBefore("/")
val recapToken =
app.get("https://www.google.com/recaptcha/api2/anchor?ar=1&hl=en&size=invisible&cb=cs3&k=$key&co=$domain&v=$vToken")
.document
.selectFirst("#recaptcha-token")?.attr("value")
if (recapToken != null) {
return app.post(
"https://www.google.com/recaptcha/api2/reload?k=$key",
data = mapOf(
"v" to vToken,
"k" to key,
"c" to recapToken,
"co" to domain,
"sa" to "",
"reason" to "q"
), cacheTime = 0
).text
.substringAfter("rresp\",\"")
.substringBefore("\"")
}
} catch (e: Exception) {
logError(e)
}
return null
}

View file

@ -10,10 +10,6 @@ import android.view.KeyEvent
import android.view.Menu
import android.view.MenuItem
import android.view.WindowManager
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.IdRes
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible
@ -36,7 +32,6 @@ import com.lagradost.cloudstream3.APIHolder.apis
import com.lagradost.cloudstream3.APIHolder.getApiDubstatusSettings
import com.lagradost.cloudstream3.APIHolder.initAll
import com.lagradost.cloudstream3.APIHolder.updateHasTrailers
import com.lagradost.cloudstream3.CommonActivity.currentToast
import com.lagradost.cloudstream3.CommonActivity.loadThemes
import com.lagradost.cloudstream3.CommonActivity.onColorSelectedEvent
import com.lagradost.cloudstream3.CommonActivity.onDialogDismissedEvent
@ -45,10 +40,12 @@ import com.lagradost.cloudstream3.CommonActivity.showToast
import com.lagradost.cloudstream3.CommonActivity.updateLocale
import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.network.initClient
import com.lagradost.cloudstream3.plugins.PluginManager
import com.lagradost.cloudstream3.receivers.VideoDownloadRestartReceiver
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.OAuth2Apis
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.accountManagers
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appString
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appStringRepo
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.inAppAuths
import com.lagradost.cloudstream3.ui.APIRepository
import com.lagradost.cloudstream3.ui.download.DOWNLOAD_NAVIGATE_TO
@ -58,8 +55,10 @@ import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isEmula
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
import com.lagradost.cloudstream3.ui.settings.SettingsGeneral
import com.lagradost.cloudstream3.ui.setup.HAS_DONE_SETUP_KEY
import com.lagradost.cloudstream3.ui.setup.SetupFragmentExtensions
import com.lagradost.cloudstream3.utils.AppUtils.isCastApiAvailable
import com.lagradost.cloudstream3.utils.AppUtils.loadCache
import com.lagradost.cloudstream3.utils.AppUtils.loadRepository
import com.lagradost.cloudstream3.utils.AppUtils.loadResult
import com.lagradost.cloudstream3.utils.BackupUtils.setUpBackup
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
@ -68,6 +67,7 @@ import com.lagradost.cloudstream3.utils.DataStore.removeKey
import com.lagradost.cloudstream3.utils.DataStore.setKey
import com.lagradost.cloudstream3.utils.DataStoreHelper.migrateResumeWatching
import com.lagradost.cloudstream3.utils.DataStoreHelper.setViewPos
import com.lagradost.cloudstream3.utils.Event
import com.lagradost.cloudstream3.utils.IOnBackPressed
import com.lagradost.cloudstream3.utils.InAppUpdater.Companion.runAutoUpdate
import com.lagradost.cloudstream3.utils.UIHelper.changeStatusBarState
@ -83,17 +83,8 @@ import com.lagradost.nicehttp.ResponseParser
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.fragment_result_swipe.*
import java.io.File
import kotlin.concurrent.thread
import kotlin.reflect.KClass
import com.lagradost.cloudstream3.plugins.PluginManager
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appStringRepo
import com.lagradost.cloudstream3.ui.setup.SetupFragmentExtensions
import com.lagradost.cloudstream3.utils.AppUtils.loadRepository
import com.lagradost.cloudstream3.utils.Coroutines.main
import com.lagradost.cloudstream3.utils.Event
import kotlinx.coroutines.delay
import java.lang.ref.WeakReference
import java.net.URI
import kotlin.reflect.KClass
const val VLC_PACKAGE = "org.videolan.vlc"
@ -659,7 +650,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
handleAppIntent(intent)
thread {
ioSafe {
runAutoUpdate()
}

View file

@ -5,11 +5,10 @@ import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.AcraApplication.Companion.getKey
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
import com.lagradost.cloudstream3.apmap
import com.lagradost.cloudstream3.apmapIndexed
import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall
import com.lagradost.cloudstream3.plugins.PluginManager.getPluginSanitizedFileName
import com.lagradost.cloudstream3.plugins.PluginManager.getPluginsLocal
import com.lagradost.cloudstream3.ui.settings.extensions.REPOSITORIES_KEY
import com.lagradost.cloudstream3.ui.settings.extensions.RepositoryData
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
@ -80,10 +79,15 @@ object RepositoryManager {
private suspend fun parsePlugins(pluginUrls: String): List<SitePlugin> {
// Take manifestVersion and such into account later
val response = app.get(pluginUrls)
// Normal parsed function not working?
// return response.parsedSafe()
return tryParseJson<Array<SitePlugin>>(response.text)?.toList() ?: emptyList()
return try {
val response = app.get(pluginUrls)
// Normal parsed function not working?
// return response.parsedSafe()
tryParseJson<Array<SitePlugin>>(response.text)?.toList() ?: emptyList()
} catch (e : Exception) {
logError(e)
emptyList()
}
}
/**

View file

@ -3,22 +3,11 @@ package com.lagradost.cloudstream3.ui.result
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.core.view.isVisible
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.button.MaterialButton
import com.lagradost.cloudstream3.ActorData
import com.lagradost.cloudstream3.ActorRole
import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.ui.download.DownloadButtonViewHolder
import com.lagradost.cloudstream3.ui.home.ParentItemAdapter
import com.lagradost.cloudstream3.ui.settings.AccountAdapter
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
import com.lagradost.cloudstream3.utils.UIHelper.setImage
import kotlinx.android.synthetic.main.cast_item.view.*
import org.schabi.newpipe.extractor.timeago.patterns.it
typealias SelectData = Pair<UiText?, Any>

View file

@ -16,6 +16,7 @@ import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.getPref
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setUpToolbar
import com.lagradost.cloudstream3.utils.BackupUtils.backup
import com.lagradost.cloudstream3.utils.BackupUtils.restorePrompt
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
import com.lagradost.cloudstream3.utils.InAppUpdater.Companion.runAutoUpdate
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard
@ -25,7 +26,6 @@ import okhttp3.internal.closeQuietly
import java.io.BufferedReader
import java.io.InputStreamReader
import java.io.OutputStream
import kotlin.concurrent.thread
class SettingsUpdates : PreferenceFragmentCompat() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -116,8 +116,8 @@ class SettingsUpdates : PreferenceFragmentCompat() {
}
getPref(R.string.manual_check_update_key)?.setOnPreferenceClickListener {
thread {
if (!requireActivity().runAutoUpdate(false)) {
ioSafe {
if (activity?.runAutoUpdate(false) == false) {
activity?.runOnUiThread {
CommonActivity.showToast(
activity,

View file

@ -41,7 +41,7 @@ class SetupFragmentProviderLanguage : Fragment() {
val langs = APIHolder.apis.map { it.lang }.toSet()
.sortedBy { SubtitleHelper.fromTwoLettersToLanguage(it) }
val currentList = current.map { langs.indexOf(it) }
val currentList = current.map { langs.indexOf(it) }.filter { it != -1 } // TODO LOOK INTO
val languageNames = langs.map {
val emoji = SubtitleHelper.getFlagFromIso(it)
val name = SubtitleHelper.fromTwoLettersToLanguage(it)

View file

@ -15,15 +15,14 @@ import com.lagradost.cloudstream3.CommonActivity.showToast
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.utils.AppUtils.parseJson
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import okio.*
import okio.BufferedSink
import okio.buffer
import okio.sink
import java.io.File
import kotlin.concurrent.thread
class InAppUpdater {
@ -68,10 +67,14 @@ class InAppUpdater {
@JsonProperty("updateNodeId") val updateNodeId: String?
)
private fun Activity.getAppUpdate(): Update {
private suspend fun Activity.getAppUpdate(): Update {
return try {
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
if (settingsManager.getBoolean(getString(R.string.prerelease_update_key), resources.getBoolean(R.bool.is_prerelease))) {
if (settingsManager.getBoolean(
getString(R.string.prerelease_update_key),
resources.getBoolean(R.bool.is_prerelease)
)
) {
getPreReleaseUpdate()
} else {
getReleaseUpdate()
@ -82,16 +85,16 @@ class InAppUpdater {
}
}
private fun Activity.getReleaseUpdate(): Update {
private suspend fun Activity.getReleaseUpdate(): Update {
val url = "https://api.github.com/repos/$GITHUB_USER_NAME/$GITHUB_REPO/releases"
val headers = mapOf("Accept" to "application/vnd.github.v3+json")
val response =
parseJson<List<GithubRelease>>(runBlocking {
parseJson<List<GithubRelease>>(
app.get(
url,
headers = headers
).text
})
)
val versionRegex = Regex("""(.*?((\d+)\.(\d+)\.(\d+))\.apk)""")
val versionRegexLocal = Regex("""(.*?((\d+)\.(\d+)\.(\d+)).*)""")
@ -148,7 +151,7 @@ class InAppUpdater {
return Update(false, null, null, null, null)
}
private fun Activity.getPreReleaseUpdate(): Update = runBlocking {
private suspend fun Activity.getPreReleaseUpdate(): Update {
val tagUrl =
"https://api.github.com/repos/$GITHUB_USER_NAME/$GITHUB_REPO/git/ref/tags/pre-release"
val releaseUrl = "https://api.github.com/repos/$GITHUB_USER_NAME/$GITHUB_REPO/releases"
@ -171,14 +174,14 @@ class InAppUpdater {
val shouldUpdate =
(getString(R.string.commit_hash)
.trim {c->c.isWhitespace()}
.trim { c -> c.isWhitespace() }
.take(7)
!=
tagResponse.github_object.sha
.trim {c->c.isWhitespace()}
.take(7))
!=
tagResponse.github_object.sha
.trim { c -> c.isWhitespace() }
.take(7))
return@runBlocking if (foundAsset != null) {
return if (foundAsset != null) {
Update(
shouldUpdate,
foundAsset.browser_download_url,
@ -194,25 +197,24 @@ class InAppUpdater {
private val updateLock = Mutex()
private fun Activity.downloadUpdate(url: String): Boolean {
private suspend fun Activity.downloadUpdate(url: String): Boolean {
try {
Log.d(LOG_TAG, "Downloading update: $url")
Log.d(LOG_TAG, "Downloading update: $url")
val localContext = this
val localContext = this
val downloadedFile = File.createTempFile("CloudStream", ".apk")
val sink: BufferedSink = downloadedFile.sink().buffer()
val downloadedFile = File.createTempFile("CloudStream",".apk")
val sink: BufferedSink = downloadedFile.sink().buffer()
ioSafe {
updateLock.withLock {
sink.writeAll(app.get(url).body.source() )
sink.writeAll(app.get(url).body.source())
sink.close()
openApk(localContext, Uri.fromFile(downloadedFile))
}
return true
} catch (e: Exception) {
return false
}
return true
}
private fun openApk(context: Context, uri: Uri) {
@ -236,7 +238,7 @@ class InAppUpdater {
}
}
fun Activity.runAutoUpdate(checkAutoUpdate: Boolean = true): Boolean {
suspend fun Activity.runAutoUpdate(checkAutoUpdate: Boolean = true): Boolean {
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
if (!checkAutoUpdate || settingsManager.getBoolean(
@ -247,7 +249,8 @@ class InAppUpdater {
val update = getAppUpdate()
if (update.shouldUpdate && update.updateURL != null) {
//Check if update should be skipped
val updateNodeId = settingsManager.getString(getString(R.string.skip_update_key), "")
val updateNodeId =
settingsManager.getString(getString(R.string.skip_update_key), "")
if (update.updateNodeId.equals(updateNodeId)) {
return false
}
@ -273,11 +276,8 @@ class InAppUpdater {
builder.apply {
setPositiveButton(R.string.update) { _, _ ->
showToast(context, R.string.download_started, Toast.LENGTH_LONG)
thread {
val downloadStatus =
normalSafeApiCall { context.downloadUpdate(update.updateURL) }
?: false
if (!downloadStatus) {
ioSafe {
if (!downloadUpdate(update.updateURL))
runOnUiThread {
showToast(
context,
@ -285,7 +285,6 @@ class InAppUpdater {
Toast.LENGTH_LONG
)
}
}
}
}
@ -293,7 +292,10 @@ class InAppUpdater {
if (checkAutoUpdate) {
setNeutralButton(R.string.skip_update) { _, _ ->
settingsManager.edit().putString(getString(R.string.skip_update_key), update.updateNodeId ?: "")
settingsManager.edit().putString(
getString(R.string.skip_update_key),
update.updateNodeId ?: ""
)
.apply()
}
}