[Ready] TMO Update (#1780)

[Ready] TMO Update
This commit is contained in:
happywillow0 2019-12-17 17:15:46 -05:00 committed by arkon
parent 468c01dfc2
commit ac6f534b06
2 changed files with 61 additions and 39 deletions

View File

@ -5,7 +5,7 @@ ext {
appName = 'Tachiyomi: TuMangaOnline'
pkgNameSuffix = 'es.tumangaonline'
extClass = '.TuMangaOnline'
extVersionCode = 12
extVersionCode = 13
libVersion = '1.2'
}

View File

@ -4,8 +4,6 @@ import android.app.Application
import android.content.SharedPreferences
import android.support.v7.preference.ListPreference
import android.support.v7.preference.PreferenceScreen
import com.github.salomonbrys.kotson.string
import com.google.gson.JsonParser
import okhttp3.*
import java.util.*
import org.jsoup.nodes.Element
@ -17,7 +15,6 @@ import eu.kanade.tachiyomi.util.asJsoup
import eu.kanade.tachiyomi.source.model.*
import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.source.ConfigurableSource
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@ -41,25 +38,27 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
.retryOnConnectionFailure(true)
.followRedirects(true)
.build()!!
private val userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0"
override fun headersBuilder(): Headers.Builder {
return Headers.Builder()
.add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) Gecko/20100101 Firefox/60")
.add("User-Agent", userAgent)
.add("Referer", "$baseUrl/")
.add("Cache-mode", "no-cache")
}
private fun getBuilder(url: String): String {
val req = Request.Builder()
.headers(headersBuilder().add("Referer", "$baseUrl/library/manga/").build())
private fun getBuilder(url: String, headers: Headers, formBody: FormBody): String {
val req = Request.Builder()
.headers(headers)
.url(url)
.post(formBody)
.build()
return client.newCall(req)
.execute()
.request()
.url()
.toString()
return client.newCall(req)
.execute()
.body()!!
.string()
}
private val preferences: SharedPreferences by lazy {
@ -83,8 +82,8 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
thumbnail_url = it.select("style").toString().substringAfter("('").substringBeforeLast("')")
}
}
override fun latestUpdatesParse(response: Response): MangasPage {
override fun latestUpdatesParse(response: Response): MangasPage {
val document = response.asJsoup()
val mangas = document.select(latestUpdatesSelector())
.distinctBy { it.select("div.thumbnail-title > h4.text-truncate").text().trim() }
@ -196,12 +195,17 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
private val scriptselector = "addEventListener"
override fun chapterListParse(response: Response): List<SChapter> {
val document = response.asJsoup()
val chapterurl = response.request().url().toString()
val script = document.select("script:containsData($scriptselector)").html()
val chapteridselector = script.substringAfter("getAttribute(\"").substringBefore("\"")
// One-shot
if (document.select("div.chapters").isEmpty()) {
return document.select(oneShotChapterListSelector()).map { oneShotChapterFromElement(it) }
return document.select(oneShotChapterListSelector()).map { oneShotChapterFromElement(it, chapterurl, chapteridselector) }
}
// Regular list of chapters
@ -212,10 +216,10 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
val scanelement = chapelement.select("ul.chapter-list > li")
val dupselect = getduppref()!!
if (dupselect=="one") {
scanelement.first { chapters.add(regularChapterFromElement(it, chaptername, chapternumber)) }
scanelement.first { chapters.add(regularChapterFromElement(it, chaptername, chapternumber, chapterurl, chapteridselector)) }
}
else {
scanelement.forEach { chapters.add(regularChapterFromElement(it, chaptername, chapternumber)) }
scanelement.forEach { chapters.add(regularChapterFromElement(it, chaptername, chapternumber, chapterurl, chapteridselector)) }
}
}
return chapters
@ -226,8 +230,9 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
private fun oneShotChapterListSelector() = "div.chapter-list-element > ul.list-group li.list-group-item"
private fun oneShotChapterFromElement(element: Element) = SChapter.create().apply {
setUrlWithoutDomain(element.select("div.row > .text-right > a").attr("href"))
private fun oneShotChapterFromElement(element: Element, chapterurl: String, chapteridselector: String) = SChapter.create().apply {
val button = element.select("div.row > .text-right > [$chapteridselector]") //button
url = "$chapterurl#${button.attr(chapteridselector)}"
name = "One Shot"
scanlator = element.select("div.col-md-6.text-truncate")?.text()
date_upload = element.select("span.badge.badge-primary.p-2").first()?.text()?.let { parseChapterDate(it) } ?: 0
@ -235,8 +240,9 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
private fun regularChapterListSelector() = "div.chapters > ul.list-group li.p-0.list-group-item"
private fun regularChapterFromElement(element: Element, chname: String, number: Float) = SChapter.create().apply {
setUrlWithoutDomain(element.select("div.row > .text-right > a").attr("href"))
private fun regularChapterFromElement(element: Element, chname: String, number: Float, chapterurl: String, chapteridselector: String) = SChapter.create().apply {
val button = element.select("div.row > .text-right > [$chapteridselector]") //button
url = "$chapterurl#${button.attr(chapteridselector)}"
name = chname
chapter_number = number
scanlator = element.select("div.col-md-6.text-truncate")?.text()
@ -246,30 +252,46 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
private fun parseChapterDate(date: String): Long = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).parse(date).time
override fun pageListRequest(chapter: SChapter): Request {
val url = getBuilder(baseUrl + chapter.url).substringBeforeLast("/") + "/cascade"
val (chapterURL, chapterID) = chapter.url.split("#")
val response = client.newCall(GET(chapterURL, headers)).execute()
val document = response.asJsoup()
val csrfToken = document.select("meta[name=csrf-token]").attr("content")
val script = document.select("script:containsData($scriptselector)").html()
val functionID = script.substringAfter("addEventListener").substringAfter("{").substringBefore("(").trim().removePrefix("_")
val function = script.substringAfter("function _$functionID(").substringBefore("});")
val goto = function.substringAfter("url: '").substringBefore("'")
val paramChapter = function.substringAfter("data").substringBefore("\":_").substringAfterLast("\"")
val getHeaders = headersBuilder()
.add("User-Agent", userAgent)
.add("Referer", chapterURL)
.add("Content-Type","application/x-www-form-urlencoded; charset=UTF-8")
.add("X-CSRF-TOKEN",csrfToken)
.add("X-Requested-With","XMLHttpRequest")
.add(functionID,functionID)
.build()
val formBody = FormBody.Builder()
.add(paramChapter, chapterID)
.build()
val url = getBuilder(goto,getHeaders,formBody).substringBeforeLast("/") + "/cascade"
// Get /cascade instead of /paginate to get all pages at once
val headers = headersBuilder()
.add("User-Agent", userAgent)
.add("Referer", chapterURL)
.build()
return GET(url, headers)
}
override fun pageListParse(response: Response): List<Page> {
override fun pageListParse(response: Response): List<Page> = mutableListOf<Page>().apply {
val body = response.asJsoup()
val imageRoute = body.select("script:containsData(imageRoute)").html().substringAfter("imageRoute = \"").substringBefore(":IMAGE_NAME")
val token = body.select("meta[name=csrf-token]").attr("content")
val base64 = body.select("script:containsData(base64)").html().substringAfter("','").substringBefore("','all');")
val chapterid = body.baseUri().substringAfter("viewer/").substringBefore("/cascade")
val headers = headersBuilder()
.add("Content-Type", "application/json; charset=utf-8")
.add("X-CSRF-TOKEN",token)
.build()
val jsonData = client.newCall(POST("$baseUrl/upload_images/$chapterid/$base64/all", headers)).execute()
val jbody = jsonData.body()!!.string()
val results = JsonParser().parse(jbody).asJsonArray
val pages = mutableListOf<Page>()
for (i in 0 until results.size()) {
pages.add(Page(i, "",imageRoute + results[i].string))
body.select("div#viewer-container > div.viewer-image-container > img.viewer-image")?.forEach {
add(Page(size, "", it.attr("src")))
}
return pages
}
override fun pageListParse(document: Document) = throw UnsupportedOperationException("Not used")