parent
4c520021b8
commit
e5bcf9190f
|
@ -5,8 +5,12 @@ ext {
|
||||||
extName = 'Manhwa-Latino'
|
extName = 'Manhwa-Latino'
|
||||||
pkgNameSuffix = 'es.manhwalatino'
|
pkgNameSuffix = 'es.manhwalatino'
|
||||||
extClass = '.ManhwaLatino'
|
extClass = '.ManhwaLatino'
|
||||||
extVersionCode = 22
|
extVersionCode = 23
|
||||||
isNsfw = true
|
isNsfw = true
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
apply from: "$rootDir/common.gradle"
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(project(':lib-cryptoaes'))
|
||||||
|
}
|
||||||
|
|
|
@ -35,6 +35,6 @@ object MLConstants {
|
||||||
const val chapterLinkParser = "a"
|
const val chapterLinkParser = "a"
|
||||||
const val chapterReleaseDateLinkParser = "span.chapter-release-date a"
|
const val chapterReleaseDateLinkParser = "span.chapter-release-date a"
|
||||||
const val chapterReleaseDateIParser = "span.chapter-release-date i"
|
const val chapterReleaseDateIParser = "span.chapter-release-date i"
|
||||||
const val pageListParseSelector = "div.read-container img"
|
const val pageListParseSelector = "div.read-container script"
|
||||||
const val imageAttribute = "abs:data-src"
|
const val imageAttribute = "abs:data-src"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package eu.kanade.tachiyomi.extension.es.manhwalatino
|
package eu.kanade.tachiyomi.extension.es.manhwalatino
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import android.util.Base64
|
||||||
import eu.kanade.tachiyomi.extension.es.manhwalatino.filters.UriFilter
|
import eu.kanade.tachiyomi.extension.es.manhwalatino.filters.UriFilter
|
||||||
|
import eu.kanade.tachiyomi.lib.cryptoaes.CryptoAES
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.asObservableSuccess
|
import eu.kanade.tachiyomi.network.asObservableSuccess
|
||||||
import eu.kanade.tachiyomi.source.model.FilterList
|
import eu.kanade.tachiyomi.source.model.FilterList
|
||||||
|
@ -10,6 +12,10 @@ import eu.kanade.tachiyomi.source.model.Page
|
||||||
import eu.kanade.tachiyomi.source.model.SChapter
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import eu.kanade.tachiyomi.util.asJsoup
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.json.jsonArray
|
||||||
|
import kotlinx.serialization.json.jsonObject
|
||||||
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
|
@ -17,6 +23,7 @@ import org.jsoup.nodes.Document
|
||||||
import org.jsoup.nodes.Element
|
import org.jsoup.nodes.Element
|
||||||
import org.jsoup.select.Elements
|
import org.jsoup.select.Elements
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
@ -39,6 +46,8 @@ class ManhwaLatinoSiteParser(
|
||||||
*/
|
*/
|
||||||
private var searchType = SearchType.SEARCH_FREE
|
private var searchType = SearchType.SEARCH_FREE
|
||||||
|
|
||||||
|
private val json by injectLazy<Json>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Latest Updates are in a Slider, this Methods get a Manga from the slide
|
* The Latest Updates are in a Slider, this Methods get a Manga from the slide
|
||||||
*/
|
*/
|
||||||
|
@ -251,12 +260,32 @@ class ManhwaLatinoSiteParser(
|
||||||
* @param response the response from the site.
|
* @param response the response from the site.
|
||||||
*/
|
*/
|
||||||
fun getPageListParse(response: Response): List<Page> {
|
fun getPageListParse(response: Response): List<Page> {
|
||||||
val list =
|
val document = response.asJsoup()
|
||||||
response.asJsoup().select(MLConstants.pageListParseSelector)
|
val scripUrl = document.select(MLConstants.pageListParseSelector).attr("src")
|
||||||
.mapIndexed { index, imgElement ->
|
val script = client.newCall(GET(scripUrl, headers)).execute().asJsoup().text()
|
||||||
Page(index, "", getImage(imgElement))
|
|
||||||
|
val password = script
|
||||||
|
.substringAfter("wpmangaprotectornonce='")
|
||||||
|
.substringBefore("';")
|
||||||
|
|
||||||
|
val chapterData = json.parseToJsonElement(
|
||||||
|
script
|
||||||
|
.substringAfter("chapter_data='")
|
||||||
|
.substringBefore("';")
|
||||||
|
.replace("\\/", "/"),
|
||||||
|
).jsonObject
|
||||||
|
|
||||||
|
val unsaltedCiphertext = Base64.decode(chapterData["ct"]!!.jsonPrimitive.content, Base64.DEFAULT)
|
||||||
|
val salt = chapterData["s"]!!.jsonPrimitive.content.decodeHex()
|
||||||
|
val ciphertext = SALTED + salt + unsaltedCiphertext
|
||||||
|
|
||||||
|
val rawImgArray = CryptoAES.decrypt(Base64.encodeToString(ciphertext, Base64.DEFAULT), password)
|
||||||
|
val imgArrayString = json.parseToJsonElement(rawImgArray).jsonPrimitive.content
|
||||||
|
val imgArray = json.parseToJsonElement(imgArrayString).jsonArray
|
||||||
|
|
||||||
|
return imgArray.mapIndexed { idx, it ->
|
||||||
|
Page(idx, document.location(), it.jsonPrimitive.content)
|
||||||
}
|
}
|
||||||
return list
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -329,16 +358,15 @@ class ManhwaLatinoSiteParser(
|
||||||
return imageUrl
|
return imageUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private fun String.decodeHex(): ByteArray {
|
||||||
* Extract the Image from the Html Element
|
check(length % 2 == 0) { "Must have an even length" }
|
||||||
* The website changes often the attr of the images
|
|
||||||
* data-src or src
|
return chunked(2)
|
||||||
*/
|
.map { it.toInt(16).toByte() }
|
||||||
private fun getImage(element: Element): String {
|
.toByteArray()
|
||||||
var imageUrl = element.attr(MLConstants.imageAttribute)
|
|
||||||
if (imageUrl.isEmpty()) {
|
|
||||||
imageUrl = element.attr("abs:src")
|
|
||||||
}
|
}
|
||||||
return imageUrl
|
|
||||||
|
companion object {
|
||||||
|
val SALTED = "Salted__".toByteArray(Charsets.UTF_8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue