Baozimanhua: fix page list parse (#12064)
* Baozimanhua: fix page list parse * Baozimanhua: make interceptor singleton * Baozimanhua: remove some overhead in interceptor
This commit is contained in:
		
							parent
							
								
									05b75dd216
								
							
						
					
					
						commit
						42e6a5064f
					
				| @ -1,3 +1,8 @@ | ||||
| ## 1.2.7 (2022-06-04) | ||||
| 
 | ||||
| - 修复章节图片解析 | ||||
| - 整理筛选器代码 | ||||
| 
 | ||||
| ## 1.2.6 (2022-05-27) | ||||
| 
 | ||||
| - 整理代码 | ||||
|  | ||||
| @ -5,7 +5,7 @@ ext { | ||||
|     extName = 'Baozimanhua' | ||||
|     pkgNameSuffix = 'zh.baozimanhua' | ||||
|     extClass = '.Baozimanhua' | ||||
|     extVersionCode = 6 | ||||
|     extVersionCode = 7 | ||||
| } | ||||
| 
 | ||||
| apply from: "$rootDir/common.gradle" | ||||
|  | ||||
| @ -9,7 +9,11 @@ package eu.kanade.tachiyomi.extension.zh.baozimanhua | ||||
| const val BANNER_BASE64 = "\ | ||||
| ''' | ||||
| 
 | ||||
| tail = b'"\n' | ||||
| tail = b'''\ | ||||
| " | ||||
| const val BANNER_WIDTH = 800 | ||||
| const val BANNER_HEIGHT = 282 | ||||
| ''' | ||||
| 
 | ||||
| with open('src/eu/kanade/tachiyomi/extension/zh/baozimanhua/BannerData.kt', 'wb') as f: | ||||
|     f.write(head) | ||||
|  | ||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -8,24 +8,20 @@ import okhttp3.MediaType.Companion.toMediaType | ||||
| import okhttp3.Response | ||||
| import okhttp3.ResponseBody.Companion.toResponseBody | ||||
| import java.io.ByteArrayOutputStream | ||||
| import java.util.EnumSet | ||||
| import kotlin.math.abs | ||||
| 
 | ||||
| class BannerInterceptor : Interceptor { | ||||
|     private val banner: Bitmap by lazy { | ||||
|         val buffer = Base64.decode(BANNER_BASE64, Base64.DEFAULT) | ||||
|         BitmapFactory.decodeByteArray(buffer, 0, buffer.size) | ||||
|     } | ||||
|     private val w by lazy { banner.width } | ||||
|     private val h by lazy { banner.height } | ||||
|     private val size by lazy { w * h } | ||||
| object BannerInterceptor : Interceptor { | ||||
|     private const val w = BANNER_WIDTH | ||||
|     private const val h = BANNER_HEIGHT | ||||
|     private const val size = w * h | ||||
|     private const val threshold = w * h * 3 // 1 per pixel per channel | ||||
|     private val bannerBuffer by lazy { | ||||
|         val buffer = IntArray(size) | ||||
|         banner.getPixels(buffer, 0, w, 0, 0, w, h) | ||||
|         banner.recycle() | ||||
|         buffer | ||||
|         val buffer = Base64.decode(BANNER_BASE64, Base64.DEFAULT) | ||||
|         val banner = BitmapFactory.decodeByteArray(buffer, 0, buffer.size) | ||||
|         val pixels = IntArray(size) | ||||
|         banner.getPixels(pixels, 0, w, 0, 0, w, h) | ||||
|         pixels | ||||
|     } | ||||
|     private val threshold by lazy { w * h * 3 } // 1 per pixel per channel | ||||
| 
 | ||||
|     override fun intercept(chain: Interceptor.Chain): Response { | ||||
|         val url = chain.request().url.toString() | ||||
| @ -36,12 +32,12 @@ class BannerInterceptor : Interceptor { | ||||
|         val content = body.bytes() | ||||
|         val bitmap = BitmapFactory.decodeByteArray(content, 0, content.size) | ||||
|         val positions = checkBanner(bitmap) | ||||
|         return if (positions.isEmpty()) { | ||||
|         return if (positions == 0) { | ||||
|             response.newBuilder().body(content.toResponseBody(contentType)).build() | ||||
|         } else { | ||||
|             val result = Bitmap.createBitmap( | ||||
|                 bitmap, 0, if (positions.contains(BannerPosition.TOP)) h else 0, | ||||
|                 bitmap.width, bitmap.height - h * positions.size | ||||
|                 bitmap, 0, if (positions and TOP == TOP) h else 0, | ||||
|                 bitmap.width, bitmap.height - if (positions == BOTH) h * 2 else h | ||||
|             ) | ||||
|             val output = ByteArrayOutputStream() | ||||
|             result.compress(Bitmap.CompressFormat.JPEG, 90, output) | ||||
| @ -50,16 +46,16 @@ class BannerInterceptor : Interceptor { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private fun checkBanner(image: Bitmap): EnumSet<BannerPosition> { | ||||
|         val result = EnumSet.noneOf(BannerPosition::class.java) | ||||
|         if (image.width < w || image.height < h) return result | ||||
|         if ((image.width - w) % 2 != 0) return result | ||||
|     private fun checkBanner(image: Bitmap): Int { | ||||
|         if (image.width < w || image.height < h) return 0 | ||||
|         if ((image.width - w) % 2 != 0) return 0 | ||||
|         val pad = (image.width - w) / 2 | ||||
|         val buf = IntArray(size) | ||||
|         var result = 0 | ||||
|         image.getPixels(buf, 0, w, pad, 0, w, h) // top | ||||
|         if (isIdentical(bannerBuffer, buf)) result.add(BannerPosition.TOP) | ||||
|         if (isIdentical(bannerBuffer, buf)) result = result or TOP | ||||
|         image.getPixels(buf, 0, w, pad, image.height - h, w, h) // bottom | ||||
|         if (isIdentical(bannerBuffer, buf)) result.add(BannerPosition.BOTTOM) | ||||
|         if (isIdentical(bannerBuffer, buf)) result = result or BOTTOM | ||||
|         return result | ||||
|     } | ||||
| 
 | ||||
| @ -76,7 +72,9 @@ class BannerInterceptor : Interceptor { | ||||
|         return true | ||||
|     } | ||||
| 
 | ||||
|     private enum class BannerPosition { TOP, BOTTOM } | ||||
| } | ||||
|     private const val TOP = 0b01 | ||||
|     private const val BOTTOM = 0b10 | ||||
|     private const val BOTH = 0b11 | ||||
| 
 | ||||
|     const val COMIC_IMAGE_SUFFIX = "#baozi" | ||||
| } | ||||
|  | ||||
| @ -40,7 +40,7 @@ class Baozimanhua : ParsedHttpSource(), ConfigurableSource { | ||||
|     override val supportsLatest = true | ||||
| 
 | ||||
|     override val client: OkHttpClient = network.cloudflareClient.newBuilder() | ||||
|         .addInterceptor(BannerInterceptor()).build() | ||||
|         .addInterceptor(BannerInterceptor).build() | ||||
| 
 | ||||
|     override fun chapterListSelector() = throw UnsupportedOperationException("Not used.") | ||||
| 
 | ||||
| @ -108,8 +108,8 @@ class Baozimanhua : ParsedHttpSource(), ConfigurableSource { | ||||
|     } | ||||
| 
 | ||||
|     override fun pageListParse(document: Document): List<Page> { | ||||
|         return document.select(".comic-contain > .chapter-img > img").mapIndexed { index, element -> | ||||
|             Page(index, imageUrl = element.attr("data-src").trim() + COMIC_IMAGE_SUFFIX) | ||||
|         return document.select(".comic-contain > amp-img").mapIndexed { index, element -> | ||||
|             Page(index, imageUrl = element.attr("src").trim() + BannerInterceptor.COMIC_IMAGE_SUFFIX) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -145,27 +145,8 @@ class Baozimanhua : ParsedHttpSource(), ConfigurableSource { | ||||
|         return if (query.isNotEmpty()) { | ||||
|             GET("$baseUrl/search?q=$query", headers) | ||||
|         } else { | ||||
|             lateinit var tag: String | ||||
|             lateinit var region: String | ||||
|             lateinit var status: String | ||||
|             lateinit var start: String | ||||
|             filters.forEach { filter -> | ||||
|                 when (filter) { | ||||
|                     is TagFilter -> { | ||||
|                         tag = filter.toUriPart() | ||||
|                     } | ||||
|                     is RegionFilter -> { | ||||
|                         region = filter.toUriPart() | ||||
|                     } | ||||
|                     is StatusFilter -> { | ||||
|                         status = filter.toUriPart() | ||||
|                     } | ||||
|                     is StartFilter -> { | ||||
|                         start = filter.toUriPart() | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             GET("$baseUrl/classify?type=$tag®ion=$region&state=$status&filter=$start&page=$page") | ||||
|             val parts = filters.filterIsInstance<UriPartFilter>().joinToString("&") { it.toUriPart() } | ||||
|             GET("$baseUrl/classify?page=$page&$parts", headers) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -194,13 +175,14 @@ class Baozimanhua : ParsedHttpSource(), ConfigurableSource { | ||||
|         StartFilter() | ||||
|     ) | ||||
| 
 | ||||
|     private open class UriPartFilter(displayName: String, val vals: Array<Pair<String, String>>) : | ||||
|         Filter.Select<String>(displayName, vals.map { it.first }.toTypedArray()) { | ||||
|         fun toUriPart() = vals[state].second | ||||
|     private open class UriPartFilter(name: String, val query: String, val vals: Array<Pair<String, String>>) : | ||||
|         Filter.Select<String>(name, vals.map { it.first }.toTypedArray()) { | ||||
|         fun toUriPart() = "$query=${vals[state].second}" | ||||
|     } | ||||
| 
 | ||||
|     private class TagFilter : UriPartFilter( | ||||
|         "标签", | ||||
|         "type", | ||||
|         arrayOf( | ||||
|             Pair("全部", "all"), | ||||
|             Pair("都市", "dushi"), | ||||
| @ -271,6 +253,7 @@ class Baozimanhua : ParsedHttpSource(), ConfigurableSource { | ||||
| 
 | ||||
|     private class RegionFilter : UriPartFilter( | ||||
|         "地区", | ||||
|         "region", | ||||
|         arrayOf( | ||||
|             Pair("全部", "all"), | ||||
|             Pair("国漫", "cn"), | ||||
| @ -282,6 +265,7 @@ class Baozimanhua : ParsedHttpSource(), ConfigurableSource { | ||||
| 
 | ||||
|     private class StatusFilter : UriPartFilter( | ||||
|         "进度", | ||||
|         "state", | ||||
|         arrayOf( | ||||
|             Pair("全部", "all"), | ||||
|             Pair("连载中", "serial"), | ||||
| @ -291,6 +275,7 @@ class Baozimanhua : ParsedHttpSource(), ConfigurableSource { | ||||
| 
 | ||||
|     private class StartFilter : UriPartFilter( | ||||
|         "标题开头", | ||||
|         "filter", | ||||
|         arrayOf( | ||||
|             Pair("全部", "*"), | ||||
|             Pair("ABCD", "ABCD"), | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 kasperskier
						kasperskier