Tsumino: bypass email protection (#10760)
* Tsumino: bypass email protection * Rewrite cfDecodeEmail Use less magic, safety is kept in mind for the key and data. Invalid key returns an empty string, invalid data is skipped. Returns not null since the Element.text() function validates that the input is not null -- and it's probably a useless distincion anyways. * further kotlin-ify cfDecodeEmails
This commit is contained in:
parent
383ba02bfc
commit
82d8a2f2ab
|
@ -6,7 +6,7 @@ ext {
|
||||||
extName = 'Tsumino'
|
extName = 'Tsumino'
|
||||||
pkgNameSuffix = 'en.tsumino'
|
pkgNameSuffix = 'en.tsumino'
|
||||||
extClass = '.Tsumino'
|
extClass = '.Tsumino'
|
||||||
extVersionCode = 5
|
extVersionCode = 6
|
||||||
isNsfw = true
|
isNsfw = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package eu.kanade.tachiyomi.extension.en.tsumino
|
package eu.kanade.tachiyomi.extension.en.tsumino
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.extension.en.tsumino.TsuminoUtils.Companion.cfDecodeEmails
|
||||||
import eu.kanade.tachiyomi.extension.en.tsumino.TsuminoUtils.Companion.getArtists
|
import eu.kanade.tachiyomi.extension.en.tsumino.TsuminoUtils.Companion.getArtists
|
||||||
import eu.kanade.tachiyomi.extension.en.tsumino.TsuminoUtils.Companion.getChapter
|
import eu.kanade.tachiyomi.extension.en.tsumino.TsuminoUtils.Companion.getChapter
|
||||||
import eu.kanade.tachiyomi.extension.en.tsumino.TsuminoUtils.Companion.getCollection
|
import eu.kanade.tachiyomi.extension.en.tsumino.TsuminoUtils.Companion.getCollection
|
||||||
|
@ -160,13 +161,13 @@ class Tsumino : HttpSource() {
|
||||||
val document = response.asJsoup()
|
val document = response.asJsoup()
|
||||||
val infoElement = document.select("div.book-page-container")
|
val infoElement = document.select("div.book-page-container")
|
||||||
return SManga.create().apply {
|
return SManga.create().apply {
|
||||||
title = infoElement.select("#Title").text()
|
title = document.select("meta[property=og:title]").first()!!.attr("content")
|
||||||
artist = getArtists(document)
|
artist = getArtists(document)
|
||||||
author = artist
|
author = artist
|
||||||
status = SManga.COMPLETED
|
status = SManga.COMPLETED
|
||||||
thumbnail_url = infoElement.select("img").attr("src")
|
thumbnail_url = infoElement.select("img").attr("src")
|
||||||
description = getDesc(document)
|
description = getDesc(document)
|
||||||
genre = document.select("#Tag a").joinToString { it.text() }
|
genre = document.select("#Tag a").joinToString { it.attr("data-define") }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,6 +175,8 @@ class Tsumino : HttpSource() {
|
||||||
|
|
||||||
override fun chapterListParse(response: Response): List<SChapter> {
|
override fun chapterListParse(response: Response): List<SChapter> {
|
||||||
val document = response.asJsoup()
|
val document = response.asJsoup()
|
||||||
|
cfDecodeEmails(document)
|
||||||
|
|
||||||
val collection = document.select(".book-collection-table a")
|
val collection = document.select(".book-collection-table a")
|
||||||
return if (collection.isNotEmpty()) {
|
return if (collection.isNotEmpty()) {
|
||||||
getCollection(document, ".book-collection-table a")
|
getCollection(document, ".book-collection-table a")
|
||||||
|
|
|
@ -11,7 +11,7 @@ class TsuminoUtils {
|
||||||
val artists = document.select("#Artist a")
|
val artists = document.select("#Artist a")
|
||||||
|
|
||||||
artists.forEach {
|
artists.forEach {
|
||||||
stringBuilder.append(it.text())
|
stringBuilder.append(it.attr("data-define"))
|
||||||
|
|
||||||
if (it != artists.last())
|
if (it != artists.last())
|
||||||
stringBuilder.append(", ")
|
stringBuilder.append(", ")
|
||||||
|
@ -25,7 +25,7 @@ class TsuminoUtils {
|
||||||
val groups = document.select("#Group a")
|
val groups = document.select("#Group a")
|
||||||
|
|
||||||
groups.forEach {
|
groups.forEach {
|
||||||
stringBuilder.append(it.text())
|
stringBuilder.append(it.attr("data-define"))
|
||||||
|
|
||||||
if (it != groups.last())
|
if (it != groups.last())
|
||||||
stringBuilder.append(", ")
|
stringBuilder.append(", ")
|
||||||
|
@ -47,7 +47,7 @@ class TsuminoUtils {
|
||||||
stringBuilder.append("Parodies: ")
|
stringBuilder.append("Parodies: ")
|
||||||
|
|
||||||
parodies.forEach {
|
parodies.forEach {
|
||||||
stringBuilder.append(it.text())
|
stringBuilder.append(it.attr("data-define"))
|
||||||
|
|
||||||
if (it != parodies.last())
|
if (it != parodies.last())
|
||||||
stringBuilder.append(", ")
|
stringBuilder.append(", ")
|
||||||
|
@ -59,7 +59,7 @@ class TsuminoUtils {
|
||||||
stringBuilder.append("Characters: ")
|
stringBuilder.append("Characters: ")
|
||||||
|
|
||||||
characters.forEach {
|
characters.forEach {
|
||||||
stringBuilder.append(it.text())
|
stringBuilder.append(it.attr("data-define"))
|
||||||
|
|
||||||
if (it != characters.last())
|
if (it != characters.last())
|
||||||
stringBuilder.append(", ")
|
stringBuilder.append(", ")
|
||||||
|
@ -93,5 +93,26 @@ class TsuminoUtils {
|
||||||
chapterList.add(chapter)
|
chapterList.add(chapter)
|
||||||
return chapterList
|
return chapterList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun cfDecodeEmails(document: Document) {
|
||||||
|
document.select(".__cf_email__")!!
|
||||||
|
.map { it to cfDecodeEmail(it.attr("data-cfemail")) }
|
||||||
|
.forEach { (element, plaintext) -> element.text(plaintext) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun cfDecodeEmail(encoded: String): String {
|
||||||
|
val encodedList = encoded
|
||||||
|
.chunked(2)
|
||||||
|
.map { it.toIntOrNull(16) }
|
||||||
|
|
||||||
|
val key = encodedList
|
||||||
|
.firstOrNull()
|
||||||
|
?: return ""
|
||||||
|
|
||||||
|
return encodedList
|
||||||
|
.drop(1)
|
||||||
|
.mapNotNull { it?.xor(key)?.toChar() }
|
||||||
|
.joinToString("")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue