Bye bye Madara (#5730)

* N-Z

* MZuki-N

* kbatch-mzuki

* remove madara

* remove wildcard

* nsfw

* pkg name

already got it from class name

* forgot className

* this too

* fix arangScans chapter and timestamp

* add mangaEffect

* add mangaGreat

* mangazuki.club multiLang

* forgot this line :v
This commit is contained in:
Riztard Lanthorn 2021-02-10 21:05:12 +07:00 committed by GitHub
parent 532ffb1892
commit bd5f42f8cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
88 changed files with 1022 additions and 1407 deletions

View File

@ -6,7 +6,8 @@ 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)) {
class ArangScans : Madara("Arang Scans", "https://arangscans.com", "en") {
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

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.en.lilymanga
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class LilyManga : Madara("Lily Manga", "https://lilymanga.com", "en", SimpleDateFormat("yyyy-MM-dd", Locale.US))

View File

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

View File

@ -0,0 +1,9 @@
package eu.kanade.tachiyomi.extension.en.manga347
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class Manga347 : Madara("Manga347", "https://manga347.com", "en", SimpleDateFormat("d MMM, yyyy", Locale.US)) {
override val pageListParseSelector = "li.blocks-gallery-item"
}

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.en.manga68
import eu.kanade.tachiyomi.multisrc.madara.Madara
class Manga68 : Madara("Manga68", "https://manga68.com", "en") {
override val pageListParseSelector = "div.page-break, div.text-left p"
}

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.ar.mangaaction
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class MangaAction : Madara("Manga Action", "https://manga-action.com", "ar", SimpleDateFormat("yyyy-MM-dd", Locale("ar")))

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.ar.mangaarabonline
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class MangaArabOnline : Madara("Manga Arab Online مانجا عرب اون لاين", "https://mangaarabonline.com", "ar", SimpleDateFormat("MMM d, yyyy", Locale.forLanguageTag("ar")))

View File

@ -0,0 +1,14 @@
package eu.kanade.tachiyomi.extension.ar.mangaarabteam
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 MangaArabTeam : Madara("مانجا عرب تيم Manga Arab Team", "https://mangaarabteam.com", "ar", SimpleDateFormat("dd MMM، yyyy", Locale.forLanguageTag("ar"))) {
override fun imageRequest(page: Page): Request {
return GET(page.imageUrl!!.replace("http:", "https:"))
}
}

View File

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

View File

@ -0,0 +1,12 @@
package eu.kanade.tachiyomi.extension.en.mangaclash
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class MangaClash : Madara(
"Manga Clash",
"https://mangaclash.com",
"en",
dateFormat = SimpleDateFormat("MM/dd/yy", Locale.US)
)

View File

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

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.en.mangadods
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class MangaDods : Madara("MangaDods", "https://www.mangadods.com", "en", SimpleDateFormat("yyyy-MM-dd", Locale.US))

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.en.mangaeffect
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class MangaEffect : Madara("MangaEffect", "https://mangaeffect.com", "en", SimpleDateFormat("dd.MM.yyyy", Locale.US))

View File

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

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.ar.mangalek
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class Mangalek : Madara("مانجا ليك", "https://mangalek.com", "ar", SimpleDateFormat("MMMM dd, yyyy", Locale("ar")))

View File

@ -0,0 +1,11 @@
package eu.kanade.tachiyomi.extension.th.mangaonlineco
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.source.model.SChapter
import okhttp3.Response
import java.text.SimpleDateFormat
import java.util.Locale
class MangaOnlineCo : Madara("Manga-Online.co", "https://www.manga-online.co", "th", SimpleDateFormat("MMM dd, yyyy", Locale("th"))) {
override fun chapterListParse(response: Response): List<SChapter> = super.chapterListParse(response).reversed()
}

View File

@ -0,0 +1,8 @@
package eu.kanade.tachiyomi.extension.tr.mangaphoenix
import eu.kanade.tachiyomi.multisrc.madara.Madara
class MangaPhoenix : Madara("Manga Diyari", "https://mangadiyari.com", "tr") {
// Formerly "Manga Phoenix"
override val id = 4308007020001642101
}

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.en.mangaread
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class MangaRead : Madara("Manga Read", "https://mangaread.co", "en", SimpleDateFormat("yyyy-MM-dd", Locale.US))

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.en.mangareadorg
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class MangaReadOrg : Madara("MangaRead.org", "https://www.mangaread.org", "en", SimpleDateFormat("dd.MM.yyy", Locale.US))

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.fr.mangascantrad
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class MangaScantrad : Madara("Manga-Scantrad", "https://manga-scantrad.net", "fr", SimpleDateFormat("d MMM yyyy", Locale.FRANCE))

View File

@ -0,0 +1,24 @@
package eu.kanade.tachiyomi.extension.ar.mangaspark
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.source.model.SManga
import org.jsoup.nodes.Element
class MangaSpark : Madara("MangaSpark", "https://mangaspark.com", "ar") {
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)?.replace("mangaspark", "mangalek")
}
}
return manga
}
}

View File

@ -0,0 +1,24 @@
package eu.kanade.tachiyomi.extension.ar.mangastarz
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.source.model.SManga
import org.jsoup.nodes.Element
class MangaStarz : Madara("Manga Starz", "https://mangastarz.com", "ar") {
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)?.replace("mangastarz", "mangalek")
}
}
return manga
}
}

View File

@ -0,0 +1,12 @@
package eu.kanade.tachiyomi.extension.en.mangasy
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.source.model.Page
import okhttp3.CacheControl
import okhttp3.Request
class MangaSY : Madara("Manga SY", "https://www.mangasy.com", "en") {
override fun imageRequest(page: Page): Request = super.imageRequest(page).newBuilder()
.cacheControl(CacheControl.FORCE_NETWORK)
.build()
}

View File

@ -0,0 +1,35 @@
package eu.kanade.tachiyomi.extension.pt.mangateca
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.source.model.SChapter
import okhttp3.Headers
import org.jsoup.nodes.Element
import java.text.SimpleDateFormat
import java.util.Locale
class MangaTeca : Madara(
"MangaTeca",
"https://www.mangateca.com",
"pt-BR",
SimpleDateFormat("MMMM dd, yyyy", Locale("pt", "BR"))
) {
override fun headersBuilder(): Headers.Builder = Headers.Builder()
.add("User-Agent", USER_AGENT)
.add("Referer", baseUrl)
.add("Origin", baseUrl)
override fun chapterFromElement(element: Element): SChapter {
val parsedChapter = super.chapterFromElement(element)
parsedChapter.date_upload = element.select("img").firstOrNull()?.attr("alt")
?.let { parseChapterDate(it) }
?: parseChapterDate(element.select("span.chapter-release-date i").firstOrNull()?.text())
return parsedChapter
}
companion object {
private const val USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36"
}
}

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.id.mangayosh
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class MangaYosh : Madara("MangaYosh", "https://mangayosh.xyz", "id", SimpleDateFormat("dd MMM yyyy", Locale.US))

View File

@ -0,0 +1,14 @@
package eu.kanade.tachiyomi.extension.all.mangazukiclub
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceFactory
class MangazukiClubFactory : SourceFactory {
override fun createSources(): List<Source> = listOf(
MangazukiClubJP(),
MangazukiClubKO(),
)
}
class MangazukiClubJP : Madara("Mangazuki.club", "https://mangazuki.club", "ja")
class MangazukiClubKO : Madara("Mangazuki.club", "https://mangazuki.club", "ko")

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.en.manhuabox
import eu.kanade.tachiyomi.multisrc.madara.Madara
class ManhuaBox : Madara("ManhuaBox", "https://manhuabox.net", "en") {
override val pageListParseSelector = "div.page-break, div.text-left p img"
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,26 @@
package eu.kanade.tachiyomi.extension.en.martialscans
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.source.model.SManga
import org.jsoup.nodes.Element
class MartialScans : Madara("Martial Scans", "https://martialscans.com", "en") {
override fun popularMangaFromElement(element: Element): SManga {
val manga = SManga.create()
with(element) {
select(popularMangaUrlSelector).last()?.let {
manga.setUrlWithoutDomain(it.attr("href"))
manga.title = it.ownText()
}
select("img").last()?.let {
manga.thumbnail_url = imageFromElement(it)
}
}
return manga
}
override fun searchMangaFromElement(element: Element): SManga = popularMangaFromElement(element)
}

View File

@ -0,0 +1,10 @@
package eu.kanade.tachiyomi.extension.en.milftoon
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.GET
import okhttp3.Request
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)
}

