Add support to the new chapter endpoint in Madara (#8594)

* Add support to the new chapter endpoint in Madara.

* Remove unused variable.

* Fix unsolved reference in a source that used the old method.
This commit is contained in:
Alessandro Jean 2021-08-16 19:56:05 -03:00 committed by GitHub
parent 20e87bd4a2
commit 9059548257
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 50 deletions

View File

@ -59,14 +59,20 @@ class ArazNovel : Madara("ArazNovel", "https://www.araznovel.com", "tr", SimpleD
) )
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
return getXhrChapters(response.asJsoup().select("div#manga-chapters-holder").attr("data-id")).let { document -> val document = response.asJsoup()
document.select("li.parent").let { elements -> val mangaId = document.select("div#manga-chapters-holder").attr("data-id")
val xhrRequest = xhrChaptersRequest(mangaId)
val xhrResponse = client.newCall(xhrRequest).execute()
return xhrResponse.asJsoup().let { xhrDocument ->
xhrDocument.select("li.parent").let { elements ->
if (!elements.isNullOrEmpty()) { if (!elements.isNullOrEmpty()) {
elements.reversed() elements.reversed()
.map { volumeElement -> volumeElement.select(chapterListSelector()).map { chapterFromElement(it) } } .map { volumeElement -> volumeElement.select(chapterListSelector()).map { chapterFromElement(it) } }
.flatten() .flatten()
} else { } else {
document.select(chapterListSelector()).map { chapterFromElement(it) } xhrDocument.select(chapterListSelector()).map { chapterFromElement(it) }
} }
} }
} }

View File

