diff --git a/src/zh/baozimanhua/CHANGELOG.md b/src/zh/baozimanhua/CHANGELOG.md index 75c83454d..27cc47868 100644 --- a/src/zh/baozimanhua/CHANGELOG.md +++ b/src/zh/baozimanhua/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.2.6 (2022-05-27) + +- 整理代码 +- 切除部分罕见情况上下端都有的 banner +- 修复部分章节较少的漫画解析章节列表为空的问题 + ## 1.2.5 (2022-05-17) - 提高 banner 识别容错率,切除噪声更多的 banner diff --git a/src/zh/baozimanhua/build.gradle b/src/zh/baozimanhua/build.gradle index b33aec10e..4fbd30bc6 100644 --- a/src/zh/baozimanhua/build.gradle +++ b/src/zh/baozimanhua/build.gradle @@ -5,7 +5,7 @@ ext { extName = 'Baozimanhua' pkgNameSuffix = 'zh.baozimanhua' extClass = '.Baozimanhua' - extVersionCode = 5 + extVersionCode = 6 } apply from: "$rootDir/common.gradle" diff --git a/src/zh/baozimanhua/src/eu/kanade/tachiyomi/extension/zh/baozimanhua/BannerInterceptor.kt b/src/zh/baozimanhua/src/eu/kanade/tachiyomi/extension/zh/baozimanhua/BannerInterceptor.kt index 2fd93a92f..9fb9aefb3 100644 --- a/src/zh/baozimanhua/src/eu/kanade/tachiyomi/extension/zh/baozimanhua/BannerInterceptor.kt +++ b/src/zh/baozimanhua/src/eu/kanade/tachiyomi/extension/zh/baozimanhua/BannerInterceptor.kt @@ -8,6 +8,7 @@ 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 { @@ -34,17 +35,13 @@ class BannerInterceptor : Interceptor { val contentType = body.contentType() val content = body.bytes() val bitmap = BitmapFactory.decodeByteArray(content, 0, content.size) - val position = checkBanner(bitmap) - return if (position == null) { + val positions = checkBanner(bitmap) + return if (positions.isEmpty()) { response.newBuilder().body(content.toResponseBody(contentType)).build() } else { val result = Bitmap.createBitmap( - bitmap, 0, - when (position) { - BannerPosition.TOP -> h - BannerPosition.BOTTOM -> 0 - }, - bitmap.width, bitmap.height - h + bitmap, 0, if (positions.contains(BannerPosition.TOP)) h else 0, + bitmap.width, bitmap.height - h * positions.size ) val output = ByteArrayOutputStream() result.compress(Bitmap.CompressFormat.JPEG, 90, output) @@ -53,16 +50,17 @@ class BannerInterceptor : Interceptor { } } - private fun checkBanner(image: Bitmap): BannerPosition? { - if (image.width < w || image.height < h) return null - if ((image.width - w) % 2 != 0) return null + private fun checkBanner(image: Bitmap): EnumSet { + val result = EnumSet.noneOf(BannerPosition::class.java) + if (image.width < w || image.height < h) return result + if ((image.width - w) % 2 != 0) return result val pad = (image.width - w) / 2 val buf = IntArray(size) image.getPixels(buf, 0, w, pad, 0, w, h) // top - if (isIdentical(bannerBuffer, buf)) return BannerPosition.TOP + if (isIdentical(bannerBuffer, buf)) result.add(BannerPosition.TOP) image.getPixels(buf, 0, w, pad, image.height - h, w, h) // bottom - if (isIdentical(bannerBuffer, buf)) return BannerPosition.BOTTOM - return null + if (isIdentical(bannerBuffer, buf)) result.add(BannerPosition.BOTTOM) + return result } private fun isIdentical(a: IntArray, b: IntArray): Boolean { diff --git a/src/zh/baozimanhua/src/eu/kanade/tachiyomi/extension/zh/baozimanhua/Baozimanhua.kt b/src/zh/baozimanhua/src/eu/kanade/tachiyomi/extension/zh/baozimanhua/Baozimanhua.kt index 5c72b8a64..5fd536613 100644 --- a/src/zh/baozimanhua/src/eu/kanade/tachiyomi/extension/zh/baozimanhua/Baozimanhua.kt +++ b/src/zh/baozimanhua/src/eu/kanade/tachiyomi/extension/zh/baozimanhua/Baozimanhua.kt @@ -40,17 +40,18 @@ class Baozimanhua : ParsedHttpSource(), ConfigurableSource { override val supportsLatest = true override val client: OkHttpClient = network.cloudflareClient.newBuilder() - .addNetworkInterceptor(BannerInterceptor()).build() + .addInterceptor(BannerInterceptor()).build() - override fun chapterListSelector(): String = "div.pure-g[id^=chapter] > div" + override fun chapterListSelector() = throw UnsupportedOperationException("Not used.") override fun chapterListParse(response: Response): List { val document = response.asJsoup() - val chapters = document.select(chapterListSelector()).map { element -> - chapterFromElement(element) - } - // chapters are listed oldest to newest in the source - return chapters.reversed() + return if (document.select(".l-box > .pure-g").size == 1) { // only latest chapters + document.select(".l-box > .pure-g > div") + } else { + // chapters are listed oldest to newest in the source + document.select(".l-box > .pure-g[id^=chapter] > div").reversed() + }.map { chapterFromElement(it) } } override fun chapterFromElement(element: Element): SChapter { @@ -70,15 +71,12 @@ class Baozimanhua : ParsedHttpSource(), ConfigurableSource { } } - override fun popularMangaNextPageSelector() = throw java.lang.UnsupportedOperationException("Not used.") + override fun popularMangaNextPageSelector(): String? = null - override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/classify", headers) + override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/classify?page=$page", headers) override fun popularMangaParse(response: Response): MangasPage { - val document = response.asJsoup() - val mangas = document.select(popularMangaSelector()).map { element -> - popularMangaFromElement(element) - } + val mangas = super.popularMangaParse(response).mangas return MangasPage(mangas, mangas.size == 36) } @@ -88,18 +86,10 @@ class Baozimanhua : ParsedHttpSource(), ConfigurableSource { return popularMangaFromElement(element) } - override fun latestUpdatesNextPageSelector() = throw java.lang.UnsupportedOperationException("Not used.") + override fun latestUpdatesNextPageSelector(): String? = null override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/list/new", headers) - override fun latestUpdatesParse(response: Response): MangasPage { - val document = response.asJsoup() - val mangas = document.select(popularMangaSelector()).map { element -> - popularMangaFromElement(element) - } - return MangasPage(mangas, mangas.size == 12) - } - override fun mangaDetailsParse(document: Document): SManga { return SManga.create().apply { title = document.select("h1.comics-detail__title").text().trim() @@ -113,23 +103,23 @@ class Baozimanhua : ParsedHttpSource(), ConfigurableSource { "已完結" -> SManga.COMPLETED else -> SManga.UNKNOWN } + // TODO: upload date by selector "em" in format "(2021年06月29日 更新)" } } override fun pageListParse(document: Document): List { - val pages = document.select(".comic-contain > .chapter-img > img").mapIndexed { index, element -> + return document.select(".comic-contain > .chapter-img > img").mapIndexed { index, element -> Page(index, imageUrl = element.attr("data-src").trim() + COMIC_IMAGE_SUFFIX) } - return pages } override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("Not used.") - override fun searchMangaSelector() = throw java.lang.UnsupportedOperationException("Not used.") + override fun searchMangaSelector() = throw UnsupportedOperationException("Not used.") - override fun searchMangaFromElement(element: Element) = throw java.lang.UnsupportedOperationException("Not used.") + override fun searchMangaFromElement(element: Element) = throw UnsupportedOperationException("Not used.") - override fun searchMangaNextPageSelector() = throw java.lang.UnsupportedOperationException("Not used.") + override fun searchMangaNextPageSelector() = throw UnsupportedOperationException("Not used.") override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable { return if (query.startsWith(ID_SEARCH_PREFIX)) {