Madara split: part 1 (#5662)

* madara 161

* 50 of madara sources

* remove moved classes part 1
This commit is contained in:
Aria Moradi 2021-02-07 07:37:31 -08:00 committed by GitHub
parent f275fc07c2
commit ee33c8fa02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
44 changed files with 1461 additions and 701 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

View File

@ -0,0 +1,13 @@
package eu.kanade.tachiyomi.extension.tr.adonisfansub
import eu.kanade.tachiyomi.annotations.Nsfw
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.GET
import okhttp3.Request
@Nsfw
class AdonisFansub : Madara("Adonis Fansub", "https://manga.adonisfansub.com", "tr") {
override val userAgentRandomizer = ""
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/manga/page/$page/?m_orderby=views", headers)
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/manga/page/$page/?m_orderby=latest", headers)
}

View File

@ -0,0 +1,43 @@
package eu.kanade.tachiyomi.extension.en.agentofchangetranslations
import android.annotation.SuppressLint
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Headers
import okhttp3.Response
class AgentofChangeTranslations : Madara("Agent of Change Translations", "https://aoc.moe", "en") {
override fun headersBuilder(): Headers.Builder = super.headersBuilder().add("Referer", baseUrl)
override fun popularMangaSelector() = "div.page-item-detail.manga:has(span.chapter)"
override fun chapterListSelector() = "li.wp-manga-chapter:has(a)"
@SuppressLint("DefaultLocale")
override fun chapterListParse(response: Response): List<SChapter> {
return response.asJsoup().let { document ->
document.select(chapterListSelector()).let { normalChapters ->
if (normalChapters.isNotEmpty()) {
normalChapters.map { chapterFromElement(it) }
} else {
// For their "fancy" volume/chapter lists
document.select("div.wpb_wrapper:contains(volume) a")
.filter { it.attr("href").contains(baseUrl) && !it.attr("href").contains("imgur") }
.map { volumeChapter ->
SChapter.create().apply {
volumeChapter.attr("href").let { url ->
name = if (url.contains("volume")) {
val volume = url.substringAfter("volume-").substringBefore("/")
val volChap = url.substringAfter("volume-$volume/").substringBefore("/").replace("-", " ").capitalize()
"Volume $volume - $volChap"
} else {
url.substringBefore("/p").substringAfterLast("/").replace("-", " ").capitalize()
}
setUrlWithoutDomain(url.substringBefore("?") + "?style=list")
}
}
}
}.reversed()
}
}
}
}

View File

@ -0,0 +1,151 @@
package eu.kanade.tachiyomi.extension.en.allporncomic
import eu.kanade.tachiyomi.annotations.Nsfw
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.GET
import okhttp3.Request
@Nsfw
class AllPornComic : Madara("AllPornComic", "https://allporncomic.com", "en") {
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/manga/page/$page/?m_orderby=views", headers)
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/manga/page/$page/?m_orderby=latest", headers)
override fun searchMangaNextPageSelector() = "a[rel=next]"
override fun getGenreList() = listOf(
Genre("3D", "3d"),
Genre("Ahegao", "ahegao"),
Genre("Alien Girl", "alien-girl"),
Genre("Anal", "anal"),
Genre("Anime", "anime"),
Genre("Anthology", "anthology"),
Genre("Artbook", "artbook"),
Genre("BBW / Chubby / Fat Woman", "bbw"),
Genre("BDSM", "bdsm"),
Genre("Big Areolae", "big-areolae"),
Genre("Big Ass", "big-ass"),
Genre("Big Balls", "big-balls"),
Genre("Big Breasts", "big-breasts"),
Genre("Big Clit", "big-clit"),
Genre("Big Nipples", "big-nipples"),
Genre("Big Penis", "big-penis"),
Genre("Bikini", "bikini"),
Genre("Blackmail", "blackmail"),
Genre("Blindfold", "blindfold"),
Genre("Body Modification", "body-modification"),
Genre("Body Swap", "body-swap"),
Genre("Body Writing", "body-writing"),
Genre("BodyStocking", "bodystocking"),
Genre("Bodysuit", "bodysuit"),
Genre("Bondage", "bondage"),
Genre("Brain Fuck", "brain-fuck"),
Genre("Cartoon", "cartoon"),
Genre("Cheerleader", "cheerleader"),
Genre("Chinese Dress", "chinese-dress"),
Genre("Collar / Choker", "collar"),
Genre("Comedy", "comedy"),
Genre("Corruption", "corruption"),
Genre("Corset", "corset"),
Genre("Crotch Tattoo", "crotch-tattoo"),
Genre("Dark Skin", "dark-skin"),
Genre("Demon Girl / Succubus", "demon-girl"),
Genre("Dick Growth", "dick-growth"),
Genre("Dickgirl On Dickgirl", "dickgirl-on-dickgirl"),
Genre("Dickgirl On Male", "dickgirl-on-male"),
Genre("Dickgirls Only", "dickgirls-only"),
Genre("Drugs", "drugs"),
Genre("Drunk", "drunk"),
Genre("Exhibitionism", "exhibitionism"),
Genre("FFM Threesome", "ffm-threesome"),
Genre("FFT Threesome", "fft-threesome"),
Genre("Females Only", "females-only"),
Genre("Femdom", "femdom"),
Genre("Feminization", "feminization"),
Genre("Full Body Tattoo", "full-body-tattoo"),
Genre("Full Color", "full-color"),
Genre("Futanari", "futanari"),
Genre("Gender Bender", "gender-bender"),
Genre("Glasses", "glasses"),
Genre("Group", "group"),
Genre("Gyaru", "gyaru"),
Genre("Gyaru-OH", "gyaru-oh"),
Genre("Harem", "harem"),
Genre("Hentai", "hentai"),
Genre("Human Pet", "human-pet"),
Genre("Humiliation", "humiliation"),
Genre("Impregnation", "impregnation"),
Genre("Incest", "incest"),
Genre("Interracial", "interracial"),
Genre("Kimono", "kimono"),
Genre("Latex", "latex"),
Genre("Leash", "leash"),
Genre("Lingerie", "lingerie"),
Genre("Lolicon", "lolicon"),
Genre("MILF", "milf"),
Genre("MMF Threesome", "mmf-threesome"),
Genre("MMT Threesome", "mmt-threesome"),
Genre("Magical Girl", "magical-girl"),
Genre("Maid", "maid"),
Genre("Male On Dickgirl", "male-on-dickgirl"),
Genre("Manhwa", "manhwa"),
Genre("Military", "military"),
Genre("Milking", "milking"),
Genre("Mind Break", "mind-break"),
Genre("Mind Control", "mind-control"),
Genre("Monster Girl", "monster-girl"),
Genre("Moral Degeneration", "moral-degeneration"),
Genre("Muscle", "muscle"),
Genre("Muscle Growth", "muscle-growth"),
Genre("Nakadashi", "nakadashi"),
Genre("Netorare", "netorare"),
Genre("Netori", "netori"),
Genre("Ninja", "ninja"),
Genre("Nun", "nun"),
Genre("Nurse", "nurse"),
Genre("Orgy", "orgy"),
Genre("Paizuri", "paizuri"),
Genre("Pegging", "pegging"),
Genre("Piercing", "piercing"),
Genre("Pixie Cut", "pixie-cut"),
Genre("Policewoman", "policewoman"),
Genre("Possession", "possession"),
Genre("Retro", "retro"),
Genre("Ryona", "ryona"),
Genre("School Swimsuit", "school-swimsuit"),
Genre("Schoolboy Uniform", "schoolboy-uniform"),
Genre("Schoolgirl Uniform", "schoolgirl-uniform"),
Genre("Shared Senses", "shared-senses"),
Genre("Shemale", "shemale"),
Genre("Shibari", "shibari"),
Genre("Shotacon", "shotacon"),
Genre("Slave", "slave"),
Genre("Slime Girl", "slime-girl"),
Genre("Small Breasts", "small-breasts"),
Genre("Stockings", "stockings"),
Genre("Strap-on", "strap-on"),
Genre("Stuck In Wall", "stuck-in-wall"),
Genre("Superhero", "superhero"),
Genre("Superheroine", "superheroine"),
Genre("Tail", "tail"),
Genre("Tail Plug", "tail-plug"),
Genre("Tankoubon", "tankoubon"),
Genre("Tentacles", "tentacles"),
Genre("Thigh High Boots", "thigh-high-boots"),
Genre("Tights", "tights"),
Genre("Time Stop", "time-stop"),
Genre("Tomboy", "tomboy"),
Genre("Tomgirl", "tomgirl"),
Genre("Torture", "torture"),
Genre("Transformation", "transformation"),
Genre("Uncensored", "uncensored"),
Genre("Unusual Pupils", "unusual-pupils"),
Genre("Unusual Teeth", "unusual-teeth"),
Genre("Vampire", "vampire"),
Genre("Virginity", "virginity"),
Genre("Voyeurism", "voyeurism"),
Genre("Webtoon", "webtoon"),
Genre("Western", "western"),
Genre("Witch", "witch"),
Genre("Yandere", "yandere"),
Genre("Yaoi", "yaoi"),
Genre("Yuri", "yuri")
)
}

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.en.aloalivn
import eu.kanade.tachiyomi.multisrc.madara.Madara
class Aloalivn : Madara("Aloalivn", "https://aloalivn.com", "en") {
override val pageListParseSelector = "li.blocks-gallery-item"
}

View File

@ -0,0 +1,11 @@
package eu.kanade.tachiyomi.extension.en.animangaes
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.source.model.SChapter
import okhttp3.Response
class AniMangaEs : Madara("AniMangaEs", "http://animangaes.com", "en") {
override val pageListParseSelector = "div.text-left noscript"
override val chapterUrlSuffix = ""
override fun chapterListParse(response: Response): List<SChapter> = super.chapterListParse(response).reversed()
}

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.es.apollcomics
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class ApollComics : Madara("ApollComics", "https://apollcomics.xyz", "es", SimpleDateFormat("dd MMMM, yyyy", Locale("es")))

View File

@ -0,0 +1,15 @@
package eu.kanade.tachiyomi.extension.en.arangscans
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.GET
import okhttp3.Request
import java.text.SimpleDateFormat
import java.util.Locale
class ArangScans : Madara("Arang Scans", "https://www.arangscans.com", "en", SimpleDateFormat("d MMM yyyy", Locale.US)) {
// has very few manga
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/manga?m_orderby=views", headers)
override fun popularMangaNextPageSelector(): String? = null
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/manga?m_orderby=latest", headers)
override fun latestUpdatesNextPageSelector(): String? = null
}

View File

@ -0,0 +1,74 @@
package eu.kanade.tachiyomi.extension.tr.araznovel
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.FormBody
import okhttp3.Response
import java.text.SimpleDateFormat
import java.util.Locale
class ArazNovel : Madara("ArazNovel", "https://www.araznovel.com", "tr", SimpleDateFormat("dd/MM/yyyy", Locale.getDefault())) {
override fun formBuilder(page: Int, popular: Boolean): FormBody.Builder = super.formBuilder(page, popular)
.add("vars[meta_query][0][0][value]", "manga")
override fun getGenreList() = listOf(
Genre("Aksiyon", "action"),
Genre("Macera", "adventure"),
Genre("Cartoon", "cartoon"),
Genre("Comic", "comic"),
Genre("Komedi", "comedy"),
Genre("Yemek", "cooking"),
Genre("Doujinshi", "doujinshi"),
Genre("Dram", "drama"),
Genre("Ecchi", "ecchi"),
Genre("Fantastik", "fantasy"),
Genre("Harem", "harem"),
Genre("Tarihi", "historical"),
Genre("Korku", "horror"),
Genre("Manga", "manga"),
Genre("Manhua", "manhua"),
Genre("Manhwa", "manhwa"),
Genre("Olgun", "mature"),
Genre("Mecha", "mecha"),
Genre("Yetişkin", "adult"),
Genre("Gizem", "mystery"),
Genre("One Shot", "one-shot"),
Genre("Isekai", "isekai"),
Genre("Josei", "josei"),
Genre("Dedektif", "detective"),
Genre("Karanlık", "smut"),
Genre("Romantizm", "romance"),
Genre("Okul Yaşamı", "school-life"),
Genre("Yaşamdan Kesit", "slice-of-life"),
Genre("Spor", "sports"),
Genre("Doğa Üstü", "supernatural"),
Genre("Trajedi", "tragedy"),
Genre("Webtoon ", "webtoon"),
Genre("Dövüş Sanatları ", "martial-arts"),
Genre("Bilim Kurgu", "sci-fi"),
Genre("Seinen", "seinen"),
Genre("Shoujo", "shoujo"),
Genre("Shoujo Ai", "shoujo-ai"),
Genre("Shounen", "shounen"),
Genre("Shounen Ai", "shounen-ai"),
Genre("Soft Yaoi", "soft-yaoi"),
Genre("Soft Yuri", "soft-yuri"),
Genre("Yaoi", "yaoi"),
Genre("Yuri", "yuri")
)
override fun chapterListParse(response: Response): List<SChapter> {
return getXhrChapters(response.asJsoup().select("div#manga-chapters-holder").attr("data-id")).let { document ->
document.select("li.parent").let { elements ->
if (!elements.isNullOrEmpty()) {
elements.reversed()
.map { volumeElement -> volumeElement.select(chapterListSelector()).map { chapterFromElement(it) } }
.flatten()
} else {
document.select(chapterListSelector()).map { chapterFromElement(it) }
}
}
}
}
}

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.pt.argosscan
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class ArgosScan : Madara("Argos Scan", "https://argosscan.com", "pt-BR", SimpleDateFormat("dd 'de' MMMM 'de' yyyy", Locale("pt", "BR")))

View File

@ -0,0 +1,20 @@
package eu.kanade.tachiyomi.extension.en.astrallibrary
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.SChapter
import okhttp3.Request
import okhttp3.Response
import java.text.SimpleDateFormat
import java.util.Locale
class AstralLibrary : Madara("Astral Library", "https://www.astrallibrary.net", "en", SimpleDateFormat("d MMM", Locale.US)) {
override fun chapterListParse(response: Response): List<SChapter> = super.chapterListParse(response).reversed()
override fun popularMangaRequest(page: Int): Request {
return GET("$baseUrl/manga-tag/manga/?m_orderby=views&page=$page", headers)
}
override fun latestUpdatesRequest(page: Int): Request {
return GET("$baseUrl/manga-tag/manga/?m_orderby=latest&page=$page", headers)
}
}

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.tr.atikrost
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class Atikrost : Madara("Atikrost", "https://atikrost.com", "tr", SimpleDateFormat("MMMM dd, yyyy", Locale("tr")))

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.fr.atmsubs
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class ATMSubs : Madara("ATM-Subs", "https://atm-subs.fr", "fr", SimpleDateFormat("d MMMM yyyy", Locale("fr")))

View File

@ -0,0 +1,22 @@
package eu.kanade.tachiyomi.extension.fr.atmsubs
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.SChapter
import okhttp3.Request
import org.jsoup.nodes.Element
class Azora : Madara("Azora", "https://www.azoramanga.com", "ar") {
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/page/$page/?m_orderby=views", headers)
override fun chapterListSelector() = "li.wp-manga-chapter:not(.premium-block)" // Filter fake chapters
override fun chapterFromElement(element: Element): SChapter {
val chapter = SChapter.create()
element.select("a").let {
chapter.url = it.attr("href").substringAfter(baseUrl)
chapter.name = it.text()
}
return chapter
}
}

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.ru.bestmanga
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class BestManga : Madara("BestManga", "https://bestmanga.club", "ru", SimpleDateFormat("dd.MM.yyyy", Locale.getDefault()))

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.en.bestmanhua
import eu.kanade.tachiyomi.multisrc.madara.Madara
class BestManhua : Madara("BestManhua", "https://bestmanhua.com", "en") {
override val pageListParseSelector = "li.blocks-gallery-item"
}

View File

@ -0,0 +1,16 @@
package eu.kanade.tachiyomi.extension.th.cattranslator
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.POST
import okhttp3.CacheControl
import okhttp3.Request
class CatTranslator : Madara("CAT-translator", "https://cat-translator.com", "th") {
override fun popularMangaRequest(page: Int): Request =
POST("$baseUrl/manga/wp-admin/admin-ajax.php", formHeaders, formBuilder(page, true).build(), CacheControl.FORCE_NETWORK)
override fun latestUpdatesRequest(page: Int): Request =
POST("$baseUrl/manga/wp-admin/admin-ajax.php", formHeaders, formBuilder(page, false).build(), CacheControl.FORCE_NETWORK)
override fun searchPage(page: Int): String = "manga/page/$page/"
}

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.en.chibimanga
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class ChibiManga : Madara("Chibi Manga", "https://www.cmreader.info", "en", dateFormat = SimpleDateFormat("MMM dd, yyyy", Locale.US))

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.en.chibimanga
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class CloverManga : Madara("Clover Manga", "Clover Manga", "tr", SimpleDateFormat("MMMM dd, yyyy", Locale("tr")))

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.en.comickiba
import eu.kanade.tachiyomi.multisrc.madara.Madara
class ComicKiba : Madara("ComicKiba", "https://comickiba.com", "en") {
override val pageListParseSelector = "li.blocks-gallery-item img:nth-child(1), div.reading-content p > img, .read-container .reading-content img"
}

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.tr.cutiepie
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class CutiePie : Madara("Cutie Pie", "https://cutiepie.ga", "tr", SimpleDateFormat("dd MMMM yyyy", Locale.forLanguageTag("tr")))

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.tr.diamondfansub
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class DiamondFansub : Madara("DiamondFansub", "https://diamondfansub.com", "tr", SimpleDateFormat("MMMM dd, yyyy", Locale.forLanguageTag("tr")))

View File

@ -0,0 +1,21 @@
package eu.kanade.tachiyomi.extension.en.disasterscans
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.source.model.SManga
import org.jsoup.nodes.Document
class DisasterScans : Madara("Disaster Scans", "https://disasterscans.com", "en") {
override val popularMangaUrlSelector = "div.post-title a:last-child"
override fun mangaDetailsParse(document: Document): SManga {
val manga = super.mangaDetailsParse(document)
with(document) {
select("div.post-title h1").first()?.let {
manga.title = it.ownText()
}
}
return manga
}
}

View File

@ -0,0 +1,106 @@
package eu.kanade.tachiyomi.extension.es.doujinhentai
import eu.kanade.tachiyomi.annotations.Nsfw
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.SManga
import okhttp3.HttpUrl
import okhttp3.Request
import org.jsoup.nodes.Element
import java.text.SimpleDateFormat
import java.util.Locale
@Nsfw
class DoujinHentai : Madara("DoujinHentai", "https://doujinhentai.net", "es", SimpleDateFormat("d MMM. yyyy", Locale.ENGLISH)) {
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/lista-manga-hentai?orderby=views&page=$page", headers)
override fun popularMangaSelector() = "div.col-md-3 a"
override fun popularMangaFromElement(element: Element): SManga {
val manga = SManga.create()
manga.setUrlWithoutDomain(element.attr("href"))
manga.title = element.select("h5").text()
manga.thumbnail_url = element.select("img").attr("abs:data-src")
return manga
}
override fun popularMangaNextPageSelector() = "a[rel=next]"
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/lista-manga-hentai?orderby=last&page=$page", headers)
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = HttpUrl.parse(baseUrl)!!.newBuilder()
if (query.isNotBlank()) {
url.addPathSegment("search")
url.addQueryParameter("query", query) // query returns results all on one page
} else {
filters.forEach { filter ->
when (filter) {
is GenreSelectFilter -> {
if (filter.state != 0) {
url.addPathSegments("lista-manga-hentai/category/${filter.toUriPart()}")
url.addQueryParameter("page", page.toString())
}
}
}
}
}
return GET(url.build().toString(), headers)
}
override fun searchMangaSelector() = "div.c-tabs-item__content > div.c-tabs-item__content, ${popularMangaSelector()}"
override fun searchMangaFromElement(element: Element): SManga {
return if (element.hasAttr("href")) {
popularMangaFromElement(element) // genre search results
} else {
super.searchMangaFromElement(element) // query search results
}
}
override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
override fun chapterListSelector() = "ul.main.version-chap > li.wp-manga-chapter:not(:last-child)" // removing empty li
override val pageListParseSelector = "div#all > img.img-responsive"
override fun getFilterList() = FilterList(
Filter.Header("Solo funciona si la consulta está en blanco"),
GenreSelectFilter()
)
class GenreSelectFilter : UriPartFilter(
"Búsqueda de género",
arrayOf(
Pair("<seleccionar>", ""),
Pair("Ecchi", "ecchi"),
Pair("Yaoi", "yaoi"),
Pair("Yuri", "yuri"),
Pair("Anal", "anal"),
Pair("Tetonas", "tetonas"),
Pair("Escolares", "escolares"),
Pair("Incesto", "incesto"),
Pair("Virgenes", "virgenes"),
Pair("Masturbacion", "masturbacion"),
Pair("Maduras", "maduras"),
Pair("Lolicon", "lolicon"),
Pair("Bikini", "bikini"),
Pair("Sirvientas", "sirvientas"),
Pair("Enfermera", "enfermera"),
Pair("Embarazada", "embarazada"),
Pair("Ahegao", "ahegao"),
Pair("Casadas", "casadas"),
Pair("Chica Con Pene", "chica-con-pene"),
Pair("Juguetes Sexuales", "juguetes-sexuales"),
Pair("Orgias", "orgias"),
Pair("Harem", "harem"),
Pair("Romance", "romance"),
Pair("Profesores", "profesores"),
Pair("Tentaculos", "tentaculos"),
Pair("Mamadas", "mamadas"),
Pair("Shota", "shota"),
Pair("Interracial", "interracial"),
Pair("Full Color", "full-colo"),
Pair("Sin Censura", "sin-censura"),
Pair("Futanari", "futanari"),
Pair("Doble Penetracion", "doble-penetracion"),
Pair("Cosplay", "cosplay")
)
)
}

