forked from recloudstream/cloudstream
fixed anilist
This commit is contained in:
parent
0a3dd24cf1
commit
8cfa9b52aa
9 changed files with 84 additions and 49 deletions
|
@ -6,6 +6,7 @@ import android.content.Context
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import android.util.Log
|
||||||
import android.view.*
|
import android.view.*
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
@ -47,13 +48,20 @@ object CommonActivity {
|
||||||
showToast(act, act.getString(message), duration)
|
showToast(act, act.getString(message), duration)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const val TAG = "COMPACT"
|
||||||
|
|
||||||
/** duration is Toast.LENGTH_SHORT if null*/
|
/** duration is Toast.LENGTH_SHORT if null*/
|
||||||
fun showToast(act: Activity?, message: String?, duration: Int? = null) {
|
fun showToast(act: Activity?, message: String?, duration: Int? = null) {
|
||||||
if (act == null || message == null) return
|
if (act == null || message == null) {
|
||||||
|
Log.w(TAG, "invalid showToast act = $act message = $message")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Log.i(TAG, "showToast = $message")
|
||||||
|
|
||||||
try {
|
try {
|
||||||
currentToast?.cancel()
|
currentToast?.cancel()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
logError(e)
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
val inflater =
|
val inflater =
|
||||||
|
@ -74,7 +82,7 @@ object CommonActivity {
|
||||||
toast.show()
|
toast.show()
|
||||||
currentToast = toast
|
currentToast = toast
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
logError(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import android.content.Intent
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
|
@ -31,6 +32,7 @@ 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
|
||||||
import com.lagradost.cloudstream3.CommonActivity.onUserLeaveHint
|
import com.lagradost.cloudstream3.CommonActivity.onUserLeaveHint
|
||||||
|
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.Requests
|
import com.lagradost.cloudstream3.network.Requests
|
||||||
|
@ -48,6 +50,7 @@ import com.lagradost.cloudstream3.utils.AppUtils.loadCache
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.loadResult
|
import com.lagradost.cloudstream3.utils.AppUtils.loadResult
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
|
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
|
||||||
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.main
|
import com.lagradost.cloudstream3.utils.Coroutines.main
|
||||||
import com.lagradost.cloudstream3.utils.DataStore.getKey
|
import com.lagradost.cloudstream3.utils.DataStore.getKey
|
||||||
import com.lagradost.cloudstream3.utils.DataStore.removeKey
|
import com.lagradost.cloudstream3.utils.DataStore.removeKey
|
||||||
|
@ -87,6 +90,10 @@ var app = Requests()
|
||||||
|
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
||||||
|
companion object {
|
||||||
|
const val TAG = "MAINACT"
|
||||||
|
}
|
||||||
|
|
||||||
override fun onColorSelected(dialogId: Int, color: Int) {
|
override fun onColorSelected(dialogId: Int, color: Int) {
|
||||||
onColorSelectedEvent.invoke(Pair(dialogId, color))
|
onColorSelectedEvent.invoke(Pair(dialogId, color))
|
||||||
}
|
}
|
||||||
|
@ -266,10 +273,23 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
|
||||||
if (str.contains(appString)) {
|
if (str.contains(appString)) {
|
||||||
for (api in OAuth2Apis) {
|
for (api in OAuth2Apis) {
|
||||||
if (str.contains("/${api.redirectUrl}")) {
|
if (str.contains("/${api.redirectUrl}")) {
|
||||||
try {
|
ioSafe {
|
||||||
api.handleRedirect(str)
|
Log.i(TAG, "handleAppIntent $str")
|
||||||
} catch (e : Exception) {
|
if (api.handleRedirect(str)) {
|
||||||
logError(e)
|
Log.i(TAG, "authenticated ${api.name}")
|
||||||
|
this.runOnUiThread {
|
||||||
|
try {
|
||||||
|
showToast(
|
||||||
|
this,
|
||||||
|
getString(R.string.authenticated_user).format(api.name)
|
||||||
|
)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
logError(e) // format might fail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.i(TAG, "failed to authenticate ${api.name}")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ interface OAuth2API {
|
||||||
// don't change this as all keys depend on it
|
// don't change this as all keys depend on it
|
||||||
val idPrefix: String
|
val idPrefix: String
|
||||||
|
|
||||||
fun handleRedirect(url: String)
|
suspend fun handleRedirect(url: String) : Boolean
|
||||||
fun authenticate()
|
fun authenticate()
|
||||||
|
|
||||||
fun loginInfo(): LoginInfo?
|
fun loginInfo(): LoginInfo?
|
||||||
|
|
|
@ -52,6 +52,7 @@ interface SyncAPI : OAuth2API {
|
||||||
val score: Int?,
|
val score: Int?,
|
||||||
val watchedEpisodes: Int?,
|
val watchedEpisodes: Int?,
|
||||||
var isFavorite: Boolean? = null,
|
var isFavorite: Boolean? = null,
|
||||||
|
var maxEpisodes : Int? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class SyncResult(
|
data class SyncResult(
|
||||||
|
|
|
@ -56,7 +56,7 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI {
|
||||||
openBrowser(request)
|
openBrowser(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleRedirect(url: String) {
|
override suspend fun handleRedirect(url: String) : Boolean {
|
||||||
val sanitizer =
|
val sanitizer =
|
||||||
splitQuery(URL(url.replace(appString, "https").replace("/#", "?"))) // FIX ERROR
|
splitQuery(URL(url.replace(appString, "https").replace("/#", "?"))) // FIX ERROR
|
||||||
val token = sanitizer["access_token"]!!
|
val token = sanitizer["access_token"]!!
|
||||||
|
@ -68,9 +68,8 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI {
|
||||||
setKey(accountId, ANILIST_UNIXTIME_KEY, endTime)
|
setKey(accountId, ANILIST_UNIXTIME_KEY, endTime)
|
||||||
setKey(accountId, ANILIST_TOKEN_KEY, token)
|
setKey(accountId, ANILIST_TOKEN_KEY, token)
|
||||||
setKey(ANILIST_SHOULD_UPDATE_LIST, true)
|
setKey(ANILIST_SHOULD_UPDATE_LIST, true)
|
||||||
ioSafe {
|
val user = getUser()
|
||||||
getUser()
|
return user != null
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun search(name: String): List<SyncAPI.SyncSearchResult>? {
|
override suspend fun search(name: String): List<SyncAPI.SyncSearchResult>? {
|
||||||
|
@ -114,9 +113,10 @@ class AniListApi(index: Int) : AccountManager(index), SyncAPI {
|
||||||
|
|
||||||
return SyncAPI.SyncStatus(
|
return SyncAPI.SyncStatus(
|
||||||
score = data.score,
|
score = data.score,
|
||||||
watchedEpisodes = data.episodes,
|
watchedEpisodes = data.progress,
|
||||||
status = data.type?.value ?: return null,
|
status = data.type?.value ?: return null,
|
||||||
isFavorite = data.isFavourite,
|
isFavorite = data.isFavourite,
|
||||||
|
maxEpisodes = data.episodes,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ class Dropbox : OAuth2API {
|
||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleRedirect(url: String) {
|
override suspend fun handleRedirect(url: String): Boolean {
|
||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ import com.lagradost.cloudstream3.syncproviders.OAuth2API.Companion.secondsToRea
|
||||||
import com.lagradost.cloudstream3.syncproviders.OAuth2API.Companion.unixTime
|
import com.lagradost.cloudstream3.syncproviders.OAuth2API.Companion.unixTime
|
||||||
import com.lagradost.cloudstream3.syncproviders.SyncAPI
|
import com.lagradost.cloudstream3.syncproviders.SyncAPI
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.splitQuery
|
import com.lagradost.cloudstream3.utils.AppUtils.splitQuery
|
||||||
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
|
||||||
import com.lagradost.cloudstream3.utils.DataStore.toKotlinObject
|
import com.lagradost.cloudstream3.utils.DataStore.toKotlinObject
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.security.SecureRandom
|
import java.security.SecureRandom
|
||||||
|
@ -250,37 +249,32 @@ class MALApi(index: Int) : AccountManager(index), SyncAPI {
|
||||||
const val MAL_TOKEN_KEY: String = "mal_token" // anilist token for api
|
const val MAL_TOKEN_KEY: String = "mal_token" // anilist token for api
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleRedirect(url: String) {
|
override suspend fun handleRedirect(url: String): Boolean {
|
||||||
val sanitizer =
|
val sanitizer =
|
||||||
splitQuery(URL(url.replace(appString, "https").replace("/#", "?"))) // FIX ERROR
|
splitQuery(URL(url.replace(appString, "https").replace("/#", "?"))) // FIX ERROR
|
||||||
val state = sanitizer["state"]!!
|
val state = sanitizer["state"]!!
|
||||||
if (state == "RequestID$requestId") {
|
if (state == "RequestID$requestId") {
|
||||||
val currentCode = sanitizer["code"]!!
|
val currentCode = sanitizer["code"]!!
|
||||||
ioSafe {
|
|
||||||
var res = ""
|
|
||||||
try {
|
|
||||||
//println("cc::::: " + codeVerifier)
|
|
||||||
res = app.post(
|
|
||||||
"https://myanimelist.net/v1/oauth2/token",
|
|
||||||
data = mapOf(
|
|
||||||
"client_id" to key,
|
|
||||||
"code" to currentCode,
|
|
||||||
"code_verifier" to codeVerifier,
|
|
||||||
"grant_type" to "authorization_code"
|
|
||||||
)
|
|
||||||
).text
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res != "") {
|
val res = app.post(
|
||||||
switchToNewAccount()
|
"https://myanimelist.net/v1/oauth2/token",
|
||||||
storeToken(res)
|
data = mapOf(
|
||||||
getMalUser()
|
"client_id" to key,
|
||||||
setKey(MAL_SHOULD_UPDATE_LIST, true)
|
"code" to currentCode,
|
||||||
}
|
"code_verifier" to codeVerifier,
|
||||||
|
"grant_type" to "authorization_code"
|
||||||
|
)
|
||||||
|
).text
|
||||||
|
|
||||||
|
if (!res.isNullOrBlank()) {
|
||||||
|
switchToNewAccount()
|
||||||
|
storeToken(res)
|
||||||
|
val user = getMalUser()
|
||||||
|
setKey(MAL_SHOULD_UPDATE_LIST, true)
|
||||||
|
return user != null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun authenticate() {
|
override fun authenticate() {
|
||||||
|
|
|
@ -1210,22 +1210,27 @@ class ResultFragment : Fragment(), PanelsChildGestureRegionObserver.GestureRegio
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentSyncProgress = 0
|
var currentSyncProgress = 0
|
||||||
|
|
||||||
|
fun setSyncMaxEpisodes(totalEpisodes: Int?) {
|
||||||
|
result_sync_episodes?.max = (totalEpisodes ?: 0) * 1000
|
||||||
|
|
||||||
|
normalSafeApiCall {
|
||||||
|
val ctx = result_sync_max_episodes?.context
|
||||||
|
result_sync_max_episodes?.text =
|
||||||
|
totalEpisodes?.let { episodes ->
|
||||||
|
ctx?.getString(R.string.sync_total_episodes_some)?.format(episodes)
|
||||||
|
} ?: run {
|
||||||
|
ctx?.getString(R.string.sync_total_episodes_none)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
observe(syncModel.metadata) { meta ->
|
observe(syncModel.metadata) { meta ->
|
||||||
when (meta) {
|
when (meta) {
|
||||||
is Resource.Success -> {
|
is Resource.Success -> {
|
||||||
val d = meta.value
|
val d = meta.value
|
||||||
result_sync_episodes?.max = (d.totalEpisodes ?: 0) * 1000
|
|
||||||
result_sync_episodes?.progress = currentSyncProgress * 1000
|
result_sync_episodes?.progress = currentSyncProgress * 1000
|
||||||
|
setSyncMaxEpisodes(d.totalEpisodes)
|
||||||
normalSafeApiCall {
|
|
||||||
val ctx = result_sync_max_episodes?.context
|
|
||||||
result_sync_max_episodes?.text =
|
|
||||||
d.totalEpisodes?.let {
|
|
||||||
ctx?.getString(R.string.sync_total_episodes_some)?.format(it)
|
|
||||||
} ?: run {
|
|
||||||
ctx?.getString(R.string.sync_total_episodes_none)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
viewModel.setMeta(d)
|
viewModel.setMeta(d)
|
||||||
}
|
}
|
||||||
is Resource.Loading -> {
|
is Resource.Loading -> {
|
||||||
|
@ -1259,6 +1264,12 @@ class ResultFragment : Fragment(), PanelsChildGestureRegionObserver.GestureRegio
|
||||||
result_sync_check?.setItemChecked(d.status + 1, true)
|
result_sync_check?.setItemChecked(d.status + 1, true)
|
||||||
val watchedEpisodes = d.watchedEpisodes ?: 0
|
val watchedEpisodes = d.watchedEpisodes ?: 0
|
||||||
currentSyncProgress = watchedEpisodes
|
currentSyncProgress = watchedEpisodes
|
||||||
|
|
||||||
|
d.maxEpisodes?.let {
|
||||||
|
// don't directly call it because we don't want to override metadata observe
|
||||||
|
setSyncMaxEpisodes(it)
|
||||||
|
}
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
result_sync_episodes?.setProgress(watchedEpisodes * 1000, true)
|
result_sync_episodes?.setProgress(watchedEpisodes * 1000, true)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -399,6 +399,7 @@
|
||||||
<string name="sync_score_format" formatted="true">%d / 10</string>
|
<string name="sync_score_format" formatted="true">%d / 10</string>
|
||||||
<string name="sync_total_episodes_none">/??</string>
|
<string name="sync_total_episodes_none">/??</string>
|
||||||
<string name="sync_total_episodes_some" formatted="true">/%d</string>
|
<string name="sync_total_episodes_some" formatted="true">/%d</string>
|
||||||
|
<string name="authenticated_user" formatted="true">Authenticated %s</string>
|
||||||
<!-- ============ -->
|
<!-- ============ -->
|
||||||
<string name="none">None</string>
|
<string name="none">None</string>
|
||||||
<string name="normal">Normal</string>
|
<string name="normal">Normal</string>
|
||||||
|
|
Loading…
Reference in a new issue