@ -2,12 +2,7 @@ package eu.kanade.tachiyomi.extension.pt.arthurscan
import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
import eu.kanade.tachiyomi.multisrc.madara.Madara import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Response
import org.jsoup.nodes.Document
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@ -25,32 +20,10 @@ class ArthurScan : Madara(
override val altName: String = "Nome alternativo: " override val altName: String = "Nome alternativo: "
override val useNewChapterEndpoint = true
override fun popularMangaSelector() = "div.page-item-detail.manga" override fun popularMangaSelector() = "div.page-item-detail.manga"
override fun getXhrChapters(mangaId: String): Document {
val xhrHeaders = headersBuilder()
.add("Referer", baseUrl)
.add("X-Requested-With", "XMLHttpRequest")
.build()
val request = POST("$mangaId/ajax/chapters", xhrHeaders)
return client.newCall(request).execute().asJsoup()
}
override fun chapterListParse(response: Response): List<SChapter> {
val document = response.asJsoup()
val dataIdSelector = "div[id^=manga-chapters-holder]"
return document.select(chapterListSelector())
.let { elements ->
if (elements.isEmpty() && !document.select(dataIdSelector).isNullOrEmpty())
getXhrChapters(document.location().removeSuffix("/")).select(chapterListSelector())
else elements
}
.map(::chapterFromElement)
}
// [...document.querySelectorAll('div.genres li a')] // [...document.querySelectorAll('div.genres li a')]
// .map(x => `Genre("${x.innerText.slice(1, -4).trim()}", "${x.href.replace(/.*-genre\/(.*)\//, '$1')}")`) // .map(x => `Genre("${x.innerText.slice(1, -4).trim()}", "${x.href.replace(/.*-genre\/(.*)\//, '$1')}")`)
// .join(',\n') // .join(',\n')

View File

@ -3,6 +3,9 @@ package eu.kanade.tachiyomi.extension.en.isekaiscancom
import eu.kanade.tachiyomi.multisrc.madara.Madara import eu.kanade.tachiyomi.multisrc.madara.Madara
class IsekaiScanCom : Madara("IsekaiScan.com", "https://isekaiscan.com", "en") { class IsekaiScanCom : Madara("IsekaiScan.com", "https://isekaiscan.com", "en") {
override val useNewChapterEndpoint = true
override fun getGenreList() = listOf( override fun getGenreList() = listOf(
Genre("4 koma", "4-koma"), Genre("4 koma", "4-koma"),
Genre("Action", "action"), Genre("Action", "action"),

View File

@ -130,7 +130,7 @@ abstract class Madara(
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> { override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
if (query.startsWith(URL_SEARCH_PREFIX)){ if (query.startsWith(URL_SEARCH_PREFIX)){
val mangaUrl = "$baseUrl/$mangaSubString/${query.substringAfter(URL_SEARCH_PREFIX)}" val mangaUrl = "$baseUrl/$mangaSubString/${query.substringAfter(URL_SEARCH_PREFIX)}"
return client.newCall(GET("$baseUrl/$mangaSubString/${query.substringAfter(URL_SEARCH_PREFIX)}", headers)) return client.newCall(GET(mangaUrl, headers))
.asObservable().map { response -> .asObservable().map { response ->
MangasPage(listOf(mangaDetailsParse(response.asJsoup()).apply { url = "/$mangaSubString/${query.substringAfter(URL_SEARCH_PREFIX)}/" }), false) MangasPage(listOf(mangaDetailsParse(response.asJsoup()).apply { url = "/$mangaSubString/${query.substringAfter(URL_SEARCH_PREFIX)}/" }), false)
} }
@ -400,25 +400,55 @@ abstract class Madara(
} }
} }
protected open fun getXhrChapters(mangaId: String): Document { /**
val xhrHeaders = headersBuilder().add("Content-Type: application/x-www-form-urlencoded; charset=UTF-8") * Set it to true if the source uses the new AJAX endpoint to
.add("Referer", baseUrl) * fetch the manga chapters instead of the old admin-ajax.php one.
*/
protected open val useNewChapterEndpoint: Boolean = false
protected open fun oldXhrChaptersRequest(mangaId: String): Request {
val form = FormBody.Builder()
.add("action", "manga_get_chapters")
.add("manga", mangaId)
.build() .build()
val body = "action=manga_get_chapters&manga=$mangaId".toRequestBody(null)
return client.newCall(POST("$baseUrl/wp-admin/admin-ajax.php", xhrHeaders, body)).execute().asJsoup() val xhrHeaders = headersBuilder()
.add("Content-Length", form.contentLength().toString())
.add("Content-Type", form.contentType().toString())
.add("Referer", baseUrl)
.add("X-Requested-With", "XMLHttpRequest")
.build()
return POST("$baseUrl/wp-admin/admin-ajax.php", xhrHeaders, form)
}
protected open fun xhrChaptersRequest(mangaUrl: String): Request {
val xhrHeaders = headersBuilder()
.add("Referer", baseUrl)
.add("X-Requested-With", "XMLHttpRequest")
.build()
return POST("$mangaUrl/ajax/chapters", xhrHeaders)
} }
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
val document = response.asJsoup() val document = response.asJsoup()
val dataIdSelector = "div[id^=manga-chapters-holder]" val chaptersWrapper = document.select("div[id^=manga-chapters-holder]")
return document.select(chapterListSelector()) var chapterElements = document.select(chapterListSelector())
.let { elements ->
if (elements.isEmpty() && !document.select(dataIdSelector).isNullOrEmpty()) if (chapterElements.isEmpty() && !chaptersWrapper.isNullOrEmpty()) {
getXhrChapters(document.select(dataIdSelector).attr("data-id")).select(chapterListSelector()) val mangaUrl = document.location().removeSuffix("/")
else elements val mangaId = chaptersWrapper.attr("data-id")
val xhrRequest = if (useNewChapterEndpoint) xhrChaptersRequest(mangaUrl) else oldXhrChaptersRequest(mangaId)
val xhrResponse = client.newCall(xhrRequest).execute()
chapterElements = xhrResponse.asJsoup().select(chapterListSelector())
xhrResponse.close()
} }
.map { chapterFromElement(it) }
return chapterElements.map(::chapterFromElement)
} }
override fun chapterListSelector() = "li.wp-manga-chapter" override fun chapterListSelector() = "li.wp-manga-chapter"

View File

@ -33,9 +33,9 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("Aqua Manga", "https://aquamanga.com", "en"), SingleLang("Aqua Manga", "https://aquamanga.com", "en"),
SingleLang("Anisa Manga", "https://anisamanga.com", "tr"), SingleLang("Anisa Manga", "https://anisamanga.com", "tr"),
SingleLang("ApollComics", "https://apollcomics.xyz", "es", overrideVersionCode = 1), SingleLang("ApollComics", "https://apollcomics.xyz", "es", overrideVersionCode = 1),
SingleLang("ArazNovel", "https://www.araznovel.com", "tr", overrideVersionCode = 1), SingleLang("ArazNovel", "https://www.araznovel.com", "tr", overrideVersionCode = 2),
SingleLang("Argos Scan", "https://argosscan.com", "pt-BR", overrideVersionCode = 3), SingleLang("Argos Scan", "https://argosscan.com", "pt-BR", overrideVersionCode = 3),
SingleLang("Arthur Scan", "https://arthurscan.xyz", "pt-BR", overrideVersionCode = 3), SingleLang("Arthur Scan", "https://arthurscan.xyz", "pt-BR", overrideVersionCode = 4),
SingleLang("Astral Library", "https://www.astrallibrary.net", "en", overrideVersionCode = 2), SingleLang("Astral Library", "https://www.astrallibrary.net", "en", overrideVersionCode = 2),
SingleLang("Asura Raw", "https://asuraraw.com", "en"), SingleLang("Asura Raw", "https://asuraraw.com", "en"),
SingleLang("Atikrost", "https://atikrost.com", "tr", overrideVersionCode = 1), SingleLang("Atikrost", "https://atikrost.com", "tr", overrideVersionCode = 1),
@ -115,7 +115,7 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("Império Scans", "https://imperioscans.com.br", "pt-BR", className = "ImperioScans"), SingleLang("Império Scans", "https://imperioscans.com.br", "pt-BR", className = "ImperioScans"),
SingleLang("Império dos Otakus", "https://imperiodosotakus.tk", "pt-BR", className = "ImperioDosOtakus", overrideVersionCode = 2), SingleLang("Império dos Otakus", "https://imperiodosotakus.tk", "pt-BR", className = "ImperioDosOtakus", overrideVersionCode = 2),
SingleLang("InfraFandub", "https://infrafandub.xyz", "es"), SingleLang("InfraFandub", "https://infrafandub.xyz", "es"),
SingleLang("IsekaiScan.com", "https://isekaiscan.com", "en", className = "IsekaiScanCom", overrideVersionCode = 2), SingleLang("IsekaiScan.com", "https://isekaiscan.com", "en", className = "IsekaiScanCom", overrideVersionCode = 3),
SingleLang("IsekaiScanManga (unoriginal)", "https://isekaiscanmanga.com", "en", className = "IsekaiScanManga", overrideVersionCode = 1), SingleLang("IsekaiScanManga (unoriginal)", "https://isekaiscanmanga.com", "en", className = "IsekaiScanManga", overrideVersionCode = 1),
SingleLang("Its Your Right Manhua", "https://itsyourightmanhua.com/", "en", overrideVersionCode = 1), SingleLang("Its Your Right Manhua", "https://itsyourightmanhua.com/", "en", overrideVersionCode = 1),
SingleLang("JaiminisBox.net", "https://jaiminisbox.net", "en", className = "Jaiminisboxnet"), SingleLang("JaiminisBox.net", "https://jaiminisbox.net", "en", className = "Jaiminisboxnet"),