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) throw ReCaptchaException("reCaptcha Challenge requested", url)
} }
val body = response.body val body = response.body
var responseBodyToReturn: String? = null val responseBodyToReturn: String = body.string()
if (body != null) {
responseBodyToReturn = body.string()
}
val latestUrl = response.request.url.toString() val latestUrl = response.request.url.toString()
return Response( return Response(
response.code, response.message, response.headers.toMultimap(), response.code, response.message, response.headers.toMultimap(),

View file

@ -88,7 +88,8 @@ object APIHolder {
} }
private fun getLoadResponseIdFromUrl(url: String, apiName: String): Int { 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 { fun LoadResponse.getId(): Int {
@ -109,6 +110,7 @@ object APIHolder {
// Try document.select("script[src*=https://www.google.com/recaptcha/api.js?render=]").attr("src").substringAfter("render=") // Try document.select("script[src*=https://www.google.com/recaptcha/api.js?render=]").attr("src").substringAfter("render=")
// To get the key // To get the key
suspend fun getCaptchaToken(url: String, key: String, referer: String? = null): String? { suspend fun getCaptchaToken(url: String, key: String, referer: String? = null): String? {
try {
val uri = Uri.parse(url) val uri = Uri.parse(url)
val domain = encodeToString( val domain = encodeToString(
(uri.scheme + "://" + uri.host + ":443").encodeToByteArray(), (uri.scheme + "://" + uri.host + ":443").encodeToByteArray(),
@ -143,6 +145,9 @@ object APIHolder {
.substringAfter("rresp\",\"") .substringAfter("rresp\",\"")
.substringBefore("\"") .substringBefore("\"")
} }
} catch (e: Exception) {
logError(e)
}
return null return null
} }

View file

@ -10,10 +10,6 @@ import android.view.KeyEvent
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.WindowManager 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.annotation.IdRes
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible 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.getApiDubstatusSettings
import com.lagradost.cloudstream3.APIHolder.initAll import com.lagradost.cloudstream3.APIHolder.initAll
import com.lagradost.cloudstream3.APIHolder.updateHasTrailers import com.lagradost.cloudstream3.APIHolder.updateHasTrailers
import com.lagradost.cloudstream3.CommonActivity.currentToast
import com.lagradost.cloudstream3.CommonActivity.loadThemes import com.lagradost.cloudstream3.CommonActivity.loadThemes
import com.lagradost.cloudstream3.CommonActivity.onColorSelectedEvent import com.lagradost.cloudstream3.CommonActivity.onColorSelectedEvent
import com.lagradost.cloudstream3.CommonActivity.onDialogDismissedEvent 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.CommonActivity.updateLocale
import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.network.initClient import com.lagradost.cloudstream3.network.initClient
import com.lagradost.cloudstream3.plugins.PluginManager
import com.lagradost.cloudstream3.receivers.VideoDownloadRestartReceiver import com.lagradost.cloudstream3.receivers.VideoDownloadRestartReceiver
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.OAuth2Apis import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.OAuth2Apis
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.accountManagers import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.accountManagers
import com.lagradost.cloudstream3.syncproviders.AccountManager.Companion.appString 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.syncproviders.AccountManager.Companion.inAppAuths
import com.lagradost.cloudstream3.ui.APIRepository import com.lagradost.cloudstream3.ui.APIRepository
import com.lagradost.cloudstream3.ui.download.DOWNLOAD_NAVIGATE_TO 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.SettingsFragment.Companion.isTvSettings
import com.lagradost.cloudstream3.ui.settings.SettingsGeneral import com.lagradost.cloudstream3.ui.settings.SettingsGeneral
import com.lagradost.cloudstream3.ui.setup.HAS_DONE_SETUP_KEY 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.isCastApiAvailable
import com.lagradost.cloudstream3.utils.AppUtils.loadCache 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.AppUtils.loadResult
import com.lagradost.cloudstream3.utils.BackupUtils.setUpBackup import com.lagradost.cloudstream3.utils.BackupUtils.setUpBackup
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe 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.DataStore.setKey
import com.lagradost.cloudstream3.utils.DataStoreHelper.migrateResumeWatching import com.lagradost.cloudstream3.utils.DataStoreHelper.migrateResumeWatching
import com.lagradost.cloudstream3.utils.DataStoreHelper.setViewPos import com.lagradost.cloudstream3.utils.DataStoreHelper.setViewPos
import com.lagradost.cloudstream3.utils.Event
import com.lagradost.cloudstream3.utils.IOnBackPressed import com.lagradost.cloudstream3.utils.IOnBackPressed
import com.lagradost.cloudstream3.utils.InAppUpdater.Companion.runAutoUpdate import com.lagradost.cloudstream3.utils.InAppUpdater.Companion.runAutoUpdate
import com.lagradost.cloudstream3.utils.UIHelper.changeStatusBarState 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.activity_main.*
import kotlinx.android.synthetic.main.fragment_result_swipe.* import kotlinx.android.synthetic.main.fragment_result_swipe.*
import java.io.File 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 java.net.URI
import kotlin.reflect.KClass
const val VLC_PACKAGE = "org.videolan.vlc" const val VLC_PACKAGE = "org.videolan.vlc"
@ -659,7 +650,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
handleAppIntent(intent) handleAppIntent(intent)
thread { ioSafe {
runAutoUpdate() 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.getKey
import com.lagradost.cloudstream3.AcraApplication.Companion.setKey import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
import com.lagradost.cloudstream3.apmap import com.lagradost.cloudstream3.apmap
import com.lagradost.cloudstream3.apmapIndexed
import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall
import com.lagradost.cloudstream3.plugins.PluginManager.getPluginSanitizedFileName 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.REPOSITORIES_KEY
import com.lagradost.cloudstream3.ui.settings.extensions.RepositoryData import com.lagradost.cloudstream3.ui.settings.extensions.RepositoryData
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
@ -80,10 +79,15 @@ object RepositoryManager {
private suspend fun parsePlugins(pluginUrls: String): List<SitePlugin> { private suspend fun parsePlugins(pluginUrls: String): List<SitePlugin> {
// Take manifestVersion and such into account later // Take manifestVersion and such into account later
return try {
val response = app.get(pluginUrls) val response = app.get(pluginUrls)
// Normal parsed function not working? // Normal parsed function not working?
// return response.parsedSafe() // return response.parsedSafe()
return tryParseJson<Array<SitePlugin>>(response.text)?.toList() ?: emptyList() 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.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup 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.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.button.MaterialButton 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.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.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> 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.ui.settings.SettingsFragment.Companion.setUpToolbar
import com.lagradost.cloudstream3.utils.BackupUtils.backup import com.lagradost.cloudstream3.utils.BackupUtils.backup
import com.lagradost.cloudstream3.utils.BackupUtils.restorePrompt 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.InAppUpdater.Companion.runAutoUpdate
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard
@ -25,7 +26,6 @@ import okhttp3.internal.closeQuietly
import java.io.BufferedReader import java.io.BufferedReader
import java.io.InputStreamReader import java.io.InputStreamReader
import java.io.OutputStream import java.io.OutputStream
import kotlin.concurrent.thread
class SettingsUpdates : PreferenceFragmentCompat() { class SettingsUpdates : PreferenceFragmentCompat() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -116,8 +116,8 @@ class SettingsUpdates : PreferenceFragmentCompat() {
} }
getPref(R.string.manual_check_update_key)?.setOnPreferenceClickListener { getPref(R.string.manual_check_update_key)?.setOnPreferenceClickListener {
thread { ioSafe {
if (!requireActivity().runAutoUpdate(false)) { if (activity?.runAutoUpdate(false) == false) {
activity?.runOnUiThread { activity?.runOnUiThread {
CommonActivity.showToast( CommonActivity.showToast(
activity, activity,

View file

@ -41,7 +41,7 @@ class SetupFragmentProviderLanguage : Fragment() {
val langs = APIHolder.apis.map { it.lang }.toSet() val langs = APIHolder.apis.map { it.lang }.toSet()
.sortedBy { SubtitleHelper.fromTwoLettersToLanguage(it) } .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 languageNames = langs.map {
val emoji = SubtitleHelper.getFlagFromIso(it) val emoji = SubtitleHelper.getFlagFromIso(it)
val name = SubtitleHelper.fromTwoLettersToLanguage(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.R
import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
import com.lagradost.cloudstream3.utils.AppUtils.parseJson import com.lagradost.cloudstream3.utils.AppUtils.parseJson
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withLock
import okio.* import okio.BufferedSink
import okio.buffer
import okio.sink
import java.io.File import java.io.File
import kotlin.concurrent.thread
class InAppUpdater { class InAppUpdater {
@ -68,10 +67,14 @@ class InAppUpdater {
@JsonProperty("updateNodeId") val updateNodeId: String? @JsonProperty("updateNodeId") val updateNodeId: String?
) )
private fun Activity.getAppUpdate(): Update { private suspend fun Activity.getAppUpdate(): Update {
return try { return try {
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this) 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() getPreReleaseUpdate()
} else { } else {
getReleaseUpdate() 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 url = "https://api.github.com/repos/$GITHUB_USER_NAME/$GITHUB_REPO/releases"
val headers = mapOf("Accept" to "application/vnd.github.v3+json") val headers = mapOf("Accept" to "application/vnd.github.v3+json")
val response = val response =
parseJson<List<GithubRelease>>(runBlocking { parseJson<List<GithubRelease>>(
app.get( app.get(
url, url,
headers = headers headers = headers
).text ).text
}) )
val versionRegex = Regex("""(.*?((\d+)\.(\d+)\.(\d+))\.apk)""") val versionRegex = Regex("""(.*?((\d+)\.(\d+)\.(\d+))\.apk)""")
val versionRegexLocal = Regex("""(.*?((\d+)\.(\d+)\.(\d+)).*)""") val versionRegexLocal = Regex("""(.*?((\d+)\.(\d+)\.(\d+)).*)""")
@ -148,7 +151,7 @@ class InAppUpdater {
return Update(false, null, null, null, null) return Update(false, null, null, null, null)
} }
private fun Activity.getPreReleaseUpdate(): Update = runBlocking { private suspend fun Activity.getPreReleaseUpdate(): Update {
val tagUrl = val tagUrl =
"https://api.github.com/repos/$GITHUB_USER_NAME/$GITHUB_REPO/git/ref/tags/pre-release" "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" val releaseUrl = "https://api.github.com/repos/$GITHUB_USER_NAME/$GITHUB_REPO/releases"
@ -178,7 +181,7 @@ class InAppUpdater {
.trim { c -> c.isWhitespace() } .trim { c -> c.isWhitespace() }
.take(7)) .take(7))
return@runBlocking if (foundAsset != null) { return if (foundAsset != null) {
Update( Update(
shouldUpdate, shouldUpdate,
foundAsset.browser_download_url, foundAsset.browser_download_url,
@ -194,8 +197,8 @@ class InAppUpdater {
private val updateLock = Mutex() 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
@ -203,16 +206,15 @@ class InAppUpdater {
val downloadedFile = File.createTempFile("CloudStream", ".apk") val downloadedFile = File.createTempFile("CloudStream", ".apk")
val sink: BufferedSink = downloadedFile.sink().buffer() val sink: BufferedSink = downloadedFile.sink().buffer()
ioSafe {
updateLock.withLock { updateLock.withLock {
sink.writeAll(app.get(url).body.source()) sink.writeAll(app.get(url).body.source())
sink.close() sink.close()
openApk(localContext, Uri.fromFile(downloadedFile)) openApk(localContext, Uri.fromFile(downloadedFile))
} }
}
return true return true
} catch (e: Exception) {
return false
}
} }
private fun openApk(context: Context, uri: Uri) { 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) val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
if (!checkAutoUpdate || settingsManager.getBoolean( if (!checkAutoUpdate || settingsManager.getBoolean(
@ -247,7 +249,8 @@ class InAppUpdater {
val update = getAppUpdate() val update = getAppUpdate()
if (update.shouldUpdate && update.updateURL != null) { if (update.shouldUpdate && update.updateURL != null) {
//Check if update should be skipped //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)) { if (update.updateNodeId.equals(updateNodeId)) {
return false return false
} }
@ -273,11 +276,8 @@ class InAppUpdater {
builder.apply { builder.apply {
setPositiveButton(R.string.update) { _, _ -> setPositiveButton(R.string.update) { _, _ ->
showToast(context, R.string.download_started, Toast.LENGTH_LONG) showToast(context, R.string.download_started, Toast.LENGTH_LONG)
thread { ioSafe {
val downloadStatus = if (!downloadUpdate(update.updateURL))
normalSafeApiCall { context.downloadUpdate(update.updateURL) }
?: false
if (!downloadStatus) {
runOnUiThread { runOnUiThread {
showToast( showToast(
context, context,
@ -287,13 +287,15 @@ class InAppUpdater {
} }
} }
} }
}
setNegativeButton(R.string.cancel) { _, _ -> } setNegativeButton(R.string.cancel) { _, _ -> }
if (checkAutoUpdate) { if (checkAutoUpdate) {
setNeutralButton(R.string.skip_update) { _, _ -> 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() .apply()
} }
} }