Tapas - new chapter list parsing (#3349)

This commit is contained in:
Mike 2020-05-29 02:49:52 -04:00 committed by GitHub
parent 95a779335e
commit 2d3aa436de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 41 deletions

View File

@ -5,7 +5,7 @@ ext {
appName = 'Tachiyomi: Tapas' appName = 'Tachiyomi: Tapas'
pkgNameSuffix = 'en.tapastic' pkgNameSuffix = 'en.tapastic'
extClass = '.Tapastic' extClass = '.Tapastic'
extVersionCode = 9 extVersionCode = 10
libVersion = '1.2' libVersion = '1.2'
} }

View File

@ -5,6 +5,13 @@ import android.content.SharedPreferences
import android.net.Uri import android.net.Uri
import android.support.v7.preference.ListPreference import android.support.v7.preference.ListPreference
import android.support.v7.preference.PreferenceScreen import android.support.v7.preference.PreferenceScreen
import com.github.salomonbrys.kotson.bool
import com.github.salomonbrys.kotson.fromJson
import com.github.salomonbrys.kotson.get
import com.github.salomonbrys.kotson.int
import com.github.salomonbrys.kotson.string
import com.google.gson.Gson
import com.google.gson.JsonObject
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.model.Filter import eu.kanade.tachiyomi.source.model.Filter
@ -18,6 +25,7 @@ import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import org.jsoup.Jsoup
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
@ -141,71 +149,70 @@ class Tapastic : ConfigurableSource, ParsedHttpSource() {
// Details // Details
override fun mangaDetailsRequest(manga: SManga): Request {
return GET(baseUrl + "${manga.url}/info")
}
override fun mangaDetailsParse(document: Document) = SManga.create().apply { override fun mangaDetailsParse(document: Document) = SManga.create().apply {
title = document.select(".desc__title").text().trim() genre = document.select("div.info-detail__row a.genre-btn").joinToString { it.text() }
author = document.select(".tag__author").text().trim() title = document.select("div.title-wrapper a.title").text()
thumbnail_url = document.select("div.thumb-wrapper img").attr("abs:src")
author = document.select("ul.creator-section a.name").joinToString { it.text() }
artist = author artist = author
description = document.select(".js-series-description").text().trim() description = document.select("div.row-body span.description__body").text()
genre = document.select("div.info__genre a, div.item__genre a")
.joinToString(", ") { it.text() }
thumbnail_url = document.select("div.header__thumb img").attr("src")
} }
// Chapters // Chapters
override fun chapterListRequest(manga: SManga): Request { /**
return GET(baseUrl + manga.url + "?sort_order=desc", headers) * Checklist: Paginated chapter lists, locked chapters, future chapters, early-access chapters (app only?), chapter order
*/
private val gson by lazy { Gson() }
private fun Element.isLockedChapter(): Boolean {
return this.hasClass("js-have-to-sign")
} }
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
val document = response.asJsoup()
val mangaId = document.select("div.info-body__bottom a").attr("data-id")
val chapters = mutableListOf<SChapter>() val chapters = mutableListOf<SChapter>()
fun List<Element>.filterLocked(boolean: Boolean): List<Element> {
return if (boolean) this.filterNot { it.select("a").hasClass("js-locked") } else this
}
// recursively build the chapter list // recursively build the chapter list
fun parseChapters(document: Document) { fun parseChapters(page: Int) {
document.select(chapterListSelector()) val url = "$baseUrl/series/$mangaId/episodes?page=$page&sort=NEWEST&init_load=0&large=true&last_access=0&"
// filter out future releases val json = gson.fromJson<JsonObject>(client.newCall(GET(url, headers)).execute().body()!!.string())["data"]
.filterNot { it.select("a").hasClass("js-coming-soon") }
Jsoup.parse(json["body"].string).select(chapterListSelector())
.let { list -> .let { list ->
// show/don't show locked chapters based on user's preferences // show/don't show locked chapters based on user's preferences
if (chapterListPref() == "free") list.filterNot { it.select("a").hasClass("js-have-to-sign") } if (chapterListPref() == "free") list.filterNot { it.isLockedChapter() } else list
else list
} }
.map { chapters.add(chapterFromElement(it)) } .map { chapters.add(chapterFromElement(it)) }
document.select("a.paging__button--next").firstOrNull()?.let { if (json["pagination"]["has_next"].bool) parseChapters(json["pagination"]["page"].int)
parseChapters(client.newCall(GET(it.attr("abs:href"), headers)).execute().asJsoup())
}
} }
parseChapters(response.asJsoup()) parseChapters(1)
return chapters return chapters
} }
override fun chapterListSelector() = "li.content__item" override fun chapterListSelector() = "li a:not(.js-early-access):not(.js-coming-soon)"
private val datePattern = Regex("""\w\w\w \d\d, \d\d\d\d""")
override fun chapterFromElement(element: Element): SChapter = SChapter.create().apply { override fun chapterFromElement(element: Element): SChapter = SChapter.create().apply {
val lock = !element.select(".sp-ico-episode-lock, .sp-ico-schedule-white").isNullOrEmpty() val episode = element.select("p.scene").text()
name = if (lock) { val chName = element.select("span.title__body").text()
"\uD83D\uDD12 " name = (if (element.isLockedChapter()) "\uD83D\uDD12 " else "") + "$episode | $chName"
} else { setUrlWithoutDomain(element.attr("href"))
"" date_upload = datePattern.find(element.select("p.additional").text())?.value.toDate()
} + element.select(".info__title").text().trim()
setUrlWithoutDomain(element.select("a").attr("href"))
chapter_number =
element.select(".info__header").text().substringAfter("Episode")
.substringBefore("Early access").trim().toFloat()
date_upload =
parseDate(element.select(".info__tag").text().substringAfter(":").substringBefore("").trim())
} }
private fun parseDate(date: String): Long { private fun String?.toDate(): Long {
return SimpleDateFormat("MMM dd, yyyy", Locale.US).parse(date)?.time ?: 0 this ?: return 0L
return SimpleDateFormat("MMM dd, yyyy", Locale.US).parse(this).time
} }
// Pages // Pages