Skip to content

Commit

Permalink
refactor(deck-download): "Too Many Requests" handling
Browse files Browse the repository at this point in the history
* document HTTP 429
* extract redirectUserToSignUpOrLogin
  * add JavaDoc
  * add comments
  * add the redirect URL to Timber
  • Loading branch information
david-allison committed Sep 25, 2024
1 parent 6d2a399 commit 59e25c7
Showing 1 changed file with 33 additions and 11 deletions.
44 changes: 33 additions & 11 deletions AnkiDroid/src/main/java/com/ichi2/anki/SharedDecksActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ class SharedDecksActivity : AnkiActivity() {
) {
super.onReceivedHttpError(view, request, errorResponse)

if (errorResponse?.statusCode != 429) return
if (errorResponse?.statusCode != HTTP_STATUS_TOO_MANY_REQUESTS) return

// If a user is logged in, they see: "Daily limit exceeded; please try again tomorrow."
// We have nothing we can do here
Expand All @@ -130,34 +130,56 @@ class SharedDecksActivity : AnkiActivity() {
// The following cases are handled below:
// "Please log in to download more decks." - on clicking "Download"
// "Please log in to perform more searches" - on searching
redirectUserToSignUpOrLogin()
}

// TODO: the result of login is typically redirecting the user to their decks
// this should be improved
override fun onReceivedError(view: WebView?, request: WebResourceRequest?, error: WebResourceError?) {
// Set mShouldHistoryBeCleared to false if error occurs since it might have been true
shouldHistoryBeCleared = false
super.onReceivedError(view, request, error)
}

/**
* Redirects the user to a login page
*
* A message is shown informing the user they need to log in to download more decks
*
* If the user has not logged in **inside AnkiDroid** then the message provides
* the user with an action to sign up
*
* The redirect is not performed if [redirectTimes] is 3 or more
*/
private fun redirectUserToSignUpOrLogin() {
// inform the user they need to log in as they've hit a rate limit
showSnackbar(R.string.shared_decks_login_required, LENGTH_INDEFINITE) {
if (isLoggedIn()) return@showSnackbar

// If a user is not logged in inside AnkiDroid, assume they have no AnkiWeb account
// and give them the option to sign up
setAction(R.string.sign_up) {
webView.loadUrl(getString(R.string.shared_decks_sign_up_url))
}
}

// redirect user to /account/login
// TODO: the result of login is typically redirecting the user to their decks
// this should be improved

if (redirectTimes++ < 3) {
Timber.i("HTTP 429, redirecting to login")
webView.loadUrl(getString(R.string.shared_decks_login_url))
val url = getString(R.string.shared_decks_login_url)
Timber.i("HTTP 429, redirecting to login: '$url'")
webView.loadUrl(url)
} else {
// Ensure that we do not have an infinite redirect
Timber.w("HTTP 429 redirect limit exceeded, only displaying message")
}
}

override fun onReceivedError(view: WebView?, request: WebResourceRequest?, error: WebResourceError?) {
// Set mShouldHistoryBeCleared to false if error occurs since it might have been true
shouldHistoryBeCleared = false
super.onReceivedError(view, request, error)
}
}

companion object {
const val SHARED_DECKS_DOWNLOAD_FRAGMENT = "SharedDecksDownloadFragment"
const val DOWNLOAD_FILE = "DownloadFile"
private const val HTTP_STATUS_TOO_MANY_REQUESTS = 429
}

// Show WebView with AnkiWeb shared decks with the functionality to capture downloads and import decks.
Expand Down

0 comments on commit 59e25c7

Please sign in to comment.