Remove 78 broken extensions ()

* Remove Franxx Mangás - 403 Forbidden

* Remove MIC MIC IDOL - coming soon

* Remove Ler Yaoi - Connection timed out

* Remove Yaoi TR - Connection timed out

* Remove Hunlight Scans - Connection timed out

* Remove Manga Time - Connection timed out

* Remove Manga-Scan - Connection timed out

* Remove Momo no Hana Scan - Connection timed out

* Remove BlogTruyen.vn (unoriginal) - Connection timed out

* Remove MangaDoom - Connection timed out

* Remove MangaStorm - Connection timed out

* Remove Etheral Radiance - default cpanel

* Remove Moon Witch Scan - Domínio não encontrado

* Remove Hensekai - empty

* Remove Lunar Scans - empty

* Remove Tecno Scans - empty

* Remove Manga-Titan - empty

* Remove Lich Subs - empty

* Remove Lector Online - for sale

* Remove I Love Manhwa - Invalid SSL certificate

* Remove ManhwaNew - Invalid SSL certificate

* Remove MangaRolls - Invalid SSL certificate

* Remove Ladron Corps - Looks like this domain isn't connected to a website yet

* Remove Kishisan - no A record

* Remove MELOKOMIK - no A record

* Remove Comic Fans - no A record

* Remove MMFenix - no A record

* Remove Manga Bari - Not Found

* Remove GMANGA (unoriginal) - Origin is unreachable

* Remove ComicExtra - Origin is unreachable

* Remove Nabi Scans - Origin is unreachable

Closes 

* Remove MangaCV - Origin is unreachable

* Remove Fay Scans - parked

* Remove Manga-fast.com - parked

* Remove Cookie Kiara - parked

* Remove Pink Tea Comic - parked

* Remove Riot Hentai - parked

* Remove Read Goblin Slayer Manga Online - parked

* Remove Mystical Merries - parked

* Remove CopyPasteScan - parked

* Remove ManhuaChill - parked

* Remove Lolicon - parked

* Remove Mystic Moon - parked

* Remove Manga68 - parked

* Remove MyRockManga - parked

* Remove Manhua Kiss - parked

* Remove AscalonScans - parked

* Remove Doujins.lat - parked

* Remove Komik Pix - parked

* Remove MirrorDesu - parked

* Remove SISI GELAP - parked

* Remove Komiksan - parked

* Remove Pian Manga - parked

* Remove Sekaikomik - parked

* Remove My Manhwa - parked

* Remove 1st Kiss-Manga (unoriginal) - parked

* Remove Lady Manga - parked

* Remove Mangá Kun - SSL handshake failed

* Remove Oh No Manga - The connection has timed out

* Remove Dark-Scan.com - The connection has timed out

* Remove Babel Wuxia - The connection has timed out

* Remove Mangazavr - The connection has timed out

* Remove Read Noblesse Manhwa Online - Unable to connect

* Remove Nirvana Scan - Unable to connect

* Remove Mantraz Scan - Unable to connect

* Remove SCARManga - Unable to connect

* Remove Gatemanga - unrelated

* Remove ManhwaBookShelf - unrelated

* Remove Read Tower of God Manhwa Manga Online - unrelated

* Remove Kofi Scans - Web server is down

* Remove Nyrax Manga - Web server is down

* Remove YD-Comics - Web server is down

* Remove AnonimusTLS - Web server is down

* Remove Mangaland - Website not found...

* Remove MangaNoon - We're having trouble finding that site

Closes 

* Remove NoonScan - We're having trouble finding that site

Closes 

* Remove SobatManKu - Your domain is expired

* Remove Comic 21 - Your domain is expired
This commit is contained in:
Vetle Ledaal 2025-02-19 08:20:02 +01:00 committed by Draff
parent 94603b3843
commit 10aa286c04
No known key found for this signature in database
GPG Key ID: E8A89F3211677653
526 changed files with 0 additions and 3835 deletions
src
all/myrockmanga
build.gradle
res
mipmap-hdpi
mipmap-mdpi
mipmap-xhdpi
mipmap-xxhdpi
mipmap-xxxhdpi
src/eu/kanade/tachiyomi/extension/all/myrockmanga
ar
aresnov
build.gradle
res
mipmap-hdpi
mipmap-mdpi
mipmap-xhdpi
mipmap-xxhdpi
mipmap-xxxhdpi
src/eu/kanade/tachiyomi/extension/ar/aresnov
gatemanga
build.gradle
res
mipmap-hdpi
mipmap-mdpi
mipmap-xhdpi
mipmap-xxhdpi
mipmap-xxxhdpi
src/eu/kanade/tachiyomi/extension/ar/gatemanga
gmangasite
build.gradle
res
mipmap-hdpi
mipmap-mdpi
mipmap-xhdpi
mipmap-xxhdpi
mipmap-xxxhdpi
src/eu/kanade/tachiyomi/extension/ar/gmangasite
manganoon
build.gradle
res
mipmap-hdpi
mipmap-mdpi
mipmap-xhdpi
mipmap-xxhdpi
mipmap-xxxhdpi
src/eu/kanade/tachiyomi/extension/ar/manganoon
mangastorm
build.gradle
res
mipmap-hdpi
mipmap-mdpi
mipmap-xhdpi
mipmap-xxhdpi
mipmap-xxxhdpi
src/eu/kanade/tachiyomi/extension/ar/mangastorm
mangatime
build.gradle
res
mipmap-hdpi
mipmap-mdpi
mipmap-xhdpi
mipmap-xxhdpi
mipmap-xxxhdpi
src/eu/kanade/tachiyomi/extension/ar/mangatime
noonscan
build.gradle
res
mipmap-hdpi
mipmap-mdpi
mipmap-xhdpi
mipmap-xxhdpi
mipmap-xxxhdpi
src/eu/kanade/tachiyomi/extension/ar/noonscan
en
ascalonscans
build.gradle
res
mipmap-hdpi
mipmap-mdpi
mipmap-xhdpi
mipmap-xxhdpi
mipmap-xxxhdpi
src/eu/kanade/tachiyomi/extension/en/ascalonscans
babelwuxia
build.gradle
res
mipmap-hdpi
mipmap-mdpi
mipmap-xhdpi
mipmap-xxhdpi
mipmap-xxxhdpi
src/eu/kanade/tachiyomi/extension/en/babelwuxia
comicextra
build.gradle
res
mipmap-hdpi
mipmap-mdpi
mipmap-xhdpi
mipmap-xxhdpi
mipmap-xxxhdpi
src/eu/kanade/tachiyomi/extension/en/comicextra
comicfans
build.gradle
res
mipmap-hdpi
mipmap-mdpi
mipmap-xhdpi
mipmap-xxhdpi
mipmap-xxxhdpi
src/eu/kanade/tachiyomi/extension/en/comicfans
cookiekiara
build.gradle
res
mipmap-hdpi
mipmap-mdpi
mipmap-xhdpi
mipmap-xxhdpi
mipmap-xxxhdpi
src/eu/kanade/tachiyomi/extension/en/cookiekiara
darkscancom
build.gradle
res
mipmap-hdpi
mipmap-mdpi
mipmap-xhdpi
mipmap-xxhdpi
mipmap-xxxhdpi
src/eu/kanade/tachiyomi/extension/en/darkscancom

