add Manhuakey (#2317)

* add ManhuaKey (th)

* newline

* remove log
This commit is contained in:
AwkwardPeak7 2024-04-10 22:42:28 +05:00 committed by Draff
parent d726f9eee1
commit bb0db200aa
7 changed files with 122 additions and 0 deletions

View File

@ -0,0 +1,14 @@
ext {
extName = 'ManhuaKey'
extClass = '.ManhuaKey'
themePkg = 'madara'
baseUrl = 'https://www.manhuakey.com'
overrideVersionCode = 0
isNsfw = true
}
apply from: "$rootDir/common.gradle"
dependencies {
implementation(project(":lib:unpacker"))
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,108 @@
package eu.kanade.tachiyomi.extension.th.manhuakey
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Rect
import eu.kanade.tachiyomi.lib.unpacker.Unpacker
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.source.model.Page
import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import okhttp3.Interceptor
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.Response
import okhttp3.ResponseBody.Companion.toResponseBody
import org.jsoup.nodes.Document
import java.io.ByteArrayOutputStream
class ManhuaKey : Madara("ManhuaKey", "https://www.manhuakey.com", "th") {
override val filterNonMangaItems = false
override fun searchMangaSelector() = "div.page-item-detail"
override val client = super.client.newBuilder()
.addNetworkInterceptor(::imageDescrambler)
.build()
override val pageListParseSelector = ".reading-content img, .reading-content div.displayImage + script:containsData(p,a,c,k,e,d)"
override fun pageListParse(document: Document): List<Page> {
launchIO { countViews(document) }
val location = document.location()
return document.select(pageListParseSelector).mapIndexed { idx, element ->
if (element.tagName().equals("img")) {
Page(idx, location, imageFromElement(element))
} else {
val unpackedScript = Unpacker.unpack(element.data())
val blockWidth = blockWidthRegex.find(unpackedScript)!!.groupValues[1].toInt()
val blockHeight = blockHeightRegex.find(unpackedScript)!!.groupValues[1].toInt()
val matrix = unpackedScript.substringAfter("[")
.substringBefore("];")
.let { "[$it]" }
val scrambledImageUrl = unpackedScript.substringAfter("url(")
.substringBefore(");")
val data = ScramblingData(
blockWidth = blockWidth,
blockHeight = blockHeight,
matrix = json.decodeFromString(matrix),
)
Page(idx, location, "$scrambledImageUrl#${json.encodeToString(data)}")
}
}
}
private val blockWidthRegex = Regex("""width:\s*"?\s*\+?\s*(\d+)\s*\+?\s*"?px;""")
private val blockHeightRegex = Regex("""height:\s*"?\s*\+?\s*(\d+)\s*\+?\s*"?px;""")
@Serializable
class ScramblingData(
val blockWidth: Int,
val blockHeight: Int,
val matrix: List<List<Double>>,
)
private fun imageDescrambler(chain: Interceptor.Chain): Response {
val request = chain.request()
val response = chain.proceed(request)
if (request.url.fragment.isNullOrEmpty()) {
return response
}
val scramblingData = json.decodeFromString<ScramblingData>(request.url.fragment!!)
val scrambledImg = BitmapFactory.decodeStream(response.body.byteStream())
val descrambledImg = Bitmap.createBitmap(scrambledImg.width, scrambledImg.height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(descrambledImg)
for (pos in scramblingData.matrix) {
val srcRect = Rect(
pos[2].toInt(),
pos[3].toInt(),
pos[2].toInt() + scramblingData.blockWidth,
pos[3].toInt() + scramblingData.blockHeight,
)
val destRect = Rect(
pos[0].toInt(),
pos[1].toInt(),
pos[0].toInt() + scramblingData.blockWidth,
pos[1].toInt() + scramblingData.blockHeight,
)
canvas.drawBitmap(scrambledImg, srcRect, destRect, null)
}
val output = ByteArrayOutputStream()
descrambledImg.compress(Bitmap.CompressFormat.JPEG, 90, output)
val image = output.toByteArray()
val body = image.toResponseBody("image/jpeg".toMediaType())
return response.newBuilder()
.body(body)
.build()
}
}