parent
0075227433
commit
f2a119ac0c
|
@ -5,7 +5,7 @@ ext {
|
||||||
appName = 'Tachiyomi: Toomics'
|
appName = 'Tachiyomi: Toomics'
|
||||||
pkgNameSuffix = 'all.toomics'
|
pkgNameSuffix = 'all.toomics'
|
||||||
extClass = '.ToomicsFactory'
|
extClass = '.ToomicsFactory'
|
||||||
extVersionCode = 2
|
extVersionCode = 3
|
||||||
libVersion = '1.2'
|
libVersion = '1.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,17 @@ import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.POST
|
import eu.kanade.tachiyomi.network.POST
|
||||||
import eu.kanade.tachiyomi.source.model.*
|
import eu.kanade.tachiyomi.source.model.*
|
||||||
import eu.kanade.tachiyomi.source.online.ParsedHttpSource
|
import eu.kanade.tachiyomi.source.online.ParsedHttpSource
|
||||||
import okhttp3.*
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.Request
|
||||||
|
import okhttp3.RequestBody
|
||||||
|
import okhttp3.Headers
|
||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
import org.jsoup.nodes.Element
|
import org.jsoup.nodes.Element
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import java.net.URLDecoder
|
import java.net.URLDecoder
|
||||||
import java.text.ParseException
|
import java.text.ParseException
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
abstract class ToomicsGlobal(private val siteLang: String,
|
abstract class ToomicsGlobal(private val siteLang: String,
|
||||||
private val dateFormat: SimpleDateFormat,
|
private val dateFormat: SimpleDateFormat,
|
||||||
|
@ -23,61 +27,73 @@ abstract class ToomicsGlobal(private val siteLang: String,
|
||||||
|
|
||||||
override val supportsLatest = true
|
override val supportsLatest = true
|
||||||
|
|
||||||
|
override val client: OkHttpClient = super.client.newBuilder()
|
||||||
|
.connectTimeout(1, TimeUnit.MINUTES)
|
||||||
|
.readTimeout(1, TimeUnit.MINUTES)
|
||||||
|
.writeTimeout(1, TimeUnit.MINUTES)
|
||||||
|
.build()
|
||||||
|
|
||||||
override fun headersBuilder(): Headers.Builder = Headers.Builder()
|
override fun headersBuilder(): Headers.Builder = Headers.Builder()
|
||||||
.add("Referer", "$baseUrl/$siteLang")
|
.add("Referer", "$baseUrl/$siteLang")
|
||||||
.add("User-Agent", USER_AGENT)
|
.add("User-Agent", USER_AGENT)
|
||||||
|
|
||||||
override fun popularMangaRequest(page: Int): Request {
|
override fun popularMangaRequest(page: Int): Request {
|
||||||
return GET("$baseUrl/$siteLang/index/set_display/?display=A&return=/$siteLang", headers)
|
return GET("$baseUrl/$siteLang/webtoon/free_all", headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToomicsGlobal does not have a popular list, so use recommended instead.
|
// ToomicsGlobal does not have a popular list, so use recommended instead.
|
||||||
override fun popularMangaSelector(): String = "div.section_most div.list_wrap ul.slick_item li div a"
|
override fun popularMangaSelector(): String = "li > div.visual"
|
||||||
|
|
||||||
override fun popularMangaFromElement(element: Element): SManga = SManga.create().apply {
|
override fun popularMangaFromElement(element: Element): SManga = SManga.create().apply {
|
||||||
title = element.select("div.visual div.main_text h4.title").text()
|
element.select("a").let {
|
||||||
thumbnail_url = element.select("div.visual > p > img").attr("src")
|
title = it.text()
|
||||||
url = element.attr("href")
|
setUrlWithoutDomain(it.attr("href"))
|
||||||
|
}
|
||||||
|
thumbnail_url = element.select("img").attr("abs:data-original")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun popularMangaNextPageSelector(): String? = null
|
override fun popularMangaNextPageSelector(): String? = null
|
||||||
|
|
||||||
override fun latestUpdatesRequest(page: Int): Request {
|
override fun latestUpdatesRequest(page: Int): Request {
|
||||||
return GET("$baseUrl/$siteLang/index/set_display/?display=A&return=/$siteLang", headers)
|
return GET("$baseUrl/$siteLang/webtoon/free", headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun latestUpdatesSelector(): String = "div#section_todayup div.list_wrap ul.slick_item li div a"
|
override fun latestUpdatesSelector(): String = popularMangaSelector()
|
||||||
|
|
||||||
override fun latestUpdatesFromElement(element: Element): SManga = popularMangaFromElement(element)
|
override fun latestUpdatesFromElement(element: Element): SManga = popularMangaFromElement(element)
|
||||||
|
|
||||||
override fun latestUpdatesNextPageSelector(): String? = null
|
override fun latestUpdatesNextPageSelector(): String? = null
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
val newHeaders = headers.newBuilder()
|
val newHeaders = headersBuilder()
|
||||||
.set("X-Requested-With", "XMLHttpRequest")
|
.add("Content-Type", "application/x-www-form-urlencoded")
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
val form = FormBody.Builder()
|
val rbody = RequestBody.create(null, "toonData=$query&offset=0&limit=20")
|
||||||
.add("toonData", query)
|
|
||||||
.build()
|
|
||||||
|
|
||||||
return POST("$baseUrl/$siteLang/webtoon/ajax_search", newHeaders, form)
|
return POST("$baseUrl/$siteLang/webtoon/ajax_search", newHeaders, rbody)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchMangaSelector(): String = "div.recently_list ul li a"
|
override fun searchMangaSelector(): String = "div.recently_list ul li"
|
||||||
|
|
||||||
override fun searchMangaFromElement(element: Element): SManga = SManga.create().apply {
|
override fun searchMangaFromElement(element: Element): SManga = SManga.create().apply {
|
||||||
title = element.select("div.search_box dl dt span.title").text()
|
title = element.select("a div.search_box dl dt span.title").text()
|
||||||
thumbnail_url = element.select("div.search_box p.img img").attr("src")
|
thumbnail_url = element.select("div.search_box p.img img").attr("abs:src")
|
||||||
|
|
||||||
// When the family mode is off, the url is encoded and is available in the onclick.
|
// When the family mode is off, the url is encoded and is available in the onclick.
|
||||||
val toonId = element.attr("onclick")
|
element.select("a:not([href^=javascript])").let {
|
||||||
.substringAfter("Base.setDisplay('A', '")
|
if (it != null) {
|
||||||
.substringBefore("'")
|
setUrlWithoutDomain(it.attr("href"))
|
||||||
.let { URLDecoder.decode(it, "UTF-8") }
|
} else {
|
||||||
.substringAfter("?toon=")
|
val toonId = element.select("a").attr("onclick")
|
||||||
.substringBefore("&")
|
.substringAfter("Base.setDisplay('A', '")
|
||||||
url = "/$siteLang/webtoon/episode/toon/$toonId"
|
.substringBefore("'")
|
||||||
|
.let { URLDecoder.decode(it, "UTF-8") }
|
||||||
|
.substringAfter("?toon=")
|
||||||
|
.substringBefore("&")
|
||||||
|
url = "/$siteLang/webtoon/episode/toon/$toonId"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchMangaNextPageSelector(): String? = null
|
override fun searchMangaNextPageSelector(): String? = null
|
||||||
|
@ -98,38 +114,29 @@ abstract class ToomicsGlobal(private val siteLang: String,
|
||||||
.map { it.reversed() }
|
.map { it.reversed() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun chapterListSelector(): String = "section.ep-body ol.list-ep li.normal_ep a:not([onclick*='login']):not([onclick*='free_in_app'])"
|
override fun chapterListSelector(): String = "li.normal_ep:has(.coin-type1)"
|
||||||
|
|
||||||
override fun chapterFromElement(element: Element): SChapter = SChapter.create().apply {
|
override fun chapterFromElement(element: Element): SChapter = SChapter.create().apply {
|
||||||
val num = element.select("div.cell-num span.num").text()
|
val num = element.select("div.cell-num").text()
|
||||||
val numText = if (num.isNotEmpty()) "$num - " else ""
|
val numText = if (num.isNotEmpty()) "$num - " else ""
|
||||||
|
|
||||||
name = numText + element.select("div.cell-title strong.tit").first().ownText()
|
name = numText + element.select("div.cell-title")?.first()?.ownText()
|
||||||
chapter_number = num.toFloatOrNull() ?: 0f
|
chapter_number = num.toFloatOrNull() ?: 0f
|
||||||
date_upload = parseChapterDate(element.select("div.cell-time time").text()!!)
|
date_upload = parseChapterDate(element.select("div.cell-time time").text()!!)
|
||||||
scanlator = "Toomics"
|
scanlator = "Toomics"
|
||||||
url = "/$siteLang" + element.attr("onclick")
|
url = element.select("a").attr("onclick")
|
||||||
.substringAfter("'/$siteLang")
|
.substringAfter("href='")
|
||||||
.substringBefore("'")
|
.substringBefore("'")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun pageListRequest(chapter: SChapter): Request {
|
|
||||||
val toonId = chapter.url.substringAfterLast("toon/")
|
|
||||||
val newHeaders = headers.newBuilder()
|
|
||||||
.set("Referer", "$baseUrl/$siteLang/webtoon/episode/toon/$toonId")
|
|
||||||
.build()
|
|
||||||
|
|
||||||
return GET(baseUrl + chapter.url, newHeaders)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun pageListParse(document: Document): List<Page> {
|
override fun pageListParse(document: Document): List<Page> {
|
||||||
val url = document.select("head meta[property='og:url']").attr("content")
|
val url = document.select("head meta[property='og:url']").attr("content")
|
||||||
|
|
||||||
return document.select("main.viewer-body div.viewer-imgs div img")
|
return document.select("div[id^=load_image_] img")
|
||||||
.mapIndexed { i, el -> Page(i, url, el.attr("data-original"))}
|
.mapIndexed { i, el -> Page(i, url, el.attr("abs:data-original"))}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun imageUrlParse(document: Document): String = ""
|
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")
|
||||||
|
|
||||||
override fun imageRequest(page: Page): Request {
|
override fun imageRequest(page: Page): Request {
|
||||||
val newHeaders = headers.newBuilder()
|
val newHeaders = headers.newBuilder()
|
||||||
|
|
Loading…
Reference in New Issue