View File

@ -0,0 +1,10 @@
package eu.kanade.tachiyomi.extension.en.mixedmanga
import eu.kanade.tachiyomi.multisrc.madara.Madara
import okhttp3.Headers
import java.text.SimpleDateFormat
import java.util.Locale
class MixedManga : Madara("Mixed Manga", "https://mixedmanga.com", "en", SimpleDateFormat("d MMM yyyy", Locale.US)) {
override fun headersBuilder(): Headers.Builder = super.headersBuilder().add("Referer", baseUrl)
}

View File

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

View File

@ -0,0 +1,9 @@
package eu.kanade.tachiyomi.extension.en.mysticalmerries
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.GET
class MysticalMerries : Madara("Mystical Merries", "https://mysticalmerries.com", "en") {
override fun popularMangaRequest(page: Int) = GET("$baseUrl/genre/manhwa/page/$page/?m_orderby=trending", headers)
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/genre/manhwa/page/$page/?m_orderby=latest", headers)
}

View File

@ -0,0 +1,11 @@
package eu.kanade.tachiyomi.extension.en.nazarickscans
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.GET
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)
override fun popularMangaNextPageSelector(): String? = null
override fun latestUpdatesNextPageSelector(): String? = null
}

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.en.neatmanga
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class NeatManga : Madara("NeatManga", "https://neatmanga.com", "en", SimpleDateFormat("dd MMM yyyy", Locale.US))

View File

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

View File

@ -0,0 +1,34 @@
package eu.kanade.tachiyomi.extension.pt.neoxscanlator
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.source.model.FilterList
import okhttp3.Headers
import okhttp3.OkHttpClient
import java.text.SimpleDateFormat
import java.util.Locale
import java.util.concurrent.TimeUnit
class NeoxScanlator : Madara(
"Neox Scanlator",
"https://neoxscans.com",
"pt-BR",
SimpleDateFormat("dd/MM/yyyy", Locale("pt", "BR"))
) {
override val client: OkHttpClient = network.cloudflareClient.newBuilder()
.connectTimeout(1, TimeUnit.MINUTES)
.readTimeout(1, TimeUnit.MINUTES)
.build()
override fun headersBuilder(): Headers.Builder = Headers.Builder()
.add("User-Agent", USER_AGENT)
.add("Referer", baseUrl)
.add("Origin", baseUrl)
// Only status and order by filter work.
override fun getFilterList(): FilterList = FilterList(super.getFilterList().slice(3..4))
companion object {
private const val USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"
}
}

View File

@ -0,0 +1,11 @@
package eu.kanade.tachiyomi.extension.en.nightcomic
import eu.kanade.tachiyomi.multisrc.madara.Madara
import okhttp3.Headers
class NightComic : Madara("Night Comic", "https://www.nightcomic.com", "en") {
override val formHeaders: Headers = headersBuilder()
.add("Content-Type", "application/x-www-form-urlencoded")
.add("X-MOD-SBB-CTYPE", "xhr")
.build()
}

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.ar.nijitranslations
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class NijiTranslations : Madara("Niji Translations", "https://niji-translations.com", "ar", SimpleDateFormat("MMMM dd, yyyy", Locale("ar")))

View File

@ -0,0 +1,12 @@
package eu.kanade.tachiyomi.extension.pt.offscan
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class OffScan : Madara(
"Off Scan",
"https://offscan.top",
"pt-BR",
dateFormat = SimpleDateFormat("dd/MM/yy", Locale.US)
)

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.en.pmscans
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class PMScans : Madara("PMScans", "https://www.pmscans.com", "en", SimpleDateFormat("MMM-dd-yy", Locale.US))

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.id.pojokmanga
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class PojokManga : Madara("Pojok Manga", "https://pojokmanga.com", "id", SimpleDateFormat("MMM dd, yyyy", Locale.US))

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.pt.projetoscanlator
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class ProjetoScanlator : Madara("Projeto Scanlator", "https://projetoscanlator.com", "pt-BR", SimpleDateFormat("dd/MM/yyyy", Locale("pt", "BR")))

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.ar.queensmanga
import eu.kanade.tachiyomi.multisrc.madara.Madara
class QueensManga : Madara("QueensManga ملكات المانجا", "https://queensmanga.com", "ar") {
override fun chapterListSelector(): String = "div.listing-chapters_wrap a"
}

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.en.randomtranslations
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class RandomTranslations : Madara("Random Translations", "https://randomtranslations.com", "en", SimpleDateFormat("dd/MM/yyyy", Locale.US))

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.ja.rawmangas
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class RawMangas : Madara("Raw Mangas", "https://rawmangas.net", "ja", SimpleDateFormat("MMMM dd, yyyy", Locale.US))

View File

@ -0,0 +1,12 @@
package eu.kanade.tachiyomi.extension.en.readmanhua
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class ReadManhua : Madara(
"ReadManhua",
"https://readmanhua.net",
"en",
dateFormat = SimpleDateFormat("dd MMM yy", Locale.US)
)

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.en.renascans
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class RenaScans : Madara("Renascence Scans (Renascans)", "https://new.renascans.com", "en", SimpleDateFormat("dd/MM/yyyy", Locale.US))

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.tr.ruyamanga
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class RuyaManga : Madara("Rüya Manga", "https://www.ruyamanga.com", "tr", SimpleDateFormat("dd MMMM yyyy", Locale.forLanguageTag("tr")))

View File

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

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.en.sixiangscans
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class SiXiangScans : Madara("SiXiang Scans", "http://www.sixiangscans.com", "en", SimpleDateFormat("MMMM dd, yyyy", Locale.US))

View File

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

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.en.soloscanlation
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class SoloScanlation : Madara("SoloScanlation", "https://soloscanlation.site", "en", SimpleDateFormat("MMMM dd, yyyy", Locale.US))

View File

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

View File

@ -0,0 +1,19 @@
package eu.kanade.tachiyomi.extension.pt.stagecomics
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.source.model.SChapter
import org.jsoup.nodes.Element
import java.text.SimpleDateFormat
import java.util.Locale
class StageComics : Madara("StageComics", "https://stagecomics.com", "pt-BR", SimpleDateFormat("MMMM dd, yyyy", Locale("pt"))) {
override fun chapterFromElement(element: Element): SChapter {
val parsedChapter = super.chapterFromElement(element)
parsedChapter.date_upload = element.select("img").firstOrNull()?.attr("alt")
?.let { parseChapterDate(it) }
?: parseChapterDate(element.select("span.chapter-release-date i").firstOrNull()?.text())
return parsedChapter
}
}

View File

@ -0,0 +1,10 @@
package eu.kanade.tachiyomi.extension.en.threesixtyfivemanga
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.GET
import okhttp3.Request
class ThreeSixtyFiveManga : Madara("365Manga", "https://365manga.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)
}

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.en.toongod
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class ToonGod : Madara("ToonGod", "https://www.toongod.com", "en", SimpleDateFormat("dd MMM yyyy", Locale.US))

View File

@ -0,0 +1,37 @@
package eu.kanade.tachiyomi.extension.en.toonily
import eu.kanade.tachiyomi.multisrc.madara.Madara
class Toonily : Madara("Toonily", "https://toonily.com", "en") {
override fun getGenreList(): List<Genre> = listOf(
Genre("Action", "action-webtoon"),
Genre("Adult", "adult-webtoon"),
Genre("Adventure", "adventure-webtoon"),
Genre("Comedy", "comedy-webtoon"),
Genre("Drama", "drama-webtoon"),
Genre("Fantasy", "fantasy-webtoon"),
Genre("Gender Bender", "gender-bender"),
Genre("Gossip", "gossip"),
Genre("Harem", "harem-webtoon"),
Genre("Historical", "webtoon-historical"),
Genre("Horror", "horror-webtoon"),
Genre("Josei", "josei-manga"),
Genre("Mature", "mature-webtoon"),
Genre("Mystery", "mystery-webtoon"),
Genre("NTR", "ntr-webtoon"),
Genre("Psychological", "psychological-webtoon"),
Genre("Romance", "romance-webtoon"),
Genre("School life", "school-life-webtoon"),
Genre("Sci-Fi", "scifi-webtoon"),
Genre("Seinen", "seinen-webtoon"),
Genre("Shoujo", "shoujo"),
Genre("Shounen", "shounen-webtoon"),
Genre("Slice of Life", "sliceoflife-webtoon"),
Genre("Supernatural", "supernatural-webtoon"),
Genre("Thriller", "thriller-webtoon"),
Genre("Tragedy", "tragedy"),
Genre("Vanilla", "vanilla-webtoon"),
Genre("Yaoi", "yaoi-webtoon"),
Genre("Yuri", "yuri-webtoon")
)
}

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.en.toonpoint
import eu.kanade.tachiyomi.multisrc.madara.Madara
class ToonPoint : Madara("ToonPoint", "https://toonpoint.com", "en") {
override val userAgentRandomizer = ""
}

View File

@ -0,0 +1,10 @@
package eu.kanade.tachiyomi.extension.en.topmanhua
import eu.kanade.tachiyomi.multisrc.madara.Madara
import okhttp3.Headers
import java.text.SimpleDateFormat
import java.util.Locale
class TopManhua : Madara("Top Manhua", "https://topmanhua.com", "en", SimpleDateFormat("MM/dd/yy", Locale.US)) {
override fun headersBuilder(): Headers.Builder = super.headersBuilder().add("Referer", baseUrl)
}

View File

@ -0,0 +1,26 @@
package eu.kanade.tachiyomi.extension.vi.truyentranhaudiocom
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SManga
import okhttp3.Request
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import java.text.SimpleDateFormat
import java.util.Locale
class TruyenTranhAudioCom : Madara("TruyenTranhAudio.com", "https://truyentranhaudio.com", "vi", SimpleDateFormat("dd/MM/yyyy", Locale.getDefault())) {
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/page/$page?s&post_type=wp-manga&m_orderby=views", headers)
override fun popularMangaSelector() = searchMangaSelector()
override fun popularMangaFromElement(element: Element): SManga = searchMangaFromElement(element)
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/page/$page?s&post_type=wp-manga&m_orderby=latest", headers)
override fun latestUpdatesSelector() = searchMangaSelector()
override fun latestUpdatesFromElement(element: Element): SManga = searchMangaFromElement(element)
override fun pageListParse(document: Document): List<Page> {
return document.select("div.reading-content img").map { it.attr("abs:src") }
.filterNot { it.isNullOrEmpty() }
.distinct()
.mapIndexed { i, url -> Page(i, "", url) }
}
}

View File

@ -0,0 +1,21 @@
package eu.kanade.tachiyomi.extension.vi.truyentranhaudioonline
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.source.model.Page
import okhttp3.Headers
import org.jsoup.nodes.Document
import java.text.SimpleDateFormat
import java.util.Locale
class TruyenTranhAudioOnline : Madara("TruyenTranhAudio.online", "https://truyentranhaudio.online", "vi", SimpleDateFormat("dd/MM/yyyy", Locale.getDefault())) {
override val formHeaders: Headers = headersBuilder()
.add("Content-Type", "application/x-www-form-urlencoded")
.build()
override fun pageListParse(document: Document): List<Page> {
return document.select("div.reading-content img").map { it.attr("abs:src") }
.filterNot { it.isNullOrEmpty() }
.distinct()
.mapIndexed { i, url -> Page(i, "", url) }
}
}

View File

@ -0,0 +1,12 @@
package eu.kanade.tachiyomi.extension.fr.tsubakinoscan
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class TsubakiNoScan : Madara(
"Tsubaki No Scan",
"https://tsubakinoscan.com",
"fr",
dateFormat = SimpleDateFormat("dd/MM/yy", Locale.US)
)

View File

@ -0,0 +1,30 @@
package eu.kanade.tachiyomi.extension.tr.turkcemanga
import eu.kanade.tachiyomi.multisrc.madara.Madara
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.FilterList
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import okhttp3.CacheControl
import okhttp3.Headers
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import java.text.SimpleDateFormat
import java.util.Locale
import java.util.concurrent.TimeUnit
class TurkceManga : Madara("Türkçe Manga", "https://turkcemanga.com", "tr") {
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/page/$page/?s&post_type=wp-manga&m_orderby=views", headers)
override fun popularMangaSelector() = searchMangaSelector()
override fun popularMangaFromElement(element: Element): SManga = searchMangaFromElement(element)
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/page/$page/?s&post_type=wp-manga&m_orderby=latest", headers)
override fun latestUpdatesSelector() = searchMangaSelector()
override fun latestUpdatesFromElement(element: Element): SManga = searchMangaFromElement(element)
}

View File

@ -0,0 +1,8 @@
package eu.kanade.tachiyomi.extension.tr.uyuyanbalik
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class UyuyanBalik : Madara("Uyuyan Balik", "https://uyuyanbalik.com/", "tr", SimpleDateFormat("dd MMMM yyyy", Locale.US))

View File

@ -0,0 +1,9 @@
package eu.kanade.tachiyomi.extension.en.voidscans
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.FilterList
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")
}

View File

@ -0,0 +1,8 @@
package eu.kanade.tachiyomi.extension.pt.warqueenscan
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class WarQueenScan : Madara("War Queen Scan", "https://wqscan.com", "pt-BR", SimpleDateFormat("dd/MM/yyyy", Locale.US))

View File

@ -0,0 +1,11 @@
package eu.kanade.tachiyomi.extension.en.webtoonxyz
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.GET
import okhttp3.Request
class WebtoonXYZ : Madara("WebtoonXYZ", "https://www.webtoon.xyz", "en") {
private fun pagePath(page: Int) = if (page > 1) "page/$page/" else ""
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/webtoons/${pagePath(page)}?m_orderby=views", headers)
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/webtoons/${pagePath(page)}?m_orderby=latest", headers)
}

View File

@ -0,0 +1,15 @@
package eu.kanade.tachiyomi.extension.en.wescans
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.FilterList
import okhttp3.Request
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
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/manhua/manga/?m_orderby=latest", headers)
override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = GET("$baseUrl/manhua/?s=$query&post_type=wp-manga")
override fun searchMangaNextPageSelector(): String? = null
override fun getFilterList(): FilterList = FilterList()
}

View File

@ -0,0 +1,8 @@
package eu.kanade.tachiyomi.extension.id.worldromancetranslation
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class WorldRomanceTranslation : Madara("World Romance Translation", "https://wrt.my.id/", "id", SimpleDateFormat("dd MMMM yyyy", Locale("id")))

View File

@ -0,0 +1,13 @@
package eu.kanade.tachiyomi.extension.en.wuxiaworld
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.FilterList
import okhttp3.Request
class WuxiaWorld : Madara("WuxiaWorld", "https://wuxiaworld.site", "en") {
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/tag/webcomic/page/$page/?m_orderby=views", headers)
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/tag/webcomic/page/$page/?m_orderby=latest", headers)
override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = super.searchMangaRequest(page, "$query comics", filters)
override fun popularMangaNextPageSelector() = "div.nav-previous.float-left"
}

View File

@ -0,0 +1,28 @@
package eu.kanade.tachiyomi.extension.pt.yaoitoshokan
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import okhttp3.Response
import org.jsoup.nodes.Document
import java.text.SimpleDateFormat
import java.util.Locale
class YaoiToshokan : Madara("Yaoi Toshokan", "https://yaoitoshokan.com.br", "pt-BR", SimpleDateFormat("dd MMM yyyy", Locale("pt", "BR"))) {
// Page has custom link to scan website.
override val popularMangaUrlSelector = "div.post-title a:not([target])"
// Chapters are listed old to new.
override fun chapterListParse(response: Response): List<SChapter> {
return super.chapterListParse(response).reversed()
}
override fun pageListParse(document: Document): List<Page> {
return document.select(pageListParseSelector)
.mapIndexed { index, element ->
// Had to add trim because of white space in source.
val imageUrl = element.select("img").attr("data-src").trim()
Page(index, document.location(), imageUrl)
}
}
}

View File

@ -0,0 +1,12 @@
package eu.kanade.tachiyomi.extension.fr.yokaijump
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class YokaiJump : Madara(
"Yokai Jump",
"https://yokaijump.fr",
"fr",
dateFormat = SimpleDateFormat("dd/MM/yy", Locale.US)
)

View File

@ -0,0 +1,12 @@
package eu.kanade.tachiyomi.extension.pt.yuriverso
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class YuriVerso : Madara(
"Yuri Verso",
"https://yuri.live",
"pt-BR",
SimpleDateFormat("dd/MM/yyyy", Locale("pt", "BR"))
)

View File

