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 { | ext { | ||||||
|     extName = 'Asura Scans' |     extName = 'Asura Scans' | ||||||
|     extClass = '.AsuraScans' |     extClass = '.AsuraScans' | ||||||
|     extVersionCode = 44 |     extVersionCode = 45 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| apply from: "$rootDir/common.gradle" | apply from: "$rootDir/common.gradle" | ||||||
|  | |||||||
| @ -17,6 +17,8 @@ import kotlinx.serialization.decodeFromString | |||||||
| import kotlinx.serialization.encodeToString | import kotlinx.serialization.encodeToString | ||||||
| import kotlinx.serialization.json.Json | import kotlinx.serialization.json.Json | ||||||
| import okhttp3.HttpUrl.Companion.toHttpUrl | import okhttp3.HttpUrl.Companion.toHttpUrl | ||||||
|  | import okhttp3.HttpUrl.Companion.toHttpUrlOrNull | ||||||
|  | import okhttp3.Interceptor | ||||||
| import okhttp3.Request | import okhttp3.Request | ||||||
| import okhttp3.Response | import okhttp3.Response | ||||||
| import org.jsoup.nodes.Document | import org.jsoup.nodes.Document | ||||||
| @ -66,9 +68,35 @@ class AsuraScans : ParsedHttpSource(), ConfigurableSource { | |||||||
|     private val json: Json by injectLazy() |     private val json: Json by injectLazy() | ||||||
| 
 | 
 | ||||||
|     override val client = network.cloudflareClient.newBuilder() |     override val client = network.cloudflareClient.newBuilder() | ||||||
|  |         .addInterceptor(::forceHighQualityInterceptor) | ||||||
|         .rateLimit(1, 3) |         .rateLimit(1, 3) | ||||||
|         .build() |         .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() |     override fun headersBuilder() = super.headersBuilder() | ||||||
|         .add("Referer", "$baseUrl/") |         .add("Referer", "$baseUrl/") | ||||||
| 
 | 
 | ||||||
| @ -272,7 +300,16 @@ class AsuraScans : ParsedHttpSource(), ConfigurableSource { | |||||||
|             .joinToString("") { it.data().substringAfter("\"").substringBeforeLast("\"") } |             .joinToString("") { it.data().substringAfter("\"").substringBeforeLast("\"") } | ||||||
|         val pagesData = PAGES_REGEX.find(scriptData)?.groupValues?.get(1) ?: throw Exception("Failed to find chapter pages") |         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 } |         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() |     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" |             summary = "Hides the chapters that require a subscription to view" | ||||||
|             setDefaultValue(true) |             setDefaultValue(true) | ||||||
|         }.let(screen::addPreference) |         }.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> |     private var SharedPreferences.slugMap: MutableMap<String, String> | ||||||
| @ -318,6 +365,10 @@ class AsuraScans : ParsedHttpSource(), ConfigurableSource { | |||||||
|         PREF_HIDE_PREMIUM_CHAPTERS, |         PREF_HIDE_PREMIUM_CHAPTERS, | ||||||
|         true, |         true, | ||||||
|     ) |     ) | ||||||
|  |     private fun SharedPreferences.forceHighQuality(): Boolean = getBoolean( | ||||||
|  |         PREF_FORCE_HIGH_QUALITY, | ||||||
|  |         false, | ||||||
|  |     ) | ||||||
| 
 | 
 | ||||||
|     private fun String.toPermSlugIfNeeded(): String { |     private fun String.toPermSlugIfNeeded(): String { | ||||||
|         if (!preferences.dynamicUrl()) return this |         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 CLEAN_DATE_REGEX = """(\d+)(st|nd|rd|th)""".toRegex() | ||||||
|         private val OLD_FORMAT_MANGA_REGEX = """^/manga/(\d+-)?([^/]+)/?$""".toRegex() |         private val OLD_FORMAT_MANGA_REGEX = """^/manga/(\d+-)?([^/]+)/?$""".toRegex() | ||||||
|         private val OLD_FORMAT_CHAPTER_REGEX = """^/(\d+-)?[^/]*-chapter-\d+(-\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_SLUG_MAP = "pref_slug_map_2" | ||||||
|         private const val PREF_DYNAMIC_URL = "pref_dynamic_url" |         private const val PREF_DYNAMIC_URL = "pref_dynamic_url" | ||||||
|         private const val PREF_HIDE_PREMIUM_CHAPTERS = "pref_hide_premium_chapters" |         private const val PREF_HIDE_PREMIUM_CHAPTERS = "pref_hide_premium_chapters" | ||||||
|  |         private const val PREF_FORCE_HIGH_QUALITY = "pref_force_high_quality" | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Vetle Ledaal
						Vetle Ledaal