View File

@ -0,0 +1,96 @@
package eu.kanade.tachiyomi.extension.id.doujinyosh
import eu.kanade.tachiyomi.multisrc.madara.Madara
class DoujinYosh : Madara("DoujinYosh", "https://doujinyosh.work", "id") {
// source issue, doing this limits results to one page but not doing it returns no results at all
override fun searchPage(page: Int) = ""
override fun getGenreList() = listOf(
Genre("4 Koma", "4koma"),
Genre("Adult", "adult"),
Genre("Ahegao", "ahegao"),
Genre("Anal", "anal"),
Genre("Animal", "animal"),
Genre("Artist CG", "artist-cg"),
Genre("Big Breast", "big-breast"),
Genre("Big Penis", "big-penis"),
Genre("Bikini", "bikini"),
Genre("Black Mail", "black-mail"),
Genre("Blowjob", "blowjob"),
Genre("Body Swap", "body-swap"),
Genre("Bondage", "bondage"),
Genre("Cheating", "cheating"),
Genre("Crossdressing", "crossdressing"),
Genre("DILF", "dilf"),
Genre("Dark Skin", "dark-skin"),
Genre("Defloration", "defloration"),
Genre("Demon Girl", "demon-girl"),
Genre("Doujin", "doujin"),
Genre("Drugs", "drugs"),
Genre("Drunk", "drunk"),
Genre("Elf", "elf"),
Genre("Famele Only", "famele-only"),
Genre("Femdom", "femdom"),
Genre("Filming", "filming"),
Genre("Footjob", "footjob"),
Genre("Full Color", "full-color"),
Genre("Furry", "furry"),
Genre("Futanari", "futanari"),
Genre("Glasses", "glasses"),
Genre("Gore", "gore"),
Genre("Group", "group"),
Genre("Gyaru", "gyaru"),
Genre("Harem", "harem"),
Genre("Humiliation", "humiliation"),
Genre("Impregnation", "impregnation"),
Genre("Incest", "incest"),
Genre("Inverted Nipples", "inverted-nipples"),
Genre("Kemomimi", "kemomimi"),
Genre("Lactation", "lactation"),
Genre("Loli", "loli"),
Genre("Lolipai", "lolipai"),
Genre("MILF", "milf"),
Genre("Maid", "maid"),
Genre("Male Only", "male-only"),
Genre("Miko", "miko"),
Genre("Mind Break", "mind-break"),
Genre("Mind Control", "mind-control"),
Genre("Monster", "monster"),
Genre("Monster Girl", "monster-girl"),
Genre("Multi-Work Series", "multi-work-series"),
Genre("Nakadashi", "nakadashi"),
Genre("Netorare", "netorare"),
Genre("Otona (R18)", "otona"),
Genre("Oyakodon", "oyakodon"),
Genre("Paizuri", "paizuri"),
Genre("Pantyhose", "pantyhose"),
Genre("Pregnant", "pregnant"),
Genre("Prostitution", "prostitution"),
Genre("Rape", "rape"),
Genre("School Uniform", "school-uniform"),
Genre("Sex Toy", "sex-toy"),
Genre("Shota", "shota"),
Genre("Sister", "sister"),
Genre("Sleep", "sleep"),
Genre("Slime", "slime"),
Genre("Small Breast", "small-breast"),
Genre("Sole Female", "sole-female"),
Genre("Sole Male", "sole-male"),
Genre("Stocking", "stocking"),
Genre("Story Arc", "story-arc"),
Genre("Sweating", "sweating"),
Genre("Swimsuit", "swimsuit"),
Genre("Teacher", "teacher"),
Genre("Tentacles", "tentacles"),
Genre("Tomboy", "tomboy"),
Genre("Tomgirl", "tomgirl"),
Genre("Torture", "torture"),
Genre("Twins", "twins"),
Genre("Virginity", "virginity"),
Genre("Webtoon", "webtoon"),
Genre("XRay", "xray"),
Genre("Yandere", "yandere"),
Genre("Yaoi", "yaoi"),
Genre("Yuri", "yuri")
)
}

View File

@ -0,0 +1,10 @@
package eu.kanade.tachiyomi.extension.pt.dropescan
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.GET
import okhttp3.Request
class DropeScan : Madara("Drope Scan", "https://dropescan.com", "pt-BR") {
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/manga/page/$page/?m_orderby=views", headers)
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/manga/page/$page/?m_orderby=latest", headers)
}

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.pt.fdmscan
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class FDMScan : Madara("FDM Scan", "https://fdmscan.com", "pt-BR", SimpleDateFormat("MMMM dd, yyyy", Locale("pt", "BR")))

View File

@ -0,0 +1,10 @@
package eu.kanade.tachiyomi.extension.en.firstkissmanga
import eu.kanade.tachiyomi.multisrc.madara.Madara
import okhttp3.Headers
import java.text.SimpleDateFormat
import java.util.Locale
class FirstKissManga : Madara("1st Kiss", "https://1stkissmanga.com", "en", dateFormat = SimpleDateFormat("dd MMM yyyy", Locale.US)) {
override fun headersBuilder(): Headers.Builder = super.headersBuilder().add("Referer", baseUrl)
}

View File

@ -0,0 +1,12 @@
package eu.kanade.tachiyomi.extension.en.firstkissmanhua
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.Page
import okhttp3.Request
import java.text.SimpleDateFormat
import java.util.Locale
class FirstKissManhua : Madara("1st Kiss Manhua", "https://1stkissmanhua.com", "en", SimpleDateFormat("d MMM yyyy", Locale.US)) {
override fun imageRequest(page: Page): Request = GET(page.imageUrl!!, headersBuilder().add("Referer", "https://1stkissmanga.com").build())
}

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.pt.furioscans
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class FurioScans : Madara("Furio Scans", "https://furioscans.com", "pt-BR", SimpleDateFormat("dd/MM/yyyy", Locale.getDefault()))

View File

@ -0,0 +1,12 @@
package eu.kanade.tachiyomi.extension.ar.goldenmanga
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.FilterList
import java.text.SimpleDateFormat
import java.util.Locale
class GeceninLordu : Madara("Gecenin Lordu", "https://geceninlordu.com/", "tr", SimpleDateFormat("dd MMM yyyy", Locale("tr"))) {
override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = GET("$baseUrl/?s=$query&post_type=wp-manga")
}

View File

@ -0,0 +1,28 @@
package eu.kanade.tachiyomi.extension.ar.goldenmanga
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import org.jsoup.nodes.Element
import java.text.SimpleDateFormat
import java.util.Locale
class GoldenManga : Madara("موقع لترجمة المانجا", "https://golden-manga.com", "ar", SimpleDateFormat("yyyy-MM-dd", Locale.US)) {
override fun searchMangaSelector() = "div.c-image-hover a"
override fun searchMangaFromElement(element: Element): SManga {
return SManga.create().apply {
setUrlWithoutDomain(element.attr("href"))
title = element.attr("title")
thumbnail_url = element.select("img").firstOrNull()?.let { imageFromElement(it) }
}
}
override fun chapterListSelector() = "div.main a"
override fun chapterFromElement(element: Element): SChapter {
return SChapter.create().apply {
setUrlWithoutDomain(element.attr("href"))
name = element.select("h6:first-of-type").text()
date_upload = parseChapterDate(element.select("h6:last-of-type").firstOrNull()?.ownText())
}
}
}

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.pt.hikariscan
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class HikariScan : Madara("Hikari Scan", "https://hikariscan.com.br", "pt-BR", SimpleDateFormat("dd 'de' MMMM 'de' yyyy", Locale("pt", "BR")))

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.tr.himerafansub
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class HimeraFansub : Madara("Himera Fansub", "https://himera-fansub.com", "tr", SimpleDateFormat("dd MMMM yyyy", Locale.forLanguageTag("tr")))

View File

@ -0,0 +1,40 @@
package eu.kanade.tachiyomi.extension.en.hiperdex
import eu.kanade.tachiyomi.multisrc.madara.Madara
class Hiperdex : Madara("Hiperdex", "https://hiperdex.com", "en") {
override fun getGenreList() = listOf(
Genre("Adult", "adult"),
Genre("Action", "action"),
Genre("Adventure", "adventure"),
Genre("Bully", "bully"),
Genre("Comedy", "comedy"),
Genre("Drama", "drama"),
Genre("Ecchi", "ecchi"),
Genre("Fantasy", "fantasy"),
Genre("Gender Bender", "gender-bender"),
Genre("Harem", "harem"),
Genre("Historical", "historical"),
Genre("Horror", "horror"),
Genre("Isekai", "isekai"),
Genre("Josei", "josei"),
Genre("Martial Arts", "martial-arts"),
Genre("Mature", "mature"),
Genre("Mystery", "mystery"),
Genre("Psychological", "psychological"),
Genre("Romance", "romance"),
Genre("School Life", "school-life"),
Genre("Sci-Fi", "sci-fi"),
Genre("Seinen", "seinen"),
Genre("Shoujo", "shoujo"),
Genre("Shounen", "shounen"),
Genre("Slice of Life", "slice-of-life"),
Genre("Smut", "smut"),
Genre("Sports", "sports"),
Genre("Supernatural", "supernatural"),
Genre("Thriller", "thriller"),
Genre("Tragedy", "tragedy"),
Genre("Yaoi", "yaoi"),
Genre("Yuri", "yuri")
)
}

View File

@ -0,0 +1,523 @@
package eu.kanade.tachiyomi.multisrc.madara
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.asObservable
import eu.kanade.tachiyomi.source.model.Filter
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.util.asJsoup
import okhttp3.CacheControl
import okhttp3.FormBody
import okhttp3.Headers
import okhttp3.HttpUrl
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.Response
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import rx.Observable
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
import java.util.concurrent.TimeUnit
import kotlin.math.absoluteValue
import kotlin.random.Random
abstract class Madara(
override val name: String,
override val baseUrl: String,
override val lang: String,
private val dateFormat: SimpleDateFormat = SimpleDateFormat("MMMM dd, yyyy", Locale.US)
) : ParsedHttpSource() {
override val supportsLatest = true
override val client: OkHttpClient = network.cloudflareClient.newBuilder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build()
// helps with cloudflare for some sources, makes it worse for others; override with empty string if the latter is true
protected open val userAgentRandomizer = " ${Random.nextInt().absoluteValue}"
override fun headersBuilder(): Headers.Builder = Headers.Builder()
.add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:77.0) Gecko/20100101 Firefox/78.0$userAgentRandomizer")
// Popular Manga
override fun popularMangaSelector() = "div.page-item-detail"
open val popularMangaUrlSelector = "div.post-title a"
override fun popularMangaFromElement(element: Element): SManga {
val manga = SManga.create()
with(element) {
select(popularMangaUrlSelector).first()?.let {
manga.setUrlWithoutDomain(it.attr("abs:href"))
manga.title = it.ownText()
}
select("img").first()?.let {
manga.thumbnail_url = imageFromElement(it)
}
}
return manga
}
open fun formBuilder(page: Int, popular: Boolean) = FormBody.Builder().apply {
add("action", "madara_load_more")
add("page", (page - 1).toString())
add("template", "madara-core/content/content-archive")
add("vars[orderby]", "meta_value_num")
add("vars[paged]", "1")
add("vars[posts_per_page]", "20")
add("vars[post_type]", "wp-manga")
add("vars[post_status]", "publish")
add("vars[meta_key]", if (popular) "_wp_manga_views" else "_latest_update")
add("vars[order]", "desc")
add("vars[sidebar]", if (popular) "full" else "right")
add("vars[manga_archives_item_layout]", "big_thumbnail")
}
open val formHeaders: Headers by lazy { headersBuilder().build() }
override fun popularMangaRequest(page: Int): Request {
return POST("$baseUrl/wp-admin/admin-ajax.php", formHeaders, formBuilder(page, true).build(), CacheControl.FORCE_NETWORK)
}
override fun popularMangaNextPageSelector(): String? = "body:not(:has(.no-posts))"
// Latest Updates
override fun latestUpdatesSelector() = popularMangaSelector()
override fun latestUpdatesFromElement(element: Element): SManga {
// Even if it's different from the popular manga's list, the relevant classes are the same
return popularMangaFromElement(element)
}
override fun latestUpdatesRequest(page: Int): Request {
return POST("$baseUrl/wp-admin/admin-ajax.php", formHeaders, formBuilder(page, false).build(), CacheControl.FORCE_NETWORK)
}
override fun latestUpdatesNextPageSelector(): String? = popularMangaNextPageSelector()
override fun latestUpdatesParse(response: Response): MangasPage {
val mp = super.latestUpdatesParse(response)
val mangas = mp.mangas.distinctBy { it.url }
return MangasPage(mangas, mp.hasNextPage)
}
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
return client.newCall(searchMangaRequest(page, query, filters))
.asObservable().doOnNext { response ->
if (!response.isSuccessful) {
response.close()
// Error message for exceeding last page
if (response.code() == 404)
error("Already on the Last Page!")
else throw Exception("HTTP error ${response.code()}")
}
}
.map { response ->
searchMangaParse(response)
}
}
// Search Manga
protected open fun searchPage(page: Int): String = "page/$page/"
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = HttpUrl.parse("$baseUrl/${searchPage(page)}")!!.newBuilder()
url.addQueryParameter("s", query)
url.addQueryParameter("post_type", "wp-manga")
filters.forEach { filter ->
when (filter) {
is AuthorFilter -> {
if (filter.state.isNotBlank()) {
url.addQueryParameter("author", filter.state)
}
}
is ArtistFilter -> {
if (filter.state.isNotBlank()) {
url.addQueryParameter("artist", filter.state)
}
}
is YearFilter -> {
if (filter.state.isNotBlank()) {
url.addQueryParameter("release", filter.state)
}
}
is StatusFilter -> {
filter.state.forEach {
if (it.state) {
url.addQueryParameter("status[]", it.id)
}
}
}
is OrderByFilter -> {
if (filter.state != 0) {
url.addQueryParameter("m_orderby", filter.toUriPart())
}
}
is GenreConditionFilter -> {
url.addQueryParameter("op", filter.toUriPart())
}
is GenreList -> {
filter.state
.filter { it.state }
.let { list ->
if (list.isNotEmpty()) { list.forEach { genre -> url.addQueryParameter("genre[]", genre.id) } }
}
}
}
}
return GET(url.toString(), headers)
}
private class AuthorFilter : Filter.Text("Author")
private class ArtistFilter : Filter.Text("Artist")
private class YearFilter : Filter.Text("Year of Released")
private class StatusFilter(status: List<Tag>) : Filter.Group<Tag>("Status", status)
private class OrderByFilter : UriPartFilter(
"Order By",
arrayOf(
Pair("<select>", ""),
Pair("Latest", "latest"),
Pair("A-Z", "alphabet"),
Pair("Rating", "rating"),
Pair("Trending", "trending"),
Pair("Most Views", "views"),
Pair("New", "new-manga")
)
)
private class GenreConditionFilter : UriPartFilter(
"Genre condition",
arrayOf(
Pair("or", ""),
Pair("and", "1")
)
)
private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Genres", genres)
class Genre(name: String, val id: String = name) : Filter.CheckBox(name)
open fun getGenreList() = listOf(
Genre("Adventure", "Adventure"),
Genre("Action", "action"),
Genre("Adventure", "adventure"),
Genre("Cars", "cars"),
Genre("4-Koma", "4-koma"),
Genre("Comedy", "comedy"),
Genre("Completed", "completed"),
Genre("Cooking", "cooking"),
Genre("Dementia", "dementia"),
Genre("Demons", "demons"),
Genre("Doujinshi", "doujinshi"),
Genre("Drama", "drama"),
Genre("Ecchi", "ecchi"),
Genre("Fantasy", "fantasy"),
Genre("Game", "game"),
Genre("Gender Bender", "gender-bender"),
Genre("Harem", "harem"),
Genre("Historical", "historical"),
Genre("Horror", "horror"),
Genre("Isekai", "isekai"),
Genre("Josei", "josei"),
Genre("Kids", "kids"),
Genre("Magic", "magic"),
Genre("Manga", "manga"),
Genre("Manhua", "manhua"),
Genre("Manhwa", "manhwa"),
Genre("Martial Arts", "martial-arts"),
Genre("Mature", "mature"),
Genre("Mecha", "mecha"),
Genre("Military", "military"),
Genre("Music", "music"),
Genre("Mystery", "mystery"),
Genre("Old Comic", "old-comic"),
Genre("One Shot", "one-shot"),
Genre("Oneshot", "oneshot"),
Genre("Parodi", "parodi"),
Genre("Parody", "parody"),
Genre("Police", "police"),
Genre("Psychological", "psychological"),
Genre("Romance", "romance"),
Genre("Samurai", "samurai"),
Genre("School", "school"),
Genre("School Life", "school-life"),
Genre("Sci-Fi", "sci-fi"),
Genre("Seinen", "seinen"),
Genre("Shoujo", "shoujo"),
Genre("Shoujo Ai", "shoujo-ai"),
Genre("Shounen", "shounen"),
Genre("Shounen ai", "shounen-ai"),
Genre("Slice of Life", "slice-of-life"),
Genre("Sports", "sports"),
Genre("Super Power", "super-power"),
Genre("Supernatural", "supernatural"),
Genre("Thriller", "thriller"),
Genre("Tragedy", "tragedy"),
Genre("Vampire", "vampire"),
Genre("Webtoons", "webtoons"),
Genre("Yaoi", "yaoi"),
Genre("Yuri", "yuri")
)
override fun getFilterList() = FilterList(
AuthorFilter(),
ArtistFilter(),
YearFilter(),
StatusFilter(getStatusList()),
OrderByFilter(),
Filter.Separator(),
Filter.Header("Genres may not work for all sources"),
GenreConditionFilter(),
GenreList(getGenreList())
)
private fun getStatusList() = listOf(
Tag("end", "Completed"),
Tag("on-going", "Ongoing"),
Tag("canceled", "Canceled"),
Tag("on-hold", "On Hold")
)
open class UriPartFilter(displayName: String, private val vals: Array<Pair<String, String>>) :
Filter.Select<String>(displayName, vals.map { it.first }.toTypedArray()) {
fun toUriPart() = vals[state].second
}
open class Tag(val id: String, name: String) : Filter.CheckBox(name)
override fun searchMangaSelector() = "div.c-tabs-item__content"
override fun searchMangaFromElement(element: Element): SManga {
val manga = SManga.create()
with(element) {
select("div.post-title a").first()?.let {
manga.setUrlWithoutDomain(it.attr("abs:href"))
manga.title = it.ownText()
}
select("img").first()?.let {
manga.thumbnail_url = imageFromElement(it)
}
}
return manga
}
override fun searchMangaNextPageSelector(): String? = "div.nav-previous, nav.navigation-ajax, a.nextpostslink"
// Manga Details Parse
override fun mangaDetailsParse(document: Document): SManga {
val manga = SManga.create()
with(document) {
select("div.post-title h3").first()?.let {
manga.title = it.ownText()
}
select("div.author-content").first()?.let {
manga.author = it.text()
}
select("div.artist-content").first()?.let {
manga.artist = it.text()
}
select("div.description-summary div.summary__content").let {
if (it.select("p").text().isNotEmpty()) {
manga.description = it.select("p").joinToString(separator = "\n\n") { p ->
p.text().replace("<br>", "\n")
}
} else {
manga.description = it.text()
}
}
select("div.summary_image img").first()?.let {
manga.thumbnail_url = imageFromElement(it)
}
select("div.summary-content").last()?.let {
manga.status = when (it.text()) {
// I don't know what's the corresponding for COMPLETED and LICENSED
// There's no support for "Canceled" or "On Hold"
"Completed", "Completo", "Concluído" -> SManga.COMPLETED
"OnGoing", "Продолжается", "Updating", "Em Lançamento", "Em andamento" -> SManga.ONGOING
else -> SManga.UNKNOWN
}
}
val genres = mutableListOf<String>()
select("div.genres-content a").forEach { element ->
val genre = element.text()
genres.add(genre)
}
manga.genre = genres.joinToString(", ")
}
return manga
}
protected fun imageFromElement(element: Element): String? {
return when {
element.hasAttr("data-src") -> element.attr("abs:data-src")
element.hasAttr("data-lazy-src") -> element.attr("abs:data-lazy-src")
element.hasAttr("srcset") -> element.attr("abs:srcset").substringBefore(" ")
else -> element.attr("abs:src")
}
}
protected fun getXhrChapters(mangaId: String): Document {
val xhrHeaders = headersBuilder().add("Content-Type: application/x-www-form-urlencoded; charset=UTF-8")
.add("Referer", baseUrl)
.build()
val body = RequestBody.create(null, "action=manga_get_chapters&manga=$mangaId")
return client.newCall(POST("$baseUrl/wp-admin/admin-ajax.php", xhrHeaders, body)).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.select(dataIdSelector).attr("data-id")).select(chapterListSelector())
else elements
}
.map { chapterFromElement(it) }
}
override fun chapterListSelector() = "li.wp-manga-chapter"
open val chapterUrlSelector = "a"
open val chapterUrlSuffix = "?style=list"
override fun chapterFromElement(element: Element): SChapter {
val chapter = SChapter.create()
with(element) {
select(chapterUrlSelector).first()?.let { urlElement ->
chapter.url = urlElement.attr("abs:href").let {
it.substringBefore("?style=paged") + if (!it.endsWith(chapterUrlSuffix)) chapterUrlSuffix else ""
}
chapter.name = urlElement.text()
}
// Dates can be part of a "new" graphic or plain text
chapter.date_upload = select("img").firstOrNull()?.attr("alt")?.let { parseRelativeDate(it) }
?: parseChapterDate(select("span.chapter-release-date i").firstOrNull()?.text())
}
return chapter
}
open fun parseChapterDate(date: String?): Long {
date ?: return 0
fun SimpleDateFormat.tryParse(string: String): Long {
return try {
parse(string)?.time ?: 0
} catch (_: ParseException) {
0
}
}
return when {
date.endsWith(" ago", ignoreCase = true) -> {
parseRelativeDate(date)
}
// Handle translated 'ago' in Portuguese.
date.endsWith(" atrás", ignoreCase = true) -> {
parseRelativeDate(date)
}
// Handle translated 'ago' in Turkish.
date.endsWith(" önce", ignoreCase = true) -> {
parseRelativeDate(date)
}
// Handle 'yesterday' and 'today', using midnight
date.startsWith("year", ignoreCase = true) -> {
Calendar.getInstance().apply {
add(Calendar.DAY_OF_MONTH, -1) // yesterday
set(Calendar.HOUR_OF_DAY, 0)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
set(Calendar.MILLISECOND, 0)
}.timeInMillis
}
date.startsWith("today", ignoreCase = true) -> {
Calendar.getInstance().apply {
set(Calendar.HOUR_OF_DAY, 0)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
set(Calendar.MILLISECOND, 0)
}.timeInMillis
}
date.contains(Regex("""\d(st|nd|rd|th)""")) -> {
// Clean date (e.g. 5th December 2019 to 5 December 2019) before parsing it
date.split(" ").map {
if (it.contains(Regex("""\d\D\D"""))) {
it.replace(Regex("""\D"""), "")
} else {
it
}
}
.let { dateFormat.tryParse(it.joinToString(" ")) }
}
else -> dateFormat.tryParse(date)
}
}
// Parses dates in this form:
// 21 horas ago
private fun parseRelativeDate(date: String): Long {
val number = Regex("""(\d+)""").find(date)?.value?.toIntOrNull() ?: return 0
val cal = Calendar.getInstance()
return when {
WordSet("hari", "gün", "jour", "día", "dia", "day").anyWordIn(date) -> cal.apply { add(Calendar.DAY_OF_MONTH, -number) }.timeInMillis
WordSet("jam", "saat", "heure", "hora", "hour").anyWordIn(date) -> cal.apply { add(Calendar.HOUR, -number) }.timeInMillis
WordSet("menit", "dakika", "min", "minute", "minuto").anyWordIn(date) -> cal.apply { add(Calendar.MINUTE, -number) }.timeInMillis
WordSet("detik", "segundo", "second").anyWordIn(date) -> cal.apply { add(Calendar.SECOND, -number) }.timeInMillis
else -> 0
}
}
override fun pageListRequest(chapter: SChapter): Request {
if (chapter.url.startsWith("http")) {
return GET(chapter.url, headers)
}
return super.pageListRequest(chapter)
}
open val pageListParseSelector = "div.page-break"
override fun pageListParse(document: Document): List<Page> {
return document.select(pageListParseSelector).mapIndexed { index, element ->
Page(
index,
document.location(),
element.select("img").first()?.let {
it.absUrl(if (it.hasAttr("data-src")) "data-src" else "src")
}
)
}
}
override fun imageRequest(page: Page): Request {
return GET(page.imageUrl!!, headers.newBuilder().set("Referer", page.url).build())
}
override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("Not used")
}
class WordSet(private vararg val words: String) { fun anyWordIn(dateString: String): Boolean = words.any { dateString.contains(it, ignoreCase = true) } }

View File

@ -0,0 +1,74 @@
package eu.kanade.tachiyomi.multisrc.madara
import eu.kanade.tachiyomi.multisrc.ThemeSourceGenerator
import eu.kanade.tachiyomi.multisrc.ThemeSourceGenerator.Companion.ThemeSourceData.SingleLang
class MadaraGenerator : ThemeSourceGenerator {
override val themePkg = "madara"
override val themeClass = "Madara"
override val baseVersionCode: Int = 1
override val sources = listOf(
SingleLang("Adonis Fansub", "https://manga.adonisfansub.com", "tr"),
SingleLang("AkuManga", "https://akumanga.com", "ar"),
SingleLang("AlianzaMarcial", "https://alianzamarcial.xyz", "es"),
SingleLang("AllPornComic", "https://allporncomic.com", "en"),
SingleLang("Aloalivn", "https://aloalivn.com", "en"),
SingleLang("AniMangaEs", "http://animangaes.com", "en"),
SingleLang("Agent of Change Translations", "https://aoc.moe", "en"),
SingleLang("ApollComics", "https://apollcomics.xyz", "es"),
SingleLang("Arang Scans", "https://www.arangscans.com", "en"),
SingleLang("ArazNovel", "https://www.araznovel.com", "tr"),
SingleLang("Argos Scan", "https://argosscan.com", "pt-BR"),
SingleLang("Asgard Team", "https://www.asgard1team.com", "ar"),
SingleLang("Astral Library", "https://www.astrallibrary.net", "en"),
SingleLang("Atikrost", "https://atikrost.com", "tr"),
SingleLang("ATM-Subs", "https://atm-subs.fr", "fr", className = "ATMSubs", pkgName = "atmsubs"),
SingleLang("Azora", "https://www.azoramanga.com", "ar"),
SingleLang("Bakaman", "https://bakaman.net", "th"),
SingleLang("BestManga", "https://bestmanga.club", "ru"),
SingleLang("BestManhua", "https://bestmanhua.com", "en"),
SingleLang("BoysLove", "https://boyslove.me", "en"),
SingleLang("CatOnHeadTranslations", "https://catonhead.com", "en"),
SingleLang("CAT-translator", "https://cat-translator.com", "th", className = "CatTranslator", pkgName = "cattranslator"),
SingleLang("Chibi Manga", "https://www.cmreader.info", "en"),
SingleLang("Clover Manga", "Clover Manga", "tr"),
SingleLang("ComicKiba", "https://comickiba.com", "en"),
SingleLang("Comics Valley", "https://comicsvalley.com", "hi", isNsfw = true),
SingleLang("CopyPasteScan", "https://copypastescan.xyz", "es"),
SingleLang("Cutie Pie", "https://cutiepie.ga", "tr"),
SingleLang("Darkyu Realm", "https://darkyuerealm.site", "pt-BR"),
SingleLang("Decadence Scans", "https://reader.decadencescans.com", "en"),
SingleLang("شبكة كونان العربية", "https://www.manga.detectiveconanar.com", "ar", className="DetectiveConanAr"),
SingleLang("DiamondFansub", "https://diamondfansub.com", "tr"),
SingleLang("Disaster Scans", "https://disasterscans.com", "en"),
SingleLang("DoujinHentai", "https://doujinhentai.net", "es", isNsfw = true),
SingleLang("DoujinYosh", "https://doujinyosh.work", "id"),
SingleLang("Dream Manga", "https://dreammanga.com/", "en"),
SingleLang("Drope Scan", "https://dropescan.com", "pt-BR"),
SingleLang("Einherjar Scan", "https://einherjarscans.space", "en"),
SingleLang("FDM Scan", "https://fdmscan.com", "pt-BR"),
SingleLang("1st Kiss", "https://1stkissmanga.com", "en", className = "FirstKissManga"),
SingleLang("1st Kiss Manhua", "https://1stkissmanhua.com","en", className="FirstKissManhua"),
SingleLang("FreeWebtoonCoins", "https://freewebtooncoins.com", "en"),
SingleLang("Furio Scans", "https://furioscans.com", "pt-BR"),
SingleLang("Gecenin Lordu", "https://geceninlordu.com/", "tr"),
SingleLang("موقع لترجمة المانجا", "https://golden-manga.com", "ar", className = "GoldenManga"),
SingleLang("GuncelManga", "https://guncelmanga.com", "tr"),
SingleLang("Hero Manhua", "https://heromanhua.com", "en"),
SingleLang("Heroz Scanlation", "https://herozscans.com", "en"),
SingleLang("Hikari Scan", "https://hikariscan.com.br", "pt-BR"),
SingleLang("Himera Fansub", "https://himera-fansub.com", "tr"),
SingleLang("Hiperdex", "https://hiperdex.com", "en"),
)
companion object {
@JvmStatic
fun main(args: Array<String>) {
MadaraGenerator().createAll()
}
}
}

View File

@ -5,7 +5,7 @@ ext {
extName = 'Madara (multiple sources)'
pkgNameSuffix = "all.madara"
extClass = '.MadaraFactory'
extVersionCode = 178
extVersionCode = 179
libVersion = '1.2'
containsNsfw = true
}

View File

@ -1,21 +1,16 @@
package eu.kanade.tachiyomi.extension.all.madara
import android.annotation.SuppressLint
import eu.kanade.tachiyomi.annotations.Nsfw
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.Filter
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.util.asJsoup
import okhttp3.CacheControl
import okhttp3.FormBody
import okhttp3.Headers
import okhttp3.HttpUrl
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
@ -27,59 +22,59 @@ import java.util.concurrent.TimeUnit
class MadaraFactory : SourceFactory {
override fun createSources(): List<Source> = listOf(
AdonisFansub(),
AkuManga(),
AlianzaMarcial(),
AllPornComic(),
Aloalivn(),
AniMangaEs(),
AoCTranslations(),
ApollComics(),
ArangScans(),
ArazNovel(),
ArgosScan(),
AsgardTeam(),
AstralLibrary(),
Atikrost(),
ATMSubs(),
Azora(),
Bakaman(),
BestManga(),
BestManhua(),
BoysLove(),
CatOnHeadTranslations(),
CatTranslator(),
ChibiManga(),
CloverManga(),
ComicKiba(),
ComicsValley(),
CopyPasteScan(),
CutiePie(),
DarkyuRealm(),
DecadenceScans(),
DetectiveConanAr(),
DiamondFansub(),
DisasterScans(),
DoujinHentai(),
DoujinYosh(),
DreamManga(),
DropeScan(),
EinherjarScan(),
FdmScan(),
FirstKissManga(),
FirstKissManhua(),
FreeWebtoonCoins(),
FurioScans(),
GeceninLordu(),
GoldenManga(),
// AdonisFansub(),
// AkuManga(),
// AlianzaMarcial(),
// AllPornComic(),
// Aloalivn(),
// AniMangaEs(),
// AoCTranslations(),
// ApollComics(),
// ArangScans(),
// ArazNovel(),
// ArgosScan(),
// AsgardTeam(),
// AstralLibrary(),
// Atikrost(),
// ATMSubs(),
// Azora(),
// Bakaman(),
// BestManga(),
// BestManhua(),
// BoysLove(),
// CatOnHeadTranslations(),
// CatTranslator(),
// ChibiManga(),
// CloverManga(),
// ComicKiba(),
// ComicsValley(),
// CopyPasteScan(),
// CutiePie(),
// DarkyuRealm(),
// DecadenceScans(),
// DetectiveConanAr(),
// DiamondFansub(),
// DisasterScans(),
// DoujinHentai(),
// DoujinYosh(),
// DreamManga(),
// DropeScan(),
// EinherjarScan(),
// FdmScan(),
// FirstKissManga(),
// FirstKissManhua(),
// FreeWebtoonCoins(),
// FurioScans(),
// GeceninLordu(),
// GoldenManga(),
GrazeScans(),
GourmetScans(),
GuncelManga(),
HeroManhua(),
HerozScanlation(),
HikariScan(),
HimeraFansub(),
Hiperdex(),
// GuncelManga(),
// HeroManhua(),
// HerozScanlation(),
// HikariScan(),
// HimeraFansub(),
// Hiperdex(),
Hscans(),
HunterFansub(),
IchirinNoHanaYuri(),
@ -276,17 +271,10 @@ class SpookyScanlations : Madara("Spooky Scanlations", "https://spookyscanlation
class RandomTranslations : Madara("Random Translations", "https://randomtranslations.com", "en", SimpleDateFormat("dd/MM/yyyy", Locale.US))
class Atikrost : Madara("Atikrost", "https://atikrost.com", "tr", SimpleDateFormat("MMMM dd, yyyy", Locale("tr"))) {
override val chapterUrlSelector = "a:not(:has(img))"
override val chapterDatesNewSelector = "img:not(.thumb)"
}
class ManhuaFast : Madara("ManhuaFast", "https://manhuafast.com", "en") {
override val pageListParseSelector = "li.blocks-gallery-item"
}
class BestManhua : Madara("BestManhua", "https://bestmanhua.com", "en")
class ManhuaSY : Madara("Manhua SY", "https://www.manhuasy.com", "en")
class MangaRave : Madara("MangaRave", "http://www.mangarave.com", "en")
@ -297,10 +285,6 @@ class Manga3S : Madara("Manga3S", "https://manga3s.com", "en")
class MGKomik : Madara("MG Komik", "https://mgkomik.my.id", "id")
class Aloalivn : Madara("Aloalivn", "https://aloalivn.com", "en") {
override val pageListParseSelector = "li.blocks-gallery-item"
}
class MangaSco : Madara("MangaSco", "https://mangasco.com", "en")
class MangaCrimson : Madara("Manga Crimson", "https://mangacrimson.com", "tr", SimpleDateFormat("dd MMMM yyyy", Locale("tr")))
@ -311,12 +295,8 @@ class NekoBreaker : Madara("NekoBreaker", "https://nekobreaker.com", "pt-BR", Si
class ManganeloLink : Madara("Manganelo.link", "https://manganelo.link", "en")
class ApollComics : Madara("ApollComics", "https://apollcomics.xyz", "es", SimpleDateFormat("dd MMMM, yyyy", Locale("es")))
class KisekiManga : Madara("KisekiManga", "https://kisekimanga.com", "en")
class FreeWebtoonCoins : Madara("FreeWebtoonCoins", "https://freewebtooncoins.com", "en")
class MangaRoma : Madara("MangaRoma", "https://mangaroma.com", "en")
class NTSVoidScans : Madara("NTS Void Scans", "https://ntsvoidscans.com", "en")
@ -329,26 +309,16 @@ class WebToonily : Madara("WebToonily", "https://webtoonily.com", "en")
class Manga18Fun : Madara("Manga18 Fun", "https://manga18.fun", "en")
class CutiePie : Madara("Cutie Pie", "https://cutiepie.ga", "tr", SimpleDateFormat("dd MMMM yyyy", Locale.forLanguageTag("tr")))
class DiamondFansub : Madara("DiamondFansub", "https://diamondfansub.com", "tr", SimpleDateFormat("MMMM dd, yyyy", Locale.forLanguageTag("tr")))
class MangaYaku : Madara("MangaYaku", "https://mangayaku.my.id", "id")
class RuyaManga : Madara("Rüya Manga", "https://www.ruyamanga.com", "tr", SimpleDateFormat("dd MMMM yyyy", Locale.forLanguageTag("tr")))
class HimeraFansub : Madara("Himera Fansub", "https://himera-fansub.com", "tr", SimpleDateFormat("dd MMMM yyyy", Locale.forLanguageTag("tr")))
class MangaBaz : Madara("MangaBaz", "https://mangabaz.com", "tr", SimpleDateFormat("dd MMMM yyyy", Locale.forLanguageTag("tr")))
class Manhuaga : Madara("Manhuaga", "https://manhuaga.com", "en")
class MangaCultivator : Madara("MangaCultivator", "https://mangacultivator.com", "en")
class HerozScanlation : Madara("Heroz Scanlation", "https://herozscans.com", "en")
class CatOnHeadTranslations : Madara("CatOnHeadTranslations", "https://catonhead.com", "en")
class OffScan : Madara(
"Off Scan",
"https://offscan.top",
@ -387,41 +357,6 @@ class JustForFun : Madara(
dateFormat = SimpleDateFormat("yy.MM.dd", Locale.US)
)
class AoCTranslations : Madara("Agent of Change Translations", "https://aoc.moe", "en") {
override fun headersBuilder(): Headers.Builder = super.headersBuilder().add("Referer", baseUrl)
override fun popularMangaSelector() = "div.page-item-detail.manga:has(span.chapter)"
override fun chapterListSelector() = "li.wp-manga-chapter:has(a)"
@SuppressLint("DefaultLocale")
override fun chapterListParse(response: Response): List<SChapter> {
return response.asJsoup().let { document ->
document.select(chapterListSelector()).let { normalChapters ->
if (normalChapters.isNotEmpty()) {
normalChapters.map { chapterFromElement(it) }
} else {
// For their "fancy" volume/chapter lists
document.select("div.wpb_wrapper:contains(volume) a")
.filter { it.attr("href").contains(baseUrl) && !it.attr("href").contains("imgur") }
.map { volumeChapter ->
SChapter.create().apply {
volumeChapter.attr("href").let { url ->
name = if (url.contains("volume")) {
val volume = url.substringAfter("volume-").substringBefore("/")
val volChap = url.substringAfter("volume-$volume/").substringBefore("/").replace("-", " ").capitalize()
"Volume $volume - $volChap"
} else {
url.substringBefore("/p").substringAfterLast("/").replace("-", " ").capitalize()
}
setUrlWithoutDomain(url.substringBefore("?") + "?style=list")
}
}
}
}.reversed()
}
}
}
}
class KomikGo : Madara("KomikGo", "https://komikgo.com", "id")
class TsubakiNoScan : Madara(
@ -450,15 +385,6 @@ class MangazukiClubJP : Madara("Mangazuki.club", "https://mangazuki.club", "ja")
class MangazukiClubKO : Madara("Mangazuki.club", "https://mangazuki.club", "ko")
class FirstKissManga : Madara(
"1st Kiss",
"https://1stkissmanga.com",
"en",
SimpleDateFormat("MMM d, yyyy", Locale.US)
) {
override fun headersBuilder(): Headers.Builder = super.headersBuilder().add("Referer", baseUrl)
}
class MangaSY : Madara("Manga SY", "https://www.mangasy.com", "en") {
override fun imageRequest(page: Page): Request = super.imageRequest(page).newBuilder()
.cacheControl(CacheControl.FORCE_NETWORK)
@ -480,13 +406,6 @@ class ManyToonMe : Madara("ManyToon.me", "https://manytoon.me", "en")
class BoysLove : Madara("BoysLove", "https://boyslove.me", "en")
class ChibiManga : Madara(
"Chibi Manga",
"https://www.cmreader.info",
"en",
dateFormat = SimpleDateFormat("MMM dd, yyyy", Locale.US)
)
class ZinManga : Madara("Zin Translator", "https://zinmanga.com", "en") {
override fun headersBuilder(): Headers.Builder = super.headersBuilder()
.add("Referer", "https://zinmanga.com/")
@ -496,306 +415,12 @@ class ManwahentaiMe : Madara("Manwahentai.me", "https://manhwahentai.me", "en")
class Manga3asq : Madara("مانجا العاشق", "https://3asq.org", "ar")
class AdonisFansub : Madara("Adonis Fansub", "https://manga.adonisfansub.com", "tr") {
override val userAgentRandomizer = ""
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/manga/page/$page/?m_orderby=views", headers)
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/manga/page/$page/?m_orderby=latest", headers)
}
@Nsfw
class AllPornComic : Madara("AllPornComic", "https://allporncomic.com", "en") {
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/manga/page/$page/?m_orderby=views", headers)
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/manga/page/$page/?m_orderby=latest", headers)
override fun searchMangaNextPageSelector() = "a[rel=next]"
override fun getGenreList() = listOf(
Genre("3D", "3d"),
Genre("Ahegao", "ahegao"),
Genre("Alien Girl", "alien-girl"),
Genre("Anal", "anal"),
Genre("Anime", "anime"),
Genre("Anthology", "anthology"),
Genre("Artbook", "artbook"),
Genre("BBW / Chubby / Fat Woman", "bbw"),
Genre("BDSM", "bdsm"),
Genre("Big Areolae", "big-areolae"),
Genre("Big Ass", "big-ass"),
Genre("Big Balls", "big-balls"),
Genre("Big Breasts", "big-breasts"),
Genre("Big Clit", "big-clit"),
Genre("Big Nipples", "big-nipples"),
Genre("Big Penis", "big-penis"),
Genre("Bikini", "bikini"),
Genre("Blackmail", "blackmail"),
Genre("Blindfold", "blindfold"),
Genre("Body Modification", "body-modification"),
Genre("Body Swap", "body-swap"),
Genre("Body Writing", "body-writing"),
Genre("BodyStocking", "bodystocking"),
Genre("Bodysuit", "bodysuit"),
Genre("Bondage", "bondage"),
Genre("Brain Fuck", "brain-fuck"),
Genre("Cartoon", "cartoon"),
Genre("Cheerleader", "cheerleader"),
Genre("Chinese Dress", "chinese-dress"),
Genre("Collar / Choker", "collar"),
Genre("Comedy", "comedy"),
Genre("Corruption", "corruption"),
Genre("Corset", "corset"),
Genre("Crotch Tattoo", "crotch-tattoo"),
Genre("Dark Skin", "dark-skin"),
Genre("Demon Girl / Succubus", "demon-girl"),
Genre("Dick Growth", "dick-growth"),
Genre("Dickgirl On Dickgirl", "dickgirl-on-dickgirl"),
Genre("Dickgirl On Male", "dickgirl-on-male"),
Genre("Dickgirls Only", "dickgirls-only"),
Genre("Drugs", "drugs"),
Genre("Drunk", "drunk"),
Genre("Exhibitionism", "exhibitionism"),
Genre("FFM Threesome", "ffm-threesome"),
Genre("FFT Threesome", "fft-threesome"),
Genre("Females Only", "females-only"),
Genre("Femdom", "femdom"),
Genre("Feminization", "feminization"),
Genre("Full Body Tattoo", "full-body-tattoo"),
Genre("Full Color", "full-color"),
Genre("Futanari", "futanari"),
Genre("Gender Bender", "gender-bender"),
Genre("Glasses", "glasses"),
Genre("Group", "group"),
Genre("Gyaru", "gyaru"),
Genre("Gyaru-OH", "gyaru-oh"),
Genre("Harem", "harem"),
Genre("Hentai", "hentai"),
Genre("Human Pet", "human-pet"),
Genre("Humiliation", "humiliation"),
Genre("Impregnation", "impregnation"),
Genre("Incest", "incest"),
Genre("Interracial", "interracial"),
Genre("Kimono", "kimono"),
Genre("Latex", "latex"),
Genre("Leash", "leash"),
Genre("Lingerie", "lingerie"),
Genre("Lolicon", "lolicon"),
Genre("MILF", "milf"),
Genre("MMF Threesome", "mmf-threesome"),
Genre("MMT Threesome", "mmt-threesome"),
Genre("Magical Girl", "magical-girl"),
Genre("Maid", "maid"),
Genre("Male On Dickgirl", "male-on-dickgirl"),
Genre("Manhwa", "manhwa"),
Genre("Military", "military"),
Genre("Milking", "milking"),
Genre("Mind Break", "mind-break"),
Genre("Mind Control", "mind-control"),
Genre("Monster Girl", "monster-girl"),
Genre("Moral Degeneration", "moral-degeneration"),
Genre("Muscle", "muscle"),
Genre("Muscle Growth", "muscle-growth"),
Genre("Nakadashi", "nakadashi"),
Genre("Netorare", "netorare"),
Genre("Netori", "netori"),
Genre("Ninja", "ninja"),
Genre("Nun", "nun"),
Genre("Nurse", "nurse"),
Genre("Orgy", "orgy"),
Genre("Paizuri", "paizuri"),
Genre("Pegging", "pegging"),
Genre("Piercing", "piercing"),
Genre("Pixie Cut", "pixie-cut"),
Genre("Policewoman", "policewoman"),
Genre("Possession", "possession"),
Genre("Retro", "retro"),
Genre("Ryona", "ryona"),
Genre("School Swimsuit", "school-swimsuit"),
Genre("Schoolboy Uniform", "schoolboy-uniform"),
Genre("Schoolgirl Uniform", "schoolgirl-uniform"),
Genre("Shared Senses", "shared-senses"),
Genre("Shemale", "shemale"),
Genre("Shibari", "shibari"),
Genre("Shotacon", "shotacon"),
Genre("Slave", "slave"),
Genre("Slime Girl", "slime-girl"),
Genre("Small Breasts", "small-breasts"),
Genre("Stockings", "stockings"),
Genre("Strap-on", "strap-on"),
Genre("Stuck In Wall", "stuck-in-wall"),
Genre("Superhero", "superhero"),
Genre("Superheroine", "superheroine"),
Genre("Tail", "tail"),
Genre("Tail Plug", "tail-plug"),
Genre("Tankoubon", "tankoubon"),
Genre("Tentacles", "tentacles"),
Genre("Thigh High Boots", "thigh-high-boots"),
Genre("Tights", "tights"),
Genre("Time Stop", "time-stop"),
Genre("Tomboy", "tomboy"),
Genre("Tomgirl", "tomgirl"),
Genre("Torture", "torture"),
Genre("Transformation", "transformation"),
Genre("Uncensored", "uncensored"),
Genre("Unusual Pupils", "unusual-pupils"),
Genre("Unusual Teeth", "unusual-teeth"),
Genre("Vampire", "vampire"),
Genre("Virginity", "virginity"),
Genre("Voyeurism", "voyeurism"),
Genre("Webtoon", "webtoon"),
Genre("Western", "western"),
Genre("Witch", "witch"),
Genre("Yandere", "yandere"),
Genre("Yaoi", "yaoi"),
Genre("Yuri", "yuri")
)
}
class Milftoon : Madara("Milftoon", "https://milftoon.xxx", "en") {
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/page/$page/?m_orderby=views", headers)
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/page/$page/?m_orderby=latest", headers)
}
class Hiperdex : Madara("Hiperdex", "https://hiperdex.com", "en") {
override fun getGenreList() = listOf(
Genre("Adult", "adult"),
Genre("Action", "action"),
Genre("Adventure", "adventure"),
Genre("Bully", "bully"),
Genre("Comedy", "comedy"),
Genre("Drama", "drama"),
Genre("Ecchi", "ecchi"),
Genre("Fantasy", "fantasy"),
Genre("Gender Bender", "gender-bender"),
Genre("Harem", "harem"),
Genre("Historical", "historical"),
Genre("Horror", "horror"),
Genre("Isekai", "isekai"),
Genre("Josei", "josei"),
Genre("Martial Arts", "martial-arts"),
Genre("Mature", "mature"),
Genre("Mystery", "mystery"),
Genre("Psychological", "psychological"),
Genre("Romance", "romance"),
Genre("School Life", "school-life"),
Genre("Sci-Fi", "sci-fi"),
Genre("Seinen", "seinen"),
Genre("Shoujo", "shoujo"),
Genre("Shounen", "shounen"),
Genre("Slice of Life", "slice-of-life"),
Genre("Smut", "smut"),
Genre("Sports", "sports"),
Genre("Supernatural", "supernatural"),
Genre("Thriller", "thriller"),
Genre("Tragedy", "tragedy"),
Genre("Yaoi", "yaoi"),
Genre("Yuri", "yuri")
)
}
@Nsfw
class DoujinHentai : Madara("DoujinHentai", "https://doujinhentai.net", "es", SimpleDateFormat("d MMM. yyyy", Locale.ENGLISH)) {
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/lista-manga-hentai?orderby=views&page=$page", headers)
override fun popularMangaSelector() = "div.col-md-3 a"
override fun popularMangaFromElement(element: Element): SManga {
val manga = SManga.create()
manga.setUrlWithoutDomain(element.attr("href"))
manga.title = element.select("h5").text()
manga.thumbnail_url = element.select("img").attr("abs:data-src")
return manga
}
override fun popularMangaNextPageSelector() = "a[rel=next]"
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/lista-manga-hentai?orderby=last&page=$page", headers)
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = HttpUrl.parse(baseUrl)!!.newBuilder()
if (query.isNotBlank()) {
url.addPathSegment("search")
url.addQueryParameter("query", query) // query returns results all on one page
} else {
filters.forEach { filter ->
when (filter) {
is GenreSelectFilter -> {
if (filter.state != 0) {
url.addPathSegments("lista-manga-hentai/category/${filter.toUriPart()}")
url.addQueryParameter("page", page.toString())
}
}
}
}
}
return GET(url.build().toString(), headers)
}
override fun searchMangaSelector() = "div.c-tabs-item__content > div.c-tabs-item__content, ${popularMangaSelector()}"
override fun searchMangaFromElement(element: Element): SManga {
return if (element.hasAttr("href")) {
popularMangaFromElement(element) // genre search results
} else {
super.searchMangaFromElement(element) // query search results
}
}
override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
override fun chapterListSelector() = "ul.main.version-chap > li.wp-manga-chapter:not(:last-child)" // removing empty li
override val pageListParseSelector = "div#all > img.img-responsive"
override fun getFilterList() = FilterList(
Filter.Header("Solo funciona si la consulta está en blanco"),
GenreSelectFilter()
)
class GenreSelectFilter : UriPartFilter(
"Búsqueda de género",
arrayOf(
Pair("<seleccionar>", ""),
Pair("Ecchi", "ecchi"),
Pair("Yaoi", "yaoi"),
Pair("Yuri", "yuri"),
Pair("Anal", "anal"),
Pair("Tetonas", "tetonas"),
Pair("Escolares", "escolares"),
Pair("Incesto", "incesto"),
Pair("Virgenes", "virgenes"),
Pair("Masturbacion", "masturbacion"),
Pair("Maduras", "maduras"),
Pair("Lolicon", "lolicon"),
Pair("Bikini", "bikini"),
Pair("Sirvientas", "sirvientas"),
Pair("Enfermera", "enfermera"),
Pair("Embarazada", "embarazada"),
Pair("Ahegao", "ahegao"),
Pair("Casadas", "casadas"),
Pair("Chica Con Pene", "chica-con-pene"),
Pair("Juguetes Sexuales", "juguetes-sexuales"),
Pair("Orgias", "orgias"),
Pair("Harem", "harem"),
Pair("Romance", "romance"),
Pair("Profesores", "profesores"),
Pair("Tentaculos", "tentaculos"),
Pair("Mamadas", "mamadas"),
Pair("Shota", "shota"),
Pair("Interracial", "interracial"),
Pair("Full Color", "full-colo"),
Pair("Sin Censura", "sin-censura"),
Pair("Futanari", "futanari"),
Pair("Doble Penetracion", "doble-penetracion"),
Pair("Cosplay", "cosplay")
)
)
}
class Azora : Madara("Azora", "https://www.azoramanga.com", "ar") {
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/page/$page/?m_orderby=views", headers)
override fun chapterListSelector() = "li.wp-manga-chapter:not(.premium-block)" // Filter fake chapters
override fun chapterFromElement(element: Element): SChapter {
val chapter = SChapter.create()
element.select("a").let {
chapter.url = it.attr("href").substringAfter(baseUrl)
chapter.name = it.text()
}
return chapter
}
}
class KMangaIn : Madara("Kissmanga.in", "https://kissmanga.in", "en")
class HunterFansub : Madara("Hunter Fansub", "https://hunterfansub.com", "es") {
@ -880,26 +505,6 @@ class YaoiToshokan : Madara("Yaoi Toshokan", "https://yaoitoshokan.com.br", "pt-
}
}
class GoldenManga : Madara("موقع لترجمة المانجا", "https://golden-manga.com", "ar", SimpleDateFormat("yyyy-MM-dd", Locale.US)) {
override fun searchMangaSelector() = "div.c-image-hover a"
override fun searchMangaFromElement(element: Element): SManga {
return SManga.create().apply {
setUrlWithoutDomain(element.attr("href"))
title = element.attr("title")
thumbnail_url = element.select("img").firstOrNull()?.let { imageFromElement(it) }
}
}
override fun chapterListSelector() = "div.main a"
override fun chapterFromElement(element: Element): SChapter {
return SChapter.create().apply {
setUrlWithoutDomain(element.attr("href"))
name = element.select("h6:first-of-type").text()
date_upload = parseChapterDate(element.select("h6:last-of-type").firstOrNull()?.ownText())
}
}
}
class Mangalek : Madara("مانجا ليك", "https://mangalek.com", "ar", SimpleDateFormat("MMMM dd, yyyy", Locale("ar")))
class AstralLibrary : Madara("Astral Library", "https://www.astrallibrary.net", "en", SimpleDateFormat("d MMM", Locale.US)) {
@ -920,8 +525,6 @@ class Manhuasnet : Madara("Manhuas.net", "https://manhuas.net", "en")
class MangaTX : Madara("MangaTX", "https://mangatx.com", "en")
class ATMSubs : Madara("ATM-Subs", "https://atm-subs.fr", "fr", SimpleDateFormat("d MMMM yyyy", Locale("fr")))
class OnManga : Madara("OnManga", "https://onmanga.com", "en")
class MangaAction : Madara("Manga Action", "https://manga-action.com", "ar", SimpleDateFormat("yyyy-MM-dd", Locale("ar")))
@ -939,22 +542,6 @@ class ThreeSixtyFiveManga : Madara("365Manga", "https://365manga.com", "en") {
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/manga/page/$page/?m_orderby=latest", headers)
}
class DisasterScans : Madara("Disaster Scans", "https://disasterscans.com", "en") {
override val popularMangaUrlSelector = "div.post-title a:last-child"
override fun mangaDetailsParse(document: Document): SManga {
val manga = super.mangaDetailsParse(document)
with(document) {
select("div.post-title h1").first()?.let {
manga.title = it.ownText()
}
}
return manga
}
}
class MangaDods : Madara("MangaDods", "https://www.mangadods.com", "en", SimpleDateFormat("yyyy-MM-dd", Locale.US))
class NeoxScanlator : Madara(
@ -1015,8 +602,6 @@ class ManhuaUS : Madara("ManhuaUS", "https://manhuaus.com", "en") {
class MangaWT : Madara("MangaWT", "https://mangawt.com", "tr")
class DecadenceScans : Madara("Decadence Scans", "https://reader.decadencescans.com", "en")
class MangaRockTeam : Madara("Manga Rock Team", "https://mangarockteam.com", "en")
class MixedManga : Madara("Mixed Manga", "https://mixedmanga.com", "en", SimpleDateFormat("d MMM yyyy", Locale.US)) {
@ -1025,75 +610,8 @@ class MixedManga : Madara("Mixed Manga", "https://mixedmanga.com", "en", SimpleD
class ManhuasWorld : Madara("Manhuas World", "https://manhuasworld.com", "en")
class ArazNovel : Madara("ArazNovel", "https://www.araznovel.com", "tr", SimpleDateFormat("dd/MM/yyyy", Locale.getDefault())) {
override fun formBuilder(page: Int, popular: Boolean): FormBody.Builder = super.formBuilder(page, popular)
.add("vars[meta_query][0][0][value]", "manga")
override fun getGenreList() = listOf(
Genre("Aksiyon", "action"),
Genre("Macera", "adventure"),
Genre("Cartoon", "cartoon"),
Genre("Comic", "comic"),
Genre("Komedi", "comedy"),
Genre("Yemek", "cooking"),
Genre("Doujinshi", "doujinshi"),
Genre("Dram", "drama"),
Genre("Ecchi", "ecchi"),
Genre("Fantastik", "fantasy"),
Genre("Harem", "harem"),
Genre("Tarihi", "historical"),
Genre("Korku", "horror"),
Genre("Manga", "manga"),
Genre("Manhua", "manhua"),
Genre("Manhwa", "manhwa"),
Genre("Olgun", "mature"),
Genre("Mecha", "mecha"),
Genre("Yetişkin", "adult"),
Genre("Gizem", "mystery"),
Genre("One Shot", "one-shot"),
Genre("Isekai", "isekai"),
Genre("Josei", "josei"),
Genre("Dedektif", "detective"),
Genre("Karanlık", "smut"),
Genre("Romantizm", "romance"),
Genre("Okul Yaşamı", "school-life"),
Genre("Yaşamdan Kesit", "slice-of-life"),
Genre("Spor", "sports"),
Genre("Doğa Üstü", "supernatural"),
Genre("Trajedi", "tragedy"),
Genre("Webtoon ", "webtoon"),
Genre("Dövüş Sanatları ", "martial-arts"),
Genre("Bilim Kurgu", "sci-fi"),
Genre("Seinen", "seinen"),
Genre("Shoujo", "shoujo"),
Genre("Shoujo Ai", "shoujo-ai"),
Genre("Shounen", "shounen"),
Genre("Shounen Ai", "shounen-ai"),
Genre("Soft Yaoi", "soft-yaoi"),
Genre("Soft Yuri", "soft-yuri"),
Genre("Yaoi", "yaoi"),
Genre("Yuri", "yuri")
)
override fun chapterListParse(response: Response): List<SChapter> {
return getXhrChapters(response.asJsoup().select("div#manga-chapters-holder").attr("data-id")).let { document ->
document.select("li.parent").let { elements ->
if (!elements.isNullOrEmpty()) {
elements.reversed()
.map { volumeElement -> volumeElement.select(chapterListSelector()).map { chapterFromElement(it) } }
.flatten()
} else {
document.select(chapterListSelector()).map { chapterFromElement(it) }
}
}
}
}
}
class ManhwaRaw : Madara("Manhwa Raw", "https://manhwaraw.com", "ko")
class GuncelManga : Madara("GuncelManga", "https://guncelmanga.com", "tr")
class WeScans : Madara("WeScans", "https://wescans.xyz", "en") {
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/manhua/manga/?m_orderby=views", headers)
override fun popularMangaNextPageSelector(): String? = null
@ -1103,15 +621,6 @@ class WeScans : Madara("WeScans", "https://wescans.xyz", "en") {
override fun getFilterList(): FilterList = FilterList()
}
class ArangScans : Madara("Arang Scans", "https://arangscans.com", "en", SimpleDateFormat("d MMM yyyy", Locale.US)) {
override val userAgentRandomizer = ""
// has very few manga
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/manga?m_orderby=views", headers)
override fun popularMangaNextPageSelector(): String? = null
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/manga?m_orderby=latest", headers)
override fun latestUpdatesNextPageSelector(): String? = null
}
@Nsfw
class MangaHentai : Madara("Manga Hentai", "https://mangahentai.me", "en")
@ -1120,12 +629,6 @@ class MangaPhoenix : Madara("Manga Diyari", "https://mangadiyari.com", "tr") {
override val id = 4308007020001642101
}
class FirstKissManhua : Madara("1st Kiss Manhua", "https://1stkissmanhua.com", "en", SimpleDateFormat("d MMM yyyy", Locale.US)) {
override fun imageRequest(page: Page): Request = GET(page.imageUrl!!, headersBuilder().add("Referer", "https://1stkissmanga.com").build())
}
class HeroManhua : Madara("Hero Manhua", "https://heromanhua.com", "en")
class MartialScans : Madara("Martial Scans", "https://martialscans.com", "en") {
override fun popularMangaFromElement(element: Element): SManga {
val manga = SManga.create()
@ -1166,101 +669,6 @@ class TurkceManga : Madara("Türkçe Manga", "https://turkcemanga.com", "tr") {
override fun latestUpdatesFromElement(element: Element): SManga = searchMangaFromElement(element)
}
class EinherjarScan : Madara("Einherjar Scan", "https://einherjarscans.space", "en")
class DoujinYosh : Madara("DoujinYosh", "https://doujinyosh.work", "id") {
// source issue, doing this limits results to one page but not doing it returns no results at all
override fun searchPage(page: Int) = ""
override fun getGenreList() = listOf(
Genre("4 Koma", "4koma"),
Genre("Adult", "adult"),
Genre("Ahegao", "ahegao"),
Genre("Anal", "anal"),
Genre("Animal", "animal"),
Genre("Artist CG", "artist-cg"),
Genre("Big Breast", "big-breast"),
Genre("Big Penis", "big-penis"),
Genre("Bikini", "bikini"),
Genre("Black Mail", "black-mail"),
Genre("Blowjob", "blowjob"),
Genre("Body Swap", "body-swap"),
Genre("Bondage", "bondage"),
Genre("Cheating", "cheating"),
Genre("Crossdressing", "crossdressing"),
Genre("DILF", "dilf"),
Genre("Dark Skin", "dark-skin"),
Genre("Defloration", "defloration"),
Genre("Demon Girl", "demon-girl"),
Genre("Doujin", "doujin"),
Genre("Drugs", "drugs"),
Genre("Drunk", "drunk"),
Genre("Elf", "elf"),
Genre("Famele Only", "famele-only"),
Genre("Femdom", "femdom"),
Genre("Filming", "filming"),
Genre("Footjob", "footjob"),
Genre("Full Color", "full-color"),
Genre("Furry", "furry"),
Genre("Futanari", "futanari"),
Genre("Glasses", "glasses"),
Genre("Gore", "gore"),
Genre("Group", "group"),
Genre("Gyaru", "gyaru"),
Genre("Harem", "harem"),
Genre("Humiliation", "humiliation"),
Genre("Impregnation", "impregnation"),
Genre("Incest", "incest"),
Genre("Inverted Nipples", "inverted-nipples"),
Genre("Kemomimi", "kemomimi"),
Genre("Lactation", "lactation"),
Genre("Loli", "loli"),
Genre("Lolipai", "lolipai"),
Genre("MILF", "milf"),
Genre("Maid", "maid"),
Genre("Male Only", "male-only"),
Genre("Miko", "miko"),
Genre("Mind Break", "mind-break"),
Genre("Mind Control", "mind-control"),
Genre("Monster", "monster"),
Genre("Monster Girl", "monster-girl"),
Genre("Multi-Work Series", "multi-work-series"),
Genre("Nakadashi", "nakadashi"),
Genre("Netorare", "netorare"),
Genre("Otona (R18)", "otona"),
Genre("Oyakodon", "oyakodon"),
Genre("Paizuri", "paizuri"),
Genre("Pantyhose", "pantyhose"),
Genre("Pregnant", "pregnant"),
Genre("Prostitution", "prostitution"),
Genre("Rape", "rape"),
Genre("School Uniform", "school-uniform"),
Genre("Sex Toy", "sex-toy"),
Genre("Shota", "shota"),
Genre("Sister", "sister"),
Genre("Sleep", "sleep"),
Genre("Slime", "slime"),
Genre("Small Breast", "small-breast"),
Genre("Sole Female", "sole-female"),
Genre("Sole Male", "sole-male"),
Genre("Stocking", "stocking"),
Genre("Story Arc", "story-arc"),
Genre("Sweating", "sweating"),
Genre("Swimsuit", "swimsuit"),
Genre("Teacher", "teacher"),
Genre("Tentacles", "tentacles"),
Genre("Tomboy", "tomboy"),
Genre("Tomgirl", "tomgirl"),
Genre("Torture", "torture"),
Genre("Twins", "twins"),
Genre("Virginity", "virginity"),
Genre("Webtoon", "webtoon"),
Genre("XRay", "xray"),
Genre("Yandere", "yandere"),
Genre("Yaoi", "yaoi"),
Genre("Yuri", "yuri")
)
}
class Manga347 : Madara("Manga347", "https://manga347.com", "en", SimpleDateFormat("d MMM, yyyy", Locale.US)) {
override val pageListParseSelector = "li.blocks-gallery-item"
}
@ -1271,11 +679,6 @@ class QueensManga : Madara("QueensManga ملكات المانجا", "https://que
override fun chapterListSelector(): String = "div.listing-chapters_wrap a"
}
class DropeScan : Madara("Drope Scan", "https://dropescan.com", "pt-BR") {
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/manga/page/$page/?m_orderby=views", headers)
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/manga/page/$page/?m_orderby=latest", headers)
}
class TheTopComic : Madara("TheTopComic", "https://thetopcomic.com", "en")
class WebNovel : Madara("WebNovel", "https://webnovel.live", "en")
@ -1310,14 +713,8 @@ class TruyenTranhAudioOnline : Madara("TruyenTranhAudio.online", "https://truyen
class MangaTurf : Madara("Manga Turf", "https://mangaturf.com", "en")
class FurioScans : Madara("Furio Scans", "https://furioscans.com", "pt-BR", SimpleDateFormat("dd/MM/yyyy", Locale.getDefault()))
class Mangareceh : Madara("Mangareceh", "https://mangareceh.id", "id")
class ComicKiba : Madara("ComicKiba", "https://comickiba.com", "en") {
override val pageListParseSelector = "li.blocks-gallery-item img:nth-child(1), div.reading-content p > img, .read-container .reading-content img"
}
class ToonPoint : Madara("ToonPoint", "https://toonpoint.com", "en") {
override val userAgentRandomizer = ""
}
@ -1328,19 +725,12 @@ class ManhuaPlus : Madara("Manhua Plus", "https://manhuaplus.com", "en") {
override val pageListParseSelector = "li.blocks-gallery-item"
}
class AkuManga : Madara("AkuManga", "https://akumanga.com", "ar")
class AsgardTeam : Madara("Asgard Team", "https://www.asgard1team.com", "ar")
@Nsfw
class ToonilyNet : Madara("Toonily.net", "https://toonily.net", "en")
class BestManga : Madara("BestManga", "https://bestmanga.club", "ru", SimpleDateFormat("dd.MM.yyyy", Locale.getDefault()))
class TwilightScans : Madara("Twilight Scans", "https://twilightscans.com", "en")
class DetectiveConanAr : Madara("شبكة كونان العربية", "https://www.manga.detectiveconanar.com", "ar")
// mostly novels
class WoopRead : Madara("WoopRead", "https://woopread.com", "en")
@ -1350,21 +740,6 @@ class ManhwaTop : Madara("Manhwatop", "https://manhwatop.com", "en")
class ImmortalUpdates : Madara("Immortal Updates", "https://immortalupdates.com", "en")
class Bakaman : Madara("Bakaman", "https://bakaman.net", "th")
class CatTranslator : Madara("CAT-translator", "https://cat-translator.com", "th") {
override fun popularMangaRequest(page: Int): Request =
POST("$baseUrl/manga/wp-admin/admin-ajax.php", formHeaders, formBuilder(page, true).build(), CacheControl.FORCE_NETWORK)
override fun latestUpdatesRequest(page: Int): Request =
POST("$baseUrl/manga/wp-admin/admin-ajax.php", formHeaders, formBuilder(page, false).build(), CacheControl.FORCE_NETWORK)
override fun searchPage(page: Int): String = "manga/page/$page/"
}
@Nsfw
class ComicsValley : Madara("Comics Valley", "https://comicsvalley.com", "hi")
class Wakascan : Madara("Wakascan", "https://wakascan.com", "fr")
class ShoujoHearts : Madara("ShoujoHearts", "http://shoujohearts.com", "en") {
@ -1377,18 +752,10 @@ class ShoujoHearts : Madara("ShoujoHearts", "http://shoujohearts.com", "en") {
override fun searchPage(page: Int): String = "reader/page/$page/"
}
class AlianzaMarcial : Madara("AlianzaMarcial", "https://alianzamarcial.xyz", "es")
class OlaoeManga : Madara("مانجا اولاو", "https://olaoe.giize.com", "ar")
class FdmScan : Madara("FDM Scan", "https://fdmscan.com", "pt-BR", SimpleDateFormat("MMMM dd, yyyy", Locale("pt", "BR")))
class ArgosScan : Madara("Argos Scan", "https://argosscan.com", "pt-BR", SimpleDateFormat("dd 'de' MMMM 'de' yyyy", Locale("pt", "BR")))
class OrigamiOrpheans : Madara("Origami Orpheans", "https://origami-orpheans.com.br", "pt-BR")
class DarkyuRealm : Madara("Darkyu Realm", "https://darkyuerealm.site", "pt-BR")
class MangaKiss : Madara("Manga Kiss", "https://mangakiss.org", "en")
class MangaRocky : Madara("Manga Rocky", "https://mangarocky.com", "en")
@ -1403,8 +770,6 @@ class Kombatch : Madara("Kombatch", "https://kombatch.com", "id", SimpleDateForm
class ProjetoScanlator : Madara("Projeto Scanlator", "https://projetoscanlator.com", "pt-BR", SimpleDateFormat("dd/MM/yyyy", Locale("pt", "BR")))
class HikariScan : Madara("Hikari Scan", "https://hikariscan.com.br", "pt-BR", SimpleDateFormat("dd 'de' MMMM 'de' yyyy", Locale("pt", "BR")))
class NazarickScans : Madara("Nazarick Scans", "https://nazarickscans.com", "en") {
override fun popularMangaRequest(page: Int) = GET("$baseUrl/manga/page/$page/?m_orderby=trending", headers)
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/manga/page/$page/?m_orderby=trending", headers)
@ -1455,12 +820,6 @@ class MysticalMerries : Madara("Mystical Merries", "https://mysticalmerries.com"
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/genre/manhwa/page/$page/?m_orderby=latest", headers)
}
class AniMangaEs : Madara("AniMangaEs", "http://animangaes.com", "en") {
override val pageListParseSelector = "div.text-left noscript"
override val chapterUrlSuffix = ""
override fun chapterListParse(response: Response): List<SChapter> = super.chapterListParse(response).reversed()
}
class MangaNine : Madara("Manga Nine", "https://manganine.com", "en")
class MarkScans : Madara("Mark Scans", "https://markscans.online", "pt-BR")
@ -1505,10 +864,6 @@ class Voidscans : Madara("Void Scans", "https://voidscans.com", "en") {
override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = GET("$baseUrl/?s=$query&post_type=wp-manga")
}
class GeceninLordu : Madara("Gecenin Lordu", "https://geceninlordu.com/", "tr", SimpleDateFormat("dd MMM yyyy", Locale("tr"))) {
override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = GET("$baseUrl/?s=$query&post_type=wp-manga")
}
class GrazeScans : Madara("Graze Scans", "https://grazescans.com/", "en")
class UyuyanBalik : Madara("Uyuyan Balik", "https://uyuyanbalik.com/", "tr", SimpleDateFormat("dd MMMM yyyy", Locale.US))
@ -1527,16 +882,12 @@ class MundoWuxia : Madara("Mundo Wuxia", "https://mundowuxia.com", "es", SimpleD
class WorldRomanceTranslation : Madara("World Romance Translation", "https://wrt.my.id/", "id", SimpleDateFormat("dd MMMM yyyy", Locale("id")))
class CloverManga : Madara("Clover Manga", "https://clover-manga.com/", "tr", SimpleDateFormat("MMMM dd, yyyy", Locale("tr")))
class VanguardBun : Madara("Vanguard Bun", "https://vanguardbun.com/", "en")
class MangaBin : Madara("Manga Bin", "https://mangabin.com/", "en")
class MangaChill : Madara("Manga Chill", "https://mangachill.com/", "en")
class DreamManga : Madara("Dream Manga", "https://dreammanga.com/", "en")
class GourmetScans : Madara("Gourmet Scans", "https://gourmetscans.net/", "en")
class ItsYourRightManhua : Madara("Its Your Right Manhua", "https://itsyourightmanhua.com/", "en")