@ -0,0 +1,9 @@
package eu.kanade.tachiyomi.extension.en.zinmanga
import eu.kanade.tachiyomi.multisrc.madara.Madara
import okhttp3.Headers
class ZinManga : Madara("Zin Translator", "https://zinmanga.com", "en") {
override fun headersBuilder(): Headers.Builder = super.headersBuilder()
.add("Referer", "https://zinmanga.com/")
}

View File

@ -1,6 +1,7 @@
package eu.kanade.tachiyomi.multisrc.madara
import eu.kanade.tachiyomi.multisrc.ThemeSourceData.SingleLang
import eu.kanade.tachiyomi.multisrc.ThemeSourceData.MultiLang
import eu.kanade.tachiyomi.multisrc.ThemeSourceGenerator
class MadaraGenerator : ThemeSourceGenerator {
@ -15,25 +16,25 @@ class MadaraGenerator : ThemeSourceGenerator {
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("AllPornComic", "https://allporncomic.com", "en", isNsfw = true),
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("Arang Scans", "https://arangscans.com", "en", overrideVersionCode = 1),
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("ATM-Subs", "https://atm-subs.fr", "fr", className = "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", overrideVersionCode = 1),
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("CAT-translator", "https://cat-translator.com", "th", className = "CatTranslator"),
SingleLang("Chibi Manga", "https://www.cmreader.info", "en"),
SingleLang("Clover Manga", "Clover Manga", "tr"),
SingleLang("ComicKiba", "https://comickiba.com", "en"),
@ -78,8 +79,151 @@ class MadaraGenerator : ThemeSourceGenerator {
SingleLang("KlikManga", "https://klikmanga.com", "id"),
SingleLang("Kissmanga.in", "https://kissmanga.in", "en", className= "KissmangaIn"),
SingleLang("Kombatch", "https://kombatch.com", "id"),
SingleLang("KomikGo", "https://komikgo.com", "id"),
SingleLang("Lily Manga", "https://lilymanga.com", "en"),
SingleLang("LovableSubs", "https://lovablesubs.com", "tr"),
SingleLang("Manga18 Fun", "https://manga18.fun", "en"),
SingleLang("Manga347", "https://manga347.com", "en"),
SingleLang("مانجا العاشق", "https://3asq.org", "ar", className = "Manga3asq"),
SingleLang("Manga3S", "https://manga3s.com", "en"),
SingleLang("Manga68", "https://manga68.com", "en"),
SingleLang("Manga Action", "https://manga-action.com", "ar"),
SingleLang("Manga Arab Online مانجا عرب اون لاين", "https://mangaarabonline.com", "ar", className = "MangaArabOnline"),
SingleLang("مانجا عرب تيم Manga Arab Team", "https://mangaarabteam.com", "ar", className = "MangaArabTeam"),
SingleLang("MangaBaz", "https://mangabaz.com", "tr"),
SingleLang("Manga Bin", "https://mangabin.com/", "en"),
SingleLang("MangaBob", "https://mangabob.com", "en"),
SingleLang("Manga Chill", "https://mangachill.com/", "en"),
SingleLang("Manga Clash", "https://mangaclash.com", "en"),
SingleLang("Manga Crimson", "https://mangacrimson.com", "tr"),
SingleLang("MangaCultivator", "https://mangacultivator.com", "en"),
SingleLang("MangaDods", "https://www.mangadods.com", "en"),
SingleLang("MangaEffect", "https://mangaeffect.com", "en"),
SingleLang("MangaGreat", "https://mangagreat.com", "en"),
SingleLang("Manga Hentai", "https://mangahentai.me", "en", isNsfw = true),
SingleLang("Manga Kiss", "https://mangakiss.org", "en"),
SingleLang("MangaKomi", "https://mangakomi.com", "en"),
SingleLang("Manga Land Arabic", "https://mangalandarabic.com", "ar"),
SingleLang("مانجا ليك", "https://mangalek.com", "ar", className = "Mangalek"),
SingleLang("Manga Lord", "https://mangalord.com", "en"),
SingleLang("Manganelo.link", "https://manganelo.link", "en", className = "ManganeloLink"),
SingleLang("Manga Nine", "https://manganine.com", "en"),
SingleLang("Manga-Online.co", "https://www.manga-online.co", "th", className = "MangaOnlineCo"),
SingleLang("Manga Diyari", "https://mangadiyari.com", "tr"),
SingleLang("MangaRave", "http://www.mangarave.com", "en"),
SingleLang("MangaRawr", "https://mangarawr.com", "en"),
SingleLang("Manga Read", "https://mangaread.co", "en"),
SingleLang("MangaRead.org", "https://www.mangaread.org", "en", className = "MangaReadOrg"),
SingleLang("Mangareceh", "https://mangareceh.id", "id"),
SingleLang("Manga Rock Team", "https://mangarockteam.com", "en"),
SingleLang("Manga Rocky", "https://mangarocky.com", "en"),
SingleLang("MangaRoma", "https://mangaroma.com", "en"),
SingleLang("Manga-Scantrad", "https://manga-scantrad.net", "fr", className = "MangaScantrad"),
SingleLang("MangaSco", "https://mangasco.com", "en"),
SingleLang("MangaSpark", "https://mangaspark.com", "ar"),
SingleLang("Manga Starz", "https://mangastarz.com", "ar"),
SingleLang("MangaStein", "https://mangastein.com", "tr"),
SingleLang("Mangasushi", "https://mangasushi.net", "en"),
SingleLang("Manga SY", "https://www.mangasy.com", "en"),
SingleLang("MangaTeca", "https://www.mangateca.com", "pt-BR"),
SingleLang("Manga Turf", "https://mangaturf.com", "en"),
SingleLang("MangaTX", "https://mangatx.com", "en"),
SingleLang("Manga Weebs", "https://mangaweebs.in", "en"),
SingleLang("MangaWT", "https://mangawt.com", "tr"),
SingleLang("MangaYaku", "https://mangayaku.my.id", "id"),
SingleLang("MangaYosh", "https://mangayosh.xyz", "id"),
MultiLang("Mangazuki.club", "https://mangazuki.club", listOf("ja", "ko"),
className = "MangazukiClubFactory"),
SingleLang("Mangazuki.me", "https://mangazuki.me", "en", className = "MangazukiMe"),
SingleLang("Mangazuki.online", "http://mangazukinew.online", "en", className = "MangazukiOnline"),
SingleLang("ManhuaBox", "https://manhuabox.net", "en"),
SingleLang("ManhuaFast", "https://manhuafast.com", "en"),
SingleLang("Manhuaga", "https://manhuaga.com", "en"),
SingleLang("Manhua Plus", "https://manhuaplus.com", "en"),
SingleLang("Manhuas.net", "https://manhuas.net", "en", className = "Manhuasnet"),
SingleLang("Manhuas World", "https://manhuasworld.com", "en"),
SingleLang("Manhua SY", "https://www.manhuasy.com", "en"),
SingleLang("ManhuaUS", "https://manhuaus.com", "en"),
SingleLang("Manhwa Raw", "https://manhwaraw.com", "ko"),
SingleLang("Manhwatop", "https://manhwatop.com", "en"),
SingleLang("Manwahentai.me", "https://manhwahentai.me", "en", className = "ManwahentaiMe", isNsfw = true),
SingleLang("Manwha Club", "https://manhwa.club", "en"),
SingleLang("ManyToon", "https://manytoon.com", "en"),
SingleLang("ManyToonClub", "https://manytoon.club", "ko"),
SingleLang("ManyToon.me", "https://manytoon.me", "en", className = "ManyToonMe"),
SingleLang("Mark Scans", "https://markscans.online", "pt-BR"),
SingleLang("Martial Scans", "https://martialscans.com", "en"),
SingleLang("MG Komik", "https://mgkomik.my.id", "id"),
SingleLang("Milftoon", "https://milftoon.xxx", "en", isNsfw = true),
SingleLang("Miracle Scans", "https://miraclescans.com", "en"),
SingleLang("Mixed Manga", "https://mixedmanga.com", "en"),
SingleLang("MMScans", "https://mm-scans.com/", "en"),
SingleLang("Mundo Wuxia", "https://mundowuxia.com", "es"),
SingleLang("Mystical Merries", "https://mysticalmerries.com", "en"),
SingleLang("Nazarick Scans", "https://nazarickscans.com", "en"),
SingleLang("NeatManga", "https://neatmanga.com", "en"),
SingleLang("NekoBreaker", "https://nekobreaker.com", "pt-BR"),
SingleLang("NekoScan", "https://nekoscan.com", "en"),
SingleLang("Neox Scanlator", "https://neoxscans.com", "pt-BR"),
SingleLang("Night Comic", "https://www.nightcomic.com", "en"),
SingleLang("Niji Translations", "https://niji-translations.com", "ar"),
SingleLang("Ninjavi", "https://ninjavi.com", "ar"),
SingleLang("NTS Void Scans", "https://ntsvoidscans.com", "en"),
SingleLang("Off Scan", "https://offscan.top", "pt-BR"),
SingleLang("مانجا اولاو", "https://olaoe.giize.com", "ar", className = "OlaoeManga"),
SingleLang("OnManga", "https://onmanga.com", "en"),
SingleLang("Origami Orpheans", "https://origami-orpheans.com.br", "pt-BR"),
SingleLang("PMScans", "https://www.pmscans.com", "en"),
SingleLang("Pojok Manga", "https://pojokmanga.com", "id"),
SingleLang("PornComix", "https://www.porncomixonline.net", "en", isNsfw = true),
SingleLang("Prime Manga", "https://primemanga.com", "en"),
SingleLang("Projeto Scanlator", "https://projetoscanlator.com", "pt-BR"),
SingleLang("QueensManga ملكات المانجا", "https://queensmanga.com", "ar", className = "QueensManga"),
SingleLang("Raider Scans", "https://raiderscans.com", "en"),
SingleLang("Random Translations", "https://randomtranslations.com", "en"),
SingleLang("Raw Mangas", "https://rawmangas.net", "ja", isNsfw = true),
SingleLang("ReadManhua", "https://readmanhua.net", "en"),
SingleLang("Renascence Scans (Renascans)", "https://new.renascans.com", "en", className = "RenaScans"),
SingleLang("Rüya Manga", "https://www.ruyamanga.com", "tr", className = "RuyaManga"),
SingleLang("S2Manga", "https://s2manga.com", "en"),
SingleLang("Sekte Doujin", "https://sektedoujin.xyz", "id", isNsfw = true),
SingleLang("ShoujoHearts", "http://shoujohearts.com", "en"),
SingleLang("SiXiang Scans", "http://www.sixiangscans.com", "en"),
SingleLang("Siyahmelek", "https://siyahmelek.com", "tr", isNsfw = true),
SingleLang("Skymanga", "https://skymanga.co", "en"),
SingleLang("SoloScanlation", "https://soloscanlation.site", "en"),
SingleLang("Spooky Scanlations", "https://spookyscanlations.xyz", "es"),
SingleLang("StageComics", "https://stagecomics.com", "pt-BR"),
SingleLang("TheTopComic", "https://thetopcomic.com", "en"),
SingleLang("365Manga", "https://365manga.com", "en", className = "ThreeSixtyFiveManga"),
SingleLang("ToonGod", "https://www.toongod.com", "en"),
SingleLang("Toonily", "https://toonily.com", "en", isNsfw = true),
SingleLang("Toonily.net", "https://toonily.net", "en", isNsfw = true, className = "ToonilyNet"),
SingleLang("ToonPoint", "https://toonpoint.com", "en"),
SingleLang("Top Manhua", "https://topmanhua.com", "en"),
SingleLang("TritiniaScans", "https://tritinia.com", "en"),
SingleLang("TruyenTranhAudio.com", "https://truyentranhaudio.com", "vi", className = "TruyenTranhAudioCom"),
SingleLang("TruyenTranhAudio.online", "https://truyentranhaudio.online", "vi", className = "TruyenTranhAudioOnline"),
SingleLang("Tsubaki No Scan", "https://tsubakinoscan.com", "fr"),
SingleLang("Türkçe Manga", "https://turkcemanga.com", "tr", className = "TurkceManga"),
SingleLang("Twilight Scans", "https://twilightscans.com", "en"),
SingleLang("Uyuyan Balik", "https://uyuyanbalik.com/", "tr"),
SingleLang("Vanguard Bun", "https://vanguardbun.com/", "en"),
SingleLang("Void Scans", "https://voidscans.com", "en"),
SingleLang("Wakascan", "https://wakascan.com", "fr"),
SingleLang("War Queen Scan", "https://wqscan.com", "pt-BR"),
SingleLang("WebNovel", "https://webnovel.live", "en"),
SingleLang("WebToonily", "https://webtoonily.com", "en"),
SingleLang("WebtoonXYZ", "https://www.webtoon.xyz", "en"),
SingleLang("WeScans", "https://wescans.xyz", "en"),
SingleLang("WoopRead", "https://woopread.com", "en"),
SingleLang("World Romance Translation", "https://wrt.my.id/", "id"),
SingleLang("WuxiaWorld", "https://wuxiaworld.site", "en"),
SingleLang("Yaoi Toshokan", "https://yaoitoshokan.com.br", "pt-BR", isNsfw = true),
SingleLang("Yokai Jump", "https://yokaijump.fr", "fr"),
SingleLang("Yuri Verso", "https://yuri.live", "pt-BR"),
SingleLang("Zin Translator", "https://zinmanga.com", "en"),
SingleLang("ZManga", "https://zmanga.org", "es"),
)
companion object {

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="eu.kanade.tachiyomi.extension" />

View File

@ -1,13 +0,0 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
ext {
extName = 'Madara (multiple sources)'
pkgNameSuffix = "all.madara"
extClass = '.MadaraFactory'
extVersionCode = 180
libVersion = '1.2'
containsNsfw = true
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

View File

@ -1,525 +0,0 @@
package eu.kanade.tachiyomi.extension.all.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", "Tamamlandı", "Tamamlandı." -> SManga.COMPLETED
"OnGoing", "Продолжается", "Updating", "Em Lançamento", "Em andamento", "Devam Ediyor", "Devam Ediyor." -> 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"
open val chapterDatesNewSelector = "img"
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(chapterDatesNewSelector).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

@ -1,861 +0,0 @@
package eu.kanade.tachiyomi.extension.all.madara
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.FilterList
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import okhttp3.CacheControl
import okhttp3.Headers
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import java.text.SimpleDateFormat
import java.util.Locale
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(),
// GrazeScans(),
// GourmetScans(),
// GuncelManga(),
// HeroManhua(),
// HerozScanlation(),
// HikariScan(),
// HimeraFansub(),
// Hiperdex(),
// Hscans(),
// HunterFansub(),
// IchirinNoHanaYuri(),
// ImmortalUpdates(),
// IsekaiScanCom(),
// ItsYourRightManhua(),
// JJutsuScans(),
// JustForFun(),
// KingzManga(),
// KisekiManga(),
// KlikManga(),
// Kombatch(),
KomikGo(),
LilyManga(),
LovableSubs(),
Manga18Fun(),
Manga347(),
Manga3asq(),
Manga3S(),
Manga68(),
MangaAction(),
MangaArabOnline(),
MangaArabTeam(),
MangaBaz(),
MangaBin(),
MangaBob(),
MangaChill(),
MangaClash(),
MangaCrimson(),
MangaCultivator(),
MangaDods(),
MangaHentai(),
MangaKiss(),
MangaKomi(),
MangaLandArabic(),
Mangalek(),
MangaLord(),
ManganeloLink(),
MangaNine(),
MangaOnlineCo(),
MangaPhoenix(),
MangaRave(),
MangaRawr(),
MangaRead(),
MangaReadOrg(),
Mangareceh(),
MangaRockTeam(),
MangaRocky(),
MangaRoma(),
MangaScantrad(),
MangaSco(),
MangaSpark(),
MangaStarz(),
MangaStein(),
Mangasushi(),
MangaSY(),
MangaTeca(),
MangaTurf(),
MangaTX(),
MangaWeebs(),
MangaWT(),
MangaYaku(),
MangaYosh(),
MangazukiClubJP(),
MangazukiClubKO(),
MangazukiMe(),
// MangazukiOnline(),
ManhuaBox(),
ManhuaFast(),
Manhuaga(),
ManhuaPlus(),
Manhuasnet(),
ManhuasWorld(),
ManhuaSY(),
ManhuaUS(),
ManhwaRaw(),
ManhwaTop(),
ManwahentaiMe(),
ManwhaClub(),
ManyToon(),
ManyToonClub(),
ManyToonMe(),
MarkScans(),
MartialScans(),
MGKomik(),
Milftoon(),
MiracleScans(),
MixedManga(),
MMScans(),
MundoWuxia(),
MysticalMerries(),
NazarickScans(),
NeatManga(),
NekoBreaker(),
NekoScan(),
NeoxScanlator(),
NightComic(),
NijiTranslations(),
Ninjavi(),
NTSVoidScans(),
OffScan(),
OlaoeManga(),
OnManga(),
OrigamiOrpheans(),
PMScans(),
PojokManga(),
PornComix(),
PrimeManga(),
ProjetoScanlator(),
QueensManga(),
RaiderScans(),
RandomTranslations(),
RawMangas(),
ReadManhua(),
RenaScans(),
RuyaManga(),
S2Manga(),
SekteDoujin(),
ShoujoHearts(),
SiXiangScans(),
Siyahmelek(),
Skymanga(),
SoloScanlation(),
SpookyScanlations(),
StageComics(),
TheTopComic(),
ThreeSixtyFiveManga(),
ToonGod(),
Toonily(),
ToonilyNet(),
ToonPoint(),
TopManhua(),
TritiniaScans(),
TruyenTranhAudioCom(),
TruyenTranhAudioOnline(),
TsubakiNoScan(),
TurkceManga(),
TwilightScans(),
UyuyanBalik(),
VanguardBun(),
Voidscans(),
Wakascan(),
WarQueenScan(),
WebNovel(),
WebToonily(),
WebtoonXYZ(),
WeScans(),
WoopRead(),
WorldRomanceTranslation(),
WuxiaWorld(),
YaoiToshokan(),
YokaiJump(),
YuriVerso(),
ZinManga(),
ZManga(),
// removed because scanlator site and they requested
// AhStudios(),
// KnightNoScanlation(),
)
}
@Nsfw
class RawMangas : Madara("Raw Mangas", "https://rawmangas.net", "ja", SimpleDateFormat("MMMM dd, yyyy", Locale.US))
class SiXiangScans : Madara("SiXiang Scans", "http://www.sixiangscans.com", "en", SimpleDateFormat("MMMM dd, yyyy", Locale.US))
class SoloScanlation : Madara("SoloScanlation", "https://soloscanlation.site", "en", SimpleDateFormat("MMMM dd, yyyy", Locale.US))
class LovableSubs : Madara("LovableSubs", "https://lovablesubs.com", "tr", SimpleDateFormat("dd MMM yyyy", Locale("tr")))
class MangaOnlineCo : Madara("Manga-Online.co", "https://www.manga-online.co", "th", SimpleDateFormat("MMM dd, yyyy", Locale("th"))) {
override fun chapterListParse(response: Response): List<SChapter> = super.chapterListParse(response).reversed()
}
class NeatManga : Madara("NeatManga", "https://neatmanga.com", "en", SimpleDateFormat("dd MMM yyyy", Locale.US))
class WarQueenScan : Madara("War Queen Scan", "https://wqscan.com", "pt-BR", SimpleDateFormat("dd/MM/yyyy", Locale.US))
class StageComics : Madara("StageComics", "https://stagecomics.com", "pt-BR", SimpleDateFormat("MMMM dd, yyyy", Locale("pt"))) {
override fun chapterFromElement(element: Element): SChapter {
val parsedChapter = super.chapterFromElement(element)
parsedChapter.date_upload = element.select("img").firstOrNull()?.attr("alt")
?.let { parseChapterDate(it) }
?: parseChapterDate(element.select("span.chapter-release-date i").firstOrNull()?.text())
return parsedChapter
}
}
class SpookyScanlations : Madara("Spooky Scanlations", "https://spookyscanlations.xyz", "es", SimpleDateFormat("MMMM dd, yyyy", Locale("es")))
class RandomTranslations : Madara("Random Translations", "https://randomtranslations.com", "en", SimpleDateFormat("dd/MM/yyyy", Locale.US))
class ManhuaFast : Madara("ManhuaFast", "https://manhuafast.com", "en") {
override val pageListParseSelector = "li.blocks-gallery-item"
}
class ManhuaSY : Madara("Manhua SY", "https://www.manhuasy.com", "en")
class MangaRave : Madara("MangaRave", "http://www.mangarave.com", "en")
class NekoScan : Madara("NekoScan", "https://nekoscan.com", "en")
class Manga3S : Madara("Manga3S", "https://manga3s.com", "en")
class MGKomik : Madara("MG Komik", "https://mgkomik.my.id", "id")
class MangaSco : Madara("MangaSco", "https://mangasco.com", "en")
class MangaCrimson : Madara("Manga Crimson", "https://mangacrimson.com", "tr", SimpleDateFormat("dd MMMM yyyy", Locale("tr")))
class PrimeManga : Madara("Prime Manga", "https://primemanga.com", "en")
class NekoBreaker : Madara("NekoBreaker", "https://nekobreaker.com", "pt-BR", SimpleDateFormat("MMMM dd, yyyy", Locale("pt")))
class ManganeloLink : Madara("Manganelo.link", "https://manganelo.link", "en")
class MangaRoma : Madara("MangaRoma", "https://mangaroma.com", "en")
class NTSVoidScans : Madara("NTS Void Scans", "https://ntsvoidscans.com", "en")
class ToonGod : Madara("ToonGod", "https://www.toongod.com", "en", SimpleDateFormat("dd MMM yyyy", Locale.US))
class WebToonily : Madara("WebToonily", "https://webtoonily.com", "en")
class Manga18Fun : Madara("Manga18 Fun", "https://manga18.fun", "en")
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 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 OffScan : Madara(
"Off Scan",
"https://offscan.top",
"pt-BR",
dateFormat = SimpleDateFormat("dd/MM/yy", Locale.US)
)
class MangaClash : Madara(
"Manga Clash",
"https://mangaclash.com",
"en",
dateFormat = SimpleDateFormat("MM/dd/yy", Locale.US)
)
class TritiniaScans : Madara("TritiniaScans", "https://tritinia.com", "en")
class CopyPasteScan : Madara("CopyPasteScan", "https://copypastescan.xyz", "es")
class Mangasushi : Madara("Mangasushi", "https://mangasushi.net", "en")
class MangaRawr : Madara("MangaRawr", "https://mangarawr.com", "en")
class ReadManhua : Madara(
"ReadManhua",
"https://readmanhua.net",
"en",
dateFormat = SimpleDateFormat("dd MMM yy", Locale.US)
)
class KomikGo : Madara("KomikGo", "https://komikgo.com", "id")
class TsubakiNoScan : Madara(
"Tsubaki No Scan",
"https://tsubakinoscan.com",
"fr",
dateFormat = SimpleDateFormat("dd/MM/yy", Locale.US)
)
class YokaiJump : Madara(
"Yokai Jump",
"https://yokaijump.fr",
"fr",
dateFormat = SimpleDateFormat("dd/MM/yy", Locale.US)
)
class ZManga : Madara("ZManga", "https://zmanga.org", "es")
class MangazukiMe : Madara("Mangazuki.me", "https://mangazuki.me", "en")
class MangazukiClubJP : Madara("Mangazuki.club", "https://mangazuki.club", "ja")
class MangazukiClubKO : Madara("Mangazuki.club", "https://mangazuki.club", "ko")
class MangaSY : Madara("Manga SY", "https://www.mangasy.com", "en") {
override fun imageRequest(page: Page): Request = super.imageRequest(page).newBuilder()
.cacheControl(CacheControl.FORCE_NETWORK)
.build()
}
class ManwhaClub : Madara("Manwha Club", "https://manhwa.club", "en")
class WuxiaWorld : Madara("WuxiaWorld", "https://wuxiaworld.site", "en") {
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/tag/webcomic/page/$page/?m_orderby=views", headers)
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/tag/webcomic/page/$page/?m_orderby=latest", headers)
override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = super.searchMangaRequest(page, "$query comics", filters)
override fun popularMangaNextPageSelector() = "div.nav-previous.float-left"
}
class ManyToon : Madara("ManyToon", "https://manytoon.com", "en")
class ManyToonMe : Madara("ManyToon.me", "https://manytoon.me", "en")
class BoysLove : Madara("BoysLove", "https://boyslove.me", "en")
class ZinManga : Madara("Zin Translator", "https://zinmanga.com", "en") {
override fun headersBuilder(): Headers.Builder = super.headersBuilder()
.add("Referer", "https://zinmanga.com/")
}
class ManwahentaiMe : Madara("Manwahentai.me", "https://manhwahentai.me", "en")
class Manga3asq : Madara("مانجا العاشق", "https://3asq.org", "ar")
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 MangaArabOnline : Madara("Manga Arab Online مانجا عرب اون لاين", "https://mangaarabonline.com", "ar", SimpleDateFormat("MMM d, yyyy", Locale.forLanguageTag("ar")))
class MangaArabTeam : Madara("مانجا عرب تيم Manga Arab Team", "https://mangaarabteam.com", "ar", SimpleDateFormat("dd MMM، yyyy", Locale.forLanguageTag("ar"))) {
override fun imageRequest(page: Page): Request {
return GET(page.imageUrl!!.replace("http:", "https:"))
}
}
class NightComic : Madara("Night Comic", "https://www.nightcomic.com", "en") {
override val formHeaders: Headers = headersBuilder()
.add("Content-Type", "application/x-www-form-urlencoded")
.add("X-MOD-SBB-CTYPE", "xhr")
.build()
}
class Skymanga : Madara("Skymanga", "https://skymanga.co", "en")
@Nsfw
class Toonily : Madara("Toonily", "https://toonily.com", "en") {
override fun getGenreList(): List<Genre> = listOf(
Genre("Action", "action-webtoon"),
Genre("Adult", "adult-webtoon"),
Genre("Adventure", "adventure-webtoon"),
Genre("Comedy", "comedy-webtoon"),
Genre("Drama", "drama-webtoon"),
Genre("Fantasy", "fantasy-webtoon"),
Genre("Gender Bender", "gender-bender"),
Genre("Gossip", "gossip"),
Genre("Harem", "harem-webtoon"),
Genre("Historical", "webtoon-historical"),
Genre("Horror", "horror-webtoon"),
Genre("Josei", "josei-manga"),
Genre("Mature", "mature-webtoon"),
Genre("Mystery", "mystery-webtoon"),
Genre("NTR", "ntr-webtoon"),
Genre("Psychological", "psychological-webtoon"),
Genre("Romance", "romance-webtoon"),
Genre("School life", "school-life-webtoon"),
Genre("Sci-Fi", "scifi-webtoon"),
Genre("Seinen", "seinen-webtoon"),
Genre("Shoujo", "shoujo"),
Genre("Shounen", "shounen-webtoon"),
Genre("Slice of Life", "sliceoflife-webtoon"),
Genre("Supernatural", "supernatural-webtoon"),
Genre("Thriller", "thriller-webtoon"),
Genre("Tragedy", "tragedy"),
Genre("Vanilla", "vanilla-webtoon"),
Genre("Yaoi", "yaoi-webtoon"),
Genre("Yuri", "yuri-webtoon")
)
}
class MangaKomi : Madara("MangaKomi", "https://mangakomi.com", "en")
@Nsfw
class YaoiToshokan : Madara("Yaoi Toshokan", "https://yaoitoshokan.com.br", "pt-BR", SimpleDateFormat("dd MMM yyyy", Locale("pt", "BR"))) {
// Page has custom link to scan website.
override val popularMangaUrlSelector = "div.post-title a:not([target])"
// Chapters are listed old to new.
override fun chapterListParse(response: Response): List<SChapter> {
return super.chapterListParse(response).reversed()
}
override fun pageListParse(document: Document): List<Page> {
return document.select(pageListParseSelector)
.mapIndexed { index, element ->
// Had to add trim because of white space in source.
val imageUrl = element.select("img").attr("data-src").trim()
Page(index, document.location(), imageUrl)
}
}
}
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)) {
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)
}
}
class MiracleScans : Madara("Miracle Scans", "https://miraclescans.com", "en")
class Manhuasnet : Madara("Manhuas.net", "https://manhuas.net", "en")
class MangaTX : Madara("MangaTX", "https://mangatx.com", "en")
class OnManga : Madara("OnManga", "https://onmanga.com", "en")
class MangaAction : Madara("Manga Action", "https://manga-action.com", "ar", SimpleDateFormat("yyyy-MM-dd", Locale("ar")))
class NijiTranslations : Madara("Niji Translations", "https://niji-translations.com", "ar", SimpleDateFormat("MMMM dd, yyyy", Locale("ar")))
class LilyManga : Madara("Lily Manga", "https://lilymanga.com", "en", SimpleDateFormat("yyyy-MM-dd", Locale.US))
class MangaBob : Madara("MangaBob", "https://mangabob.com", "en")
class ThreeSixtyFiveManga : Madara("365Manga", "https://365manga.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)
}
class MangaDods : Madara("MangaDods", "https://www.mangadods.com", "en", SimpleDateFormat("yyyy-MM-dd", Locale.US))
class NeoxScanlator : Madara(
"Neox Scanlator",
"https://neoxscans.com",
"pt-BR",
SimpleDateFormat("dd/MM/yyyy", Locale("pt", "BR"))
) {
override val client: OkHttpClient = network.cloudflareClient.newBuilder()
.connectTimeout(1, TimeUnit.MINUTES)
.readTimeout(1, TimeUnit.MINUTES)
.build()
override fun headersBuilder(): Headers.Builder = Headers.Builder()
.add("User-Agent", USER_AGENT)
.add("Referer", baseUrl)
.add("Origin", baseUrl)
// Only status and order by filter work.
override fun getFilterList(): FilterList = FilterList(super.getFilterList().slice(3..4))
companion object {
private const val USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"
}
}
class MangaLord : Madara("Manga Lord", "https://mangalord.com", "en")
@Nsfw
class PornComix : Madara("PornComix", "https://www.porncomixonline.net", "en")
class PMScans : Madara("PMScans", "https://www.pmscans.com", "en", SimpleDateFormat("MMM-dd-yy", Locale.US))
class MangaRead : Madara("Manga Read", "https://mangaread.co", "en", SimpleDateFormat("yyyy-MM-dd", Locale.US))
class Manga68 : Madara("Manga68", "https://manga68.com", "en") {
override val pageListParseSelector = "div.page-break, div.text-left p"
}
class ManhuaBox : Madara("ManhuaBox", "https://manhuabox.net", "en") {
override val pageListParseSelector = "div.page-break, div.text-left p img"
}
class RaiderScans : Madara("Raider Scans", "https://raiderscans.com", "en")
class PojokManga : Madara("Pojok Manga", "https://pojokmanga.com", "id", SimpleDateFormat("MMM dd, yyyy", Locale.US))
class TopManhua : Madara("Top Manhua", "https://topmanhua.com", "en", SimpleDateFormat("MM/dd/yy", Locale.US)) {
override fun headersBuilder(): Headers.Builder = super.headersBuilder().add("Referer", baseUrl)
}
class ManyToonClub : Madara("ManyToonClub", "https://manytoon.club", "ko")
class ManhuaUS : Madara("ManhuaUS", "https://manhuaus.com", "en") {
override val pageListParseSelector = "li.blocks-gallery-item"
}
class MangaWT : Madara("MangaWT", "https://mangawt.com", "tr")
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)) {
override fun headersBuilder(): Headers.Builder = super.headersBuilder().add("Referer", baseUrl)
}
class ManhuasWorld : Madara("Manhuas World", "https://manhuasworld.com", "en")
class ManhwaRaw : Madara("Manhwa Raw", "https://manhwaraw.com", "ko")
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
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/manhua/manga/?m_orderby=latest", headers)
override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = GET("$baseUrl/manhua/?s=$query&post_type=wp-manga")
override fun searchMangaNextPageSelector(): String? = null
override fun getFilterList(): FilterList = FilterList()
}
@Nsfw
class MangaHentai : Madara("Manga Hentai", "https://mangahentai.me", "en")
class MangaPhoenix : Madara("Manga Diyari", "https://mangadiyari.com", "tr") {
// Formerly "Manga Phoenix"
override val id = 4308007020001642101
}
class MartialScans : Madara("Martial Scans", "https://martialscans.com", "en") {
override fun popularMangaFromElement(element: Element): SManga {
val manga = SManga.create()
with(element) {
select(popularMangaUrlSelector).last()?.let {
manga.setUrlWithoutDomain(it.attr("href"))
manga.title = it.ownText()
}
select("img").last()?.let {
manga.thumbnail_url = imageFromElement(it)
}
}
return manga
}
override fun searchMangaFromElement(element: Element): SManga = popularMangaFromElement(element)
}
class MangaYosh : Madara("MangaYosh", "https://mangayosh.xyz", "id", SimpleDateFormat("dd MMM yyyy", Locale.US))
class WebtoonXYZ : Madara("WebtoonXYZ", "https://www.webtoon.xyz", "en") {
private fun pagePath(page: Int) = if (page > 1) "page/$page/" else ""
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/webtoons/${pagePath(page)}?m_orderby=views", headers)
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/webtoons/${pagePath(page)}?m_orderby=latest", headers)
}
class MangaReadOrg : Madara("MangaRead.org", "https://www.mangaread.org", "en", SimpleDateFormat("dd.MM.yyy", Locale.US))
class TurkceManga : Madara("Türkçe Manga", "https://turkcemanga.com", "tr") {
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/page/$page/?s&post_type=wp-manga&m_orderby=views", headers)
override fun popularMangaSelector() = searchMangaSelector()
override fun popularMangaFromElement(element: Element): SManga = searchMangaFromElement(element)
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/page/$page/?s&post_type=wp-manga&m_orderby=latest", headers)
override fun latestUpdatesSelector() = searchMangaSelector()
override fun latestUpdatesFromElement(element: Element): SManga = searchMangaFromElement(element)
}
class Manga347 : Madara("Manga347", "https://manga347.com", "en", SimpleDateFormat("d MMM, yyyy", Locale.US)) {
override val pageListParseSelector = "li.blocks-gallery-item"
}
class RenaScans : Madara("Renascence Scans (Renascans)", "https://new.renascans.com", "en", SimpleDateFormat("dd/MM/yyyy", Locale.US))
class QueensManga : Madara("QueensManga ملكات المانجا", "https://queensmanga.com", "ar") {
override fun chapterListSelector(): String = "div.listing-chapters_wrap a"
}
class TheTopComic : Madara("TheTopComic", "https://thetopcomic.com", "en")
class WebNovel : Madara("WebNovel", "https://webnovel.live", "en")
class TruyenTranhAudioCom : Madara("TruyenTranhAudio.com", "https://truyentranhaudio.com", "vi", SimpleDateFormat("dd/MM/yyyy", Locale.getDefault())) {
override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/page/$page?s&post_type=wp-manga&m_orderby=views", headers)
override fun popularMangaSelector() = searchMangaSelector()
override fun popularMangaFromElement(element: Element): SManga = searchMangaFromElement(element)
override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/page/$page?s&post_type=wp-manga&m_orderby=latest", headers)
override fun latestUpdatesSelector() = searchMangaSelector()
override fun latestUpdatesFromElement(element: Element): SManga = searchMangaFromElement(element)
override fun pageListParse(document: Document): List<Page> {
return document.select("div.reading-content img").map { it.attr("abs:src") }
.filterNot { it.isNullOrEmpty() }
.distinct()
.mapIndexed { i, url -> Page(i, "", url) }
}
}
class TruyenTranhAudioOnline : Madara("TruyenTranhAudio.online", "https://truyentranhaudio.online", "vi", SimpleDateFormat("dd/MM/yyyy", Locale.getDefault())) {
override val formHeaders: Headers = headersBuilder()
.add("Content-Type", "application/x-www-form-urlencoded")
.build()
override fun pageListParse(document: Document): List<Page> {
return document.select("div.reading-content img").map { it.attr("abs:src") }
.filterNot { it.isNullOrEmpty() }
.distinct()
.mapIndexed { i, url -> Page(i, "", url) }
}
}
class MangaTurf : Madara("Manga Turf", "https://mangaturf.com", "en")
class Mangareceh : Madara("Mangareceh", "https://mangareceh.id", "id")
class ToonPoint : Madara("ToonPoint", "https://toonpoint.com", "en") {
override val userAgentRandomizer = ""
}
class MangaScantrad : Madara("Manga-Scantrad", "https://manga-scantrad.net", "fr", SimpleDateFormat("d MMM yyyy", Locale.FRANCE))
class ManhuaPlus : Madara("Manhua Plus", "https://manhuaplus.com", "en") {
override val pageListParseSelector = "li.blocks-gallery-item"
}
@Nsfw
class ToonilyNet : Madara("Toonily.net", "https://toonily.net", "en")
class TwilightScans : Madara("Twilight Scans", "https://twilightscans.com", "en")
// mostly novels
class WoopRead : Madara("WoopRead", "https://woopread.com", "en")
class Ninjavi : Madara("Ninjavi", "https://ninjavi.com", "ar")
class ManhwaTop : Madara("Manhwatop", "https://manhwatop.com", "en")
class Wakascan : Madara("Wakascan", "https://wakascan.com", "fr")
class ShoujoHearts : Madara("ShoujoHearts", "http://shoujohearts.com", "en") {
override fun popularMangaRequest(page: Int): Request =
POST("$baseUrl/reader/wp-admin/admin-ajax.php", formHeaders, formBuilder(page, true).build(), CacheControl.FORCE_NETWORK)
override fun latestUpdatesRequest(page: Int): Request =
POST("$baseUrl/reader/wp-admin/admin-ajax.php", formHeaders, formBuilder(page, false).build(), CacheControl.FORCE_NETWORK)
override fun searchPage(page: Int): String = "reader/page/$page/"
}
class OlaoeManga : Madara("مانجا اولاو", "https://olaoe.giize.com", "ar")
class OrigamiOrpheans : Madara("Origami Orpheans", "https://origami-orpheans.com.br", "pt-BR")
class MangaKiss : Madara("Manga Kiss", "https://mangakiss.org", "en")
class MangaRocky : Madara("Manga Rocky", "https://mangarocky.com", "en")
class S2Manga : Madara("S2Manga", "https://s2manga.com", "en")
class MangaLandArabic : Madara("Manga Land Arabic", "https://mangalandarabic.com", "ar")
class ProjetoScanlator : Madara("Projeto Scanlator", "https://projetoscanlator.com", "pt-BR", SimpleDateFormat("dd/MM/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)
override fun popularMangaNextPageSelector(): String? = null
override fun latestUpdatesNextPageSelector(): String? = null
}
class MangaSpark : Madara("MangaSpark", "https://mangaspark.com", "ar") {
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)?.replace("mangaspark", "mangalek")
}
}
return manga
}
}
class MangaStarz : Madara("Manga Starz", "https://mangastarz.com", "ar") {
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)?.replace("mangastarz", "mangalek")
}
}
return manga
}
}
class MysticalMerries : Madara("Mystical Merries", "https://mysticalmerries.com", "en") {
override fun popularMangaRequest(page: Int) = GET("$baseUrl/genre/manhwa/page/$page/?m_orderby=trending", headers)
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/genre/manhwa/page/$page/?m_orderby=latest", headers)
}
class MangaNine : Madara("Manga Nine", "https://manganine.com", "en")
class MarkScans : Madara("Mark Scans", "https://markscans.online", "pt-BR")
class YuriVerso : Madara(
"Yuri Verso",
"https://yuri.live",
"pt-BR",
SimpleDateFormat("dd/MM/yyyy", Locale("pt", "BR"))
)
class MangaStein : Madara("MangaStein", "https://mangastein.com", "tr")
class MangaTeca : Madara(
"MangaTeca",
"https://www.mangateca.com",
"pt-BR",
SimpleDateFormat("MMMM dd, yyyy", Locale("pt", "BR"))
) {
override fun headersBuilder(): Headers.Builder = Headers.Builder()
.add("User-Agent", USER_AGENT)
.add("Referer", baseUrl)
.add("Origin", baseUrl)
override fun chapterFromElement(element: Element): SChapter {
val parsedChapter = super.chapterFromElement(element)
parsedChapter.date_upload = element.select("img").firstOrNull()?.attr("alt")
?.let { parseChapterDate(it) }
?: parseChapterDate(element.select("span.chapter-release-date i").firstOrNull()?.text())
return parsedChapter
}
companion object {
private const val USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36"
}
}
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 UyuyanBalik : Madara("Uyuyan Balik", "https://uyuyanbalik.com/", "tr", SimpleDateFormat("dd MMMM yyyy", Locale.US))
class MangaWeebs : Madara("Manga Weebs", "https://mangaweebs.in", "en")
class MMScans : Madara("MMScans", "https://mm-scans.com/", "en")
@Nsfw
class Siyahmelek : Madara("Siyahmelek", "https://siyahmelek.com", "tr", SimpleDateFormat("dd MMM yyyy", Locale("tr")))
@Nsfw
class SekteDoujin : Madara("Sekte Doujin", "https://sektedoujin.xyz", "id")
class MundoWuxia : Madara("Mundo Wuxia", "https://mundowuxia.com", "es", SimpleDateFormat("MMMM dd, yyyy", Locale("es")))
class WorldRomanceTranslation : Madara("World Romance Translation", "https://wrt.my.id/", "id", SimpleDateFormat("dd MMMM yyyy", Locale("id")))
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")