more QoL fixes for MangaDex (#18672)
* fix spelling for villainess in en translations * custom user agent + more md@h logging adds a custom user agent setting primarily intended for testing do note that spoofing to be a different browser might fetch you trouble as MangaDex's new hotlink/bot abusers can kick in action also add logging to figure out which MD@H node users are hitting as currently, the fallback was not observed to be changing even after a while; leading to user's keep failing to fetch images * more improvements make the `Extra` header more verbose use a `customUserAgent` sharedpreferences variable so that code looks cleaner move the useragent logic into an interceptor so that there is no need for restarting the app after every useragent change * completely switch to useragent interceptor removes builder header modification remove additional logging while testing (didn't really work as expected since I kept hitting uploads.mangadex.org anyhow, + the interceptor logs weren't useful otherwise) switch to hardcoding version code in header since it wasn't working as expected... add linting from android studio gradle release build * increment extVersionCode * oopsie be careful of comments * properly close unsuccessful requests to mdah node need to ensure this so that it doesn't crash (which has happened before) inb4 this is why the fallback url never works....
This commit is contained in:
parent
b5e30c3e35
commit
fc7598bdcf
|
@ -137,10 +137,14 @@ theme_time_travel=Time Travel
|
|||
theme_traditional_games=Traditional Games
|
||||
theme_vampires=Vampires
|
||||
theme_video_games=Video Games
|
||||
theme_villainess=Vilania
|
||||
theme_villainess=Villainess
|
||||
theme_virtual_reality=Virtual Reality
|
||||
theme_zombies=Zombies
|
||||
try_using_first_volume_cover=Attempt to use the first volume cover as cover
|
||||
try_using_first_volume_cover_summary=May need to manually refresh entries already in library. Otherwise, clear database to have new covers to show up.
|
||||
unable_to_process_chapter_request=Unable to process Chapter request. HTTP code: %d
|
||||
uploaded_by=Uploaded by %s
|
||||
set_custom_useragent=Set custom User-Agent
|
||||
set_custom_useragent_summary=Keep it as default
|
||||
set_custom_useragent_dialog=\n\nSpecify a custom user agent\n After each modification, the application needs to be restarted.\n\nDefault value:\n%s
|
||||
set_custom_useragent_error_invalid=Invalid User-Agent: %s
|
||||
|
|
|
@ -6,7 +6,7 @@ ext {
|
|||
extName = 'MangaDex'
|
||||
pkgNameSuffix = 'all.mangadex'
|
||||
extClass = '.MangaDexFactory'
|
||||
extVersionCode = 189
|
||||
extVersionCode = 190
|
||||
isNsfw = true
|
||||
}
|
||||
|
||||
|
|
|
@ -138,6 +138,13 @@ object MDConstants {
|
|||
return "${altTitlesInDescPref}_$dexLang"
|
||||
}
|
||||
|
||||
private const val customUserAgentPref = "customUserAgent"
|
||||
fun getCustomUserAgentPrefKey(dexLang: String): String {
|
||||
return "${customUserAgentPref}_$dexLang"
|
||||
}
|
||||
|
||||
val defaultUserAgent = "Tachiyomi " + System.getProperty("http.agent")
|
||||
|
||||
private const val tagGroupContent = "content"
|
||||
private const val tagGroupFormat = "format"
|
||||
private const val tagGroupGenre = "genre"
|
||||
|
|
|
@ -2,11 +2,14 @@ package eu.kanade.tachiyomi.extension.all.mangadex
|
|||
|
||||
import android.app.Application
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Build
|
||||
import android.widget.Toast
|
||||
import androidx.preference.EditTextPreference
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.MultiSelectListPreference
|
||||
import androidx.preference.PreferenceScreen
|
||||
import androidx.preference.SwitchPreferenceCompat
|
||||
import eu.kanade.tachiyomi.AppInfo
|
||||
import eu.kanade.tachiyomi.extension.all.mangadex.dto.AggregateDto
|
||||
import eu.kanade.tachiyomi.extension.all.mangadex.dto.AggregateVolume
|
||||
import eu.kanade.tachiyomi.extension.all.mangadex.dto.AtHomeDto
|
||||
|
@ -56,13 +59,23 @@ abstract class MangaDex(final override val lang: String, private val dexLang: St
|
|||
|
||||
private val helper = MangaDexHelper(lang)
|
||||
|
||||
final override fun headersBuilder() = Headers.Builder()
|
||||
.add("Referer", "$baseUrl/")
|
||||
.add("User-Agent", "Tachiyomi " + System.getProperty("http.agent"))
|
||||
final override fun headersBuilder(): Headers.Builder {
|
||||
val extraHeader = "Android/${Build.VERSION.RELEASE} " +
|
||||
"Tachiyomi/${AppInfo.getVersionName()} " +
|
||||
"MangaDex/1.4.190"
|
||||
|
||||
val builder = super.headersBuilder().apply {
|
||||
set("Referer", "$baseUrl/")
|
||||
set("Extra", extraHeader)
|
||||
}
|
||||
|
||||
return builder
|
||||
}
|
||||
|
||||
override val client = network.client.newBuilder()
|
||||
.rateLimit(3)
|
||||
.addInterceptor(MdAtHomeReportInterceptor(network.client, headers))
|
||||
.addInterceptor(MdUserAgentInterceptor(preferences, dexLang))
|
||||
.build()
|
||||
|
||||
init {
|
||||
|
@ -745,6 +758,30 @@ abstract class MangaDex(final override val lang: String, private val dexLang: St
|
|||
}
|
||||
}
|
||||
|
||||
val userAgentPref = EditTextPreference(screen.context).apply {
|
||||
key = MDConstants.getCustomUserAgentPrefKey(dexLang)
|
||||
title = helper.intl["set_custom_useragent"]
|
||||
summary = helper.intl["set_custom_useragent_summary"]
|
||||
dialogMessage = helper.intl.format(
|
||||
"set_custom_useragent_dialog",
|
||||
MDConstants.defaultUserAgent,
|
||||
)
|
||||
|
||||
setDefaultValue(MDConstants.defaultUserAgent)
|
||||
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
try {
|
||||
Headers.Builder().add("User-Agent", newValue as String)
|
||||
summary = newValue
|
||||
true
|
||||
} catch (e: Throwable) {
|
||||
val errorMessage = helper.intl.format("set_custom_useragent_error_invalid", e.message)
|
||||
Toast.makeText(screen.context, errorMessage, Toast.LENGTH_LONG).show()
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
screen.addPreference(coverQualityPref)
|
||||
screen.addPreference(tryUsingFirstVolumeCoverPref)
|
||||
screen.addPreference(dataSaverPref)
|
||||
|
@ -754,6 +791,7 @@ abstract class MangaDex(final override val lang: String, private val dexLang: St
|
|||
screen.addPreference(originalLanguagePref)
|
||||
screen.addPreference(blockedGroupsPref)
|
||||
screen.addPreference(blockedUploaderPref)
|
||||
screen.addPreference(userAgentPref)
|
||||
}
|
||||
|
||||
override fun getFilterList(): FilterList =
|
||||
|
@ -828,6 +866,12 @@ abstract class MangaDex(final override val lang: String, private val dexLang: St
|
|||
private val SharedPreferences.altTitlesInDesc
|
||||
get() = getBoolean(MDConstants.getAltTitlesInDescPrefKey(dexLang), false)
|
||||
|
||||
private val SharedPreferences.customUserAgent
|
||||
get() = getString(
|
||||
MDConstants.getCustomUserAgentPrefKey(dexLang),
|
||||
MDConstants.defaultUserAgent,
|
||||
)
|
||||
|
||||
/**
|
||||
* Previous versions of the extension allowed invalid UUID values to be stored in the
|
||||
* preferences. This method clear invalid UUIDs in case the user have updated from
|
||||
|
|
|
@ -36,6 +36,8 @@ class MdAtHomeReportInterceptor(
|
|||
return response
|
||||
}
|
||||
|
||||
Log.e("MangaDex", "Connecting to MD@Home node at $url")
|
||||
|
||||
val result = ImageReportDto(
|
||||
url = url,
|
||||
success = response.isSuccessful,
|
||||
|
@ -61,6 +63,8 @@ class MdAtHomeReportInterceptor(
|
|||
return response
|
||||
}
|
||||
|
||||
response.close()
|
||||
|
||||
Log.e("MangaDex", "Error connecting to MD@Home node, fallback to uploads server")
|
||||
|
||||
val fallbackUrl = MDConstants.cdnUrl.toHttpUrl().newBuilder()
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
package eu.kanade.tachiyomi.extension.all.mangadex
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Response
|
||||
import java.io.IOException
|
||||
|
||||
/**
|
||||
* Interceptor to set custom useragent for MangaDex
|
||||
*/
|
||||
class MdUserAgentInterceptor(
|
||||
private val preferences: SharedPreferences,
|
||||
private val dexLang: String,
|
||||
) : Interceptor {
|
||||
|
||||
private val SharedPreferences.customUserAgent
|
||||
get() = getString(
|
||||
MDConstants.getCustomUserAgentPrefKey(dexLang),
|
||||
MDConstants.defaultUserAgent,
|
||||
)
|
||||
|
||||
private fun getUserAgent(): String? {
|
||||
return preferences.customUserAgent
|
||||
}
|
||||
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
try {
|
||||
val originalRequest = chain.request()
|
||||
|
||||
val newUserAgent = getUserAgent() ?: return chain.proceed(originalRequest)
|
||||
|
||||
val originalHeaders = originalRequest.headers
|
||||
|
||||
val modifiedHeaders = originalHeaders.newBuilder()
|
||||
.set("User-Agent", newUserAgent)
|
||||
.build()
|
||||
|
||||
return chain.proceed(
|
||||
originalRequest.newBuilder()
|
||||
.headers(modifiedHeaders)
|
||||
.build(),
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
throw IOException("MdUserAgentInterceptor failed with error: ${e.message}")
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue