diff --git a/src/all/toomics/build.gradle b/src/all/toomics/build.gradle index aa0213fc4..81832e49c 100644 --- a/src/all/toomics/build.gradle +++ b/src/all/toomics/build.gradle @@ -5,7 +5,7 @@ ext { appName = 'Tachiyomi: Toomics' pkgNameSuffix = 'all.toomics' extClass = '.ToomicsFactory' - extVersionCode = 2 + extVersionCode = 3 libVersion = '1.2' } diff --git a/src/all/toomics/src/eu/kanade/tachiyomi/extension/all/toomics/ToomicsGlobal.kt b/src/all/toomics/src/eu/kanade/tachiyomi/extension/all/toomics/ToomicsGlobal.kt index 0b56e007e..5a43502d4 100644 --- a/src/all/toomics/src/eu/kanade/tachiyomi/extension/all/toomics/ToomicsGlobal.kt +++ b/src/all/toomics/src/eu/kanade/tachiyomi/extension/all/toomics/ToomicsGlobal.kt @@ -4,13 +4,17 @@ import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.source.model.* 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.Element import rx.Observable import java.net.URLDecoder import java.text.ParseException import java.text.SimpleDateFormat +import java.util.concurrent.TimeUnit abstract class ToomicsGlobal(private val siteLang: String, private val dateFormat: SimpleDateFormat, @@ -23,61 +27,73 @@ abstract class ToomicsGlobal(private val siteLang: String, 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() .add("Referer", "$baseUrl/$siteLang") .add("User-Agent", USER_AGENT) 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. - 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 { - title = element.select("div.visual div.main_text h4.title").text() - thumbnail_url = element.select("div.visual > p > img").attr("src") - url = element.attr("href") + element.select("a").let { + title = it.text() + setUrlWithoutDomain(it.attr("href")) + } + thumbnail_url = element.select("img").attr("abs:data-original") } override fun popularMangaNextPageSelector(): String? = null 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 latestUpdatesNextPageSelector(): String? = null override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { - val newHeaders = headers.newBuilder() - .set("X-Requested-With", "XMLHttpRequest") + val newHeaders = headersBuilder() + .add("Content-Type", "application/x-www-form-urlencoded") .build() - val form = FormBody.Builder() - .add("toonData", query) - .build() + val rbody = RequestBody.create(null, "toonData=$query&offset=0&limit=20") - 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 { - title = element.select("div.search_box dl dt span.title").text() - thumbnail_url = element.select("div.search_box p.img img").attr("src") + title = element.select("a div.search_box dl dt span.title").text() + 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. - val toonId = element.attr("onclick") - .substringAfter("Base.setDisplay('A', '") - .substringBefore("'") - .let { URLDecoder.decode(it, "UTF-8") } - .substringAfter("?toon=") - .substringBefore("&") - url = "/$siteLang/webtoon/episode/toon/$toonId" + element.select("a:not([href^=javascript])").let { + if (it != null) { + setUrlWithoutDomain(it.attr("href")) + } else { + val toonId = element.select("a").attr("onclick") + .substringAfter("Base.setDisplay('A', '") + .substringBefore("'") + .let { URLDecoder.decode(it, "UTF-8") } + .substringAfter("?toon=") + .substringBefore("&") + url = "/$siteLang/webtoon/episode/toon/$toonId" + } + } } override fun searchMangaNextPageSelector(): String? = null @@ -98,38 +114,29 @@ abstract class ToomicsGlobal(private val siteLang: String, .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 { - 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 "" - 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 date_upload = parseChapterDate(element.select("div.cell-time time").text()!!) scanlator = "Toomics" - url = "/$siteLang" + element.attr("onclick") - .substringAfter("'/$siteLang") + url = element.select("a").attr("onclick") + .substringAfter("href='") .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 { val url = document.select("head meta[property='og:url']").attr("content") - return document.select("main.viewer-body div.viewer-imgs div img") - .mapIndexed { i, el -> Page(i, url, el.attr("data-original"))} + return document.select("div[id^=load_image_] img") + .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 { val newHeaders = headers.newBuilder()