Asura Scans: support high quality chapter images (#6657)
* Asura Scans: support high quality chapter images * Only rewrite chapter images, add fallback if broken - explained in ext settings
This commit is contained in:
parent
0382073769
commit
f03fd3c5f7
|
@ -1,7 +1,7 @@
|
|||
ext {
|
||||
extName = 'Asura Scans'
|
||||
extClass = '.AsuraScans'
|
||||
extVersionCode = 44
|
||||
extVersionCode = 45
|
||||
}
|
||||
|
||||
apply from: "$rootDir/common.gradle"
|
||||
|
|
|
@ -17,6 +17,8 @@ import kotlinx.serialization.decodeFromString
|
|||
import kotlinx.serialization.encodeToString
|
||||
import kotlinx.serialization.json.Json
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import org.jsoup.nodes.Document
|
||||
|
@ -66,9 +68,35 @@ class AsuraScans : ParsedHttpSource(), ConfigurableSource {
|
|||
private val json: Json by injectLazy()
|
||||
|
||||
override val client = network.cloudflareClient.newBuilder()
|
||||
.addInterceptor(::forceHighQualityInterceptor)
|
||||
.rateLimit(1, 3)
|
||||
.build()
|
||||
|
||||
private var failedHighQuality = false
|
||||
|
||||
private fun forceHighQualityInterceptor(chain: Interceptor.Chain): Response {
|
||||
val request = chain.request()
|
||||
|
||||
if (preferences.forceHighQuality() && !failedHighQuality && request.url.fragment == "pageListParse") {
|
||||
OPTIMIZED_IMAGE_PATH_REGEX.find(request.url.encodedPath)?.also { match ->
|
||||
val (id, page) = match.destructured
|
||||
val newUrl = request.url.newBuilder()
|
||||
.encodedPath("/storage/media/$id/$page.webp")
|
||||
.build()
|
||||
|
||||
val response = chain.proceed(request.newBuilder().url(newUrl).build())
|
||||
if (response.code != 404) {
|
||||
return response
|
||||
} else {
|
||||
failedHighQuality = true
|
||||
response.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return chain.proceed(request)
|
||||
}
|
||||
|
||||
override fun headersBuilder() = super.headersBuilder()
|
||||
.add("Referer", "$baseUrl/")
|
||||
|
||||
|
@ -272,7 +300,16 @@ class AsuraScans : ParsedHttpSource(), ConfigurableSource {
|
|||
.joinToString("") { it.data().substringAfter("\"").substringBeforeLast("\"") }
|
||||
val pagesData = PAGES_REGEX.find(scriptData)?.groupValues?.get(1) ?: throw Exception("Failed to find chapter pages")
|
||||
val pageList = json.decodeFromString<List<PageDto>>(pagesData.unescape()).sortedBy { it.order }
|
||||
return pageList.mapIndexed { i, page -> Page(i, imageUrl = page.url) }
|
||||
return pageList.mapIndexed { i, page ->
|
||||
val newUrl = page.url.toHttpUrlOrNull()?.run {
|
||||
newBuilder()
|
||||
.fragment("pageListParse")
|
||||
.build()
|
||||
.toString()
|
||||
}
|
||||
|
||||
Page(i, imageUrl = newUrl ?: page.url)
|
||||
}
|
||||
}
|
||||
|
||||
override fun imageUrlParse(document: Document) = throw UnsupportedOperationException()
|
||||
|
@ -296,6 +333,16 @@ class AsuraScans : ParsedHttpSource(), ConfigurableSource {
|
|||
summary = "Hides the chapters that require a subscription to view"
|
||||
setDefaultValue(true)
|
||||
}.let(screen::addPreference)
|
||||
|
||||
SwitchPreferenceCompat(screen.context).apply {
|
||||
key = PREF_FORCE_HIGH_QUALITY
|
||||
title = "Force high quality chapter images"
|
||||
summary = "Attempt to use high quality chapter images.\nWill increase bandwidth by ~50%."
|
||||
if (failedHighQuality) {
|
||||
summary = "$summary\n*DISABLED* because of missing high quality images."
|
||||
}
|
||||
setDefaultValue(false)
|
||||
}.let(screen::addPreference)
|
||||
}
|
||||
|
||||
private var SharedPreferences.slugMap: MutableMap<String, String>
|
||||
|
@ -318,6 +365,10 @@ class AsuraScans : ParsedHttpSource(), ConfigurableSource {
|
|||
PREF_HIDE_PREMIUM_CHAPTERS,
|
||||
true,
|
||||
)
|
||||
private fun SharedPreferences.forceHighQuality(): Boolean = getBoolean(
|
||||
PREF_FORCE_HIGH_QUALITY,
|
||||
false,
|
||||
)
|
||||
|
||||
private fun String.toPermSlugIfNeeded(): String {
|
||||
if (!preferences.dynamicUrl()) return this
|
||||
|
@ -337,8 +388,11 @@ class AsuraScans : ParsedHttpSource(), ConfigurableSource {
|
|||
private val CLEAN_DATE_REGEX = """(\d+)(st|nd|rd|th)""".toRegex()
|
||||
private val OLD_FORMAT_MANGA_REGEX = """^/manga/(\d+-)?([^/]+)/?$""".toRegex()
|
||||
private val OLD_FORMAT_CHAPTER_REGEX = """^/(\d+-)?[^/]*-chapter-\d+(-\d+)*/?$""".toRegex()
|
||||
private val OPTIMIZED_IMAGE_PATH_REGEX = """^/storage/media/(\d+)/conversions/(.*)-optimized\.webp$""".toRegex()
|
||||
|
||||
private const val PREF_SLUG_MAP = "pref_slug_map_2"
|
||||
private const val PREF_DYNAMIC_URL = "pref_dynamic_url"
|
||||
private const val PREF_HIDE_PREMIUM_CHAPTERS = "pref_hide_premium_chapters"
|
||||
private const val PREF_FORCE_HIGH_QUALITY = "pref_force_high_quality"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue