Support reset image limits

This commit is contained in:
FooIbar authored and tarsin committed 2023-02-11 07:54:11 +08:00
1 parent 6413ed67c6
commit 8a2cb42546
9 files changed
+220 -11

No files matched your search

@@ -45,6 +45,7 @@ public class Settings {
public static final String KEY_THEME = "theme";
public static final String KEY_ACCOUNT = "account";
public static final String KEY_IMAGE_LIMITS = "image_limits";
public static final String KEY_BLACK_DARK_THEME = "black_dark_theme";
public static final int THEME_SYSTEM = -1;
public static final String KEY_GALLERY_SITE = "gallery_site";
@@ -51,6 +51,8 @@ import com.hippo.ehviewer.client.parser.VoteTagParser
import com.hippo.network.StatusCodeException
import com.hippo.util.ExceptionUtils
import com.hippo.yorozuya.AssertUtils
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import okhttp3.FormBody
import okhttp3.Headers
@@ -783,6 +785,68 @@ object EhEngine {
}
}
@Throws(Throwable::class)
private suspend fun getImageLimitsInternal(): HomeParser.Limits {
val url = EhUrl.URL_HOME
Log.d(TAG, url)
val request = EhRequestBuilder(url, null).build()
val call = okHttpClient.newCall(request)
var body: String? = null
var headers: Headers? = null
var code = -1
try {
call.executeAsync().use { response ->
code = response.code
headers = response.headers
body = response.body.string()
return HomeParser.parse(body!!)
}
} catch (e: Throwable) {
ExceptionUtils.throwIfFatal(e)
transformException(code, headers, body, e)
throw e
}
}
@Throws(Throwable::class)
suspend fun getImageLimits(): HomeParser.Result = coroutineScope {
val limitsDeferred = async {
getImageLimitsInternal()
}
val fundsDeferred = async {
getFunds()
}
HomeParser.Result(limitsDeferred.await(), fundsDeferred.await())
}
@Throws(Throwable::class)
suspend fun resetImageLimits(): HomeParser.Limits? {
val builder = FormBody.Builder()
.add("act", "limits")
.add("reset", "Reset Limit")
val url = EhUrl.URL_HOME
Log.d(TAG, url)
val request = EhRequestBuilder(url, null)
.post(builder.build())
.build()
val call = okHttpClient.newCall(request)
var body: String? = null
var headers: Headers? = null
var code = -1
try {
call.executeAsync().use { response ->
code = response.code
headers = response.headers
body = response.body.string()
return HomeParser.parseResetLimits(body!!)
}
} catch (e: Throwable) {
ExceptionUtils.throwIfFatal(e)
transformException(code, headers, body, e)
throw e
}
}
@Throws(Throwable::class)
private suspend fun getProfileInternal(
url: String, referer: String
@@ -44,7 +44,8 @@ object EhUrl {
const val URL_SIGN_IN = "https://forums.e-hentai.org/index.php?act=Login"
const val URL_REGISTER = "https://forums.e-hentai.org/index.php?act=Reg&CODE=00"
const val URL_FORUMS = "https://forums.e-hentai.org/"
const val URL_FUNDS = "https://e-hentai.org/exchange.php?t=gp"
const val URL_FUNDS = HOST_E + "exchange.php?t=gp"
const val URL_HOME = HOST_E + "home.php"
const val REFERER_EX = "https://$DOMAIN_EX"
const val ORIGIN_EX = REFERER_EX
const val REFERER_E = "https://$DOMAIN_E"
@@ -1,10 +1,33 @@
package com.hippo.ehviewer.client.parser
import com.hippo.ehviewer.client.exception.ParseException
import org.jsoup.Jsoup
object HomeParser {
private val PATTERN_FUNDS =
Regex("Available: ([\\d,]+) Credits.*Available: ([\\d,]+) kGP", RegexOption.DOT_MATCHES_ALL)
private const val RESET_SUCCEED = "Image limit was successfully reset."
fun parse(body: String): Limits {
Jsoup.parse(body).selectFirst("div.homebox")?.let {
val es = it.select("p > strong")
if (es.size == 3) {
val current = ParserUtils.parseInt(es[0].text(), 0)
val maximum = ParserUtils.parseInt(es[1].text(), 0)
val resetCost = ParserUtils.parseInt(es[2].text(), 0)
return Limits(current, maximum, resetCost)
}
}
throw ParseException("Parse image limits error", body)
}
fun parseResetLimits(body: String): Limits? {
return if (body.contains(RESET_SUCCEED)){
null
} else {
parse(body)
}
}
fun parseFunds(body: String): Funds {
PATTERN_FUNDS.find(body)?.groupValues?.run {
@@ -15,5 +38,7 @@ object HomeParser {
throw ParseException("Parse funds error", body)
}
data class Limits(val current: Int = 0, val maximum: Int, val resetCost: Int = 0)
data class Funds(val fundsGP: Int, val fundsC: Int)
class Result(val limits: Limits, val funds: Funds)
}
@@ -0,0 +1,95 @@
package com.hippo.ehviewer.preference
import android.content.Context
import android.content.DialogInterface
import android.util.AttributeSet
import android.view.View
import android.widget.Button
import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.LifecycleCoroutineScope
import androidx.lifecycle.lifecycleScope
import com.hippo.ehviewer.R
import com.hippo.ehviewer.client.EhEngine
import com.hippo.ehviewer.client.parser.HomeParser
import com.hippo.ehviewer.ui.SettingsActivity
import com.hippo.ehviewer.ui.scene.BaseScene
import com.hippo.preference.DialogPreference
import eu.kanade.tachiyomi.util.lang.launchIO
import eu.kanade.tachiyomi.util.lang.withUIContext
class ImageLimitsPreference(context: Context, attrs: AttributeSet) :
DialogPreference(context, attrs), View.OnClickListener {
private val mActivity = context as SettingsActivity
private val placeholder = context.getString(R.string.please_wait)
private lateinit var coroutineScope: LifecycleCoroutineScope
private lateinit var resetButton: Button
private lateinit var mDialog: AlertDialog
private lateinit var mLimits: HomeParser.Limits
private lateinit var mFunds: HomeParser.Funds
override fun onPrepareDialogBuilder(builder: AlertDialog.Builder) {
super.onPrepareDialogBuilder(builder)
builder.setMessage(placeholder)
}
override fun onDialogCreated(dialog: AlertDialog) {
super.onDialogCreated(dialog)
mDialog = dialog
coroutineScope = dialog.lifecycleScope
resetButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE)
resetButton.setOnClickListener(this)
resetButton.isEnabled = false
coroutineScope.launchIO {
getImageLimits()
}
}
private suspend fun getImageLimits() {
runCatching {
EhEngine.getImageLimits()
}.onFailure {
it.printStackTrace()
withUIContext {
mDialog.setMessage(it.message)
}
}.onSuccess {
mLimits = it.limits
mFunds = it.funds
withUIContext {
bind()
}
}
}
private fun bind() {
val (current, maximum, resetCost) = mLimits
val (fundsGP, fundsC) = mFunds
val cost = if (fundsGP >= resetCost) "$resetCost GP" else "$resetCost Credits"
val message = mActivity.getString(R.string.current_limits, "$current / $maximum", cost) +
"\n" + mActivity.getString(R.string.current_funds, "$fundsGP+", fundsC)
mDialog.setMessage(message)
resetButton.isEnabled = resetCost in 1..maxOf(fundsGP, fundsC)
}
override fun onClick(v: View) {
resetButton.isEnabled = false
mDialog.setMessage(placeholder)
coroutineScope.launchIO {
runCatching {
EhEngine.resetImageLimits()
}.onFailure {
it.printStackTrace()
withUIContext {
mDialog.setMessage(it.message)
}
}.onSuccess {
withUIContext {
mLimits = it ?: HomeParser.Limits(maximum = mLimits.maximum).also {
mActivity.showTip(R.string.reset_limits_succeed, BaseScene.LENGTH_SHORT)
}
bind()
}
}
}
}
}
@@ -25,6 +25,7 @@ import androidx.preference.Preference
import com.hippo.ehviewer.EhApplication
import com.hippo.ehviewer.R
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.EhCookieStore
import com.hippo.ehviewer.client.EhEngine
import com.hippo.ehviewer.client.EhTagDatabase
import eu.kanade.tachiyomi.util.lang.launchIO
@@ -33,6 +34,7 @@ class EhFragment : BasePreferenceFragment() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.eh_settings)
val account = findPreference<Preference>(Settings.KEY_ACCOUNT)
val imageLimits = findPreference<Preference>(Settings.KEY_IMAGE_LIMITS)
val theme = findPreference<Preference>(Settings.KEY_THEME)
val blackDarkTheme = findPreference<Preference>(Settings.KEY_BLACK_DARK_THEME)
val gallerySite = findPreference<Preference>(Settings.KEY_GALLERY_SITE)
@@ -59,6 +61,9 @@ class EhFragment : BasePreferenceFragment() {
preferenceScreen.removePreference(showTagTranslations)
preferenceScreen.removePreference(tagTranslationsSource!!)
}
if (!EhCookieStore.hasSignedIn()) {
preferenceScreen.removePreference(imageLimits!!)
}
}
override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {