parent
0f2c985b19
commit
98ccbbde25
|
@ -4,8 +4,8 @@ apply plugin: 'kotlin-android'
|
|||
ext {
|
||||
appName = 'Tachiyomi: MangaMx & Doujin-Yang'
|
||||
pkgNameSuffix = 'es.mangamx'
|
||||
extClass = '.MangaMxFactory'
|
||||
extVersionCode = 5
|
||||
extClass = '.MangaMx'
|
||||
extVersionCode = 6
|
||||
libVersion = '1.2'
|
||||
}
|
||||
|
||||
|
|
|
@ -21,123 +21,145 @@ import java.util.Locale
|
|||
|
||||
open class MangaMx : ParsedHttpSource() {
|
||||
|
||||
//Info
|
||||
|
||||
override val name = "MangaMx"
|
||||
override val baseUrl = "https://manga-mx.com"
|
||||
override val lang = "es"
|
||||
override val supportsLatest = true
|
||||
private var csrfToken = ""
|
||||
|
||||
override fun popularMangaSelector() = "article[id=item]"
|
||||
override fun latestUpdatesSelector() = "div.manga-item"
|
||||
override fun searchMangaSelector() = "article[id=item]"
|
||||
override fun chapterListSelector() = throw Exception ("Not Used")
|
||||
//Popular
|
||||
|
||||
override fun popularMangaNextPageSelector() = "a[href*=directorio]:containsOwn(Última)"
|
||||
override fun latestUpdatesNextPageSelector() = "a[href*=reciente]:containsOwn(Última)"
|
||||
override fun searchMangaNextPageSelector() = "a[href*=/?s]:containsOwn(Última), a[href*=directorio]:containsOwn(Última)"
|
||||
override fun popularMangaRequest(page: Int) =
|
||||
GET("$baseUrl/directorio?filtro=visitas&p=$page", headers)
|
||||
|
||||
|
||||
override fun popularMangaRequest(page: Int) = GET("$baseUrl/directorio/?orden=visitas&p=$page", headers)
|
||||
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/reciente/capitulos?p=$page", headers)
|
||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||
val uri = if (query.isNotBlank()) {
|
||||
Uri.parse(baseUrl).buildUpon()
|
||||
.appendQueryParameter("s", query)
|
||||
} else {
|
||||
val uri = Uri.parse("$baseUrl/directorio").buildUpon()
|
||||
//Append uri filters
|
||||
filters.forEach {
|
||||
if (it is UriFilter)
|
||||
it.addToUri(uri)
|
||||
}
|
||||
uri.appendQueryParameter("p", page.toString())
|
||||
}
|
||||
return GET(uri.toString(), headers)
|
||||
override fun popularMangaNextPageSelector() = ".page-item a[rel=next]"
|
||||
override fun popularMangaSelector() = "#article-div a"
|
||||
override fun popularMangaFromElement(element: Element): SManga = SManga.create().apply {
|
||||
setUrlWithoutDomain(element.attr("href"))
|
||||
thumbnail_url = element.select("img").attr("src")
|
||||
title = element.select("div:eq(1)").text().trim()
|
||||
}
|
||||
|
||||
//override fun mangaDetailsRequest(manga: SManga) = GET(baseUrl + manga.url, headers)
|
||||
//override fun pageListRequest(chapter: SChapter) = GET(baseUrl + chapter.url, headers)
|
||||
|
||||
override fun chapterListRequest(manga: SManga): Request {
|
||||
val body = FormBody.Builder()
|
||||
.addEncoded("cap_list","")
|
||||
.build()
|
||||
val headers = headersBuilder()
|
||||
.add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
|
||||
.build()
|
||||
return POST(baseUrl + manga.url, headers, body)
|
||||
}
|
||||
|
||||
override fun latestUpdatesParse(response: Response): MangasPage {
|
||||
override fun popularMangaParse(response: Response): MangasPage {
|
||||
val document = response.asJsoup()
|
||||
val mangas = document.select(latestUpdatesSelector())
|
||||
.distinctBy { it.select("a").first().attr("abs:href") }
|
||||
.map { latestUpdatesFromElement(it) }
|
||||
val hasNextPage = latestUpdatesNextPageSelector().let { selector ->
|
||||
csrfToken = document.select("meta[name=csrf-token]").attr("content")
|
||||
|
||||
val mangas = document.select(popularMangaSelector()).map { element ->
|
||||
popularMangaFromElement(element)
|
||||
}
|
||||
|
||||
val hasNextPage = popularMangaNextPageSelector().let { selector ->
|
||||
document.select(selector).first()
|
||||
} != null
|
||||
|
||||
return MangasPage(mangas, hasNextPage)
|
||||
}
|
||||
|
||||
override fun popularMangaFromElement(element: Element) = mangaFromElement(element)
|
||||
override fun latestUpdatesFromElement(element: Element): SManga {
|
||||
val manga = SManga.create()
|
||||
manga.setUrlWithoutDomain(element.select("a").first().attr("abs:href"))
|
||||
manga.title = element.select("a").first().text().trim()
|
||||
return manga
|
||||
}
|
||||
override fun searchMangaFromElement(element: Element)= mangaFromElement(element)
|
||||
//Latest
|
||||
|
||||
private fun mangaFromElement(element: Element): SManga {
|
||||
val manga = SManga.create()
|
||||
manga.setUrlWithoutDomain(element.select("a").first().attr("abs:href"))
|
||||
manga.title = element.select("h2").text().trim()
|
||||
//manga.thumbnail_url = "https:" + element.select("img").attr("src")
|
||||
manga.thumbnail_url = element.select("img").attr("abs:src")
|
||||
return manga
|
||||
}
|
||||
|
||||
|
||||
override fun chapterListParse(response: Response): List<SChapter> {
|
||||
val jsonData = response.body()!!.string()
|
||||
val results = JsonParser().parse(jsonData).asJsonArray
|
||||
val chapters = mutableListOf<SChapter>()
|
||||
val url = "https:" + results[0].string
|
||||
for (i in 1 until results.size()) {
|
||||
val obj = results[i]
|
||||
chapters.add(chapterFromJson(obj, url))
|
||||
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/recientes?p=$page", headers)
|
||||
override fun latestUpdatesNextPageSelector(): String? = popularMangaNextPageSelector()
|
||||
override fun latestUpdatesSelector() = "div._1bJU3"
|
||||
override fun latestUpdatesFromElement(element: Element): SManga = SManga.create().apply {
|
||||
thumbnail_url = element.select("img").attr("src")
|
||||
element.select("div a").apply {
|
||||
title = this.text().trim()
|
||||
setUrlWithoutDomain(this.attr("href"))
|
||||
}
|
||||
return chapters
|
||||
}
|
||||
|
||||
private fun chapterFromJson (obj: JsonElement, url: String): SChapter {
|
||||
val chapter = SChapter.create()
|
||||
chapter.setUrlWithoutDomain(url + obj["id"].string)
|
||||
chapter.name = obj["tc"].string + obj["titulo"].string
|
||||
chapter.chapter_number = obj["numero"].string.toFloat()
|
||||
chapter.date_upload = parseDate(obj["datetime"].string)
|
||||
return chapter
|
||||
//Search
|
||||
|
||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||
if (query.isNotBlank()) {
|
||||
val formBody = FormBody.Builder()
|
||||
.add("buscar", query)
|
||||
.add("_token", csrfToken)
|
||||
.build()
|
||||
val searchHeaders = headers.newBuilder().add("X-Requested-With", "XMLHttpRequest")
|
||||
.add("Referer", baseUrl).build()
|
||||
return POST("$baseUrl/buscar", searchHeaders, formBody)
|
||||
} else {
|
||||
val uri = Uri.parse("$baseUrl/directorio").buildUpon()
|
||||
//Append uri filters
|
||||
for (filter in filters) {
|
||||
when (filter) {
|
||||
is StatusFilter -> uri.appendQueryParameter(
|
||||
filter.name.toLowerCase(Locale.ROOT),
|
||||
statusArray[filter.state].second
|
||||
)
|
||||
is FilterFilter -> uri.appendQueryParameter(
|
||||
filter.name.toLowerCase(Locale.ROOT),
|
||||
filterArray[filter.state].second
|
||||
)
|
||||
is TypeFilter -> uri.appendQueryParameter(
|
||||
filter.name.toLowerCase(Locale.ROOT),
|
||||
typedArray[filter.state].second
|
||||
)
|
||||
is AdultFilter -> uri.appendQueryParameter(
|
||||
filter.name.toLowerCase(Locale.ROOT),
|
||||
adultArray[filter.state].second
|
||||
)
|
||||
is OrderFilter -> uri.appendQueryParameter(
|
||||
filter.name.toLowerCase(Locale.ROOT),
|
||||
orderArray[filter.state].second
|
||||
)
|
||||
}
|
||||
}
|
||||
uri.appendQueryParameter("p", page.toString())
|
||||
return GET(uri.toString(), headers)
|
||||
}
|
||||
}
|
||||
|
||||
override fun searchMangaNextPageSelector(): String? = popularMangaNextPageSelector()
|
||||
override fun searchMangaSelector(): String = popularMangaSelector()
|
||||
override fun searchMangaFromElement(element: Element): SManga = popularMangaFromElement(element)
|
||||
override fun searchMangaParse(response: Response): MangasPage {
|
||||
if (!response.isSuccessful) throw Exception("Búsqueda fallida ${response.code()}")
|
||||
if ("directorio" in response.request().url().toString()) {
|
||||
val document = response.asJsoup()
|
||||
val mangas = document.select(searchMangaSelector()).map { element ->
|
||||
searchMangaFromElement(element)
|
||||
}
|
||||
|
||||
private fun parseDate(date: String): Long {
|
||||
return SimpleDateFormat("yyyy-MM-dd kk:mm:ss", Locale.US ).parse(date).time
|
||||
val hasNextPage = searchMangaNextPageSelector()?.let { selector ->
|
||||
document.select(selector).first()
|
||||
} != null
|
||||
|
||||
return MangasPage(mangas, hasNextPage)
|
||||
} else {
|
||||
val body = response.body()!!.string()
|
||||
if (body == "[]") throw Exception("Término de búsqueda demasiado corto")
|
||||
val json = JsonParser().parse(body)["mangas"].asJsonArray
|
||||
|
||||
val mangas = json.map { jsonElement -> searchMangaFromJson(jsonElement) }
|
||||
val hasNextPage = false
|
||||
return MangasPage(mangas, hasNextPage)
|
||||
}
|
||||
}
|
||||
|
||||
override fun chapterFromElement(element: Element)= throw Exception("Not used")
|
||||
private fun searchMangaFromJson(jsonElement: JsonElement): SManga = SManga.create().apply {
|
||||
title = jsonElement["nombre"].string
|
||||
setUrlWithoutDomain(jsonElement["url"].string)
|
||||
thumbnail_url = jsonElement["img"].string.replace("/thumb", "/cover")
|
||||
}
|
||||
|
||||
//Details
|
||||
|
||||
override fun mangaDetailsParse(document: Document): SManga {
|
||||
val manga = SManga.create()
|
||||
manga.thumbnail_url = document.select("img[src*=cover]").attr("abs:src")
|
||||
manga.description = document.select("div[id=sinopsis]").last().ownText()
|
||||
manga.author = document.select("div[id=info-i]").text().let {
|
||||
manga.description = document.select("div#sinopsis").last().ownText()
|
||||
manga.author = document.select("div#info-i").text().let {
|
||||
if (it.contains("Autor", true)) {
|
||||
it.substringAfter("Autor:").substringBefore("Fecha:").trim()
|
||||
} else "N/A"
|
||||
}
|
||||
manga.artist = manga.author
|
||||
val glist = document.select("div[id=categ] a[href*=genero]").map { it.text() }
|
||||
manga.genre = glist.joinToString(", ")
|
||||
manga.status = when (document.select("span[id=desarrollo]")?.first()?.text()) {
|
||||
manga.genre = document.select("div#categ a").joinToString(", ") { it.text() }
|
||||
manga.status = when (document.select("span#desarrollo")?.first()?.text()) {
|
||||
"En desarrollo" -> SManga.ONGOING
|
||||
//"Completed" -> SManga.COMPLETED
|
||||
else -> SManga.UNKNOWN
|
||||
|
@ -145,156 +167,88 @@ open class MangaMx : ParsedHttpSource() {
|
|||
return manga
|
||||
}
|
||||
|
||||
override fun pageListParse(response: Response): List<Page> {
|
||||
val body = response.asJsoup()
|
||||
val script = body.select("script:containsData(cap_info)").html()
|
||||
val jsonData = script.substringAfter("var cap_info = ").substringBeforeLast(";")
|
||||
val results = JsonParser().parse(jsonData).asJsonArray
|
||||
val jsonImg = results[1].asJsonArray
|
||||
val url = "https:" + jsonImg[0].string
|
||||
val pages = mutableListOf<Page>()
|
||||
for (i in 1 until jsonImg.size()) {
|
||||
pages.add(Page(i, "",url + jsonImg[i].string))
|
||||
}
|
||||
return pages
|
||||
//Chapters
|
||||
|
||||
override fun chapterListSelector(): String = "div#c_list a"
|
||||
override fun chapterFromElement(element: Element): SChapter = SChapter.create().apply {
|
||||
name = element.text().trim()
|
||||
setUrlWithoutDomain(element.attr("href"))
|
||||
chapter_number = element.select("span").attr("data-num").toFloat()
|
||||
date_upload = parseDate(element.select("span").attr("datetime"))
|
||||
}
|
||||
|
||||
private fun parseDate(date: String): Long {
|
||||
return SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US).parse(date)?.time ?: 0
|
||||
}
|
||||
|
||||
//Pages
|
||||
|
||||
override fun pageListParse(document: Document): List<Page> = mutableListOf<Page>().apply {
|
||||
val script = document.select("script:containsData(hojas)").html()
|
||||
val dir = script.substringAfter("var dir = '").substringBefore("';")
|
||||
val imgList =
|
||||
script.substringAfter("var hojas = [\"").substringBefore("\"];").split("\",\"")
|
||||
imgList.forEach {
|
||||
add(Page(size, "", dir + it))
|
||||
}
|
||||
}
|
||||
|
||||
override fun pageListParse(document: Document)= throw Exception("Not Used")
|
||||
override fun imageUrlParse(document: Document) = throw Exception("Not Used")
|
||||
|
||||
//Filters
|
||||
|
||||
override fun getFilterList() = FilterList(
|
||||
Filter.Header("NOTA: ¡Ignorado si usa la búsqueda de texto!"),
|
||||
Filter.Separator(),
|
||||
GenreFilter(),
|
||||
LetterFilter(),
|
||||
StatusFilter(),
|
||||
TypeFilter(),
|
||||
AdultFilter(),
|
||||
SortFilter()
|
||||
StatusFilter("Estado", statusArray),
|
||||
FilterFilter("Filtro", filterArray),
|
||||
TypeFilter("Tipo", typedArray),
|
||||
AdultFilter("Adulto", adultArray),
|
||||
OrderFilter("Orden", orderArray)
|
||||
)
|
||||
|
||||
class GenreFilter : UriPartFilter("Género", "genero", arrayOf(
|
||||
Pair("all","All"),
|
||||
Pair("3","Acción"),
|
||||
Pair("35","Artes Marciales"),
|
||||
Pair("7","Aventura"),
|
||||
Pair("31","Ciencia ficción"),
|
||||
Pair("1","Comedia"),
|
||||
Pair("37","Demonios"),
|
||||
Pair("10","Deportes"),
|
||||
Pair("2","Drama"),
|
||||
Pair("6","Ecchi"),
|
||||
Pair("42","Eroge"),
|
||||
Pair("4","Escolar"),
|
||||
Pair("12","Fantasía"),
|
||||
Pair("20","Ficción"),
|
||||
Pair("14","Gore"),
|
||||
Pair("21","Harem"),
|
||||
Pair("27","Histórico"),
|
||||
Pair("36","Horror"),
|
||||
Pair("43","Isekai"),
|
||||
Pair("33","Josei"),
|
||||
Pair("34","Magia"),
|
||||
Pair("13","Mecha"),
|
||||
Pair("41","Militar"),
|
||||
Pair("17","Misterio"),
|
||||
Pair("30","Músical"),
|
||||
Pair("11","Psicológico"),
|
||||
Pair("39","Recuentos de la vida"),
|
||||
Pair("5","Romance"),
|
||||
Pair("19","Seinen"),
|
||||
Pair("9","Shōjo"),
|
||||
Pair("32","Shōjo-ai"),
|
||||
Pair("8","Shōnen"),
|
||||
Pair("40","Shōnen ai"),
|
||||
Pair("18","Sobrenatural"),
|
||||
Pair("38","Supervivencia"),
|
||||
Pair("25","Webtoon"),
|
||||
Pair("15","Yaoi"),
|
||||
Pair("16","Yuri")
|
||||
))
|
||||
|
||||
class LetterFilter : UriPartFilter("Letra","letra", arrayOf(
|
||||
Pair("all","All"),
|
||||
Pair("a","A"),
|
||||
Pair("b","B"),
|
||||
Pair("c","C"),
|
||||
Pair("d","D"),
|
||||
Pair("e","E"),
|
||||
Pair("f","F"),
|
||||
Pair("g","G"),
|
||||
Pair("h","H"),
|
||||
Pair("i","I"),
|
||||
Pair("j","J"),
|
||||
Pair("k","K"),
|
||||
Pair("l","L"),
|
||||
Pair("m","M"),
|
||||
Pair("n","N"),
|
||||
Pair("o","O"),
|
||||
Pair("p","P"),
|
||||
Pair("q","Q"),
|
||||
Pair("r","R"),
|
||||
Pair("s","S"),
|
||||
Pair("t","T"),
|
||||
Pair("u","U"),
|
||||
Pair("v","V"),
|
||||
Pair("w","W"),
|
||||
Pair("x","X"),
|
||||
Pair("y","Y"),
|
||||
Pair("z","Z")
|
||||
))
|
||||
private class StatusFilter(name: String, values: Array<Pair<String, String>>) :
|
||||
Filter.Select<String>(name, values.map { it.first }.toTypedArray())
|
||||
|
||||
class StatusFilter : UriPartFilter("Estado", "estado", arrayOf(
|
||||
Pair("all","All"),Pair("1","En desarrollo"), Pair("0","Finalizado")))
|
||||
private class FilterFilter(name: String, values: Array<Pair<String, String>>) :
|
||||
Filter.Select<String>(name, values.map { it.first }.toTypedArray())
|
||||
|
||||
private class TypeFilter : UriPartFilter("Tipo", "tipo", arrayOf(
|
||||
Pair("all","All"),
|
||||
Pair("0","Manga"),
|
||||
Pair("1","Manhwa"),
|
||||
Pair("2","One Shot"),
|
||||
Pair("3","Manhua"),
|
||||
Pair("4","Novela")
|
||||
))
|
||||
private class TypeFilter(name: String, values: Array<Pair<String, String>>) :
|
||||
Filter.Select<String>(name, values.map { it.first }.toTypedArray())
|
||||
|
||||
private class AdultFilter : UriPartFilter("Filtro adulto", "adulto", arrayOf(
|
||||
Pair("all","All"),Pair("0","Mostrar solo +18"), Pair("1","No mostrar +18")))
|
||||
private class AdultFilter(name: String, values: Array<Pair<String, String>>) :
|
||||
Filter.Select<String>(name, values.map { it.first }.toTypedArray())
|
||||
|
||||
class SortFilter : UriPartFilterreq("Sort", "orden", arrayOf(
|
||||
Pair("visitas","Visitas"),
|
||||
Pair("desc","Descendente"),
|
||||
Pair("asc","Ascendente"),
|
||||
Pair("lanzamiento","Lanzamiento"),
|
||||
Pair("nombre","Nombre")
|
||||
))
|
||||
private class OrderFilter(name: String, values: Array<Pair<String, String>>) :
|
||||
Filter.Select<String>(name, values.map { it.first }.toTypedArray())
|
||||
|
||||
/**
|
||||
* Class that creates a select filter. Each entry in the dropdown has a name and a display name.
|
||||
* If an entry is selected it is appended as a query parameter onto the end of the URI.
|
||||
* If `firstIsUnspecified` is set to true, if the first entry is selected, nothing will be appended on the the URI.
|
||||
*/
|
||||
//vals: <name, display>
|
||||
open class UriPartFilter(displayName: String, private val uriParam: String, private val vals: Array<Pair<String, String>>,
|
||||
private val firstIsUnspecified: Boolean = true,
|
||||
defaultValue: Int = 0) :
|
||||
Filter.Select<String>(displayName, vals.map { it.second }.toTypedArray(), defaultValue), UriFilter {
|
||||
override fun addToUri(uri: Uri.Builder) {
|
||||
if (state != 0 || !firstIsUnspecified)
|
||||
uri.appendQueryParameter(uriParam, vals[state].first)
|
||||
}
|
||||
}
|
||||
|
||||
open class UriPartFilterreq(displayName: String, private val uriParam: String, private val vals: Array<Pair<String, String>>) :
|
||||
Filter.Select<String>(displayName, vals.map { it.second }.toTypedArray()), UriFilter {
|
||||
override fun addToUri(uri: Uri.Builder) {
|
||||
uri.appendQueryParameter(uriParam, vals[state].first)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a filter that is able to modify a URI.
|
||||
*/
|
||||
private interface UriFilter {
|
||||
fun addToUri(uri: Uri.Builder)
|
||||
}
|
||||
private val statusArray = arrayOf(
|
||||
Pair("Estado", "false"),
|
||||
Pair("En desarrollo", "1"),
|
||||
Pair("Completo", "0")
|
||||
)
|
||||
private val filterArray = arrayOf(
|
||||
Pair("Visitas", "visitas"),
|
||||
Pair("Recientes", "id"),
|
||||
Pair("Alfabético", "nombre")
|
||||
)
|
||||
private val typedArray = arrayOf(
|
||||
Pair("Todo", "false"),
|
||||
Pair("Mangas", "0"),
|
||||
Pair("Manhwas", "1"),
|
||||
Pair("One Shot", "2"),
|
||||
Pair("Manhuas", "3"),
|
||||
Pair("Novelas", "4")
|
||||
)
|
||||
private val adultArray = arrayOf(
|
||||
Pair("Filtro adulto", "false"),
|
||||
Pair("No mostrar +18", "0"),
|
||||
Pair("Mostrar +18", "1")
|
||||
)
|
||||
private val orderArray = arrayOf(
|
||||
Pair("Descendente", "desc"),
|
||||
Pair("Ascendente", "asc")
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,156 +0,0 @@
|
|||
package eu.kanade.tachiyomi.extension.es.mangamx
|
||||
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.POST
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.SourceFactory
|
||||
import eu.kanade.tachiyomi.source.model.*
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import okhttp3.Request
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.Response
|
||||
|
||||
class MangaMxFactory : SourceFactory {
|
||||
override fun createSources(): List<Source> = listOf(
|
||||
MangaMx(),
|
||||
DoujinYang()
|
||||
)
|
||||
}
|
||||
|
||||
class DoujinYang: MangaMx() {
|
||||
override val baseUrl = "https://doujin-yang.es"
|
||||
|
||||
override val name = "Doujin-Yang"
|
||||
|
||||
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/reciente/doujin?p=$page", headers)
|
||||
|
||||
override fun latestUpdatesSelector() = popularMangaSelector()
|
||||
|
||||
override fun latestUpdatesNextPageSelector() = "nav#paginacion a:contains(Última)"
|
||||
|
||||
override fun searchMangaNextPageSelector() = latestUpdatesNextPageSelector()
|
||||
|
||||
override fun chapterListRequest(manga: SManga): Request {
|
||||
return GET(baseUrl + manga.url, headers)
|
||||
}
|
||||
|
||||
override fun chapterListParse(response: Response): List<SChapter> {
|
||||
return response.asJsoup().select("div#c_list a").map { element ->
|
||||
SChapter.create().apply {
|
||||
name = element.select("h3").text()
|
||||
setUrlWithoutDomain(element.attr("abs:href"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun pageListRequest(chapter: SChapter): Request {
|
||||
return POST(baseUrl + chapter.url,
|
||||
headersBuilder().add("Content-Type", "application/x-www-form-urlencoded").build(),
|
||||
RequestBody.create(null, "info")
|
||||
)
|
||||
}
|
||||
|
||||
override fun pageListParse(response: Response): List<Page> {
|
||||
return response.body()!!.string().substringAfter(",[").substringBefore("]")
|
||||
.replace(Regex("""[\\"]"""), "").split(",").let { list ->
|
||||
val path = "https:" + list[0]
|
||||
list.drop(1).mapIndexed { i, img -> Page(i, "", path + img) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun getFilterList() = FilterList(
|
||||
Filter.Header("NOTA: ¡La búsqueda de títulos no funciona!"), // "Title search not working"
|
||||
Filter.Separator(),
|
||||
GenreFilter(),
|
||||
LetterFilter(),
|
||||
StatusFilter(),
|
||||
SortFilter()
|
||||
)
|
||||
|
||||
class GenreFilter : UriPartFilter("Género", "genero", arrayOf(
|
||||
Pair("all","All"),
|
||||
Pair("1","Ahegao"),
|
||||
Pair("379","Alien"),
|
||||
Pair("2","Anal"),
|
||||
Pair("490","Android18"),
|
||||
Pair("717","Angel"),
|
||||
Pair("633","Asphyxiation"),
|
||||
Pair("237","Bandages"),
|
||||
Pair("77","Bbw"),
|
||||
Pair("143","Bdsm"),
|
||||
Pair("23","Blackmail"),
|
||||
Pair("113","Blindfold"),
|
||||
Pair("24","Blowjob"),
|
||||
Pair("166","Blowjobface"),
|
||||
Pair("25","Body Writing"),
|
||||
Pair("314","Bodymodification"),
|
||||
Pair("806","Bodystocking"),
|
||||
Pair("366","Bodysuit"),
|
||||
Pair("419","Bodyswap"),
|
||||
Pair("325","Bodywriting"),
|
||||
Pair("5","Bondage"),
|
||||
Pair("51","Bukkake"),
|
||||
Pair("410","Catgirl"),
|
||||
Pair("61","Chastitybelt"),
|
||||
Pair("78","Cheating"),
|
||||
Pair("293","Cheerleader"),
|
||||
Pair("62","Collar"),
|
||||
Pair("120","Compilation"),
|
||||
Pair("74","Condom"),
|
||||
Pair("63","Corruption"),
|
||||
Pair("191","Corset"),
|
||||
Pair("234","Cosplaying"),
|
||||
Pair("389","Cowgirl"),
|
||||
Pair("256","Crossdressing"),
|
||||
Pair("179","Crotchtattoo"),
|
||||
Pair("689","Crown"),
|
||||
Pair("733","Cumflation"),
|
||||
Pair("385","Cumswap"),
|
||||
Pair("251","Cunnilingus"),
|
||||
Pair("75","Darkskin"),
|
||||
Pair("180","Daughter"),
|
||||
Pair("52","Deepthroat"),
|
||||
Pair("28","Defloration"),
|
||||
Pair("198","Demon"),
|
||||
Pair("145","Demongirl"),
|
||||
Pair("64","Drugs"),
|
||||
Pair("95","Drunk"),
|
||||
Pair("462","Femalesonly"),
|
||||
Pair("82","Femdom"),
|
||||
Pair("139","Ffmthreesome"),
|
||||
Pair("823","Fftthreesome"),
|
||||
Pair("55","Full Color"),
|
||||
Pair("181","Fullbodytattoo"),
|
||||
Pair("203","Fullcensorship"),
|
||||
Pair("111","Fullcolor"),
|
||||
Pair("114","Gag"),
|
||||
Pair("3","Glasses"),
|
||||
Pair("515","Gloryhole"),
|
||||
Pair("116","Humanpet"),
|
||||
Pair("32","Humiliation"),
|
||||
Pair("147","Latex"),
|
||||
Pair("12","Maid"),
|
||||
Pair("4","Milf"),
|
||||
Pair("245","Military"),
|
||||
Pair("414","Milking"),
|
||||
Pair("34","Mind Control"),
|
||||
Pair("68","Mindbreak"),
|
||||
Pair("124","Mindcontrol"),
|
||||
Pair("645","Nun"),
|
||||
Pair("312","Nurse"),
|
||||
Pair("272","Robot"),
|
||||
Pair("7","Romance"),
|
||||
Pair("761","Sundress"),
|
||||
Pair("412","Tailplug"),
|
||||
Pair("253","Tutor"),
|
||||
Pair("259","Twins"),
|
||||
Pair("207","Twintails"),
|
||||
Pair("840","Valkyrie"),
|
||||
Pair("530","Vampire"),
|
||||
Pair("16","Yuri"),
|
||||
Pair("273","Zombie")
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue