Update TuMangaOnline, LectorManga & TMOHentai (#2656)
* Update filters, update latest URL to prevent server ban for too many requests. * Update TMO. * Update filters, fix latest updates URL.
This commit is contained in:
parent
7357093dde
commit
8b120ef5d6
@ -5,12 +5,11 @@ ext {
|
|||||||
appName = 'Tachiyomi: LectorManga'
|
appName = 'Tachiyomi: LectorManga'
|
||||||
pkgNameSuffix = 'es.lectormanga'
|
pkgNameSuffix = 'es.lectormanga'
|
||||||
extClass = '.LectorManga'
|
extClass = '.LectorManga'
|
||||||
extVersionCode = 10
|
extVersionCode = 11
|
||||||
libVersion = '1.2'
|
libVersion = '1.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation project(':lib-ratelimit')
|
|
||||||
compileOnly project(':preference-stub')
|
compileOnly project(':preference-stub')
|
||||||
compileOnly 'com.github.inorichi.injekt:injekt-core:65b0440'
|
compileOnly 'com.github.inorichi.injekt:injekt-core:65b0440'
|
||||||
}
|
}
|
||||||
|
@ -2,34 +2,19 @@ package eu.kanade.tachiyomi.extension.es.lectormanga
|
|||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.support.v7.preference.ListPreference
|
import android.support.v7.preference.*
|
||||||
import android.support.v7.preference.PreferenceScreen
|
|
||||||
import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
|
|
||||||
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.*
|
||||||
import eu.kanade.tachiyomi.source.model.FilterList
|
|
||||||
import eu.kanade.tachiyomi.source.model.MangasPage
|
|
||||||
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.source.online.ParsedHttpSource
|
||||||
import eu.kanade.tachiyomi.util.asJsoup
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
import okhttp3.FormBody
|
import okhttp3.*
|
||||||
import okhttp3.Headers
|
|
||||||
import okhttp3.HttpUrl
|
|
||||||
import okhttp3.OkHttpClient
|
|
||||||
import okhttp3.Request
|
|
||||||
import okhttp3.Response
|
|
||||||
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
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Date
|
import java.util.*
|
||||||
import java.util.Locale
|
|
||||||
import java.util.TimeZone
|
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note: this source is similar to TuMangaOnline.
|
* Note: this source is similar to TuMangaOnline.
|
||||||
@ -43,16 +28,6 @@ class LectorManga : ConfigurableSource, ParsedHttpSource() {
|
|||||||
override val lang = "es"
|
override val lang = "es"
|
||||||
override val supportsLatest = true
|
override val supportsLatest = true
|
||||||
|
|
||||||
//Client
|
|
||||||
|
|
||||||
private val rateLimitInterceptor = RateLimitInterceptor(1)
|
|
||||||
override val client: OkHttpClient = network.cloudflareClient.newBuilder()
|
|
||||||
.addNetworkInterceptor(rateLimitInterceptor)
|
|
||||||
.connectTimeout(1, TimeUnit.MINUTES)
|
|
||||||
.readTimeout(1, TimeUnit.MINUTES)
|
|
||||||
.retryOnConnectionFailure(true)
|
|
||||||
.followRedirects(true)
|
|
||||||
.build()
|
|
||||||
private val userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36"
|
private val userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36"
|
||||||
override fun headersBuilder(): Headers.Builder {
|
override fun headersBuilder(): Headers.Builder {
|
||||||
return Headers.Builder()
|
return Headers.Builder()
|
||||||
@ -88,25 +63,10 @@ class LectorManga : ConfigurableSource, ParsedHttpSource() {
|
|||||||
|
|
||||||
//Latest
|
//Latest
|
||||||
|
|
||||||
override fun latestUpdatesRequest(page: Int) = GET(baseUrl, headers)
|
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/library?order_item=creation&order_dir=desc&page=$page", headers)
|
||||||
override fun latestUpdatesNextPageSelector(): String? = null
|
override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector()
|
||||||
override fun latestUpdatesSelector() = "div.table-responsive:first-child td[scope=row]:nth-child(5n-3)"
|
override fun latestUpdatesSelector() = popularMangaSelector()
|
||||||
override fun latestUpdatesParse(response: Response): MangasPage {
|
override fun latestUpdatesFromElement(element: Element) = popularMangaFromElement(element)
|
||||||
val document = response.asJsoup()
|
|
||||||
val mangas = document.select(latestUpdatesSelector())
|
|
||||||
.distinctBy { it.select("td").text().trim() }
|
|
||||||
.map { latestUpdatesFromElement(it) }
|
|
||||||
val hasNextPage = false
|
|
||||||
return MangasPage(mangas, hasNextPage)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun latestUpdatesFromElement(element: Element): SManga {
|
|
||||||
|
|
||||||
val manga = SManga.create()
|
|
||||||
manga.setUrlWithoutDomain(element.select("a").first().attr("href"))
|
|
||||||
manga.title = element.select("td").text().trim()
|
|
||||||
return manga
|
|
||||||
}
|
|
||||||
|
|
||||||
//Search
|
//Search
|
||||||
|
|
||||||
@ -127,11 +87,14 @@ class LectorManga : ConfigurableSource, ParsedHttpSource() {
|
|||||||
is FilterBy -> {
|
is FilterBy -> {
|
||||||
url.addQueryParameter("filter_by", filter.toUriPart())
|
url.addQueryParameter("filter_by", filter.toUriPart())
|
||||||
}
|
}
|
||||||
is OrderBy -> {
|
is SortBy -> {
|
||||||
url.addQueryParameter("order_item", filter.toUriPart())
|
if (filter.state != null) {
|
||||||
|
url.addQueryParameter("order_item", SORTABLES[filter.state!!.index].second)
|
||||||
|
url.addQueryParameter(
|
||||||
|
"order_dir",
|
||||||
|
if (filter.state!!.ascending) { "asc" } else { "desc" }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
is OrderDir -> {
|
|
||||||
url.addQueryParameter("order_dir", filter.toUriPart())
|
|
||||||
}
|
}
|
||||||
is WebcomicFilter -> {
|
is WebcomicFilter -> {
|
||||||
url.addQueryParameter("webcomic", when (filter.state) {
|
url.addQueryParameter("webcomic", when (filter.state) {
|
||||||
@ -195,7 +158,7 @@ class LectorManga : ConfigurableSource, ParsedHttpSource() {
|
|||||||
|
|
||||||
//Chapters
|
//Chapters
|
||||||
|
|
||||||
override fun chapterListParse(response: Response): List<SChapter> {
|
override fun chapterListParse(response: Response): List<SChapter> = mutableListOf<SChapter>().apply {
|
||||||
time = serverTime() //Get time when the chapter page is opened
|
time = serverTime() //Get time when the chapter page is opened
|
||||||
|
|
||||||
val document = response.asJsoup()
|
val document = response.asJsoup()
|
||||||
@ -207,20 +170,19 @@ class LectorManga : ConfigurableSource, ParsedHttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Regular list of chapters
|
// Regular list of chapters
|
||||||
val chapters = mutableListOf<SChapter>()
|
|
||||||
val dupselect = getduppref()!!
|
val dupselect = getduppref()!!
|
||||||
val chapterNames = document.select("#chapters h4.text-truncate")
|
val chapterNames = document.select("#chapters h4.text-truncate")
|
||||||
val chapterNumbers = chapterNames.map { it.text().substringAfter("Capítulo").substringBefore("|").trim().toFloat() }
|
val chapterNumbers = chapterNames.map { it.text().substringAfter("Capítulo").substringBefore("|").trim().toFloat() }
|
||||||
val chapterInfos = document.select("#chapters .chapter-list")
|
val chapterInfos = document.select("#chapters .chapter-list")
|
||||||
|
|
||||||
chapterNames.forEachIndexed { index, _ ->
|
chapterNames.forEachIndexed { index, _ ->
|
||||||
val scanlator = chapterInfos[index].select("li")
|
val scanlator = chapterInfos[index].select("li")
|
||||||
if (dupselect == "one") {
|
if (dupselect == "one") {
|
||||||
scanlator.last { chapters.add(regularChapterFromElement(chapterNames[index].text(), it, chapterNumbers[index], chapterUrl)) }
|
scanlator.last { add(regularChapterFromElement(chapterNames[index].text(), it, chapterNumbers[index], chapterUrl)) }
|
||||||
} else {
|
} else {
|
||||||
scanlator.forEach { chapters.add(regularChapterFromElement(chapterNames[index].text(), it, chapterNumbers[index], chapterUrl)) }
|
scanlator.forEach { add(regularChapterFromElement(chapterNames[index].text(), it, chapterNumbers[index], chapterUrl)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return chapters
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun chapterListSelector() = throw UnsupportedOperationException("Not used")
|
override fun chapterListSelector() = throw UnsupportedOperationException("Not used")
|
||||||
@ -236,19 +198,20 @@ class LectorManga : ConfigurableSource, ParsedHttpSource() {
|
|||||||
?: 0
|
?: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun regularChapterFromElement(chapterName: String, info: Element, number: Float, chapterUrl: String): SChapter {
|
private fun regularChapterFromElement(chapterName: String, info: Element, number: Float, chapterUrl: String) = SChapter.create().apply {
|
||||||
val chapter = SChapter.create()
|
url = "$chapterUrl#${info.select("div.row > .text-right > form").attr("id")}"
|
||||||
chapter.url = "$chapterUrl#${info.select("div.row > .text-right > form").attr("id")}"
|
name = chapterName
|
||||||
chapter.name = chapterName
|
scanlator = info.select("div.col-md-6.text-truncate")?.text()
|
||||||
chapter.scanlator = info.select("div.col-md-6.text-truncate")?.text()
|
date_upload = info.select("span.badge.badge-primary.p-2").first()?.text()?.let {
|
||||||
chapter.date_upload = info.select("span.badge.badge-primary.p-2").first()?.text()?.let { parseChapterDate(it) }
|
parseChapterDate(it)
|
||||||
?: 0
|
} ?: 0
|
||||||
chapter.chapter_number = number
|
chapter_number = number
|
||||||
return chapter
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseChapterDate(date: String): Long = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).parse(date)?.time
|
private fun parseChapterDate(date: String): Long {
|
||||||
?: 0
|
return SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
|
||||||
|
.parse(date)?.time ?: 0
|
||||||
|
}
|
||||||
|
|
||||||
//Utilities
|
//Utilities
|
||||||
|
|
||||||
@ -262,12 +225,11 @@ class LectorManga : ConfigurableSource, ParsedHttpSource() {
|
|||||||
//Pages
|
//Pages
|
||||||
|
|
||||||
override fun pageListRequest(chapter: SChapter): Request {
|
override fun pageListRequest(chapter: SChapter): Request {
|
||||||
|
|
||||||
val (chapterURL, chapterID) = chapter.url.split("#")
|
val (chapterURL, chapterID) = chapter.url.split("#")
|
||||||
val response = client.newCall(GET(chapterURL, headers)).execute() //Get chapter page for current token
|
val response = client.newCall(GET(chapterURL, headers)).execute() //Get chapter page for current token
|
||||||
if (!response.isSuccessful) throw Exception("Lector Manga HTTP Error ${response.code()}")
|
if (!response.isSuccessful) throw Exception("Lector Manga HTTP Error ${response.code()}")
|
||||||
val document = response.asJsoup()
|
val document = response.asJsoup()
|
||||||
val geturl = document.select("form#$chapterID").attr("action") + "/$time" //Get redirect URL
|
val getUrl = document.select("form#$chapterID").attr("action") + "/$time" //Get redirect URL
|
||||||
val token = document.select("form#$chapterID input").attr("value") //Get token
|
val token = document.select("form#$chapterID input").attr("value") //Get token
|
||||||
val method = document.select("form#$chapterID").attr("method") //Check POST or GET
|
val method = document.select("form#$chapterID").attr("method") //Check POST or GET
|
||||||
time = serverTime() //Update time for next chapter
|
time = serverTime() //Update time for next chapter
|
||||||
@ -286,18 +248,18 @@ class LectorManga : ConfigurableSource, ParsedHttpSource() {
|
|||||||
else -> throw UnsupportedOperationException("Lector Manga something else broke.")
|
else -> throw UnsupportedOperationException("Lector Manga something else broke.")
|
||||||
}
|
}
|
||||||
|
|
||||||
val newurl = getBuilder(geturl, getHeaders, formBody, method)
|
val newUrl = getBuilder(getUrl, getHeaders, formBody, method)
|
||||||
|
|
||||||
// Get /cascade instead of /paginate to get all pages at once
|
// Get /cascade instead of /paginate to get all pages at once
|
||||||
val url = if (getPageMethod() == "cascade" && newurl.contains("paginated")) {
|
val url = if (getPageMethod() == "cascade" && newUrl.contains("paginated")) {
|
||||||
newurl.substringBefore("paginated") + "cascade"
|
newUrl.substringBefore("paginated") + "cascade"
|
||||||
} else if (getPageMethod() == "paginated" && newurl.contains("cascade")) {
|
} else if (getPageMethod() == "paginated" && newUrl.contains("cascade")) {
|
||||||
newurl.substringBefore("cascade") + "paginated"
|
newUrl.substringBefore("cascade") + "paginated"
|
||||||
} else newurl
|
} else newUrl
|
||||||
|
|
||||||
val headers = headersBuilder()
|
val headers = headersBuilder()
|
||||||
.add("User-Agent", userAgent)
|
.add("User-Agent", userAgent)
|
||||||
.add("Referer", newurl)
|
.add("Referer", newUrl)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
return GET(url, headers)
|
return GET(url, headers)
|
||||||
@ -324,7 +286,7 @@ class LectorManga : ConfigurableSource, ParsedHttpSource() {
|
|||||||
|
|
||||||
//Filters
|
//Filters
|
||||||
|
|
||||||
private class Types : UriPartFilter("Tipo", arrayOf(
|
private class Types : UriPartFilter("Filtrar por tipo", arrayOf(
|
||||||
Pair("Ver todo", ""),
|
Pair("Ver todo", ""),
|
||||||
Pair("Manga", "manga"),
|
Pair("Manga", "manga"),
|
||||||
Pair("Manhua", "manhua"),
|
Pair("Manhua", "manhua"),
|
||||||
@ -335,7 +297,7 @@ class LectorManga : ConfigurableSource, ParsedHttpSource() {
|
|||||||
Pair("Oel", "oel")
|
Pair("Oel", "oel")
|
||||||
))
|
))
|
||||||
|
|
||||||
private class Demography : UriPartFilter("Demografía", arrayOf(
|
private class Demography : UriPartFilter("Filtrar por demografía", arrayOf(
|
||||||
Pair("Ver todo", ""),
|
Pair("Ver todo", ""),
|
||||||
Pair("Seinen", "seinen"),
|
Pair("Seinen", "seinen"),
|
||||||
Pair("Shoujo", "shoujo"),
|
Pair("Shoujo", "shoujo"),
|
||||||
@ -344,24 +306,17 @@ class LectorManga : ConfigurableSource, ParsedHttpSource() {
|
|||||||
Pair("Kodomo", "kodomo")
|
Pair("Kodomo", "kodomo")
|
||||||
))
|
))
|
||||||
|
|
||||||
private class FilterBy : UriPartFilter("Ordenar por", arrayOf(
|
private class FilterBy : UriPartFilter("Campo de orden", arrayOf(
|
||||||
Pair("Título", "title"),
|
Pair("Título", "title"),
|
||||||
Pair("Autor", "author"),
|
Pair("Autor", "author"),
|
||||||
Pair("Compañia", "company")
|
Pair("Compañia", "company")
|
||||||
))
|
))
|
||||||
|
|
||||||
private class OrderBy : UriPartFilter("Ordenar por", arrayOf(
|
class SortBy : Filter.Sort(
|
||||||
Pair("Me gusta", "likes_count"),
|
"Ordenar por",
|
||||||
Pair("Alfabético", "alphabetically"),
|
SORTABLES.map { it.first }.toTypedArray(),
|
||||||
Pair("Puntuación", "score"),
|
Selection(0, false)
|
||||||
Pair("Creación", "creation"),
|
)
|
||||||
Pair("Fecha estreno", "release_date")
|
|
||||||
))
|
|
||||||
|
|
||||||
private class OrderDir : UriPartFilter("Ordenar por", arrayOf(
|
|
||||||
Pair("DESC", "desc"),
|
|
||||||
Pair("ASC", "asc")
|
|
||||||
))
|
|
||||||
|
|
||||||
private class WebcomicFilter : Filter.TriState("Webcomic")
|
private class WebcomicFilter : Filter.TriState("Webcomic")
|
||||||
private class FourKomaFilter : Filter.TriState("Yonkoma")
|
private class FourKomaFilter : Filter.TriState("Yonkoma")
|
||||||
@ -369,15 +324,14 @@ class LectorManga : ConfigurableSource, ParsedHttpSource() {
|
|||||||
private class EroticFilter : Filter.TriState("Erótico")
|
private class EroticFilter : Filter.TriState("Erótico")
|
||||||
|
|
||||||
private class Genre(name: String, val id: String) : Filter.CheckBox(name)
|
private class Genre(name: String, val id: String) : Filter.CheckBox(name)
|
||||||
private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Géneros", genres)
|
private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Filtrar por géneros", genres)
|
||||||
|
|
||||||
override fun getFilterList() = FilterList(
|
override fun getFilterList() = FilterList(
|
||||||
Types(),
|
Types(),
|
||||||
Demography(),
|
Demography(),
|
||||||
Filter.Separator(),
|
Filter.Separator(),
|
||||||
FilterBy(),
|
FilterBy(),
|
||||||
OrderBy(),
|
SortBy(),
|
||||||
OrderDir(),
|
|
||||||
Filter.Separator(),
|
Filter.Separator(),
|
||||||
WebcomicFilter(),
|
WebcomicFilter(),
|
||||||
FourKomaFilter(),
|
FourKomaFilter(),
|
||||||
@ -386,8 +340,10 @@ class LectorManga : ConfigurableSource, ParsedHttpSource() {
|
|||||||
GenreList(getGenreList())
|
GenreList(getGenreList())
|
||||||
)
|
)
|
||||||
|
|
||||||
// Array.from(document.querySelectorAll('#advancedSearch .custom-checkbox')).map(a => `Genre("${a.querySelector('label').innerText}", "${a.querySelector('input').value}")`).join(',\n')
|
// Array.from(document.querySelectorAll('#advancedSearch .custom-checkbox'))
|
||||||
|
// .map(a => `Genre("${a.querySelector('label').innerText}", "${a.querySelector('input').value}")`).join(',\n')
|
||||||
// on https://lectormanga.com/library
|
// on https://lectormanga.com/library
|
||||||
|
// Last revision 13/04/2020
|
||||||
private fun getGenreList() = listOf(
|
private fun getGenreList() = listOf(
|
||||||
Genre("Acción", "1"),
|
Genre("Acción", "1"),
|
||||||
Genre("Aventura", "2"),
|
Genre("Aventura", "2"),
|
||||||
@ -480,6 +436,7 @@ class LectorManga : ConfigurableSource, ParsedHttpSource() {
|
|||||||
preferences.edit().putString(PAGEGET_PREF, entry).commit()
|
preferences.edit().putString(PAGEGET_PREF, entry).commit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
screen.addPreference(deduppref)
|
screen.addPreference(deduppref)
|
||||||
screen.addPreference(pageMethod)
|
screen.addPreference(pageMethod)
|
||||||
}
|
}
|
||||||
@ -514,19 +471,26 @@ class LectorManga : ConfigurableSource, ParsedHttpSource() {
|
|||||||
preferences.edit().putString(PAGEGET_PREF, entry).commit()
|
preferences.edit().putString(PAGEGET_PREF, entry).commit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
screen.addPreference(deduppref)
|
screen.addPreference(deduppref)
|
||||||
screen.addPreference(pageMethod)
|
screen.addPreference(pageMethod)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getduppref() = preferences.getString(DEDUP_PREF, "all")
|
private fun getduppref() = preferences.getString(DEDUP_PREF, "all")
|
||||||
private fun getPageMethod() = preferences.getString(PAGEGET_PREF, "cascade")
|
private fun getPageMethod() = preferences.getString(PAGEGET_PREF, "cascade")
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val DEDUP_PREF_Title = "Chapter List Scanlator Preference"
|
private const val DEDUP_PREF_Title = "Chapter List Scanlator Preference"
|
||||||
private const val DEDUP_PREF = "deduppref"
|
private const val DEDUP_PREF = "deduppref"
|
||||||
private const val PAGEGET_PREF_Title = "Método para obtener imágenes"
|
private const val PAGEGET_PREF_Title = "Método para obtener imágenes"
|
||||||
private const val PAGEGET_PREF = "pagemethodpref"
|
private const val PAGEGET_PREF = "pagemethodpref"
|
||||||
|
|
||||||
|
private val SORTABLES = listOf(
|
||||||
|
Pair("Me gusta", "likes_count"),
|
||||||
|
Pair("Alfabético", "alphabetically"),
|
||||||
|
Pair("Puntuación", "score"),
|
||||||
|
Pair("Creación", "creation"),
|
||||||
|
Pair("Fecha estreno", "release_date")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ ext {
|
|||||||
appName = 'Tachiyomi: TMOHentai'
|
appName = 'Tachiyomi: TMOHentai'
|
||||||
pkgNameSuffix = 'es.tmohentai'
|
pkgNameSuffix = 'es.tmohentai'
|
||||||
extClass = '.TMOHentai'
|
extClass = '.TMOHentai'
|
||||||
extVersionCode = 1
|
extVersionCode = 2
|
||||||
libVersion = '1.2'
|
libVersion = '1.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ class TMOHentai : ParsedHttpSource() {
|
|||||||
|
|
||||||
override val supportsLatest = true
|
override val supportsLatest = true
|
||||||
|
|
||||||
override fun popularMangaRequest(page: Int) = GET("$baseUrl/section/hentai?view=list&page=$page&order=publication_date&order-dir=asc&search%5BsearchText%5D=&search%5BsearchBy%5D=name&type=all", headers)
|
override fun popularMangaRequest(page: Int) = GET("$baseUrl/section/all?view=list&page=$page&order=popularity&order-dir=desc&search[searchText]=&search[searchBy]=name&type=all", headers)
|
||||||
|
|
||||||
override fun popularMangaSelector() = "table > tbody > tr[data-toggle=popover]"
|
override fun popularMangaSelector() = "table > tbody > tr[data-toggle=popover]"
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ class TMOHentai : ParsedHttpSource() {
|
|||||||
|
|
||||||
override fun popularMangaNextPageSelector() = "a[rel=next]"
|
override fun popularMangaNextPageSelector() = "a[rel=next]"
|
||||||
|
|
||||||
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/filter/all?view=list&page=$page")
|
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/section/all?view=list&page=$page&order=publication_date&order-dir=desc&search[searchText]=&search[searchBy]=name&type=all", headers)
|
||||||
|
|
||||||
override fun latestUpdatesSelector() = popularMangaSelector()
|
override fun latestUpdatesSelector() = popularMangaSelector()
|
||||||
|
|
||||||
@ -75,10 +75,9 @@ class TMOHentai : ParsedHttpSource() {
|
|||||||
override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("Not used")
|
override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("Not used")
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
val url = HttpUrl.parse("$baseUrl/section/hentai?view=list")!!.newBuilder()
|
val url = HttpUrl.parse("$baseUrl/section/all?view=list")!!.newBuilder()
|
||||||
|
|
||||||
url.addQueryParameter("search[searchText]", query)
|
url.addQueryParameter("search[searchText]", query)
|
||||||
url.addQueryParameter("search[searchBy]", "name")
|
|
||||||
url.addQueryParameter("page", page.toString())
|
url.addQueryParameter("page", page.toString())
|
||||||
|
|
||||||
filters.forEach { filter ->
|
filters.forEach { filter ->
|
||||||
@ -86,17 +85,23 @@ class TMOHentai : ParsedHttpSource() {
|
|||||||
is Types -> {
|
is Types -> {
|
||||||
url.addQueryParameter("type", filter.toUriPart())
|
url.addQueryParameter("type", filter.toUriPart())
|
||||||
}
|
}
|
||||||
is OrderBy -> {
|
|
||||||
url.addQueryParameter("order", filter.toUriPart())
|
|
||||||
}
|
|
||||||
is OrderDir -> {
|
|
||||||
url.addQueryParameter("order-dir", filter.toUriPart())
|
|
||||||
}
|
|
||||||
is GenreList -> {
|
is GenreList -> {
|
||||||
filter.state
|
filter.state
|
||||||
.filter { genre -> genre.state }
|
.filter { genre -> genre.state }
|
||||||
.forEach { genre -> url.addQueryParameter("genders[]", genre.id) }
|
.forEach { genre -> url.addQueryParameter("genders[]", genre.id) }
|
||||||
}
|
}
|
||||||
|
is FilterBy -> {
|
||||||
|
url.addQueryParameter("search[searchBy]", filter.toUriPart())
|
||||||
|
}
|
||||||
|
is SortBy -> {
|
||||||
|
if (filter.state != null) {
|
||||||
|
url.addQueryParameter("order", SORTABLES[filter.state!!.index].second)
|
||||||
|
url.addQueryParameter(
|
||||||
|
"order-dir",
|
||||||
|
if (filter.state!!.ascending) { "asc" } else { "desc" }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,13 +115,14 @@ class TMOHentai : ParsedHttpSource() {
|
|||||||
override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
|
override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
|
||||||
|
|
||||||
private class Genre(name: String, val id: String) : Filter.CheckBox(name)
|
private class Genre(name: String, val id: String) : Filter.CheckBox(name)
|
||||||
|
|
||||||
private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Géneros", genres)
|
private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Géneros", genres)
|
||||||
|
|
||||||
override fun getFilterList() = FilterList(
|
override fun getFilterList() = FilterList(
|
||||||
Types(),
|
Types(),
|
||||||
Filter.Separator(),
|
Filter.Separator(),
|
||||||
OrderBy(),
|
FilterBy(),
|
||||||
OrderDir(),
|
SortBy(),
|
||||||
Filter.Separator(),
|
Filter.Separator(),
|
||||||
GenreList(getGenreList())
|
GenreList(getGenreList())
|
||||||
)
|
)
|
||||||
@ -126,7 +132,7 @@ class TMOHentai : ParsedHttpSource() {
|
|||||||
fun toUriPart() = vals[state].second
|
fun toUriPart() = vals[state].second
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Types : UriPartFilter("Tipo", arrayOf(
|
private class Types : UriPartFilter("Filtrar por tipo", arrayOf(
|
||||||
Pair("Ver todos", "all"),
|
Pair("Ver todos", "all"),
|
||||||
Pair("Manga", "hentai"),
|
Pair("Manga", "hentai"),
|
||||||
Pair("Light Hentai", "light-hentai"),
|
Pair("Light Hentai", "light-hentai"),
|
||||||
@ -135,18 +141,21 @@ class TMOHentai : ParsedHttpSource() {
|
|||||||
Pair("Other", "otro")
|
Pair("Other", "otro")
|
||||||
))
|
))
|
||||||
|
|
||||||
private class OrderBy : UriPartFilter("Ordenar por", arrayOf(
|
private class FilterBy : UriPartFilter("Campo de orden", arrayOf(
|
||||||
Pair("Alfabético", "alphabetic"),
|
Pair("Nombre", "name"),
|
||||||
Pair("Creación", "publication_date"),
|
Pair("Artista", "artist"),
|
||||||
Pair("Popularidad", "popularity")
|
Pair("Revista", "magazine"),
|
||||||
|
Pair("Tag", "tag")
|
||||||
))
|
))
|
||||||
|
|
||||||
private class OrderDir : UriPartFilter("Ordenar por", arrayOf(
|
class SortBy : Filter.Sort(
|
||||||
Pair("ASC", "asc"),
|
"Ordenar por",
|
||||||
Pair("DESC", "desc")
|
SORTABLES.map { it.first }.toTypedArray(),
|
||||||
))
|
Selection(2, false)
|
||||||
|
)
|
||||||
|
|
||||||
// Array.from(document.querySelectorAll('#advancedSearch .list-group .list-group-item')).map(a => `Genre("${a.querySelector('span').innerText.replace(' ', '')}", "${a.querySelector('input').value}")`).join(',\n')
|
// Array.from(document.querySelectorAll('#advancedSearch .list-group .list-group-item'))
|
||||||
|
// .map(a => `Genre("${a.querySelector('span').innerText.replace(' ', '')}", "${a.querySelector('input').value}")`).join(',\n')
|
||||||
// https://tmohentai.com/section/hentai
|
// https://tmohentai.com/section/hentai
|
||||||
private fun getGenreList() = listOf(
|
private fun getGenreList() = listOf(
|
||||||
Genre("Romance", "1"),
|
Genre("Romance", "1"),
|
||||||
@ -196,4 +205,13 @@ class TMOHentai : ParsedHttpSource() {
|
|||||||
Genre("Tsundere", "45"),
|
Genre("Tsundere", "45"),
|
||||||
Genre("Yandere", "46")
|
Genre("Yandere", "46")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val SORTABLES = listOf(
|
||||||
|
Pair("Alfabético", "alphabetic"),
|
||||||
|
Pair("Creación", "publication_date"),
|
||||||
|
Pair("Popularidad", "popularity")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -5,12 +5,11 @@ ext {
|
|||||||
appName = 'Tachiyomi: TuMangaOnline'
|
appName = 'Tachiyomi: TuMangaOnline'
|
||||||
pkgNameSuffix = 'es.tumangaonline'
|
pkgNameSuffix = 'es.tumangaonline'
|
||||||
extClass = '.TuMangaOnline'
|
extClass = '.TuMangaOnline'
|
||||||
extVersionCode = 25
|
extVersionCode = 26
|
||||||
libVersion = '1.2'
|
libVersion = '1.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation project(':lib-ratelimit')
|
|
||||||
compileOnly project(':preference-stub')
|
compileOnly project(':preference-stub')
|
||||||
compileOnly 'com.github.inorichi.injekt:injekt-core:65b0440'
|
compileOnly 'com.github.inorichi.injekt:injekt-core:65b0440'
|
||||||
}
|
}
|
||||||
|
@ -4,30 +4,18 @@ import android.app.Application
|
|||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
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 eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
|
|
||||||
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.*
|
||||||
import eu.kanade.tachiyomi.source.model.FilterList
|
|
||||||
import eu.kanade.tachiyomi.source.model.MangasPage
|
|
||||||
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.source.online.ParsedHttpSource
|
||||||
import eu.kanade.tachiyomi.util.asJsoup
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
import okhttp3.FormBody
|
import okhttp3.*
|
||||||
import okhttp3.Headers
|
|
||||||
import okhttp3.HttpUrl
|
|
||||||
import okhttp3.OkHttpClient
|
|
||||||
import okhttp3.Request
|
|
||||||
import okhttp3.Response
|
|
||||||
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
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
|
||||||
class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
|
class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
|
||||||
|
|
||||||
@ -40,14 +28,6 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
|
|||||||
|
|
||||||
//Client
|
//Client
|
||||||
|
|
||||||
private val rateLimitInterceptor = RateLimitInterceptor(1, 1)
|
|
||||||
override val client: OkHttpClient = network.cloudflareClient.newBuilder()
|
|
||||||
.addNetworkInterceptor(rateLimitInterceptor)
|
|
||||||
.connectTimeout(1, TimeUnit.MINUTES)
|
|
||||||
.readTimeout(1, TimeUnit.MINUTES)
|
|
||||||
.retryOnConnectionFailure(true)
|
|
||||||
.followRedirects(true)
|
|
||||||
.build()!!
|
|
||||||
private val userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36"
|
private val userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36"
|
||||||
override fun headersBuilder(): Headers.Builder {
|
override fun headersBuilder(): Headers.Builder {
|
||||||
return Headers.Builder()
|
return Headers.Builder()
|
||||||
@ -61,7 +41,6 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
|
|||||||
.headers(headers)
|
.headers(headers)
|
||||||
.url(url)
|
.url(url)
|
||||||
.method(method, formBody)
|
.method(method, formBody)
|
||||||
//.post(formBody)
|
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
return client.newCall(req)
|
return client.newCall(req)
|
||||||
@ -69,9 +48,6 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
|
|||||||
.request()
|
.request()
|
||||||
.url()
|
.url()
|
||||||
.toString()
|
.toString()
|
||||||
/*.execute()
|
|
||||||
.body()!!
|
|
||||||
.string()*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Popular
|
//Popular
|
||||||
@ -89,27 +65,10 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
|
|||||||
|
|
||||||
//Latest
|
//Latest
|
||||||
|
|
||||||
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/latest_uploads?page=$page&uploads_mode=thumbnail", headers)
|
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/library?order_item=creation&order_dir=desc&filter_by=title&_page=1&page=$page", headers)
|
||||||
override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector()
|
override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector()
|
||||||
override fun latestUpdatesSelector() = "div.upload-file-row"
|
override fun latestUpdatesSelector() = popularMangaSelector()
|
||||||
override fun latestUpdatesParse(response: Response): MangasPage {
|
override fun latestUpdatesFromElement(element: Element) = popularMangaFromElement(element)
|
||||||
val document = response.asJsoup()
|
|
||||||
val mangas = document.select(latestUpdatesSelector())
|
|
||||||
.distinctBy { it.select("div.thumbnail-title > h4.text-truncate").text().trim() }
|
|
||||||
.map { latestUpdatesFromElement(it) }
|
|
||||||
val hasNextPage = latestUpdatesNextPageSelector().let { selector ->
|
|
||||||
document.select(selector).first()
|
|
||||||
} != null
|
|
||||||
return MangasPage(mangas, hasNextPage)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun latestUpdatesFromElement(element: Element) = SManga.create().apply {
|
|
||||||
element.select("div.upload-file-row > a").let {
|
|
||||||
setUrlWithoutDomain(it.attr("href"))
|
|
||||||
title = it.select("div.thumbnail-title > h4.text-truncate").text()
|
|
||||||
thumbnail_url = it.select("div.thumbnail > style").toString().substringAfter("url('").substringBefore("');")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Search
|
//Search
|
||||||
|
|
||||||
@ -131,11 +90,14 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
|
|||||||
is FilterBy -> {
|
is FilterBy -> {
|
||||||
url.addQueryParameter("filter_by", filter.toUriPart())
|
url.addQueryParameter("filter_by", filter.toUriPart())
|
||||||
}
|
}
|
||||||
is OrderBy -> {
|
is SortBy -> {
|
||||||
url.addQueryParameter("order_item", filter.toUriPart())
|
if (filter.state != null) {
|
||||||
|
url.addQueryParameter("order_item", SORTABLES[filter.state!!.index].second)
|
||||||
|
url.addQueryParameter(
|
||||||
|
"order_dir",
|
||||||
|
if (filter.state!!.ascending) { "asc" } else { "desc" }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
is OrderDir -> {
|
|
||||||
url.addQueryParameter("order_dir", filter.toUriPart())
|
|
||||||
}
|
}
|
||||||
is WebcomicFilter -> {
|
is WebcomicFilter -> {
|
||||||
url.addQueryParameter("webcomic", when (filter.state) {
|
url.addQueryParameter("webcomic", when (filter.state) {
|
||||||
@ -217,7 +179,11 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
|
|||||||
// Regular list of chapters
|
// Regular list of chapters
|
||||||
val chapters = mutableListOf<SChapter>()
|
val chapters = mutableListOf<SChapter>()
|
||||||
document.select(regularChapterListSelector()).forEach { chapelement ->
|
document.select(regularChapterListSelector()).forEach { chapelement ->
|
||||||
val chapternumber = chapelement.select("a.btn-collapse").text().substringBefore(":").substringAfter("Capítulo").trim().toFloat()
|
val chapternumber = chapelement.select("a.btn-collapse").text()
|
||||||
|
.substringBefore(":")
|
||||||
|
.substringAfter("Capítulo")
|
||||||
|
.trim()
|
||||||
|
.toFloat()
|
||||||
val chaptername = chapelement.select("div.col-10.text-truncate").text()
|
val chaptername = chapelement.select("div.col-10.text-truncate").text()
|
||||||
val scanelement = chapelement.select("ul.chapter-list > li")
|
val scanelement = chapelement.select("ul.chapter-list > li")
|
||||||
val dupselect = getduppref()!!
|
val dupselect = getduppref()!!
|
||||||
@ -231,6 +197,7 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun chapterListSelector() = throw UnsupportedOperationException("Not used")
|
override fun chapterListSelector() = throw UnsupportedOperationException("Not used")
|
||||||
|
|
||||||
override fun chapterFromElement(element: Element) = throw UnsupportedOperationException("Not used")
|
override fun chapterFromElement(element: Element) = throw UnsupportedOperationException("Not used")
|
||||||
|
|
||||||
private fun oneShotChapterListSelector() = "div.chapter-list-element > ul.list-group li.list-group-item"
|
private fun oneShotChapterListSelector() = "div.chapter-list-element > ul.list-group li.list-group-item"
|
||||||
@ -318,7 +285,7 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
|
|||||||
|
|
||||||
//Filters
|
//Filters
|
||||||
|
|
||||||
private class Types : UriPartFilter("Tipo", arrayOf(
|
private class Types : UriPartFilter("Filtrar por tipo", arrayOf(
|
||||||
Pair("Ver todo", ""),
|
Pair("Ver todo", ""),
|
||||||
Pair("Manga", "manga"),
|
Pair("Manga", "manga"),
|
||||||
Pair("Manhua", "manhua"),
|
Pair("Manhua", "manhua"),
|
||||||
@ -329,7 +296,7 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
|
|||||||
Pair("Oel", "oel")
|
Pair("Oel", "oel")
|
||||||
))
|
))
|
||||||
|
|
||||||
private class Demography : UriPartFilter("Demografía", arrayOf(
|
private class Demography : UriPartFilter("Filtrar por demografía", arrayOf(
|
||||||
Pair("Ver todo", ""),
|
Pair("Ver todo", ""),
|
||||||
Pair("Seinen", "seinen"),
|
Pair("Seinen", "seinen"),
|
||||||
Pair("Shoujo", "shoujo"),
|
Pair("Shoujo", "shoujo"),
|
||||||
@ -338,24 +305,17 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
|
|||||||
Pair("Kodomo", "kodomo")
|
Pair("Kodomo", "kodomo")
|
||||||
))
|
))
|
||||||
|
|
||||||
private class FilterBy : UriPartFilter("Ordenar por", arrayOf(
|
private class FilterBy : UriPartFilter("Campo de orden", arrayOf(
|
||||||
Pair("Título", "title"),
|
Pair("Título", "title"),
|
||||||
Pair("Autor", "author"),
|
Pair("Autor", "author"),
|
||||||
Pair("Compañia", "company")
|
Pair("Compañia", "company")
|
||||||
))
|
))
|
||||||
|
|
||||||
private class OrderBy : UriPartFilter("Ordenar por", arrayOf(
|
class SortBy : Filter.Sort(
|
||||||
Pair("Me gusta", "likes_count"),
|
"Ordenar por",
|
||||||
Pair("Alfabético", "alphabetically"),
|
SORTABLES.map { it.first }.toTypedArray(),
|
||||||
Pair("Puntuación", "score"),
|
Selection(0, false)
|
||||||
Pair("Creación", "creation"),
|
)
|
||||||
Pair("Fecha estreno", "release_date")
|
|
||||||
))
|
|
||||||
|
|
||||||
private class OrderDir : UriPartFilter("Ordenar por", arrayOf(
|
|
||||||
Pair("ASC", "asc"),
|
|
||||||
Pair("DESC", "desc")
|
|
||||||
))
|
|
||||||
|
|
||||||
private class WebcomicFilter : Filter.TriState("Webcomic")
|
private class WebcomicFilter : Filter.TriState("Webcomic")
|
||||||
private class FourKomaFilter : Filter.TriState("Yonkoma")
|
private class FourKomaFilter : Filter.TriState("Yonkoma")
|
||||||
@ -363,15 +323,14 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
|
|||||||
private class EroticFilter : Filter.TriState("Erótico")
|
private class EroticFilter : Filter.TriState("Erótico")
|
||||||
|
|
||||||
private class Genre(name: String, val id: String) : Filter.CheckBox(name)
|
private class Genre(name: String, val id: String) : Filter.CheckBox(name)
|
||||||
private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Géneros", genres)
|
private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Filtrar por géneros", genres)
|
||||||
|
|
||||||
override fun getFilterList() = FilterList(
|
override fun getFilterList() = FilterList(
|
||||||
Types(),
|
Types(),
|
||||||
Demography(),
|
Demography(),
|
||||||
Filter.Separator(),
|
Filter.Separator(),
|
||||||
FilterBy(),
|
FilterBy(),
|
||||||
OrderBy(),
|
SortBy(),
|
||||||
OrderDir(),
|
|
||||||
Filter.Separator(),
|
Filter.Separator(),
|
||||||
WebcomicFilter(),
|
WebcomicFilter(),
|
||||||
FourKomaFilter(),
|
FourKomaFilter(),
|
||||||
@ -380,8 +339,10 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
|
|||||||
GenreList(getGenreList())
|
GenreList(getGenreList())
|
||||||
)
|
)
|
||||||
|
|
||||||
// Array.from(document.querySelectorAll('#books-genders .col-auto .custom-control')).map(a => `Genre("${a.querySelector('label').innerText}", "${a.querySelector('input').value}")`).join(',\n')
|
// Array.from(document.querySelectorAll('#books-genders .col-auto .custom-control'))
|
||||||
|
// .map(a => `Genre("${a.querySelector('label').innerText}", "${a.querySelector('input').value}")`).join(',\n')
|
||||||
// on https://tumangaonline.me/library
|
// on https://tumangaonline.me/library
|
||||||
|
// Last revision 13/04/2020
|
||||||
private fun getGenreList() = listOf(
|
private fun getGenreList() = listOf(
|
||||||
Genre("Acción", "1"),
|
Genre("Acción", "1"),
|
||||||
Genre("Aventura", "2"),
|
Genre("Aventura", "2"),
|
||||||
@ -474,6 +435,7 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
|
|||||||
preferences.edit().putString(PAGEGET_PREF, entry).commit()
|
preferences.edit().putString(PAGEGET_PREF, entry).commit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
screen.addPreference(deduppref)
|
screen.addPreference(deduppref)
|
||||||
screen.addPreference(pageMethod)
|
screen.addPreference(pageMethod)
|
||||||
}
|
}
|
||||||
@ -508,19 +470,27 @@ class TuMangaOnline : ConfigurableSource, ParsedHttpSource() {
|
|||||||
preferences.edit().putString(PAGEGET_PREF, entry).commit()
|
preferences.edit().putString(PAGEGET_PREF, entry).commit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
screen.addPreference(deduppref)
|
screen.addPreference(deduppref)
|
||||||
screen.addPreference(pageMethod)
|
screen.addPreference(pageMethod)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getduppref() = preferences.getString(DEDUP_PREF, "all")
|
private fun getduppref() = preferences.getString(DEDUP_PREF, "all")
|
||||||
private fun getPageMethod() = preferences.getString(PAGEGET_PREF, "cascade")
|
private fun getPageMethod() = preferences.getString(PAGEGET_PREF, "cascade")
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val DEDUP_PREF_Title = "Chapter List Scanlator Preference"
|
private const val DEDUP_PREF_Title = "Chapter List Scanlator Preference"
|
||||||
private const val DEDUP_PREF = "deduppref"
|
private const val DEDUP_PREF = "deduppref"
|
||||||
private const val PAGEGET_PREF_Title = "Método para obtener imágenes"
|
private const val PAGEGET_PREF_Title = "Método para obtener imágenes"
|
||||||
private const val PAGEGET_PREF = "pagemethodpref"
|
private const val PAGEGET_PREF = "pagemethodpref"
|
||||||
|
|
||||||
|
private val SORTABLES = listOf(
|
||||||
|
Pair("Me gusta", "likes_count"),
|
||||||
|
Pair("Alfabético", "alphabetically"),
|
||||||
|
Pair("Puntuación", "score"),
|
||||||
|
Pair("Creación", "creation"),
|
||||||
|
Pair("Fecha estreno", "release_date"),
|
||||||
|
Pair("Núm. Capítulos", "num_chapters")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user