Merge pull request #4015 from edgarMejia/master

Add Plot Twist No Fansub, Fix TMO & LectorManga "Cascada" mode
This commit is contained in:
Mike 2020-08-06 23:36:32 -04:00 committed by GitHub
commit 25c7e8e5f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 194 additions and 4 deletions

View File

@ -5,7 +5,7 @@ ext {
extName = 'LectorManga'
pkgNameSuffix = 'es.lectormanga'
extClass = '.LectorManga'
extVersionCode = 12
extVersionCode = 13
libVersion = '1.2'
}

View File

@ -219,7 +219,7 @@ class LectorManga : ConfigurableSource, ParsedHttpSource() {
override fun pageListParse(document: Document): List<Page> = mutableListOf<Page>().apply {
if (getPageMethod() == "cascade") {
document.select("img.viewer-img").forEach {
document.select("div.viewer-container img").forEach {
add(Page(size, "", it.let {
if (it.hasAttr("data-src"))
it.attr("abs:data-src") else it.attr("abs:src")

View File

@ -0,0 +1,17 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
ext {
extName = 'Plot Twist No Fansub'
pkgNameSuffix = 'es.plottwistnofansub'
extClass = '.PlotTwistNoFansub'
extVersionCode = 1
libVersion = '1.2'
}
dependencies {
compileOnly 'com.google.code.gson:gson:2.8.5'
compileOnly 'com.github.salomonbrys.kotson:kotson:2.5.0'
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

After

Width:  |  Height:  |  Size: 518 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

View File

@ -0,0 +1,173 @@
package eu.kanade.tachiyomi.extension.es.plottwistnofansub
import com.github.salomonbrys.kotson.array
import com.github.salomonbrys.kotson.get
import com.github.salomonbrys.kotson.string
import com.google.gson.JsonArray
import com.google.gson.JsonElement
import com.google.gson.JsonParser
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.FormBody
import okhttp3.Response
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
class PlotTwistNoFansub : ParsedHttpSource() {
override val baseUrl = "https://www.plot-twistnf-scans.com"
override val lang = "es"
override val name = "Plot Twist No Fansub"
override val supportsLatest = true
override fun popularMangaRequest(page: Int) = GET("$baseUrl/page/$page/?s", headers)
override fun popularMangaSelector() = "div.td-module-thumb [href*=\"archivos\"]"
override fun popularMangaFromElement(element: Element) = SManga.create().apply {
element.select("a").let {
setUrlWithoutDomain(it.attr("href"))
title = it.attr("title")
thumbnail_url = it.select("img").attr("src").replace("-150x150", "")
}
}
private fun mangaUrlBuilderFromChapterUrl(chapterUrl: String): String {
val postName = chapterUrl.substringAfter("read/").substringBefore("/chapter")
return "/archivos/manga/$postName/"
}
override fun popularMangaNextPageSelector() = "div.page-nav a:has(i)"
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/ulti/", headers)
override fun latestUpdatesSelector() = "div.row.last-updates div.item"
override fun latestUpdatesFromElement(element: Element) = SManga.create().apply {
element.select("div.item").let {
setUrlWithoutDomain(mangaUrlBuilderFromChapterUrl(it.select("a.lastup").attr("href")))
title = it.select("a.lastup").text()
thumbnail_url = it.select("img.lazy.imgigh").attr("data-lazy-src")
}
}
override fun latestUpdatesNextPageSelector(): String? = null
override fun mangaDetailsParse(document: Document) = SManga.create().apply {
document.select("article[id^=post-]").let { it ->
thumbnail_url = it.select("img.entry-thumb").attr("src")
description = it.select("strong")?.text()
genre = it.select("div.mangaInfo a").joinToString(", ") {
it.text()
}
}
}
override fun chapterListSelector() = throw Exception("Not Used")
private fun chapterUrlBuilder(postName: String, chapterNumber: String): String {
return "/read/$postName/chapter-$chapterNumber/"
}
private fun paginationFormBuilder(page: Int, mangaId: Int) = FormBody.Builder().apply {
add("action", "lcap")
add("manga_id", mangaId.toString())
add("pageNumber", page.toString())
}
private fun parseJson(json: String): JsonElement {
return JsonParser().parse(json)
}
private fun fetchChaptersPertPage(page: Int, mangaId: Int): JsonArray {
val res = client.newCall(POST("$baseUrl/wp-admin/admin-ajax.php", headers, paginationFormBuilder(page, mangaId).build())).execute().body()!!.string()
return parseJson(res.toString()).array
}
private fun chapterFromJsonElement(jsonElement: JsonElement) = SChapter.create().apply {
val nameStr = jsonElement["chapter_name"].string
val chapterNumber = jsonElement["chapter_number"].string
name = if (nameStr.contains("Capitulo") || nameStr.contains("Capítulo")) {
nameStr
} else if (nameStr.contains("ap&iacute;tulo")) {
nameStr.replace("&iacute;", "í")
} else {
"Capítulo $chapterNumber: $nameStr"
}
url = chapterUrlBuilder(jsonElement["post_name"].string, chapterNumber)
scanlator = "Plot Twist No Fansub"
}
override fun chapterListParse(response: Response): List<SChapter> = mutableListOf<SChapter>().apply {
val document = response.asJsoup()
val mangaId = document.select("link[rel=shortlink]")
.attr("href")
.substringAfter("?p=")
.toIntOrNull()
if (mangaId != null) {
var page = 1
var moreChapters = true
// This source uses an AJAX paginated plugin to get the chapter list (5 chapters per page),
// if there are no more chapters it returns [], knowing that:
var currentPageChaptersList: JsonArray
val allChaptersList = JsonArray()
while (moreChapters) {
currentPageChaptersList = fetchChaptersPertPage(page, mangaId)
allChaptersList.addAll(currentPageChaptersList)
if (currentPageChaptersList.size() == 5) page++
else moreChapters = false
}
allChaptersList.forEach {
add(chapterFromJsonElement(it))
}
} else throw Exception("No fue posible obtener la lista capítulos")
}
override fun chapterFromElement(element: Element) = throw Exception("Not Used")
private fun imageUrlBuilder(postName: String, mangaId: String, chapterNumber: String, imgName: String): String {
return "$baseUrl/wp-manga/${postName}_$mangaId/ch_$chapterNumber/$imgName"
}
override fun pageListParse(document: Document): List<Page> = mutableListOf<Page>().apply {
val jsonStr = document.select("script:containsData(var obj =)")
.toString()
.substringAfter("obj =")
.substringBeforeLast(";").trim()
val jsonObject = parseJson(jsonStr)
val imagesList = jsonObject["images"].array
val mangaPostName = jsonObject["title"].string
val chapterNumber = jsonObject["actual"].string
imagesList.forEach {
add(Page(size, "", imageUrlBuilder(mangaPostName, it["manga_id"].string, chapterNumber, it["image_name"].string)))
}
}
override fun imageUrlParse(document: Document) = throw Exception("Not Used")
override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = GET("$baseUrl/page/$page/?s=$query")
override fun searchMangaFromElement(element: Element) = popularMangaFromElement(element)
override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
override fun searchMangaSelector() = popularMangaSelector()
}

View File

@ -5,7 +5,7 @@ ext {
extName = 'TuMangaOnline'
pkgNameSuffix = 'es.tumangaonline'
extClass = '.TuMangaOnline'
extVersionCode = 27
extVersionCode = 28
libVersion = '1.2'
}

View File

@ -229,7 +229,7 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
override fun pageListParse(document: Document): List<Page> = mutableListOf<Page>().apply {
if (getPageMethod() == "cascade") {
document.select("img.viewer-img").forEach {
document.select("div.viewer-container img").forEach {
add(Page(size, "", it.let {
if (it.hasAttr("data-src"))
it.attr("abs:data-src") else it.attr("abs:src")