Fix GS not loading the chapters and add some improvements (#6787)

* Fix GS not loading the chapters and add some improvements.

* Disable latest listing.
This commit is contained in:
Alessandro Jean 2021-05-02 02:26:14 -03:00 committed by GitHub
parent 039207c85a
commit 371202df93
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 22 deletions

View File

@ -0,0 +1,4 @@
dependencies {
implementation project(':lib-ratelimit')
}

View File

@ -0,0 +1,31 @@
package eu.kanade.tachiyomi.extension.pt.gekkouscan
import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
import eu.kanade.tachiyomi.multisrc.mmrcms.MMRCMS
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.Page
import okhttp3.OkHttpClient
import okhttp3.Request
import java.util.concurrent.TimeUnit
class GekkouScans : MMRCMS("Gekkou Scans", "https://leitor.gekkouscans.com.br", "pt-BR") {
override val client: OkHttpClient = super.client.newBuilder()
.addInterceptor(RateLimitInterceptor(1, 1, TimeUnit.SECONDS))
.build()
override fun chapterListSelector() = "ul.domaintld > li.li"
override fun imageRequest(page: Page): Request {
val newHeaders = headersBuilder()
.add("Accept", ACCEPT_IMAGE)
.add("Referer", page.url)
.build()
return GET(page.imageUrl!!, newHeaders)
}
companion object {
private const val ACCEPT_IMAGE = "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8"
}
}

View File

@ -2,9 +2,13 @@ package eu.kanade.tachiyomi.multisrc.mmrcms
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.net.Uri import android.net.Uri
import android.util.Base64
import com.github.salomonbrys.kotson.array import com.github.salomonbrys.kotson.array
import com.github.salomonbrys.kotson.bool
import com.github.salomonbrys.kotson.get import com.github.salomonbrys.kotson.get
import com.github.salomonbrys.kotson.string import com.github.salomonbrys.kotson.string
import com.google.gson.JsonArray
import com.google.gson.JsonObject
import com.google.gson.JsonParser import com.google.gson.JsonParser
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.asObservableSuccess
@ -21,27 +25,21 @@ import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import rx.Observable import rx.Observable
import java.net.URLDecoder
import java.text.ParseException import java.text.ParseException
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
import com.github.salomonbrys.kotson.array
import com.github.salomonbrys.kotson.bool
import com.github.salomonbrys.kotson.string
import com.google.gson.JsonArray
import com.google.gson.JsonObject
import android.util.Base64
import java.net.URLDecoder
abstract class MMRCMS ( abstract class MMRCMS(
override val name: String, override val name: String,
override val baseUrl: String, override val baseUrl: String,
override val lang: String, override val lang: String,
private val sourceInfo: String = "", private val sourceInfo: String = "",
) : HttpSource() { ) : HttpSource() {
open val jsonData = if(sourceInfo == "") { open val jsonData = if (sourceInfo == "") {
SourceData.giveMetaData(baseUrl) SourceData.giveMetaData(baseUrl)
} else{ } else {
sourceInfo sourceInfo
} }
/** /**
@ -80,7 +78,7 @@ abstract class MMRCMS (
override val supportsLatest = jsonObject["supports_latest"].bool override val supportsLatest = jsonObject["supports_latest"].bool
open val itemUrl = jsonObject["item_url"].string open val itemUrl = jsonObject["item_url"].string
open val categoryMappings = mapToPairs(jsonObject["categories"].array) open val categoryMappings = mapToPairs(jsonObject["categories"].array)
open var tagMappings = if (jsonObject["tags"].isJsonArray) { open var tagMappings = if (jsonObject["tags"].isJsonArray) {
mapToPairs(jsonObject["tags"].asJsonArray) mapToPairs(jsonObject["tags"].asJsonArray)
} else { } else {
emptyList<Pair<String, String>>() emptyList<Pair<String, String>>()
@ -102,12 +100,9 @@ abstract class MMRCMS (
it["id"].string to it["name"].string it["id"].string to it["name"].string
} }
private val itemUrlPath = Uri.parse(itemUrl).pathSegments.firstOrNull() private val itemUrlPath = Uri.parse(itemUrl).pathSegments.firstOrNull()
private val parsedBaseUrl = Uri.parse(baseUrl) private val parsedBaseUrl = Uri.parse(baseUrl)
override val client: OkHttpClient = network.cloudflareClient.newBuilder() override val client: OkHttpClient = network.cloudflareClient.newBuilder()
.connectTimeout(1, TimeUnit.MINUTES) .connectTimeout(1, TimeUnit.MINUTES)
.readTimeout(1, TimeUnit.MINUTES) .readTimeout(1, TimeUnit.MINUTES)
@ -309,7 +304,7 @@ abstract class MMRCMS (
val detailGenre = setOf("categories", "categorías", "catégories", "ジャンル", "kategoriler", "categorias", "kategorie", "التصنيفات", "жанр", "kategori", "tagi") val detailGenre = setOf("categories", "categorías", "catégories", "ジャンル", "kategoriler", "categorias", "kategorie", "التصنيفات", "жанр", "kategori", "tagi")
val detailStatus = setOf("status", "statut", "estado", "状態", "durum", "الحالة", "статус") val detailStatus = setOf("status", "statut", "estado", "状態", "durum", "الحالة", "статус")
val detailStatusComplete = setOf("complete", "مكتملة", "complet", "completo", "zakończone") val detailStatusComplete = setOf("complete", "مكتملة", "complet", "completo", "zakończone")
val detailStatusOngoing = setOf("ongoing", "مستمرة", "en cours", "em lançamento", "prace w toku") val detailStatusOngoing = setOf("ongoing", "مستمرة", "en cours", "em lançamento", "prace w toku", "ativo")
val detailDescription = setOf("description", "resumen") val detailDescription = setOf("description", "resumen")
for (element in document.select(".row .dl-horizontal dt")) { for (element in document.select(".row .dl-horizontal dt")) {
@ -359,7 +354,7 @@ abstract class MMRCMS (
/** /**
* Returns the Jsoup selector that returns a list of [Element] corresponding to each chapter. * Returns the Jsoup selector that returns a list of [Element] corresponding to each chapter.
*/ */
private fun chapterListSelector() = "ul[class^=chapters] > li:not(.btn), table.table tr" protected open fun chapterListSelector() = "ul[class^=chapters] > li:not(.btn), table.table tr"
// Some websites add characters after "chapters" thus the need of checking classes that starts with "chapters" // Some websites add characters after "chapters" thus the need of checking classes that starts with "chapters"
/** /**
@ -432,10 +427,9 @@ abstract class MMRCMS (
url = URLDecoder.decode(url, "UTF-8") url = URLDecoder.decode(url, "UTF-8")
} }
Page(i, "", url) Page(i, response.request.url.toString(), url)
} }
override fun imageUrlParse(response: Response) = throw UnsupportedOperationException("Unused method called!") override fun imageUrlParse(response: Response) = throw UnsupportedOperationException("Unused method called!")
private fun getInitialFilterList() = listOf<Filter<*>>( private fun getInitialFilterList() = listOf<Filter<*>>(
@ -469,7 +463,7 @@ abstract class MMRCMS (
override fun getFilterList(): FilterList { override fun getFilterList(): FilterList {
return when { return when {
name == "Mangas.pw" -> FilterList() name == "Mangas.pw" -> FilterList()
tagMappings != emptyList<Pair<String, String>>()-> { tagMappings != emptyList<Pair<String, String>>() -> {
FilterList( FilterList(
getInitialFilterList() + UriSelectFilter( getInitialFilterList() + UriSelectFilter(
"Tag", "Tag",

View File

@ -66,7 +66,7 @@ class MMRCMSSources {
SourceData.Single("Jpmangas", "https://jpmangas.co", "fr"), SourceData.Single("Jpmangas", "https://jpmangas.co", "fr"),
SourceData.Single("Op-VF", "https://www.op-vf.com", "fr", className = "OpVF"), SourceData.Single("Op-VF", "https://www.op-vf.com", "fr", className = "OpVF"),
SourceData.Single("FR Scan", "https://frscan.cc", "fr"), SourceData.Single("FR Scan", "https://frscan.cc", "fr"),
SourceData.Single("GekkouScan", "https://leitor.gekkouscans.com.br", "pt-BR"), SourceData.Single("Gekkou Scans", "https://leitor.gekkouscans.com.br", "pt-BR", isNsfw = true, pkgName = "gekkouscan", overrideVersionCode = 1),
// NOTE: THIS SOURCE CONTAINS A CUSTOM LANGUAGE SYSTEM (which will be ignored)! // NOTE: THIS SOURCE CONTAINS A CUSTOM LANGUAGE SYSTEM (which will be ignored)!
SourceData.Single("HentaiShark", "https://www.hentaishark.com", "all", isNsfw = true), SourceData.Single("HentaiShark", "https://www.hentaishark.com", "all", isNsfw = true),
//MultiLang("HentaiShark", "https://www.hentaishark.com", listOf("en", "ja", "zh", "de", "nl", "ko", "cz", "eo", "mn", "ar", "sk", "la", "ua", "ceb", "tl", "fi", "bg", "tr"), isNsfw = true, className = "HentaiSharkFactory"), //MultiLang("HentaiShark", "https://www.hentaishark.com", listOf("en", "ja", "zh", "de", "nl", "ko", "cz", "eo", "mn", "ar", "sk", "la", "ua", "ceb", "tl", "fi", "bg", "tr"), isNsfw = true, className = "HentaiSharkFactory"),

View File

@ -1,7 +1,7 @@
package eu.kanade.tachiyomi.multisrc.mmrcms package eu.kanade.tachiyomi.multisrc.mmrcms
// GENERATED FILE, DO NOT MODIFY! // GENERATED FILE, DO NOT MODIFY!
// Generated Fri, 30 Apr 2021 15:59:47 +1200 // Generated Sun, 2 May 2021 02:14:53 GMT
class SourceData() { class SourceData() {
companion object { companion object {
@ -39,7 +39,7 @@ class SourceData() {
"https://www.op-vf.com" -> """{"name":"Op-VF","base_url":"https://www.op-vf.com","supports_latest":true,"item_url":"https://www.op-vf.com/manga/","categories":[],"tags":"null"}""" "https://www.op-vf.com" -> """{"name":"Op-VF","base_url":"https://www.op-vf.com","supports_latest":true,"item_url":"https://www.op-vf.com/manga/","categories":[],"tags":"null"}"""
"https://frscan.cc" -> """{"name":"FR Scan","base_url":"https://frscan.cc","supports_latest":true,"item_url":"https://frscan.cc/manga/","categories":[{"id":"1","name":"Action"},{"id":"2","name":"Adventure"},{"id":"3","name":"Comedy"},{"id":"4","name":"Doujinshi"},{"id":"5","name":"Drama"},{"id":"6","name":"Ecchi"},{"id":"7","name":"Fantasy"},{"id":"8","name":"Gender Bender"},{"id":"9","name":"Harem"},{"id":"10","name":"Historical"},{"id":"11","name":"Horror"},{"id":"12","name":"Josei"},{"id":"13","name":"Martial Arts"},{"id":"14","name":"Mature"},{"id":"15","name":"Mecha"},{"id":"16","name":"Mystery"},{"id":"17","name":"One Shot"},{"id":"18","name":"Psychological"},{"id":"19","name":"Romance"},{"id":"20","name":"Vie Scolaire"},{"id":"21","name":"Sci-fi"},{"id":"22","name":"Seinen"},{"id":"23","name":"Shoujo"},{"id":"24","name":"Shoujo Ai"},{"id":"25","name":"Shounen"},{"id":"26","name":"Shounen Ai"},{"id":"27","name":"Tranche de vie"},{"id":"28","name":"Sports"},{"id":"29","name":"Supernatural"},{"id":"30","name":"Tragedie"},{"id":"31","name":"Yaoi"},{"id":"32","name":"Yuri"},{"id":"33","name":"Autre"},{"id":"34","name":"BD Occidentale"},{"id":"35","name":"Webtoon"}],"tags":"null"}""" "https://frscan.cc" -> """{"name":"FR Scan","base_url":"https://frscan.cc","supports_latest":true,"item_url":"https://frscan.cc/manga/","categories":[{"id":"1","name":"Action"},{"id":"2","name":"Adventure"},{"id":"3","name":"Comedy"},{"id":"4","name":"Doujinshi"},{"id":"5","name":"Drama"},{"id":"6","name":"Ecchi"},{"id":"7","name":"Fantasy"},{"id":"8","name":"Gender Bender"},{"id":"9","name":"Harem"},{"id":"10","name":"Historical"},{"id":"11","name":"Horror"},{"id":"12","name":"Josei"},{"id":"13","name":"Martial Arts"},{"id":"14","name":"Mature"},{"id":"15","name":"Mecha"},{"id":"16","name":"Mystery"},{"id":"17","name":"One Shot"},{"id":"18","name":"Psychological"},{"id":"19","name":"Romance"},{"id":"20","name":"Vie Scolaire"},{"id":"21","name":"Sci-fi"},{"id":"22","name":"Seinen"},{"id":"23","name":"Shoujo"},{"id":"24","name":"Shoujo Ai"},{"id":"25","name":"Shounen"},{"id":"26","name":"Shounen Ai"},{"id":"27","name":"Tranche de vie"},{"id":"28","name":"Sports"},{"id":"29","name":"Supernatural"},{"id":"30","name":"Tragedie"},{"id":"31","name":"Yaoi"},{"id":"32","name":"Yuri"},{"id":"33","name":"Autre"},{"id":"34","name":"BD Occidentale"},{"id":"35","name":"Webtoon"}],"tags":"null"}"""
"https://www.hentaishark.com" -> """{"name":"HentaiShark","base_url":"https://www.hentaishark.com","supports_latest":true,"item_url":"https://www.hentaishark.com/manga/","categories":[{"id":"1","name":"Doujinshi"},{"id":"2","name":"Manga"},{"id":"3","name":"Western"},{"id":"4","name":"non-h"},{"id":"5","name":"imageset"},{"id":"6","name":"artistcg"},{"id":"7","name":"misc"}],"tags":"null"}""" "https://www.hentaishark.com" -> """{"name":"HentaiShark","base_url":"https://www.hentaishark.com","supports_latest":true,"item_url":"https://www.hentaishark.com/manga/","categories":[{"id":"1","name":"Doujinshi"},{"id":"2","name":"Manga"},{"id":"3","name":"Western"},{"id":"4","name":"non-h"},{"id":"5","name":"imageset"},{"id":"6","name":"artistcg"},{"id":"7","name":"misc"}],"tags":"null"}"""
"https://leitor.gekkouscans.com.br" -> """{"name":"GekkouScan","base_url":"https://leitor.gekkouscans.com.br","supports_latest":true,"item_url":"https://leitor.gekkouscans.com.br/manga/","categories":[{"id":"1","name":"Action"},{"id":"2","name":"Adventure"},{"id":"3","name":"Comedy"},{"id":"4","name":"Doujinshi"},{"id":"5","name":"Drama"},{"id":"6","name":"Ecchi"},{"id":"7","name":"Fantasy"},{"id":"8","name":"Gender Bender"},{"id":"9","name":"Harem"},{"id":"10","name":"Historical"},{"id":"11","name":"Horror"},{"id":"12","name":"Josei"},{"id":"13","name":"Martial Arts"},{"id":"14","name":"Mature"},{"id":"15","name":"Mecha"},{"id":"16","name":"Mystery"},{"id":"17","name":"One Shot"},{"id":"18","name":"Psychological"},{"id":"19","name":"Romance"},{"id":"20","name":"School Life"},{"id":"21","name":"Sci-fi"},{"id":"22","name":"Seinen"},{"id":"23","name":"Shoujo"},{"id":"24","name":"Shoujo Ai"},{"id":"25","name":"Shounen"},{"id":"26","name":"Shounen Ai"},{"id":"27","name":"Slice of Life"},{"id":"28","name":"Sports"},{"id":"29","name":"Supernatural"},{"id":"30","name":"Tragedy"},{"id":"31","name":"Yaoi"},{"id":"32","name":"Yuri"}],"tags":"null"}""" "https://leitor.gekkouscans.com.br" -> """{"name":"Gekkou Scans","base_url":"https://leitor.gekkouscans.com.br","supports_latest":false,"item_url":"https://leitor.gekkouscans.com.br/manga/","categories":[{"id":"1","name":"Ação"},{"id":"2","name":"Aventura"},{"id":"3","name":"Comédia"},{"id":"4","name":"Doujinshi"},{"id":"5","name":"Drama"},{"id":"6","name":"Ecchi"},{"id":"7","name":"Fantasia"},{"id":"8","name":"Harém"},{"id":"9","name":"Histórico"},{"id":"10","name":"Horror"},{"id":"11","name":"Josei"},{"id":"12","name":"Martial Arts"},{"id":"13","name":"Adulto"},{"id":"14","name":"Mecha"},{"id":"15","name":"Mistério"},{"id":"16","name":"One Shot"},{"id":"17","name":"Psicológico"},{"id":"18","name":"Romance"},{"id":"19","name":"Escolar"},{"id":"20","name":"Sci-fi"},{"id":"21","name":"Seinen"},{"id":"22","name":"Shoujo"},{"id":"23","name":"Shoujo Ai"},{"id":"24","name":"Shounen"},{"id":"25","name":"Shounen Ai"},{"id":"26","name":"Vida Cotidiana"},{"id":"27","name":"Esportes"},{"id":"28","name":"Sobrenatural"},{"id":"29","name":"Tragédia"},{"id":"30","name":"Yaoi"},{"id":"31","name":"Yuri"},{"id":"32","name":"Webtoon"},{"id":"33","name":"Superpoderes"}],"tags":"null"}"""
else -> "" else -> ""
} }
} }