Tapas - new chapter list parsing (#3349)
This commit is contained in:
parent
95a779335e
commit
2d3aa436de
|
@ -5,7 +5,7 @@ ext {
|
|||
appName = 'Tachiyomi: Tapas'
|
||||
pkgNameSuffix = 'en.tapastic'
|
||||
extClass = '.Tapastic'
|
||||
extVersionCode = 9
|
||||
extVersionCode = 10
|
||||
libVersion = '1.2'
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,13 @@ import android.content.SharedPreferences
|
|||
import android.net.Uri
|
||||
import android.support.v7.preference.ListPreference
|
||||
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.source.ConfigurableSource
|
||||
import eu.kanade.tachiyomi.source.model.Filter
|
||||
|
@ -18,6 +25,7 @@ import java.text.SimpleDateFormat
|
|||
import java.util.Locale
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import org.jsoup.Jsoup
|
||||
import org.jsoup.nodes.Document
|
||||
import org.jsoup.nodes.Element
|
||||
import uy.kohesive.injekt.Injekt
|
||||
|
@ -141,71 +149,70 @@ class Tapastic : ConfigurableSource, ParsedHttpSource() {
|
|||
|
||||
// Details
|
||||
|
||||
override fun mangaDetailsRequest(manga: SManga): Request {
|
||||
return GET(baseUrl + "${manga.url}/info")
|
||||
}
|
||||
|
||||
override fun mangaDetailsParse(document: Document) = SManga.create().apply {
|
||||
title = document.select(".desc__title").text().trim()
|
||||
author = document.select(".tag__author").text().trim()
|
||||
genre = document.select("div.info-detail__row a.genre-btn").joinToString { it.text() }
|
||||
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
|
||||
description = document.select(".js-series-description").text().trim()
|
||||
genre = document.select("div.info__genre a, div.item__genre a")
|
||||
.joinToString(", ") { it.text() }
|
||||
thumbnail_url = document.select("div.header__thumb img").attr("src")
|
||||
description = document.select("div.row-body span.description__body").text()
|
||||
}
|
||||
|
||||
// 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> {
|
||||
val document = response.asJsoup()
|
||||
val mangaId = document.select("div.info-body__bottom a").attr("data-id")
|
||||
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
|
||||
fun parseChapters(document: Document) {
|
||||
document.select(chapterListSelector())
|
||||
// filter out future releases
|
||||
.filterNot { it.select("a").hasClass("js-coming-soon") }
|
||||
fun parseChapters(page: Int) {
|
||||
val url = "$baseUrl/series/$mangaId/episodes?page=$page&sort=NEWEST&init_load=0&large=true&last_access=0&"
|
||||
val json = gson.fromJson<JsonObject>(client.newCall(GET(url, headers)).execute().body()!!.string())["data"]
|
||||
|
||||
Jsoup.parse(json["body"].string).select(chapterListSelector())
|
||||
.let { list ->
|
||||
// show/don't show locked chapters based on user's preferences
|
||||
if (chapterListPref() == "free") list.filterNot { it.select("a").hasClass("js-have-to-sign") }
|
||||
else list
|
||||
if (chapterListPref() == "free") list.filterNot { it.isLockedChapter() } else list
|
||||
}
|
||||
.map { chapters.add(chapterFromElement(it)) }
|
||||
|
||||
document.select("a.paging__button--next").firstOrNull()?.let {
|
||||
parseChapters(client.newCall(GET(it.attr("abs:href"), headers)).execute().asJsoup())
|
||||
}
|
||||
if (json["pagination"]["has_next"].bool) parseChapters(json["pagination"]["page"].int)
|
||||
}
|
||||
|
||||
parseChapters(response.asJsoup())
|
||||
parseChapters(1)
|
||||
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 {
|
||||
val lock = !element.select(".sp-ico-episode-lock, .sp-ico-schedule-white").isNullOrEmpty()
|
||||
name = if (lock) {
|
||||
"\uD83D\uDD12 "
|
||||
} else {
|
||||
""
|
||||
} + 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())
|
||||
val episode = element.select("p.scene").text()
|
||||
val chName = element.select("span.title__body").text()
|
||||
name = (if (element.isLockedChapter()) "\uD83D\uDD12 " else "") + "$episode | $chName"
|
||||
setUrlWithoutDomain(element.attr("href"))
|
||||
date_upload = datePattern.find(element.select("p.additional").text())?.value.toDate()
|
||||
}
|
||||
|
||||
private fun parseDate(date: String): Long {
|
||||
return SimpleDateFormat("MMM dd, yyyy", Locale.US).parse(date)?.time ?: 0
|
||||
private fun String?.toDate(): Long {
|
||||
this ?: return 0L
|
||||
return SimpleDateFormat("MMM dd, yyyy", Locale.US).parse(this).time
|
||||
}
|
||||
|
||||
// Pages
|
||||
|
|
Loading…
Reference in New Issue