@ -1,10 +0,0 @@
ext {
extName = 'MyRockManga'
extClass = '.MyRockMangaFactory'
themePkg = 'otakusanctuary'
baseUrl = 'https://myrockmanga.com'
overrideVersionCode = 0
isNsfw = true
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

Before

(image error) Size: 5.7 KiB

Binary file not shown.

Before

(image error) Size: 2.9 KiB

Binary file not shown.

Before

(image error) Size: 9.0 KiB

Binary file not shown.

Before

(image error) Size: 18 KiB

Binary file not shown.

Before

(image error) Size: 30 KiB

@ -1,14 +0,0 @@
package eu.kanade.tachiyomi.extension.all.myrockmanga
import eu.kanade.tachiyomi.multisrc.otakusanctuary.OtakuSanctuary
import eu.kanade.tachiyomi.source.SourceFactory
class MyRockMangaFactory : SourceFactory {
override fun createSources() = listOf(
OtakuSanctuary("MyRockManga", "https://myrockmanga.com", "all"),
OtakuSanctuary("MyRockManga", "https://myrockmanga.com", "vi"),
OtakuSanctuary("MyRockManga", "https://myrockmanga.com", "en"),
OtakuSanctuary("MyRockManga", "https://myrockmanga.com", "it"),
OtakuSanctuary("MyRockManga", "https://myrockmanga.com", "es"),
)
}

@ -1,9 +0,0 @@
ext {
extName = 'SCARManga'
extClass = '.ScarManga'
themePkg = 'mangathemesia'
baseUrl = 'https://scarmanga.com'
overrideVersionCode = 2
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

Before

(image error) Size: 8.1 KiB

Binary file not shown.

Before

(image error) Size: 4.0 KiB

Binary file not shown.

Before

(image error) Size: 13 KiB

Binary file not shown.

Before

(image error) Size: 27 KiB

Binary file not shown.

Before

(image error) Size: 43 KiB

@ -1,15 +0,0 @@
package eu.kanade.tachiyomi.extension.ar.aresnov
import eu.kanade.tachiyomi.multisrc.mangathemesia.MangaThemesia
import java.text.SimpleDateFormat
import java.util.Locale
class ScarManga : MangaThemesia(
"SCARManga",
"https://scarmanga.com",
"ar",
mangaUrlDirectory = "/series",
dateFormat = SimpleDateFormat("MMMMM dd, yyyy", Locale("ar")),
) {
override val id = 1046935749022479891
}

@ -1,9 +0,0 @@
ext {
extName = 'Gatemanga'
extClass = '.Gatemanga'
themePkg = 'madara'
baseUrl = 'https://gatemanga.com'
overrideVersionCode = 2
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

Before

(image error) Size: 7.0 KiB

Binary file not shown.

Before

(image error) Size: 3.5 KiB

Binary file not shown.

Before

(image error) Size: 9.4 KiB

Binary file not shown.

Before

(image error) Size: 18 KiB

Binary file not shown.

Before

(image error) Size: 26 KiB

@ -1,14 +0,0 @@
package eu.kanade.tachiyomi.extension.ar.gatemanga
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class Gatemanga : Madara(
"Gatemanga",
"https://gatemanga.com",
"ar",
dateFormat = SimpleDateFormat("d MMMM، yyyy", Locale("ar")),
) {
override val mangaSubString = "ar"
}

@ -1,9 +0,0 @@
ext {
extName = 'GMANGA (unoriginal)'
extClass = '.GmangaSite'
themePkg = 'madara'
baseUrl = 'https://gmanga.site'
overrideVersionCode = 0
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

Before

(image error) Size: 4.9 KiB

Binary file not shown.

Before

(image error) Size: 2.6 KiB

Binary file not shown.

Before

(image error) Size: 6.8 KiB

Binary file not shown.

Before

(image error) Size: 13 KiB

Binary file not shown.

Before

(image error) Size: 18 KiB

@ -1,16 +0,0 @@
package eu.kanade.tachiyomi.extension.ar.gmangasite
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class GmangaSite : Madara(
"GMANGA (unoriginal)",
"https://gmanga.site",
"ar",
dateFormat = SimpleDateFormat("MMMM dd، yyyy", Locale("ar")),
) {
override val chapterUrlSuffix = ""
override val useLoadMoreRequest = LoadMoreStrategy.Always
override val useNewChapterEndpoint = true
}

@ -1,10 +0,0 @@
ext {
extName = 'MangaNoon'
extClass = '.MangaNoon'
themePkg = 'mangathemesia'
baseUrl = 'https://vrnoin.site'
overrideVersionCode = 8
isNsfw = false
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

Before

(image error) Size: 6.8 KiB

Binary file not shown.

Before

(image error) Size: 3.5 KiB

Binary file not shown.

Before

(image error) Size: 11 KiB

Binary file not shown.

Before

(image error) Size: 22 KiB

Binary file not shown.

Before

(image error) Size: 36 KiB

@ -1,89 +0,0 @@
package eu.kanade.tachiyomi.extension.ar.manganoon
import eu.kanade.tachiyomi.multisrc.mangathemesia.MangaThemesia
import eu.kanade.tachiyomi.source.model.SChapter
import org.jsoup.nodes.Element
import java.util.Calendar
class MangaNoon : MangaThemesia(
"مانجا نون",
"https://vrnoin.site",
"ar",
) {
override fun chapterFromElement(element: Element): SChapter {
return super.chapterFromElement(element).apply {
date_upload = element.selectFirst(".chapterdate")?.text().parseChapterDate()
}
}
// From Galaxy
override fun String?.parseChapterDate(): Long {
this ?: return 0L
val number = Regex("""(\d+)""").find(this)?.value?.toIntOrNull() ?: 0
val cal = Calendar.getInstance()
return when {
listOf("second", "ثانية").any { contains(it, true) } -> {
cal.apply { add(Calendar.SECOND, -number) }.timeInMillis
}
contains("دقيقتين", true) -> {
cal.apply { add(Calendar.MINUTE, -2) }.timeInMillis
}
listOf("minute", "دقائق").any { contains(it, true) } -> {
cal.apply { add(Calendar.MINUTE, -number) }.timeInMillis
}
contains("ساعتان", true) -> {
cal.apply { add(Calendar.HOUR, -2) }.timeInMillis
}
listOf("hour", "ساعات").any { contains(it, true) } -> {
cal.apply { add(Calendar.HOUR, -number) }.timeInMillis
}
contains("يوم", true) -> {
cal.apply { add(Calendar.DAY_OF_YEAR, -1) }.timeInMillis
}
contains("يومين", true) -> {
cal.apply { add(Calendar.DAY_OF_YEAR, -2) }.timeInMillis
}
listOf("day", "أيام").any { contains(it, true) } -> {
cal.apply { add(Calendar.DAY_OF_YEAR, -number) }.timeInMillis
}
contains("أسبوع", true) -> {
cal.apply { add(Calendar.WEEK_OF_YEAR, -1) }.timeInMillis
}
contains("أسبوعين", true) -> {
cal.apply { add(Calendar.WEEK_OF_YEAR, -2) }.timeInMillis
}
listOf("week", "أسابيع").any { contains(it, true) } -> {
cal.apply { add(Calendar.WEEK_OF_YEAR, -number) }.timeInMillis
}
contains("شهر", true) -> {
cal.apply { add(Calendar.MONTH, -1) }.timeInMillis
}
contains("شهرين", true) -> {
cal.apply { add(Calendar.MONTH, -2) }.timeInMillis
}
listOf("month", "أشهر").any { contains(it, true) } -> {
cal.apply { add(Calendar.MONTH, -number) }.timeInMillis
}
contains("سنة", true) -> {
cal.apply { add(Calendar.YEAR, -1) }.timeInMillis
}
contains("سنتان", true) -> {
cal.apply { add(Calendar.YEAR, -2) }.timeInMillis
}
listOf("year", "سنوات").any { contains(it, true) } -> {
cal.apply { add(Calendar.YEAR, -number) }.timeInMillis
}
else -> 0L
}
}
}

@ -1,11 +0,0 @@
ext {
extName = 'MangaStorm'
extClass = '.MangaStorm'
extVersionCode = 1
}
apply from: "$rootDir/common.gradle"
dependencies {
implementation(project(":lib:randomua"))
}

Binary file not shown.

Before

(image error) Size: 4.5 KiB

Binary file not shown.

Before

(image error) Size: 2.4 KiB

Binary file not shown.

Before

(image error) Size: 6.4 KiB

Binary file not shown.

Before

(image error) Size: 12 KiB

Binary file not shown.

Before

(image error) Size: 17 KiB

@ -1,105 +0,0 @@
package eu.kanade.tachiyomi.extension.ar.mangastorm
import eu.kanade.tachiyomi.lib.randomua.UserAgentType
import eu.kanade.tachiyomi.lib.randomua.setRandomUserAgent
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Request
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import java.lang.UnsupportedOperationException
class MangaStorm : ParsedHttpSource() {
override val name = "MangaStorm"
override val lang = "ar"
override val baseUrl = "https://mangastorm.org"
override val supportsLatest = true
override val client = network.cloudflareClient.newBuilder()
.setRandomUserAgent(
UserAgentType.DESKTOP,
filterInclude = listOf("chrome"),
)
.build()
override fun headersBuilder() = super.headersBuilder()
.set("Referer", "$baseUrl/")
override fun popularMangaRequest(page: Int): Request {
return GET("$baseUrl/mangas?page=$page", headers)
}
override fun popularMangaSelector() = "div.row div.col"
override fun popularMangaNextPageSelector() = ".page-link[rel=next]"
override fun popularMangaFromElement(element: Element) = SManga.create().apply {
setUrlWithoutDomain(element.selectFirst("a")!!.absUrl("href"))
title = element.select(".manga-ct-title").text()
thumbnail_url = element.selectFirst("img")?.imgAttr()
}
override fun latestUpdatesRequest(page: Int): Request {
return GET(baseUrl, headers)
}
override fun latestUpdatesSelector() = popularMangaSelector()
override fun latestUpdatesNextPageSelector() = null
override fun latestUpdatesFromElement(element: Element) = popularMangaFromElement(element)
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = "$baseUrl/mangas".toHttpUrl().newBuilder()
.addQueryParameter("page", page.toString())
.addQueryParameter("query", query.trim())
.build()
return GET(url, headers)
}
override fun searchMangaSelector() = popularMangaSelector()
override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
override fun searchMangaFromElement(element: Element) = popularMangaFromElement(element)
override fun mangaDetailsParse(document: Document): SManga {
val root = document.selectFirst(".card-body .col-lg-9")!!
return SManga.create().apply {
title = document.select(".card-header").text()
thumbnail_url = document.selectFirst("img.card-img-right")?.imgAttr()
genre = root.select(".flex-wrap a").eachText().joinToString()
description = root.selectFirst(".card-text")?.text()
}
}
override fun chapterListSelector() = ".card-body a.btn-fixed-width"
override fun chapterFromElement(element: Element) = SChapter.create().apply {
setUrlWithoutDomain(element.absUrl("href"))
name = element.text()
}
override fun pageListParse(document: Document): List<Page> {
return document.select("div.text-center .img-fluid")
.mapIndexed { idx, img ->
Page(idx, "", img.imgAttr())
}
}
override fun imageUrlParse(document: Document) = throw UnsupportedOperationException()
private fun Element.imgAttr() = when {
hasAttr("data-cfsrc") -> attr("abs:data-cfsrc")
hasAttr("data-src") -> attr("abs:data-src")
hasAttr("data-lazy-src") -> attr("abs:data-lazy-src")
hasAttr("srcset") -> attr("abs:srcset").substringBefore(" ")
else -> attr("abs:src")
}
}

@ -1,10 +0,0 @@
ext {
extName = 'Manga Time'
extClass = '.MangaTime'
themePkg = 'madara'
baseUrl = 'https://mangatime.us'
overrideVersionCode = 1
isNsfw = false
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

Before

(image error) Size: 4.0 KiB

Binary file not shown.

Before

(image error) Size: 2.2 KiB

Binary file not shown.

Before

(image error) Size: 5.3 KiB

Binary file not shown.

Before

(image error) Size: 9.5 KiB

Binary file not shown.

Before

(image error) Size: 13 KiB

@ -1,15 +0,0 @@
package eu.kanade.tachiyomi.extension.ar.mangatime
import eu.kanade.tachiyomi.multisrc.madara.Madara
import java.text.SimpleDateFormat
import java.util.Locale
class MangaTime : Madara(
"Manga Time",
"https://mangatime.us",
"ar",
dateFormat = SimpleDateFormat("dd MMMM، yyyy", Locale("ar")),
) {
override val useLoadMoreRequest = LoadMoreStrategy.Always
override val useNewChapterEndpoint = true
}

@ -1,10 +0,0 @@
ext {
extName = 'NoonScan'
extClass = '.NoonScan'
themePkg = 'mangathemesia'
baseUrl = 'https://noonscan.com'
overrideVersionCode = 0
isNsfw = false
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

Before

(image error) Size: 6.9 KiB

Binary file not shown.

Before

(image error) Size: 3.4 KiB

Binary file not shown.

Before

(image error) Size: 12 KiB

Binary file not shown.

Before

(image error) Size: 25 KiB

Binary file not shown.

Before

(image error) Size: 43 KiB

@ -1,12 +0,0 @@
package eu.kanade.tachiyomi.extension.ar.noonscan
import eu.kanade.tachiyomi.multisrc.mangathemesia.MangaThemesia
import java.text.SimpleDateFormat
import java.util.Locale
class NoonScan : MangaThemesia(
"نون سكان",
"https://noonscan.com",
"ar",
dateFormat = SimpleDateFormat("MMMM d, yyyy", Locale("ar")),
)

@ -1,9 +0,0 @@
ext {
extName = 'AscalonScans'
extClass = '.AscalonScans'
themePkg = 'mangathemesia'
baseUrl = 'https://ascalonscans.com'
overrideVersionCode = 1
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

Before

(image error) Size: 4.4 KiB

Binary file not shown.

Before

(image error) Size: 2.3 KiB

Binary file not shown.

Before

(image error) Size: 7.0 KiB

Binary file not shown.

Before

(image error) Size: 13 KiB

Binary file not shown.

Before

(image error) Size: 22 KiB

@ -1,55 +0,0 @@
package eu.kanade.tachiyomi.extension.en.ascalonscans
import eu.kanade.tachiyomi.multisrc.mangathemesia.MangaThemesia
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.interceptor.rateLimitHost
import okhttp3.FormBody
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Interceptor
import okhttp3.Response
import java.io.IOException
import java.security.MessageDigest
class AscalonScans : MangaThemesia("AscalonScans", "https://ascalonscans.com", "en") {
override val client = super.client.newBuilder()
.rateLimitHost(baseUrl.toHttpUrl(), 2)
.addInterceptor(::jsChallengeInterceptor)
.build()
private fun jsChallengeInterceptor(chain: Interceptor.Chain): Response {
val request = chain.request()
val origRes = chain.proceed(request)
if (origRes.code != 403) return origRes
origRes.close()
// Same delay as the source
Thread.sleep(3000L)
val token = fetchToken(chain).sha256()
val body = FormBody.Builder().add("challenge", token).build()
val challengeReq = POST("$baseUrl/hcdn-cgi/jschallenge-validate", headers, body = body)
val challengeResponse = chain.proceed(challengeReq)
challengeResponse.close()
if (challengeResponse.code != 200) throw IOException("Failed to bypass js challenge!")
return chain.proceed(request)
}
private tailrec fun fetchToken(chain: Interceptor.Chain, attempt: Int = 0): String {
if (attempt > 5) throw IOException("Failed to fetch challenge token!")
val request = GET("$baseUrl/hcdn-cgi/jschallenge", headers)
val res = chain.proceed(request).body.string()
return res.substringAfter("cjs = '").substringBefore("'")
.takeUnless { it == "nil" } ?: fetchToken(chain, attempt + 1)
}
private fun String.sha256(): String {
return MessageDigest
.getInstance("SHA-256")
.digest(toByteArray())
.fold("", { str, it -> str + "%02x".format(it) })
}
}

@ -1,9 +0,0 @@
ext {
extName = 'Babel Wuxia'
extClass = '.BabelWuxia'
themePkg = 'madara'
baseUrl = 'https://babelwuxia.com'
overrideVersionCode = 1
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

Before

(image error) Size: 4.0 KiB

Binary file not shown.

Before

(image error) Size: 2.0 KiB

Binary file not shown.

Before

(image error) Size: 5.4 KiB

Binary file not shown.

Before

(image error) Size: 11 KiB

Binary file not shown.

Before

(image error) Size: 17 KiB

@ -1,11 +0,0 @@
package eu.kanade.tachiyomi.extension.en.babelwuxia
import eu.kanade.tachiyomi.multisrc.madara.Madara
class BabelWuxia : Madara("Babel Wuxia", "https://babelwuxia.com", "en") {
// moved from MangaThemesia
override val versionId = 2
override val useNewChapterEndpoint = true
override val useLoadMoreRequest = LoadMoreStrategy.Always
}

@ -1,7 +0,0 @@
ext {
extName = 'ComicExtra'
extClass = '.ComicExtra'
extVersionCode = 17
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

Before

(image error) Size: 2.7 KiB

Binary file not shown.

Before

(image error) Size: 1.5 KiB

Binary file not shown.

Before

(image error) Size: 3.0 KiB

Binary file not shown.

Before

(image error) Size: 5.5 KiB

Binary file not shown.

Before

(image error) Size: 6.7 KiB

@ -1,243 +0,0 @@
package eu.kanade.tachiyomi.extension.en.comicextra
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.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.HttpUrl.Companion.toHttpUrl
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.ArrayList
import java.util.Date
import java.util.Locale
class ComicExtra : ParsedHttpSource() {
override val name = "ComicExtra"
override val baseUrl = "https://azcomix.me"
override val lang = "en"
override val supportsLatest = true
override val client: OkHttpClient = network.cloudflareClient
override fun popularMangaSelector() = "div.eg-box"
override fun latestUpdatesSelector() = "ul.line-list"
override fun popularMangaRequest(page: Int) = GET("$baseUrl/popular-comics?page=$page", headers)
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/comic-updates?page=$page", headers)
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = "$baseUrl/advanced-search".toHttpUrl().newBuilder().apply {
if (query.isNotBlank()) addQueryParameter("key", query)
if (page > 1) addQueryParameter("page", page.toString())
filters.forEach { filter ->
when (filter) {
is GenreGroupFilter -> {
with(filter) {
addQueryParameter("wg", included.joinToString("%20"))
addQueryParameter("wog", excluded.joinToString("%20"))
}
}
is StatusFilter -> addQueryParameter("status", filter.selected)
else -> {}
}
}
}.build()
return GET(url, headers)
}
override fun popularMangaFromElement(element: Element) = SManga.create().apply {
setUrlWithoutDomain(element.selectFirst("a.eg-image")!!.absUrl("href"))
title = element.selectFirst("div.egb-right a")!!.text()
element.selectFirst("img")?.also { thumbnail_url = it.absUrl("src") }
}
override fun latestUpdatesFromElement(element: Element) = SManga.create().apply {
setUrlWithoutDomain(element.selectFirst("a.big-link")!!.absUrl("href"))
title = element.selectFirst(".big-link")!!.text()
thumbnail_url = "https://azcomix.me/images/sites/default.jpg"
}
override fun popularMangaNextPageSelector() = "div.general-nav > a:contains(Next)"
override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector()
override fun searchMangaSelector() = "div.dl-box"
override fun searchMangaFromElement(element: Element) = SManga.create().apply {
setUrlWithoutDomain(element.selectFirst("a.dlb-image")!!.absUrl("href"))
title = element.selectFirst("div.dlb-right a.dlb-title")!!.text()
element.selectFirst("a.dlb-image img")?.also { thumbnail_url = it.absUrl("src") }
}
override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
override fun mangaDetailsParse(document: Document): SManga {
return SManga.create().apply {
title = document.selectFirst("h1")!!.text()
thumbnail_url = document.selectFirst("div.anime-image > img")?.absUrl("src")
document.selectFirst(".status a")?.also { status = parseStatus(it.text()) }
document.selectFirst("td:contains(Author:) + td")?.also { author = it.text() }
document.selectFirst("div.detail-desc-content p")?.also { description = it.text() }
genre = document.select("ul.anime-genres > li + li").joinToString { it.text() }
}
}
private fun parseStatus(element: String): Int = when {
element.contains("Completed") -> SManga.COMPLETED
element.contains("Ongoing") -> SManga.ONGOING
else -> SManga.UNKNOWN
}
override fun chapterListParse(response: Response): List<SChapter> {
val document = response.asJsoup()
val chapters = ArrayList<SChapter>()
document.select(chapterListSelector()).forEach {
chapters.add(chapterFromElement(it))
}
return chapters
}
override fun chapterListSelector() = "ul.basic-list li"
override fun chapterFromElement(element: Element): SChapter {
val urlEl = element.selectFirst("a")
val dateEl = element.selectFirst("span")
return SChapter.create().apply {
urlEl!!.also {
setUrlWithoutDomain(it.absUrl("href").replace(" ", "%20"))
name = it.text()
}
dateEl?.also { date_upload = dateParse(it.text()) }
}
}
private fun dateParse(dateAsString: String): Long {
val date: Date? = SimpleDateFormat("MM/dd/yy", Locale.ENGLISH).parse(dateAsString)
return date?.time ?: 0L
}
override fun pageListRequest(chapter: SChapter): Request {
return GET(baseUrl + chapter.url + "/full", headers)
}
override fun pageListParse(document: Document): List<Page> {
val pages = mutableListOf<Page>()
document.select("div.chapter-container img").forEachIndexed { i, img ->
pages.add(Page(i, "", img.absUrl("src")))
}
return pages
}
override fun imageUrlParse(document: Document) = throw UnsupportedOperationException()
// Filters
override fun getFilterList() = FilterList(
Filter.Header("Note: can't leave both filters as default with a blank search string"),
Filter.Separator(),
StatusFilter(getStatusList, 0),
GenreGroupFilter(getGenreList()),
)
class SelectFilterOption(val name: String, val value: String)
class TriStateFilterOption(val value: String, name: String, default: Int = 0) : Filter.TriState(name, default)
abstract class SelectFilter(name: String, private val options: List<SelectFilterOption>, default: Int = 0) : Filter.Select<String>(name, options.map { it.name }.toTypedArray(), default) {
val selected: String
get() = options[state].value
}
abstract class TriStateGroupFilter(name: String, options: List<TriStateFilterOption>) : Filter.Group<TriStateFilterOption>(name, options) {
val included: List<String>
get() = state.filter { it.isIncluded() }.map { it.value }
val excluded: List<String>
get() = state.filter { it.isExcluded() }.map { it.value }
}
class StatusFilter(options: List<SelectFilterOption>, default: Int) : SelectFilter("Status", options, default)
class GenreGroupFilter(options: List<TriStateFilterOption>) : TriStateGroupFilter("Genre", options)
private val getStatusList = listOf(
SelectFilterOption("All", ""),
SelectFilterOption("Ongoing", "ONG"),
SelectFilterOption("Completed", "CMP"),
)
private fun getGenreList() = listOf(
TriStateFilterOption("Action", "Action"),
TriStateFilterOption("Adventure", "Adventure"),
TriStateFilterOption("Anthology", "Anthology"),
TriStateFilterOption("Anthropomorphic", "Anthropomorphic"),
TriStateFilterOption("Biography", "Biography"),
TriStateFilterOption("Children", "Children"),
TriStateFilterOption("Comedy", "Comedy"),
TriStateFilterOption("Crime", "Crime"),
TriStateFilterOption("Cyborgs", "Cyborgs"),
TriStateFilterOption("DC Comics", "DC Comics"),
TriStateFilterOption("Dark Horse", "Dark Horse"),
TriStateFilterOption("Demons", "Demons"),
TriStateFilterOption("Drama", "Drama"),
TriStateFilterOption("Family", "Family"),
TriStateFilterOption("Fantasy", "Fantasy"),
TriStateFilterOption("Fighting", "Fighting"),
TriStateFilterOption("Gore", "Gore"),
TriStateFilterOption("Graphic Novels", "Graphic Novels"),
TriStateFilterOption("Historical", "Historical"),
TriStateFilterOption("Horror", "Horror"),
TriStateFilterOption("Leading Ladies", "Leading Ladies"),
TriStateFilterOption("Literature", "Literature"),
TriStateFilterOption("Magic", "Magic"),
TriStateFilterOption("Manga", "Manga"),
TriStateFilterOption("Martial Arts", "Martial Arts"),
TriStateFilterOption("Marvel", "Marvel"),
TriStateFilterOption("Mature", "Mature"),
TriStateFilterOption("Mecha", "Mecha"),
TriStateFilterOption("Military", "Military"),
TriStateFilterOption("Movie Cinematic Link", "Movie Cinematic Link"),
TriStateFilterOption("Mystery", "Mystery"),
TriStateFilterOption("Mythology", "Mythology"),
TriStateFilterOption("Personal", "Personal"),
TriStateFilterOption("Political", "Political"),
TriStateFilterOption("Post-Apocalyptic", "Post-Apocalyptic"),
TriStateFilterOption("Psychological", "Psychological"),
TriStateFilterOption("Pulp", "Pulp"),
TriStateFilterOption("Robots", "Robots"),
TriStateFilterOption("Romance", "Romance"),
TriStateFilterOption("Sci-Fi", "Sci-Fi"),
TriStateFilterOption("Science Fiction", "Science Fiction"),
TriStateFilterOption("Slice of Life", "Slice of Life"),
TriStateFilterOption("Sports", "Sports"),
TriStateFilterOption("Spy", "Spy"),
TriStateFilterOption("Superhero", "Superhero"),
TriStateFilterOption("Supernatural", "Supernatural"),
TriStateFilterOption("Suspense", "Suspense"),
TriStateFilterOption("Thriller", "Thriller"),
TriStateFilterOption("Tragedy", "Tragedy"),
TriStateFilterOption("Vampires", "Vampires"),
TriStateFilterOption("Vertigo", "Vertigo"),
TriStateFilterOption("Video Games", "Video Games"),
TriStateFilterOption("War", "War"),
TriStateFilterOption("Western", "Western"),
TriStateFilterOption("Zombies", "Zombies"),
)
}

@ -1,7 +0,0 @@
ext {
extName = 'Comic Fans'
extClass = '.ComicFans'
extVersionCode = 1
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

Before

(image error) Size: 5.0 KiB

Binary file not shown.

Before

(image error) Size: 2.4 KiB

Binary file not shown.

Before

(image error) Size: 7.9 KiB

Binary file not shown.

Before

(image error) Size: 15 KiB

Binary file not shown.

Before

(image error) Size: 24 KiB

@ -1,205 +0,0 @@
package eu.kanade.tachiyomi.extension.en.comicfans
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.interceptor.rateLimit
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.HttpSource
import eu.kanade.tachiyomi.util.asJsoup
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.put
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import uy.kohesive.injekt.injectLazy
class ComicFans : HttpSource() {
override val name = "Comic Fans"
override val baseUrl = "https://comicfans.io"
private val apiUrl = "https://api.comicfans.io/comic-backend/api/v1/content"
private val cdnUrl = "https://static.comicfans.io"
override val lang = "en"
override val supportsLatest = true
override val client = network.cloudflareClient.newBuilder()
.rateLimit(2)
.build()
override fun headersBuilder() = super.headersBuilder()
.add("Referer", "$baseUrl/")
private fun apiHeadersBuilder() = headersBuilder().apply {
add("Accept", "*/*")
add("Host", apiUrl.toHttpUrl().host)
add("Origin", baseUrl)
add("site-domain", "www.${baseUrl.toHttpUrl().host}")
}
private val apiHeaders by lazy { apiHeadersBuilder().build() }
private val json: Json by injectLazy()
// ============================== Popular ===============================
override fun popularMangaRequest(page: Int): Request {
val body = buildJsonObject {
put("conditionJson", "{\"title\":\"You may also like\",\"maxSize\":15}")
put("pageNumber", page)
put("pageSize", 30)
}.let(json::encodeToString).toRequestBody("application/json; charset=utf-8".toMediaTypeOrNull())
val popularHeaders = apiHeadersBuilder().apply {
set("Accept", "application/json")
}.build()
return POST("$apiUrl/books/custom/MostPopularLocal#$page", popularHeaders, body)
}
override fun popularMangaParse(response: Response): MangasPage {
val data = response.parseAs<ListDataDto<MangaDto>>().data
val hasNextPage = response.request.url.fragment!!.toInt() < data.totalPages
return MangasPage(data.list.map { it.toSManga(cdnUrl) }, hasNextPage)
}
// =============================== Latest ===============================
override fun latestUpdatesRequest(page: Int): Request = GET(baseUrl, headers)
override fun latestUpdatesParse(response: Response): MangasPage {
val document = response.asJsoup()
val mangaList = document.select(
"div:has(>.block-title-bar > .title:contains(New Updates))" +
"> .book-container > .book",
).map { element ->
SManga.create().apply {
thumbnail_url = element.selectFirst("img")!!.attr("abs:src")
with(element.selectFirst(".book-name > a")!!) {
title = text()
setUrlWithoutDomain(attr("abs:href"))
}
}
}
return MangasPage(mangaList, false)
}
// =============================== Search ===============================
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = "$apiUrl/books".toHttpUrl().newBuilder().apply {
addQueryParameter("pageNumber", page.toString())
addQueryParameter("pageSize", "20")
fragment(page.toString())
if (query.isNotBlank()) {
addPathSegment("search")
addQueryParameter("keyWord", query)
} else {
filters.getUriPart<GenreFilter>()?.let {
addQueryParameter("genre", it)
}
filters.getUriPart<LastUpdateFilter>()?.let {
addQueryParameter("withinDay", it)
}
filters.getUriPart<StatusFilter>()?.let {
addQueryParameter("status", it)
}
}
}.build()
return GET(url, apiHeaders)
}
override fun searchMangaParse(response: Response): MangasPage =
popularMangaParse(response)
// =============================== Filters ==============================
override fun getFilterList(): FilterList = FilterList(
Filter.Header("Text search ignores filters"),
Filter.Separator(),
GenreFilter(),
LastUpdateFilter(),
StatusFilter(),
)
// =========================== Manga Details ============================
override fun getMangaUrl(manga: SManga): String = baseUrl + manga.url
override fun mangaDetailsRequest(manga: SManga): Request {
val bookId = manga.url.substringAfter("/comic/")
.substringBefore("-")
return GET("$apiUrl/books/$bookId", apiHeaders)
}
override fun mangaDetailsParse(response: Response): SManga {
return response.parseAs<DataDto<MangaDto>>().data.toSManga(cdnUrl)
}
// ============================== Chapters ==============================
override fun getChapterUrl(chapter: SChapter): String = baseUrl + chapter.url
override fun chapterListRequest(manga: SManga): Request {
val bookId = manga.url.substringAfter("/comic/")
.substringBefore("-")
return GET("$apiUrl/chapters/page?sortDirection=ASC&bookId=$bookId&pageNumber=1&pageSize=9999", apiHeaders)
}
override fun chapterListParse(response: Response): List<SChapter> {
return response.parseAs<ListDataDto<ChapterDto>>().data.list.mapIndexed { index, chapterDto ->
chapterDto.toSChapter(index + 1)
}.reversed()
}
// =============================== Pages ================================
override fun pageListRequest(chapter: SChapter): Request {
val chapterId = chapter.url.substringAfter("/episode/")
.substringBefore("-")
return GET("$apiUrl/chapters/$chapterId", apiHeaders)
}
override fun pageListParse(response: Response): List<Page> {
return response.parseAs<DataDto<PageDataDto>>().data.comicImageList.map {
Page(it.sortNum, imageUrl = "$cdnUrl/${it.imageUrl}")
}
}
override fun imageRequest(page: Page): Request {
val imgHeaders = headersBuilder().apply {
add("Accept", "image/avif,image/webp,*/*")
add("Host", page.imageUrl!!.toHttpUrl().host)
}.build()
return GET(page.imageUrl!!, imgHeaders)
}
override fun imageUrlParse(response: Response): String =
throw UnsupportedOperationException()
// ============================= Utilities ==============================
private inline fun <reified T> Response.parseAs(): T {
return json.decodeFromString(body.string())
}
}

@ -1,89 +0,0 @@
package eu.kanade.tachiyomi.extension.en.comicfans
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import kotlinx.serialization.Serializable
typealias ListDataDto<T> = DataDto<ListDto<T>>
@Serializable
class ListDto<T>(
val totalPages: Int,
val list: List<T>,
)
@Serializable
class DataDto<T>(
val data: T,
)
@Serializable
class MangaDto(
val id: Int,
val title: String,
val coverImgUrl: String,
val status: Int,
val authorPseudonym: String? = null,
val synopsis: String? = null,
) {
fun toSManga(cdnUrl: String): SManga = SManga.create().apply {
title = this@MangaDto.title
thumbnail_url = "$cdnUrl/$coverImgUrl"
author = authorPseudonym
url = buildString {
append("/comic/")
append(slugify(id, title))
}
description = synopsis
status = when (this@MangaDto.status) {
0 -> SManga.ONGOING
1 -> SManga.COMPLETED
else -> SManga.UNKNOWN
}
initialized = true
}
}
@Serializable
class ChapterDto(
val id: Int,
val title: String,
val updateTime: Long? = null,
) {
fun toSChapter(index: Int): SChapter = SChapter.create().apply {
name = "Ch. $index - $title"
chapter_number = index.toFloat()
date_upload = updateTime ?: 0L
url = buildString {
append("/episode/")
append(slugify(id, title))
}
}
}
@Serializable
class PageDataDto(
val comicImageList: List<PageDto>,
) {
@Serializable
class PageDto(
val imageUrl: String,
val sortNum: Int,
)
}
private val symbolsRegex = Regex("\\W")
private val hyphenRegex = Regex("-{2,}")
private fun slugify(id: Int, title: String): String = buildString {
append(id)
append("-")
append(
title.lowercase()
.replace(symbolsRegex, "-")
.replace(hyphenRegex, "-")
.removeSuffix("-")
.removePrefix("-"),
)
}

@ -1,64 +0,0 @@
package eu.kanade.tachiyomi.extension.en.comicfans
import eu.kanade.tachiyomi.source.model.Filter
open class UriPartFilter(displayName: String, val vals: Array<Pair<String, String>>) :
Filter.Select<String>(displayName, vals.map { it.first }.toTypedArray()) {
fun toUriPart() = vals[state].second
}
inline fun <reified R> List<*>.getUriPart(): String? =
(filterIsInstance<R>().first() as UriPartFilter).toUriPart().takeIf { it.isNotEmpty() }
class GenreFilter : UriPartFilter(
"Genre",
arrayOf(
Pair("All", ""),
Pair("BL", "1001"),
Pair("Fantasy", "1002"),
Pair("GL", "1003"),
Pair("CEO", "1004"),
Pair("Romance", "1005"),
Pair("Harem", "1006"),
Pair("Action", "1007"),
Pair("Teen", "1008"),
Pair("Adventure", "1009"),
Pair("Eastern", "1010"),
Pair("Comedy", "1011"),
Pair("Esports", "1012"),
Pair("Historical", "1013"),
Pair("Mystery", "1014"),
Pair("Modern", "1015"),
Pair("Urban", "1016"),
Pair("Wuxia", "1017"),
Pair("Suspense", "1018"),
Pair("Female Lead", "1019"),
Pair("Western Fantasy", "1020"),
Pair("Horror", "1022"),
Pair("Realistic Fiction", "1023"),
Pair("Cute", "1024"),
Pair("Campus", "1025"),
Pair("Sci-fi", "1026"),
Pair("History", "1027"),
),
)
class LastUpdateFilter : UriPartFilter(
"Last Update",
arrayOf(
Pair("All", ""),
Pair("Within 3 Days", "3"),
Pair("Within 7 Days", "7"),
Pair("Within 15 Days", "15"),
Pair("Within 30 Days", "30"),
),
)
class StatusFilter : UriPartFilter(
"Status",
arrayOf(
Pair("All", ""),
Pair("Ongoing", "0"),
Pair("Completed", "1"),
),
)

@ -1,10 +0,0 @@
ext {
extName = 'Cookie Kiara'
extClass = '.CookieKiara'
themePkg = 'madara'
baseUrl = 'https://18.kiara.cool'
overrideVersionCode = 0
isNsfw = true
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

Before

(image error) Size: 4.6 KiB

Binary file not shown.

Before

(image error) Size: 2.4 KiB

Binary file not shown.

Before

(image error) Size: 6.5 KiB

Binary file not shown.

Before

(image error) Size: 12 KiB

Binary file not shown.

Before

(image error) Size: 18 KiB

@ -1,11 +0,0 @@
package eu.kanade.tachiyomi.extension.en.cookiekiara
import eu.kanade.tachiyomi.multisrc.madara.Madara
import eu.kanade.tachiyomi.source.model.SChapter
import okhttp3.Response
class CookieKiara : Madara("Cookie Kiara", "https://18.kiara.cool", "en") {
override fun chapterListParse(response: Response): List<SChapter> {
return super.chapterListParse(response).reversed()
}
}

@ -1,10 +0,0 @@
ext {
extName = 'Dark-Scan.com'
extClass = '.DarkScanCom'
themePkg = 'madara'
baseUrl = 'https://dark-scan.com'
overrideVersionCode = 0
isNsfw = false
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

Before

(image error) Size: 8.0 KiB

Binary file not shown.

Before

(image error) Size: 3.9 KiB

Binary file not shown.

Before

(image error) Size: 13 KiB

Binary file not shown.

Before

(image error) Size: 28 KiB

Binary file not shown.

Before

(image error) Size: 48 KiB

@ -1,14 +0,0 @@
package eu.kanade.tachiyomi.extension.en.darkscancom
import eu.kanade.tachiyomi.multisrc.madara.Madara
class DarkScanCom : Madara(
"Dark-Scan.com",
"https://dark-scan.com",
"en",
) {
override val useLoadMoreRequest = LoadMoreStrategy.Never
override val useNewChapterEndpoint = true
override val mangaDetailsSelectorStatus = "div.summary-heading:contains(Status) + div.summary-content"
}

Some files were not shown because too many files have changed in this diff Show More