diff --git a/multisrc/overrides/wpmangastream/boosei/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/boosei/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..476ff0422 Binary files /dev/null and b/multisrc/overrides/wpmangastream/boosei/res/mipmap-hdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/boosei/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/boosei/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..e1a0a5730 Binary files /dev/null and b/multisrc/overrides/wpmangastream/boosei/res/mipmap-mdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/boosei/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/boosei/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..fe2c933bb Binary files /dev/null and b/multisrc/overrides/wpmangastream/boosei/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/boosei/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/boosei/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..09c5ee3e4 Binary files /dev/null and b/multisrc/overrides/wpmangastream/boosei/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/boosei/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/boosei/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..fb70d271f Binary files /dev/null and b/multisrc/overrides/wpmangastream/boosei/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/boosei/res/web_hi_res_512.png b/multisrc/overrides/wpmangastream/boosei/res/web_hi_res_512.png new file mode 100644 index 000000000..39cccab55 Binary files /dev/null and b/multisrc/overrides/wpmangastream/boosei/res/web_hi_res_512.png differ diff --git a/multisrc/overrides/wpmangastream/boosei/src/Boosei.kt b/multisrc/overrides/wpmangastream/boosei/src/Boosei.kt new file mode 100644 index 000000000..cd058d935 --- /dev/null +++ b/multisrc/overrides/wpmangastream/boosei/src/Boosei.kt @@ -0,0 +1,16 @@ +package eu.kanade.tachiyomi.extension.id.boosei + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import okhttp3.OkHttpClient +import java.util.concurrent.TimeUnit + +class Boosei : WPMangaStream("Boosei", "https://boosei.com", "id") { + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() +} diff --git a/multisrc/overrides/wpmangastream/chiotaku/src/ChiOtaku.kt b/multisrc/overrides/wpmangastream/chiotaku/src/ChiOtaku.kt new file mode 100644 index 000000000..e2cf88516 --- /dev/null +++ b/multisrc/overrides/wpmangastream/chiotaku/src/ChiOtaku.kt @@ -0,0 +1,16 @@ +package eu.kanade.tachiyomi.extension.id.chiotaku + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import okhttp3.OkHttpClient +import java.util.concurrent.TimeUnit + +class ChiOtaku : WPMangaStream("ChiOtaku", "https://chiotaku.com", "id") { + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() +} diff --git a/multisrc/overrides/wpmangastream/default/additional.gradle.kts b/multisrc/overrides/wpmangastream/default/additional.gradle.kts new file mode 100644 index 000000000..10beb8157 --- /dev/null +++ b/multisrc/overrides/wpmangastream/default/additional.gradle.kts @@ -0,0 +1,4 @@ + +dependencies { + implementation project(':lib-ratelimit') +} diff --git a/src/all/wpmangastream/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/default/res/mipmap-hdpi/ic_launcher.png old mode 100755 new mode 100644 similarity index 100% rename from src/all/wpmangastream/res/mipmap-hdpi/ic_launcher.png rename to multisrc/overrides/wpmangastream/default/res/mipmap-hdpi/ic_launcher.png diff --git a/src/all/wpmangastream/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/default/res/mipmap-mdpi/ic_launcher.png old mode 100755 new mode 100644 similarity index 100% rename from src/all/wpmangastream/res/mipmap-mdpi/ic_launcher.png rename to multisrc/overrides/wpmangastream/default/res/mipmap-mdpi/ic_launcher.png diff --git a/src/all/wpmangastream/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/default/res/mipmap-xhdpi/ic_launcher.png old mode 100755 new mode 100644 similarity index 100% rename from src/all/wpmangastream/res/mipmap-xhdpi/ic_launcher.png rename to multisrc/overrides/wpmangastream/default/res/mipmap-xhdpi/ic_launcher.png diff --git a/src/all/wpmangastream/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/default/res/mipmap-xxhdpi/ic_launcher.png old mode 100755 new mode 100644 similarity index 100% rename from src/all/wpmangastream/res/mipmap-xxhdpi/ic_launcher.png rename to multisrc/overrides/wpmangastream/default/res/mipmap-xxhdpi/ic_launcher.png diff --git a/src/all/wpmangastream/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/default/res/mipmap-xxxhdpi/ic_launcher.png old mode 100755 new mode 100644 similarity index 100% rename from src/all/wpmangastream/res/mipmap-xxxhdpi/ic_launcher.png rename to multisrc/overrides/wpmangastream/default/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/src/all/wpmangastream/res/web_hi_res_512.png b/multisrc/overrides/wpmangastream/default/res/web_hi_res_512.png old mode 100755 new mode 100644 similarity index 100% rename from src/all/wpmangastream/res/web_hi_res_512.png rename to multisrc/overrides/wpmangastream/default/res/web_hi_res_512.png diff --git a/multisrc/overrides/wpmangastream/flamescans/src/FlameScans.kt b/multisrc/overrides/wpmangastream/flamescans/src/FlameScans.kt new file mode 100644 index 000000000..941c74d07 --- /dev/null +++ b/multisrc/overrides/wpmangastream/flamescans/src/FlameScans.kt @@ -0,0 +1,16 @@ +package eu.kanade.tachiyomi.extension.en.flamescans + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import okhttp3.OkHttpClient +import java.util.concurrent.TimeUnit + +class FlameScans : WPMangaStream("Flame Scans", "http://flamescans.org", "en") { + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() +} diff --git a/multisrc/overrides/wpmangastream/gurukomik/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/gurukomik/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..ad0a153ce Binary files /dev/null and b/multisrc/overrides/wpmangastream/gurukomik/res/mipmap-hdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/gurukomik/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/gurukomik/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..830db4ac9 Binary files /dev/null and b/multisrc/overrides/wpmangastream/gurukomik/res/mipmap-mdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/gurukomik/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/gurukomik/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..cf0ca5f1d Binary files /dev/null and b/multisrc/overrides/wpmangastream/gurukomik/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/gurukomik/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/gurukomik/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..f8f78fbb3 Binary files /dev/null and b/multisrc/overrides/wpmangastream/gurukomik/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/gurukomik/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/gurukomik/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..9acb8e590 Binary files /dev/null and b/multisrc/overrides/wpmangastream/gurukomik/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/gurukomik/res/web_hi_res_512.png b/multisrc/overrides/wpmangastream/gurukomik/res/web_hi_res_512.png new file mode 100644 index 000000000..e5d331a09 Binary files /dev/null and b/multisrc/overrides/wpmangastream/gurukomik/res/web_hi_res_512.png differ diff --git a/multisrc/overrides/wpmangastream/gurukomik/src/GURUKomik.kt b/multisrc/overrides/wpmangastream/gurukomik/src/GURUKomik.kt new file mode 100644 index 000000000..c731e77a0 --- /dev/null +++ b/multisrc/overrides/wpmangastream/gurukomik/src/GURUKomik.kt @@ -0,0 +1,19 @@ +package eu.kanade.tachiyomi.extension.id.gurukomik + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import java.text.SimpleDateFormat +import java.util.Locale +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import java.util.concurrent.TimeUnit +import okhttp3.OkHttpClient + +class GURUKomik : WPMangaStream("GURU Komik", "https://gurukomik.com", "id", SimpleDateFormat("MMMM dd, yyyy", Locale.forLanguageTag("id"))) { + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() + +} diff --git a/multisrc/overrides/wpmangastream/kaisarkomik/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/kaisarkomik/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..1362ec0f8 Binary files /dev/null and b/multisrc/overrides/wpmangastream/kaisarkomik/res/mipmap-hdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/kaisarkomik/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/kaisarkomik/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..594e42d56 Binary files /dev/null and b/multisrc/overrides/wpmangastream/kaisarkomik/res/mipmap-mdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/kaisarkomik/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/kaisarkomik/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..ae0f7b2a1 Binary files /dev/null and b/multisrc/overrides/wpmangastream/kaisarkomik/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/kaisarkomik/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/kaisarkomik/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..543898ba8 Binary files /dev/null and b/multisrc/overrides/wpmangastream/kaisarkomik/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/kaisarkomik/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/kaisarkomik/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..7ab7fddfd Binary files /dev/null and b/multisrc/overrides/wpmangastream/kaisarkomik/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/kaisarkomik/res/web_hi_res_512.png b/multisrc/overrides/wpmangastream/kaisarkomik/res/web_hi_res_512.png new file mode 100644 index 000000000..05bbe42eb Binary files /dev/null and b/multisrc/overrides/wpmangastream/kaisarkomik/res/web_hi_res_512.png differ diff --git a/multisrc/overrides/wpmangastream/kaisarkomik/src/KaisarKomik.kt b/multisrc/overrides/wpmangastream/kaisarkomik/src/KaisarKomik.kt new file mode 100644 index 000000000..efd4dceb6 --- /dev/null +++ b/multisrc/overrides/wpmangastream/kaisarkomik/src/KaisarKomik.kt @@ -0,0 +1,16 @@ +package eu.kanade.tachiyomi.extension.id.kaisarkomik + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import okhttp3.OkHttpClient +import java.util.concurrent.TimeUnit + +class KaisarKomik : WPMangaStream("Kaisar Komik", "https://kaisarkomik.com", "id") { + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() +} diff --git a/multisrc/overrides/wpmangastream/kiryuu/src/Kiryuu.kt b/multisrc/overrides/wpmangastream/kiryuu/src/Kiryuu.kt new file mode 100644 index 000000000..345faddb0 --- /dev/null +++ b/multisrc/overrides/wpmangastream/kiryuu/src/Kiryuu.kt @@ -0,0 +1,27 @@ +package eu.kanade.tachiyomi.extension.id.kiryuu + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import eu.kanade.tachiyomi.source.model.Page +import org.jsoup.nodes.Document +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import java.util.concurrent.TimeUnit +import okhttp3.OkHttpClient + +class Kiryuu : WPMangaStream("Kiryuu", "https://kiryuu.co", "id") { + // Formerly "Kiryuu (WP Manga Stream)" + override val id = 3639673976007021338 + + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() + + override fun pageListParse(document: Document): List { + return document.select("div#readerarea img").map { it.attr("abs:src") } + .filterNot { it.substringAfterLast("/").contains(Regex("""(filerun|photothumb\.db)""")) } + .mapIndexed { i, image -> Page(i, "", image) } + } +} diff --git a/multisrc/overrides/wpmangastream/klankomik/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/klankomik/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..00f9534f5 Binary files /dev/null and b/multisrc/overrides/wpmangastream/klankomik/res/mipmap-hdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/klankomik/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/klankomik/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..c6e4656bc Binary files /dev/null and b/multisrc/overrides/wpmangastream/klankomik/res/mipmap-mdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/klankomik/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/klankomik/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..7eddc9b4d Binary files /dev/null and b/multisrc/overrides/wpmangastream/klankomik/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/klankomik/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/klankomik/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..022f76425 Binary files /dev/null and b/multisrc/overrides/wpmangastream/klankomik/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/klankomik/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/klankomik/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..11150551d Binary files /dev/null and b/multisrc/overrides/wpmangastream/klankomik/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/klankomik/res/web_hi_res_512.png b/multisrc/overrides/wpmangastream/klankomik/res/web_hi_res_512.png new file mode 100644 index 000000000..90b726d8a Binary files /dev/null and b/multisrc/overrides/wpmangastream/klankomik/res/web_hi_res_512.png differ diff --git a/multisrc/overrides/wpmangastream/klankomik/src/KlanKomik.kt b/multisrc/overrides/wpmangastream/klankomik/src/KlanKomik.kt new file mode 100644 index 000000000..3f0754bc6 --- /dev/null +++ b/multisrc/overrides/wpmangastream/klankomik/src/KlanKomik.kt @@ -0,0 +1,16 @@ +package eu.kanade.tachiyomi.extension.id.klankomik + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import okhttp3.OkHttpClient +import java.util.concurrent.TimeUnit + +class KlanKomik : WPMangaStream("KlanKomik", "https://klankomik.com", "id") { + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() +} diff --git a/multisrc/overrides/wpmangastream/komikav/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/komikav/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..7451aaca0 Binary files /dev/null and b/multisrc/overrides/wpmangastream/komikav/res/mipmap-hdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/komikav/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/komikav/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..feaaee5c3 Binary files /dev/null and b/multisrc/overrides/wpmangastream/komikav/res/mipmap-mdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/komikav/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/komikav/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..2da936298 Binary files /dev/null and b/multisrc/overrides/wpmangastream/komikav/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/komikav/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/komikav/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..0461d35bc Binary files /dev/null and b/multisrc/overrides/wpmangastream/komikav/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/komikav/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/komikav/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..c9ceffca6 Binary files /dev/null and b/multisrc/overrides/wpmangastream/komikav/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/komikav/res/web_hi_res_512.png b/multisrc/overrides/wpmangastream/komikav/res/web_hi_res_512.png new file mode 100644 index 000000000..b9f01a2e3 Binary files /dev/null and b/multisrc/overrides/wpmangastream/komikav/res/web_hi_res_512.png differ diff --git a/multisrc/overrides/wpmangastream/komikav/src/KomikAV.kt b/multisrc/overrides/wpmangastream/komikav/src/KomikAV.kt new file mode 100644 index 000000000..d094c8699 --- /dev/null +++ b/multisrc/overrides/wpmangastream/komikav/src/KomikAV.kt @@ -0,0 +1,33 @@ +package eu.kanade.tachiyomi.extension.id.komikav + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.source.model.Page +import okhttp3.Request +import java.text.SimpleDateFormat +import java.util.Locale +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import java.util.concurrent.TimeUnit +import okhttp3.OkHttpClient + +class KomikAV : WPMangaStream( + "Komik AV (WP Manga Stream)", + "https://komikav.com", + "id", + dateFormat = SimpleDateFormat("MMMM dd, yyyy", Locale.forLanguageTag("id")) +) { + // Formerly "Komik AV (WP Manga Stream)" + override val id = 7875815514004535629 + + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() + + override fun imageRequest(page: Page): Request { + return GET(page.imageUrl!!, headers) + } +} diff --git a/multisrc/overrides/wpmangastream/komikcast/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/komikcast/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..962261925 Binary files /dev/null and b/multisrc/overrides/wpmangastream/komikcast/res/mipmap-hdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/komikcast/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/komikcast/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..1dcc96472 Binary files /dev/null and b/multisrc/overrides/wpmangastream/komikcast/res/mipmap-mdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/komikcast/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/komikcast/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..d1f3b286c Binary files /dev/null and b/multisrc/overrides/wpmangastream/komikcast/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/komikcast/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/komikcast/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..f3d455682 Binary files /dev/null and b/multisrc/overrides/wpmangastream/komikcast/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/komikcast/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/komikcast/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..badf7ef26 Binary files /dev/null and b/multisrc/overrides/wpmangastream/komikcast/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/komikcast/res/web_hi_res_512.png b/multisrc/overrides/wpmangastream/komikcast/res/web_hi_res_512.png new file mode 100644 index 000000000..48c25bff2 Binary files /dev/null and b/multisrc/overrides/wpmangastream/komikcast/res/web_hi_res_512.png differ diff --git a/multisrc/overrides/wpmangastream/komikcast/src/KomikCast.kt b/multisrc/overrides/wpmangastream/komikcast/src/KomikCast.kt new file mode 100644 index 000000000..dce41e4e0 --- /dev/null +++ b/multisrc/overrides/wpmangastream/komikcast/src/KomikCast.kt @@ -0,0 +1,102 @@ +package eu.kanade.tachiyomi.extension.id.komikcast + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +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.SManga +import okhttp3.HttpUrl +import okhttp3.Request +import org.jsoup.nodes.Document +import org.jsoup.nodes.Element +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import java.util.concurrent.TimeUnit +import okhttp3.OkHttpClient + +class KomikCast : WPMangaStream("Komik Cast", "https://komikcast.com", "id") { + // Formerly "Komik Cast (WP Manga Stream)" + override val id = 972717448578983812 + + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() + + override fun popularMangaRequest(page: Int): Request { + return GET("$baseUrl/daftar-komik/page/$page/?order=popular", headers) + } + + override fun latestUpdatesRequest(page: Int): Request { + return GET("$baseUrl/komik/page/$page/", headers) + } + + override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { + val url = if (query.isNotBlank()) { + val url = HttpUrl.parse("$baseUrl/page/$page")!!.newBuilder() + val pattern = "\\s+".toRegex() + val q = query.replace(pattern, "+") + if (query.isNotEmpty()) { + url.addQueryParameter("s", q) + } else { + url.addQueryParameter("s", "") + } + url.toString() + } else { + val url = HttpUrl.parse("$baseUrl/daftar-komik/page/$page")!!.newBuilder() + var orderBy: String + (if (filters.isEmpty()) getFilterList() else filters).forEach { filter -> + when (filter) { + is StatusFilter -> url.addQueryParameter("status", arrayOf("", "ongoing", "completed")[filter.state]) + is GenreListFilter -> { + val genreInclude = mutableListOf() + filter.state.forEach { + if (it.state == 1) { + genreInclude.add(it.id) + } + } + if (genreInclude.isNotEmpty()) { + genreInclude.forEach { genre -> + url.addQueryParameter("genre[]", genre) + } + } + } + is SortByFilter -> { + orderBy = filter.toUriPart() + url.addQueryParameter("order", orderBy) + } + } + } + url.toString() + } + return GET(url, headers) + } + + override fun popularMangaFromElement(element: Element): SManga { + val manga = SManga.create() + manga.thumbnail_url = element.select("div.limit img").attr("src") + element.select("div.bigor > a").first().let { + manga.setUrlWithoutDomain(it.attr("href")) + manga.title = it.attr("title") + } + return manga + } + + override fun pageListParse(document: Document): List { + return document.select("div#readerarea img.size-full") + .mapIndexed { i, img -> Page(i, "", img.attr("abs:Src")) } + } + + override fun getFilterList() = FilterList( + Filter.Header("NOTE: Ignored if using text search!"), + Filter.Separator(), + SortByFilter(), + Filter.Separator(), + StatusFilter(), + Filter.Separator(), + GenreListFilter(getGenreList()) + ) +} diff --git a/multisrc/overrides/wpmangastream/komikgo/src/KomikGo.kt b/multisrc/overrides/wpmangastream/komikgo/src/KomikGo.kt new file mode 100644 index 000000000..5f7c4515a --- /dev/null +++ b/multisrc/overrides/wpmangastream/komikgo/src/KomikGo.kt @@ -0,0 +1,238 @@ +package eu.kanade.tachiyomi.extension.id.komikgo + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +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 okhttp3.Request +import org.jsoup.nodes.Document +import org.jsoup.nodes.Element +import eu.kanade.tachiyomi.source.model.Filter +import okhttp3.HttpUrl +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import java.util.concurrent.TimeUnit +import okhttp3.OkHttpClient + +class KomikGo : WPMangaStream("Komik GO", "https://komikgo.com", "id") { + // Formerly "Komik GO (WP Manga Stream)" + override val id = 1070674823324721554 + + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() + + override fun popularMangaRequest(page: Int): Request { + return GET("$baseUrl/page/$page?s&post_type=wp-manga&m_orderby=views", headers) + } + + override fun latestUpdatesRequest(page: Int): Request { + return GET("$baseUrl/page/$page?s&post_type=wp-manga&m_orderby=latest", headers) + } + + override fun popularMangaSelector() = "div.c-tabs-item__content" + + override fun popularMangaFromElement(element: Element): SManga { + val manga = SManga.create() + manga.thumbnail_url = element.select("div.tab-thumb > a > img").attr("data-src") + element.select("div.tab-thumb > a").first().let { + manga.setUrlWithoutDomain(it.attr("href")) + manga.title = it.attr("title") + } + return manga + } + + override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { + val url = HttpUrl.parse("$baseUrl/page/$page")!!.newBuilder() + url.addQueryParameter("post_type", "wp-manga") + val pattern = "\\s+".toRegex() + val q = query.replace(pattern, "+") + if (query.isNotEmpty()) { + url.addQueryParameter("s", q) + } else { + url.addQueryParameter("s", "") + } + + var orderBy: String + + (if (filters.isEmpty()) getFilterList() else filters).forEach { filter -> + when (filter) { +// is Status -> url.addQueryParameter("manga_status", arrayOf("", "completed", "ongoing")[filter.state]) + is GenreListFilter -> { + val genreInclude = mutableListOf() + filter.state.forEach { + if (it.state == 1) { + genreInclude.add(it.id) + } + } + if (genreInclude.isNotEmpty()) { + genreInclude.forEach { genre -> + url.addQueryParameter("genre[]", genre) + } + } + } + is StatusList -> { + val statuses = mutableListOf() + filter.state.forEach { + if (it.state == 1) { + statuses.add(it.id) + } + } + if (statuses.isNotEmpty()) { + statuses.forEach { status -> + url.addQueryParameter("status[]", status) + } + } + } + + is SortBy -> { + orderBy = filter.toUriPart() + url.addQueryParameter("m_orderby", orderBy) + } + is TextField -> url.addQueryParameter(filter.key, filter.state) + } + } + + return GET(url.toString(), headers) + } + + override fun popularMangaNextPageSelector() = "#navigation-ajax" + + override fun mangaDetailsParse(document: Document): SManga { + val infoElement = document.select("div.site-content").first() + + val manga = SManga.create() + manga.author = infoElement.select("div.author-content")?.text() + manga.artist = infoElement.select("div.artist-content")?.text() + + val genres = mutableListOf() + infoElement.select("div.genres-content a").forEach { element -> + val genre = element.text() + genres.add(genre) + } + manga.genre = genres.joinToString(", ") + manga.status = parseStatus(infoElement.select("div.post-status > div:nth-child(2) div").text()) + + manga.description = document.select("div.description-summary")?.text() + manga.thumbnail_url = document.select("div.summary_image > a > img").attr("data-src") + + return manga + } + + override fun chapterListSelector() = "li.wp-manga-chapter" + + override fun chapterFromElement(element: Element): SChapter { + val urlElement = element.select("a").first() + val chapter = SChapter.create() + chapter.setUrlWithoutDomain(urlElement.attr("href")) + chapter.name = urlElement.text() + chapter.date_upload = parseChapterDate(element.select("span.chapter-release-date i").text()) + return chapter + } + + override fun pageListParse(document: Document): List { + return document.select("div.reading-content * img").mapIndexed { i, img -> + Page(i, "", img.imgAttr()) + } + } + + private class TextField(name: String, val key: String) : Filter.Text(name) + + private class SortBy : UriPartFilter( + "Sort by", + arrayOf( + Pair("Relevance", ""), + Pair("Latest", "latest"), + Pair("A-Z", "alphabet"), + Pair("Rating", "rating"), + Pair("Trending", "trending"), + Pair("Most View", "views"), + Pair("New", "new-manga") + ) + ) + + private class Status(name: String, val id: String = name) : Filter.TriState(name) + private class StatusList(statuses: List) : Filter.Group("Status", statuses) + + override fun getFilterList() = FilterList( + TextField("Author", "author"), + TextField("Year", "release"), + SortBy(), + StatusList(getStatusList()), + GenreListFilter(getGenreList()) + ) + + private fun getStatusList() = listOf( + Status("Completed", "end"), + Status("Ongoing", "on-going"), + Status("Canceled", "canceled"), + Status("Onhold", "on-hold") + ) + + override fun getGenreList(): List = 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") + ) +} diff --git a/multisrc/overrides/wpmangastream/komikindoco/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/komikindoco/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..e8eb41825 Binary files /dev/null and b/multisrc/overrides/wpmangastream/komikindoco/res/mipmap-hdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/komikindoco/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/komikindoco/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..3264e021d Binary files /dev/null and b/multisrc/overrides/wpmangastream/komikindoco/res/mipmap-mdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/komikindoco/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/komikindoco/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..d82025017 Binary files /dev/null and b/multisrc/overrides/wpmangastream/komikindoco/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/komikindoco/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/komikindoco/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..871a3a5d7 Binary files /dev/null and b/multisrc/overrides/wpmangastream/komikindoco/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/komikindoco/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/komikindoco/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..b0775865a Binary files /dev/null and b/multisrc/overrides/wpmangastream/komikindoco/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/komikindoco/res/web_hi_res_512.png b/multisrc/overrides/wpmangastream/komikindoco/res/web_hi_res_512.png new file mode 100644 index 000000000..bf03065f4 Binary files /dev/null and b/multisrc/overrides/wpmangastream/komikindoco/res/web_hi_res_512.png differ diff --git a/multisrc/overrides/wpmangastream/komikindoco/src/KomikindoCo.kt b/multisrc/overrides/wpmangastream/komikindoco/src/KomikindoCo.kt new file mode 100644 index 000000000..84746032e --- /dev/null +++ b/multisrc/overrides/wpmangastream/komikindoco/src/KomikindoCo.kt @@ -0,0 +1,19 @@ +package eu.kanade.tachiyomi.extension.id.komikindoco + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import okhttp3.OkHttpClient +import java.util.concurrent.TimeUnit + +class KomikindoCo : WPMangaStream("KomikIndo.co", "https://komikindo.co", "id") { + // Formerly "Komikindo.co" + override val id = 734619124437406170 + + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() +} diff --git a/src/id/komikindo/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/komikindowpms/res/mipmap-hdpi/ic_launcher.png old mode 100755 new mode 100644 similarity index 100% rename from src/id/komikindo/res/mipmap-hdpi/ic_launcher.png rename to multisrc/overrides/wpmangastream/komikindowpms/res/mipmap-hdpi/ic_launcher.png diff --git a/src/id/komikindo/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/komikindowpms/res/mipmap-mdpi/ic_launcher.png old mode 100755 new mode 100644 similarity index 100% rename from src/id/komikindo/res/mipmap-mdpi/ic_launcher.png rename to multisrc/overrides/wpmangastream/komikindowpms/res/mipmap-mdpi/ic_launcher.png diff --git a/src/id/komikindo/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/komikindowpms/res/mipmap-xhdpi/ic_launcher.png old mode 100755 new mode 100644 similarity index 100% rename from src/id/komikindo/res/mipmap-xhdpi/ic_launcher.png rename to multisrc/overrides/wpmangastream/komikindowpms/res/mipmap-xhdpi/ic_launcher.png diff --git a/src/id/komikindo/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/komikindowpms/res/mipmap-xxhdpi/ic_launcher.png old mode 100755 new mode 100644 similarity index 100% rename from src/id/komikindo/res/mipmap-xxhdpi/ic_launcher.png rename to multisrc/overrides/wpmangastream/komikindowpms/res/mipmap-xxhdpi/ic_launcher.png diff --git a/src/id/komikindo/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/komikindowpms/res/mipmap-xxxhdpi/ic_launcher.png old mode 100755 new mode 100644 similarity index 100% rename from src/id/komikindo/res/mipmap-xxxhdpi/ic_launcher.png rename to multisrc/overrides/wpmangastream/komikindowpms/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/src/id/komikindo/res/web_hi_res_512.png b/multisrc/overrides/wpmangastream/komikindowpms/res/web_hi_res_512.png old mode 100755 new mode 100644 similarity index 100% rename from src/id/komikindo/res/web_hi_res_512.png rename to multisrc/overrides/wpmangastream/komikindowpms/res/web_hi_res_512.png diff --git a/multisrc/overrides/wpmangastream/komikindowpms/src/KomikIndoWPMS.kt b/multisrc/overrides/wpmangastream/komikindowpms/src/KomikIndoWPMS.kt new file mode 100644 index 000000000..2d675ca6a --- /dev/null +++ b/multisrc/overrides/wpmangastream/komikindowpms/src/KomikIndoWPMS.kt @@ -0,0 +1,20 @@ +package eu.kanade.tachiyomi.extension.id.komikindowpms + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import java.util.concurrent.TimeUnit +import okhttp3.OkHttpClient + +class KomikIndoWPMS : WPMangaStream("Komik Indo", "https://www.komikindo.web.id", "id") { + // Formerly "Komik Indo (WP Manga Stream)" + override val id = 1481562643469779882 + + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() + +} diff --git a/multisrc/overrides/wpmangastream/komikru/src/KomikRu.kt b/multisrc/overrides/wpmangastream/komikru/src/KomikRu.kt new file mode 100644 index 000000000..7ee5cac0f --- /dev/null +++ b/multisrc/overrides/wpmangastream/komikru/src/KomikRu.kt @@ -0,0 +1,19 @@ +package eu.kanade.tachiyomi.extension.id.komikru + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import java.text.SimpleDateFormat +import java.util.Locale +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import java.util.concurrent.TimeUnit +import okhttp3.OkHttpClient + +class KomikRu : WPMangaStream("KomikRu", "https://komikru.com", "id", SimpleDateFormat("MMMM dd, yyyy", Locale.forLanguageTag("id"))) { + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() + +} diff --git a/multisrc/overrides/wpmangastream/komikstation/src/KomikStation.kt b/multisrc/overrides/wpmangastream/komikstation/src/KomikStation.kt new file mode 100644 index 000000000..d253e95fb --- /dev/null +++ b/multisrc/overrides/wpmangastream/komikstation/src/KomikStation.kt @@ -0,0 +1,20 @@ +package eu.kanade.tachiyomi.extension.id.komikstation + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import okhttp3.OkHttpClient +import java.util.concurrent.TimeUnit +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor + +class KomikStation : WPMangaStream("Komik Station", "https://komikstation.com", "id") { + // Formerly "Komik Station (WP Manga Stream)" + override val id = 6148605743576635261 + + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() + +} diff --git a/multisrc/overrides/wpmangastream/komiktap/src/KomikTap.kt b/multisrc/overrides/wpmangastream/komiktap/src/KomikTap.kt new file mode 100644 index 000000000..0b09858c2 --- /dev/null +++ b/multisrc/overrides/wpmangastream/komiktap/src/KomikTap.kt @@ -0,0 +1,16 @@ +package eu.kanade.tachiyomi.extension.id.komiktap + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import okhttp3.OkHttpClient +import java.util.concurrent.TimeUnit + +class KomikTap : WPMangaStream("KomikTap", "https://komiktap.in/", "id") { + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() +} diff --git a/multisrc/overrides/wpmangastream/kumascans/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/kumascans/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..610fd03f9 Binary files /dev/null and b/multisrc/overrides/wpmangastream/kumascans/res/mipmap-hdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/kumascans/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/kumascans/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..020ad4368 Binary files /dev/null and b/multisrc/overrides/wpmangastream/kumascans/res/mipmap-mdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/kumascans/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/kumascans/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..bf167bf81 Binary files /dev/null and b/multisrc/overrides/wpmangastream/kumascans/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/kumascans/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/kumascans/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..cbbcdd73d Binary files /dev/null and b/multisrc/overrides/wpmangastream/kumascans/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/kumascans/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/kumascans/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..6a6899cc7 Binary files /dev/null and b/multisrc/overrides/wpmangastream/kumascans/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/kumascans/res/web_hi_res_512.png b/multisrc/overrides/wpmangastream/kumascans/res/web_hi_res_512.png new file mode 100644 index 000000000..ed1d20dd7 Binary files /dev/null and b/multisrc/overrides/wpmangastream/kumascans/res/web_hi_res_512.png differ diff --git a/multisrc/overrides/wpmangastream/kumascans/src/KumaScans.kt b/multisrc/overrides/wpmangastream/kumascans/src/KumaScans.kt new file mode 100644 index 000000000..a1d743cef --- /dev/null +++ b/multisrc/overrides/wpmangastream/kumascans/src/KumaScans.kt @@ -0,0 +1,16 @@ +package eu.kanade.tachiyomi.extension.en.kumascans + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import okhttp3.OkHttpClient +import java.util.concurrent.TimeUnit + +class KumaScans : WPMangaStream("Kuma Scans (Kuma Translation)", "https://kumascans.com", "en") { + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() +} diff --git a/multisrc/overrides/wpmangastream/liebeschneehiver/src/LiebeSchneeHiver.kt b/multisrc/overrides/wpmangastream/liebeschneehiver/src/LiebeSchneeHiver.kt new file mode 100644 index 000000000..5d8a5bec5 --- /dev/null +++ b/multisrc/overrides/wpmangastream/liebeschneehiver/src/LiebeSchneeHiver.kt @@ -0,0 +1,24 @@ +package eu.kanade.tachiyomi.extension.tr.liebeschneehiver + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import java.text.SimpleDateFormat +import java.util.Locale +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import java.util.concurrent.TimeUnit +import okhttp3.OkHttpClient + +class LiebeSchneeHiver : WPMangaStream( + "Liebe Schnee Hiver", + "https://www.liebeschneehiver.com", + "tr", + SimpleDateFormat("MMMM dd, yyyy", Locale.forLanguageTag("tr")) +) { + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() + +} diff --git a/multisrc/overrides/wpmangastream/mangaindonesia/src/MangaIndonesia.kt b/multisrc/overrides/wpmangastream/mangaindonesia/src/MangaIndonesia.kt new file mode 100644 index 000000000..95823ae49 --- /dev/null +++ b/multisrc/overrides/wpmangastream/mangaindonesia/src/MangaIndonesia.kt @@ -0,0 +1,53 @@ +package eu.kanade.tachiyomi.extension.id.mangaindonesia + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.source.model.FilterList +import eu.kanade.tachiyomi.source.model.SChapter +import eu.kanade.tachiyomi.source.model.SManga +import okhttp3.Request +import org.jsoup.nodes.Element +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import java.util.concurrent.TimeUnit +import okhttp3.OkHttpClient + +class MangaIndonesia : WPMangaStream("MangaIndonesia", "https://mangaindonesia.net", "id") { + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() + + override fun popularMangaRequest(page: Int): Request { +// return GET("$baseUrl/popular" + if (page > 1) "/${(page - 1) * 30}" else "", headers) +// return GET("$baseUrl/$popularPath" + if (page > 1) "?page=$page" else "", headers) + return GET("$baseUrl/update/" + if (page > 1) "?page=$page" else "", headers) + } + override fun latestUpdatesRequest(page: Int): Request { + return GET(baseUrl, headers) + } + override fun latestUpdatesSelector() = ".listupd:not(.project) .uta .imgu" + override fun latestUpdatesFromElement(element: Element): SManga { + val manga = SManga.create() + manga.thumbnail_url = element.select("a img").imgAttr() + element.select("a").first().let { + manga.setUrlWithoutDomain(it.attr("href")) + manga.title = it.attr("title") + } + return manga + } + override fun latestUpdatesNextPageSelector(): String? = null + override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { + return GET("$baseUrl/page/$page/$query", headers) + } + override fun chapterListSelector() = "div.bxcl ul li:has(span)" + override fun chapterFromElement(element: Element): SChapter { + val chapter = SChapter.create() + chapter.setUrlWithoutDomain(element.select("a").attr("href")) + chapter.name = element.select("a").text() + chapter.date_upload = element.select("span.dt").firstOrNull()?.text()?.let { parseChapterDate(it) } ?: 0 + return chapter + } +} diff --git a/multisrc/overrides/wpmangastream/mangakyo/src/Mangakyo.kt b/multisrc/overrides/wpmangastream/mangakyo/src/Mangakyo.kt new file mode 100644 index 000000000..1d382b264 --- /dev/null +++ b/multisrc/overrides/wpmangastream/mangakyo/src/Mangakyo.kt @@ -0,0 +1,16 @@ +package eu.kanade.tachiyomi.extension.id.mangakyo + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import okhttp3.OkHttpClient +import java.util.concurrent.TimeUnit + +class Mangakyo : WPMangaStream("Mangakyo", "https://www.mangakyo.me", "id") { + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() +} diff --git a/multisrc/overrides/wpmangastream/mangap/src/MangaP.kt b/multisrc/overrides/wpmangastream/mangap/src/MangaP.kt new file mode 100644 index 000000000..5bd5139bd --- /dev/null +++ b/multisrc/overrides/wpmangastream/mangap/src/MangaP.kt @@ -0,0 +1,16 @@ +package eu.kanade.tachiyomi.extension.ar.mangap + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import okhttp3.OkHttpClient +import java.util.concurrent.TimeUnit + +class MangaP : WPMangaStream("MangaP", "https://mangap.me", "ar") { + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() +} diff --git a/multisrc/overrides/wpmangastream/mangaproz/src/MangaProZ.kt b/multisrc/overrides/wpmangastream/mangaproz/src/MangaProZ.kt new file mode 100644 index 000000000..6d45b6ee5 --- /dev/null +++ b/multisrc/overrides/wpmangastream/mangaproz/src/MangaProZ.kt @@ -0,0 +1,20 @@ +package eu.kanade.tachiyomi.extension.ar.mangaproz + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import eu.kanade.tachiyomi.source.model.SChapter +import org.jsoup.nodes.Element +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import java.util.concurrent.TimeUnit +import okhttp3.OkHttpClient + +class MangaProZ : WPMangaStream("Manga Pro Z", "https://mangaproz.com", "ar") { + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() + + override fun chapterFromElement(element: Element): SChapter = super.chapterFromElement(element).apply { name = name.removeSuffix(" free") } +} diff --git a/multisrc/overrides/wpmangastream/mangaraw/src/MangaRaw.kt b/multisrc/overrides/wpmangastream/mangaraw/src/MangaRaw.kt new file mode 100644 index 000000000..ffb1169cb --- /dev/null +++ b/multisrc/overrides/wpmangastream/mangaraw/src/MangaRaw.kt @@ -0,0 +1,61 @@ +package eu.kanade.tachiyomi.extension.ja.mangaraw + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +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 okhttp3.Request +import okhttp3.Response +import org.jsoup.nodes.Document +import org.jsoup.nodes.Element +import eu.kanade.tachiyomi.network.asObservableSuccess +import eu.kanade.tachiyomi.util.asJsoup +import rx.Observable +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import java.util.concurrent.TimeUnit +import okhttp3.OkHttpClient + +class MangaRaw : WPMangaStream("Manga Raw", "https://mangaraw.org", "ja") { + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() + + override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/search?order=popular&page=$page", headers) + override fun popularMangaSelector() = "div.bsx" + override fun popularMangaFromElement(element: Element): SManga { + return SManga.create().apply { + element.select("div.bigor > a").let { + setUrlWithoutDomain(it.attr("href")) + title = it.text() + } + thumbnail_url = element.select("img").attr("abs:src") + } + } + override fun popularMangaNextPageSelector() = "a[rel=next]" + override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/search?order=update&page=$page", headers) + override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = + GET("$baseUrl/search?s=$query&page=$page") + override fun searchMangaFromElement(element: Element): SManga = popularMangaFromElement(element) + override fun mangaDetailsParse(document: Document): SManga = super.mangaDetailsParse(document) + .apply { description = document.select("div.bottom").firstOrNull()?.ownText() } + override fun fetchPageList(chapter: SChapter): Observable> { + return client.newCall(pageListRequest(chapter)) + .asObservableSuccess() + .map { response -> + pageListParse(response, baseUrl + chapter.url.removeSuffix("/")) + } + } + private fun pageListParse(response: Response, chapterUrl: String): List { + return response.asJsoup().select("span.page-link").first().ownText().substringAfterLast(" ").toInt() + .let { lastNum -> IntRange(1, lastNum) } + .map { num -> Page(num, "$chapterUrl/$num") } + } + override fun imageUrlParse(document: Document): String = document.select("a.img-block img").attr("abs:src") + override fun getFilterList(): FilterList = FilterList() +} diff --git a/multisrc/overrides/wpmangastream/mangashiro/src/MangaShiro.kt b/multisrc/overrides/wpmangastream/mangashiro/src/MangaShiro.kt new file mode 100644 index 000000000..ab16ace24 --- /dev/null +++ b/multisrc/overrides/wpmangastream/mangashiro/src/MangaShiro.kt @@ -0,0 +1,16 @@ +package eu.kanade.tachiyomi.extension.id.mangashiro + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import okhttp3.OkHttpClient +import java.util.concurrent.TimeUnit + +class MangaShiro : WPMangaStream("MangaShiro", "https://mangashiro.co", "id") { + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() +} diff --git a/multisrc/overrides/wpmangastream/mangaswat/src/MangaSwat.kt b/multisrc/overrides/wpmangastream/mangaswat/src/MangaSwat.kt new file mode 100644 index 000000000..e176c1526 --- /dev/null +++ b/multisrc/overrides/wpmangastream/mangaswat/src/MangaSwat.kt @@ -0,0 +1,112 @@ +package eu.kanade.tachiyomi.extension.ar.mangaswat + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.source.model.FilterList +import eu.kanade.tachiyomi.source.model.SChapter +import eu.kanade.tachiyomi.source.model.SManga +import okhttp3.Headers +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.Response +import org.jsoup.nodes.Document +import okhttp3.Interceptor +import java.io.IOException + +class MangaSwat : WPMangaStream("MangaSwat", "https://mangaswat.com", "ar") { + /** + * Use IOException or the app crashes! + * x-sucuri-cache header is never present on images; specify webpages or glide won't load images! + */ + private class Sucuri : Interceptor { + override fun intercept(chain: Interceptor.Chain): Response { + val response = chain.proceed(chain.request()) + if (response.header("x-sucuri-cache").isNullOrEmpty() && response.request().url().toString().contains("//mangaswat.com")) + throw IOException("Site protected, open webview | موقع محمي ، عرض ويب مفتوح") + return response + } + } + override val client: OkHttpClient = super.client.newBuilder().addInterceptor(Sucuri()).build() + + override fun headersBuilder(): Headers.Builder = Headers.Builder() + .add("Referer", baseUrl) + .add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0") + .add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3") + + override fun mangaDetailsParse(document: Document): SManga { + return SManga.create().apply { + document.select("div.bigcontent").firstOrNull()?.let { infoElement -> + genre = infoElement.select("span:contains(التصنيف) a").joinToString { it.text() } + status = parseStatus(infoElement.select("span:contains(الحالة)").firstOrNull()?.ownText()) + author = infoElement.select("span:contains(المؤلف) i").firstOrNull()?.ownText() + artist = author + description = infoElement.select("div.desc").text() + thumbnail_url = infoElement.select("img").imgAttr() + } + } + } + override fun pageListRequest(chapter: SChapter): Request { + return GET(baseUrl + chapter.url + "?/", headers) // Bypass "linkvertise" ads + } + + override fun getFilterList() = FilterList( + StatusFilter(), + TypeFilter(), + SortByFilter(), + GenreListFilter(getGenrePairs()) + ) + + private class GenreListFilter(pairs: Array>) : UriPartFilter("Genre", pairs) + + private fun getGenrePairs() = arrayOf( + Pair("<--->", ""), + Pair("آلات", "%d8%a2%d9%84%d8%a7%d8%aa"), + Pair("أكشن", "%d8%a3%d9%83%d8%b4%d9%86"), + Pair("إثارة", "%d8%a5%d8%ab%d8%a7%d8%b1%d8%a9"), + Pair("إعادة", "%d8%a5%d8%b9%d8%a7%d8%af%d8%a9-%d8%a5%d8%ad%d9%8a%d8%a7%d8%a1"), + Pair("الحياة", "%d8%a7%d9%84%d8%ad%d9%8a%d8%a7%d8%a9-%d8%a7%d9%84%d9%85%d8%af%d8%b1%d8%b3%d9%8a%d8%a9"), + Pair("الحياة", "%d8%a7%d9%84%d8%ad%d9%8a%d8%a7%d8%a9-%d8%a7%d9%84%d9%8a%d9%88%d9%85%d9%8a%d8%a9"), + Pair("العاب", "%d8%a7%d9%84%d8%b9%d8%a7%d8%a8-%d9%81%d9%8a%d8%af%d9%8a%d9%88"), + Pair("ايتشي", "%d8%a7%d9%8a%d8%aa%d8%b4%d9%8a"), + Pair("ايسكاي", "%d8%a7%d9%8a%d8%b3%d9%83%d8%a7%d9%8a"), + Pair("بالغ", "%d8%a8%d8%a7%d9%84%d8%ba"), + Pair("تاريخي", "%d8%aa%d8%a7%d8%b1%d9%8a%d8%ae%d9%8a"), + Pair("تراجيدي", "%d8%aa%d8%b1%d8%a7%d8%ac%d9%8a%d8%af%d9%8a"), + Pair("جوسيه", "%d8%ac%d9%88%d8%b3%d9%8a%d9%87"), + Pair("جيندر", "%d8%ac%d9%8a%d9%86%d8%af%d8%b1-%d8%a8%d9%86%d8%af%d8%b1"), + Pair("حربي", "%d8%ad%d8%b1%d8%a8%d9%8a"), + Pair("حريم", "%d8%ad%d8%b1%d9%8a%d9%85"), + Pair("خارق", "%d8%ae%d8%a7%d8%b1%d9%82-%d9%84%d9%84%d8%b7%d8%a8%d9%8a%d8%b9%d8%a9"), + Pair("خيال", "%d8%ae%d9%8a%d8%a7%d9%84"), + Pair("خيال", "%d8%ae%d9%8a%d8%a7%d9%84-%d8%b9%d9%84%d9%85%d9%8a"), + Pair("دراما", "%d8%af%d8%b1%d8%a7%d9%85%d8%a7"), + Pair("دموي", "%d8%af%d9%85%d9%88%d9%8a"), + Pair("رعب", "%d8%b1%d8%b9%d8%a8"), + Pair("رومانسي", "%d8%b1%d9%88%d9%85%d8%a7%d9%86%d8%b3%d9%8a"), + Pair("رياضة", "%d8%b1%d9%8a%d8%a7%d8%b6%d8%a9"), + Pair("زمكاني", "%d8%b2%d9%85%d9%83%d8%a7%d9%86%d9%8a"), + Pair("زومبي", "%d8%b2%d9%88%d9%85%d8%a8%d9%8a"), + Pair("سحر", "%d8%b3%d8%ad%d8%b1"), + Pair("سينين", "%d8%b3%d9%8a%d9%86%d9%8a%d9%86"), + Pair("شريحة", "%d8%b4%d8%b1%d9%8a%d8%ad%d8%a9-%d9%85%d9%86-%d8%a7%d9%84%d8%ad%d9%8a%d8%a7%d8%a9"), + Pair("شوجو", "%d8%b4%d9%88%d8%ac%d9%88"), + Pair("شونين", "%d8%b4%d9%88%d9%86%d9%8a%d9%86"), + Pair("شياطين", "%d8%b4%d9%8a%d8%a7%d8%b7%d9%8a%d9%86"), + Pair("طبخ", "%d8%b7%d8%a8%d8%ae"), + Pair("طبي", "%d8%b7%d8%a8%d9%8a"), + Pair("غموض", "%d8%ba%d9%85%d9%88%d8%b6"), + Pair("فانتازي", "%d9%81%d8%a7%d9%86%d8%aa%d8%a7%d8%b2%d9%8a"), + Pair("فنون", "%d9%81%d9%86%d9%88%d9%86-%d9%82%d8%aa%d8%a7%d9%84%d9%8a%d8%a9"), + Pair("فوق", "%d9%81%d9%88%d9%82-%d8%a7%d9%84%d8%b7%d8%a8%d9%8a%d8%b9%d8%a9"), + Pair("قوى", "%d9%82%d9%88%d9%89-%d8%ae%d8%a7%d8%b1%d9%82%d8%a9"), + Pair("كوميدي", "%d9%83%d9%88%d9%85%d9%8a%d8%af%d9%8a"), + Pair("لعبة", "%d9%84%d8%b9%d8%a8%d8%a9"), + Pair("مافيا", "%d9%85%d8%a7%d9%81%d9%8a%d8%a7"), + Pair("مصاصى", "%d9%85%d8%b5%d8%a7%d8%b5%d9%89-%d8%a7%d9%84%d8%af%d9%85%d8%a7%d8%a1"), + Pair("مغامرات", "%d9%85%d8%ba%d8%a7%d9%85%d8%b1%d8%a7%d8%aa"), + Pair("ميكا", "%d9%85%d9%8a%d9%83%d8%a7"), + Pair("نفسي", "%d9%86%d9%81%d8%b3%d9%8a"), + Pair("وحوش", "%d9%88%d8%ad%d9%88%d8%b4"), + Pair("ويب-تون", "%d9%88%d9%8a%d8%a8-%d8%aa%d9%88%d9%86") + ) +} diff --git a/multisrc/overrides/wpmangastream/masterkomik/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/masterkomik/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..2be925c7d Binary files /dev/null and b/multisrc/overrides/wpmangastream/masterkomik/res/mipmap-hdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/masterkomik/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/masterkomik/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..2da032104 Binary files /dev/null and b/multisrc/overrides/wpmangastream/masterkomik/res/mipmap-mdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/masterkomik/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/masterkomik/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..8bc21baa3 Binary files /dev/null and b/multisrc/overrides/wpmangastream/masterkomik/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/masterkomik/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/masterkomik/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..9c02b6d37 Binary files /dev/null and b/multisrc/overrides/wpmangastream/masterkomik/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/masterkomik/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/masterkomik/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..42b6479b1 Binary files /dev/null and b/multisrc/overrides/wpmangastream/masterkomik/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/masterkomik/res/web_hi_res_512.png b/multisrc/overrides/wpmangastream/masterkomik/res/web_hi_res_512.png new file mode 100644 index 000000000..bb9dd6dca Binary files /dev/null and b/multisrc/overrides/wpmangastream/masterkomik/res/web_hi_res_512.png differ diff --git a/multisrc/overrides/wpmangastream/masterkomik/src/MasterKomik.kt b/multisrc/overrides/wpmangastream/masterkomik/src/MasterKomik.kt new file mode 100644 index 000000000..51115d0b8 --- /dev/null +++ b/multisrc/overrides/wpmangastream/masterkomik/src/MasterKomik.kt @@ -0,0 +1,16 @@ +package eu.kanade.tachiyomi.extension.id.masterkomik + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import okhttp3.OkHttpClient +import java.util.concurrent.TimeUnit + +class MasterKomik : WPMangaStream("MasterKomik", "https://masterkomik.com", "id") { + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() +} diff --git a/multisrc/overrides/wpmangastream/matakomik/src/Matakomik.kt b/multisrc/overrides/wpmangastream/matakomik/src/Matakomik.kt new file mode 100644 index 000000000..5c8be3260 --- /dev/null +++ b/multisrc/overrides/wpmangastream/matakomik/src/Matakomik.kt @@ -0,0 +1,24 @@ +package eu.kanade.tachiyomi.extension.id.matakomik + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import eu.kanade.tachiyomi.source.model.Page +import org.jsoup.nodes.Document +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import java.util.concurrent.TimeUnit +import okhttp3.OkHttpClient + +class Matakomik : WPMangaStream("Matakomik", "https://matakomik.com", "id") { + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() + + override fun pageListParse(document: Document): List { + return document.select("div#readerarea a").mapIndexed { i, a -> + Page(i, "", a.attr("abs:href")) + } + } +} diff --git a/multisrc/overrides/wpmangastream/nonstopscans/src/NonStopScans.kt b/multisrc/overrides/wpmangastream/nonstopscans/src/NonStopScans.kt new file mode 100644 index 000000000..b98ae916d --- /dev/null +++ b/multisrc/overrides/wpmangastream/nonstopscans/src/NonStopScans.kt @@ -0,0 +1,16 @@ +package eu.kanade.tachiyomi.extension.en.nonstopscans + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import okhttp3.OkHttpClient +import java.util.concurrent.TimeUnit + +class NonStopScans : WPMangaStream("Non-Stop Scans", "https://www.nonstopscans.com", "en") { + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() +} diff --git a/multisrc/overrides/wpmangastream/rawkuma/src/Rawkuma.kt b/multisrc/overrides/wpmangastream/rawkuma/src/Rawkuma.kt new file mode 100644 index 000000000..72992adb7 --- /dev/null +++ b/multisrc/overrides/wpmangastream/rawkuma/src/Rawkuma.kt @@ -0,0 +1,16 @@ +package eu.kanade.tachiyomi.extension.ja.rawkuma + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import okhttp3.OkHttpClient +import java.util.concurrent.TimeUnit + +class Rawkuma : WPMangaStream("Rawkuma", "https://rawkuma.com/", "ja") { + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() +} diff --git a/multisrc/overrides/wpmangastream/readkomik/src/ReadKomik.kt b/multisrc/overrides/wpmangastream/readkomik/src/ReadKomik.kt new file mode 100644 index 000000000..61d0c26d9 --- /dev/null +++ b/multisrc/overrides/wpmangastream/readkomik/src/ReadKomik.kt @@ -0,0 +1,16 @@ +package eu.kanade.tachiyomi.extension.en.readkomik + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import okhttp3.OkHttpClient +import java.util.concurrent.TimeUnit + +class ReadKomik : WPMangaStream("Readkomik", "https://readkomik.com", "en") { + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() +} diff --git a/multisrc/overrides/wpmangastream/resetscans/src/ResetScans.kt b/multisrc/overrides/wpmangastream/resetscans/src/ResetScans.kt new file mode 100644 index 000000000..b56417bad --- /dev/null +++ b/multisrc/overrides/wpmangastream/resetscans/src/ResetScans.kt @@ -0,0 +1,16 @@ +package eu.kanade.tachiyomi.extension.en.resetscans + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import okhttp3.OkHttpClient +import java.util.concurrent.TimeUnit + +class ResetScans : WPMangaStream("Reset Scans", "https://reset-scans.com", "en") { + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() +} diff --git a/multisrc/overrides/wpmangastream/sektekomik/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/sektekomik/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..176417503 Binary files /dev/null and b/multisrc/overrides/wpmangastream/sektekomik/res/mipmap-hdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/sektekomik/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/sektekomik/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..2e301fb7f Binary files /dev/null and b/multisrc/overrides/wpmangastream/sektekomik/res/mipmap-mdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/sektekomik/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/sektekomik/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..c34e090da Binary files /dev/null and b/multisrc/overrides/wpmangastream/sektekomik/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/sektekomik/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/sektekomik/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..b22d56bdc Binary files /dev/null and b/multisrc/overrides/wpmangastream/sektekomik/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/sektekomik/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/sektekomik/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..b1607f62e Binary files /dev/null and b/multisrc/overrides/wpmangastream/sektekomik/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/sektekomik/res/web_hi_res_512.png b/multisrc/overrides/wpmangastream/sektekomik/res/web_hi_res_512.png new file mode 100644 index 000000000..5ec0638c1 Binary files /dev/null and b/multisrc/overrides/wpmangastream/sektekomik/res/web_hi_res_512.png differ diff --git a/multisrc/overrides/wpmangastream/sektekomik/src/SekteKomik.kt b/multisrc/overrides/wpmangastream/sektekomik/src/SekteKomik.kt new file mode 100644 index 000000000..554bf1ee9 --- /dev/null +++ b/multisrc/overrides/wpmangastream/sektekomik/src/SekteKomik.kt @@ -0,0 +1,20 @@ +package eu.kanade.tachiyomi.extension.id.sektekomik + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import java.util.concurrent.TimeUnit +import okhttp3.OkHttpClient + +class SekteKomik : WPMangaStream("Sekte Komik", "https://sektekomik.com", "id") { + // Formerly "Sekte Komik (WP Manga Stream)" + override val id = 7866629035053218469 + + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() + +} diff --git a/multisrc/overrides/wpmangastream/sheamanga/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/sheamanga/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..4b7509ab4 Binary files /dev/null and b/multisrc/overrides/wpmangastream/sheamanga/res/mipmap-hdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/sheamanga/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/sheamanga/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..397427742 Binary files /dev/null and b/multisrc/overrides/wpmangastream/sheamanga/res/mipmap-mdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/sheamanga/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/sheamanga/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..74db56150 Binary files /dev/null and b/multisrc/overrides/wpmangastream/sheamanga/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/sheamanga/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/sheamanga/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..0184cbf4c Binary files /dev/null and b/multisrc/overrides/wpmangastream/sheamanga/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/sheamanga/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/sheamanga/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..69e0368cf Binary files /dev/null and b/multisrc/overrides/wpmangastream/sheamanga/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/sheamanga/res/web_hi_res_512.png b/multisrc/overrides/wpmangastream/sheamanga/res/web_hi_res_512.png new file mode 100644 index 000000000..2c686e748 Binary files /dev/null and b/multisrc/overrides/wpmangastream/sheamanga/res/web_hi_res_512.png differ diff --git a/multisrc/overrides/wpmangastream/sheamanga/src/SheaManga.kt b/multisrc/overrides/wpmangastream/sheamanga/src/SheaManga.kt new file mode 100644 index 000000000..5b73d5e0f --- /dev/null +++ b/multisrc/overrides/wpmangastream/sheamanga/src/SheaManga.kt @@ -0,0 +1,24 @@ +package eu.kanade.tachiyomi.extension.id.sheamanga + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import java.text.SimpleDateFormat +import java.util.Locale +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import java.util.concurrent.TimeUnit +import okhttp3.OkHttpClient + +class SheaManga : WPMangaStream( + "Shea Manga", + "https://sheamanga.my.id", + "id", + dateFormat = SimpleDateFormat("MMMM dd, yyyy", Locale.forLanguageTag("id")) +) { + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() + +} diff --git a/multisrc/overrides/wpmangastream/silencescan/src/SilenceScan.kt b/multisrc/overrides/wpmangastream/silencescan/src/SilenceScan.kt new file mode 100644 index 000000000..84bd7923f --- /dev/null +++ b/multisrc/overrides/wpmangastream/silencescan/src/SilenceScan.kt @@ -0,0 +1,109 @@ +package eu.kanade.tachiyomi.extension.pt.silencescan + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import eu.kanade.tachiyomi.source.model.Page +import eu.kanade.tachiyomi.source.model.SChapter +import eu.kanade.tachiyomi.source.model.SManga +import org.jsoup.nodes.Document +import org.jsoup.nodes.Element +import java.text.SimpleDateFormat +import java.util.Locale +import com.github.salomonbrys.kotson.array +import com.github.salomonbrys.kotson.obj +import com.github.salomonbrys.kotson.string +import com.google.gson.JsonParser +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import java.util.concurrent.TimeUnit +import okhttp3.OkHttpClient + +class SilenceScan : WPMangaStream( + "Silence Scan", + "https://silencescan.net", + "pt-BR", + SimpleDateFormat("MMMM dd, yyyy", Locale("pt", "BR")) +) { + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() + + override fun mangaDetailsParse(document: Document): SManga = SManga.create().apply { + val infoEl = document.select("div.bigcontent, div.animefull").first() + + author = infoEl.select("b:contains(Autor) + span").text() + artist = infoEl.select("b:contains(Artista) + span").text() + status = parseStatus(infoEl.select("div.imptdt:contains(Status) i").text()) + description = infoEl.select("h2:contains(Sinopse) + div p").joinToString("\n") { it.text() } + genre = infoEl.select("b:contains(Gêneros) + span a").joinToString { it.text() } + thumbnail_url = infoEl.select("div.thumb img").imgAttr() + } + + override fun chapterFromElement(element: Element): SChapter = SChapter.create().apply { + name = element.select("span.chapternum").text() + scanlator = this@SilenceScan.name + date_upload = element.select("span.chapterdate").firstOrNull()?.text() + ?.let { parseChapterDate(it) } ?: 0 + setUrlWithoutDomain(element.select("div.eph-num > a").attr("href")) + } + + override fun pageListParse(document: Document): List { + val chapterObj = document.select("script:containsData(ts_reader)").first() + .data() + .substringAfter("run(") + .substringBeforeLast(");") + .let { JSON_PARSER.parse(it) } + .obj + + if (chapterObj["sources"].array.size() == 0) { + return emptyList() + } + + val firstServerAvailable = chapterObj["sources"].array[0].obj + + return firstServerAvailable["images"].array + .mapIndexed { i, pageUrl -> Page(i, "", pageUrl.string) } + } + + override fun getGenreList(): List = listOf( + Genre("4-koma", "4-koma"), + Genre("Ação", "acao"), + Genre("Adulto", "adulto"), + Genre("Artes marciais", "artes-marciais"), + Genre("Comédia", "comedia"), + Genre("Comedy", "comedy"), + Genre("Culinária", "culinaria"), + Genre("Drama", "drama"), + Genre("Ecchi", "ecchi"), + Genre("Esporte", "esporte"), + Genre("Fantasia", "fantasia"), + Genre("Gore", "gore"), + Genre("Harém", "harem"), + Genre("Horror", "horror"), + Genre("Isekai", "isekai"), + Genre("Militar", "militar"), + Genre("Mistério", "misterio"), + Genre("Oneshot", "oneshot"), + Genre("Parcialmente Dropado", "parcialmente-dropado"), + Genre("Psicológico", "psicologico"), + Genre("Romance", "romance"), + Genre("School Life", "school-life"), + Genre("Sci-fi", "sci-fi"), + Genre("Seinen", "seinen"), + Genre("Shoujo Ai", "shoujo-ai"), + Genre("Shounen", "shounen"), + Genre("Slice of life", "slice-of-life"), + Genre("Sobrenatural", "sobrenatural"), + Genre("Supernatural", "supernatural"), + Genre("Tragédia", "tragedia"), + Genre("Vida Escolar", "vida-escolar"), + Genre("Violência sexual", "violencia-sexual"), + Genre("Yuri", "yuri") + ) + + companion object { + private val JSON_PARSER by lazy { JsonParser() } + } +} diff --git a/multisrc/overrides/wpmangastream/tempestmanga/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/tempestmanga/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..c4e7492eb Binary files /dev/null and b/multisrc/overrides/wpmangastream/tempestmanga/res/mipmap-hdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/tempestmanga/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/tempestmanga/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..1ea1c621d Binary files /dev/null and b/multisrc/overrides/wpmangastream/tempestmanga/res/mipmap-mdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/tempestmanga/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/tempestmanga/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..20b7f8844 Binary files /dev/null and b/multisrc/overrides/wpmangastream/tempestmanga/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/tempestmanga/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/tempestmanga/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..0b0700d9d Binary files /dev/null and b/multisrc/overrides/wpmangastream/tempestmanga/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/tempestmanga/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/tempestmanga/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..b1ef94223 Binary files /dev/null and b/multisrc/overrides/wpmangastream/tempestmanga/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/tempestmanga/res/web_hi_res_512.png b/multisrc/overrides/wpmangastream/tempestmanga/res/web_hi_res_512.png new file mode 100644 index 000000000..c1b465e98 Binary files /dev/null and b/multisrc/overrides/wpmangastream/tempestmanga/res/web_hi_res_512.png differ diff --git a/multisrc/overrides/wpmangastream/tempestmanga/src/TempestManga.kt b/multisrc/overrides/wpmangastream/tempestmanga/src/TempestManga.kt new file mode 100644 index 000000000..7683fceff --- /dev/null +++ b/multisrc/overrides/wpmangastream/tempestmanga/src/TempestManga.kt @@ -0,0 +1,21 @@ +package eu.kanade.tachiyomi.extension.tr.tempestmanga + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import java.text.SimpleDateFormat +import java.util.Locale +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import java.util.concurrent.TimeUnit +import okhttp3.OkHttpClient + +class TempestManga : WPMangaStream("Tempest Manga", "https://manga.tempestfansub.com", "tr", + SimpleDateFormat("MMMM dd, yyyy", Locale("tr")) +) { + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() + +} diff --git a/multisrc/overrides/wpmangastream/westmanga/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/westmanga/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..993382c03 Binary files /dev/null and b/multisrc/overrides/wpmangastream/westmanga/res/mipmap-hdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/westmanga/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/westmanga/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..93f64d95e Binary files /dev/null and b/multisrc/overrides/wpmangastream/westmanga/res/mipmap-mdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/westmanga/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/westmanga/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..4b2aad975 Binary files /dev/null and b/multisrc/overrides/wpmangastream/westmanga/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/westmanga/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/westmanga/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..904b507ab Binary files /dev/null and b/multisrc/overrides/wpmangastream/westmanga/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/westmanga/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/wpmangastream/westmanga/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..7ad91c47f Binary files /dev/null and b/multisrc/overrides/wpmangastream/westmanga/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/wpmangastream/westmanga/res/web_hi_res_512.png b/multisrc/overrides/wpmangastream/westmanga/res/web_hi_res_512.png new file mode 100644 index 000000000..96e277da3 Binary files /dev/null and b/multisrc/overrides/wpmangastream/westmanga/res/web_hi_res_512.png differ diff --git a/multisrc/overrides/wpmangastream/westmanga/src/WestManga.kt b/multisrc/overrides/wpmangastream/westmanga/src/WestManga.kt new file mode 100644 index 000000000..581f73216 --- /dev/null +++ b/multisrc/overrides/wpmangastream/westmanga/src/WestManga.kt @@ -0,0 +1,103 @@ +package eu.kanade.tachiyomi.extension.id.westmanga + +import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream +import eu.kanade.tachiyomi.source.model.SManga +import org.jsoup.nodes.Document +import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +import java.util.concurrent.TimeUnit +import okhttp3.OkHttpClient + + +class WestManga : WPMangaStream("West Manga", "https://westmanga.info", "id") { + // Formerly "West Manga (WP Manga Stream)" + override val id = 8883916630998758688 + + private val rateLimitInterceptor = RateLimitInterceptor(4) + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .addNetworkInterceptor(rateLimitInterceptor) + .build() + + override fun mangaDetailsParse(document: Document): SManga { + return SManga.create().apply { + document.select(".seriestucontent").firstOrNull()?.let { infoElement -> + genre = infoElement.select(".seriestugenre a").joinToString { it.text() } + status = parseStatus(infoElement.select(".infotable tr:contains(Status) td:last-child").firstOrNull()?.ownText()) + author = infoElement.select(".infotable tr:contains(Author) td:last-child").firstOrNull()?.ownText() + description = infoElement.select(".entry-content-single[itemprop=\"description\"]").joinToString("\n") { it.text() } + thumbnail_url = infoElement.select("div.thumb img").imgAttr() + } + } + } + override fun getGenreList(): List = listOf( + Genre("4 Koma", "344"), + Genre("Action", "13"), + Genre("Adventure", "4"), + Genre("Anthology", "1494"), + Genre("Comedy", "5"), + Genre("Cooking", "54"), + Genre("Crime", "856"), + Genre("Crossdressing", "1306"), + Genre("Demon", "64"), + Genre("Drama", "6"), + Genre("Ecchi", "14"), + Genre("Fantasy", "7"), + Genre("Game", "36"), + Genre("Gender Bender", "149"), + Genre("Genderswap", "157"), + Genre("Gore", "56"), + Genre("Gyaru", "812"), + Genre("Harem", "17"), + Genre("Historical", "44"), + Genre("Horror", "211"), + Genre("Isekai", "20"), + Genre("Isekai Action", "742"), + Genre("Josei", "164"), + Genre("Magic", "65"), + Genre("Manga", "268"), + Genre("Manhua", "32"), + Genre("Martial Art", "754"), + Genre("Martial Arts", "8"), + Genre("Mature", "46"), + Genre("Mecha", "22"), + Genre("Medical", "704"), + Genre("Medy", "1439"), + Genre("Monsters", "91"), + Genre("Music", "457"), + Genre("Mystery", "30"), + Genre("Office Workers", "1501"), + Genre("Oneshot", "405"), + Genre("Project", "313"), + Genre("Psychological", "23"), + Genre("Reincarnation", "57"), + Genre("Reinkarnasi", "1170"), + Genre("Romance", "15"), + Genre("School", "102"), + Genre("School Life", "9"), + Genre("Sci-fi", "33"), + Genre("Seinen", "18"), + Genre("Shotacon", "1070"), + Genre("Shoujo", "110"), + Genre("Shoujo Ai", "113"), + Genre("Shounen", "10"), + Genre("Shounen Ai", "shounen-ai"), + Genre("Si-fi", "776"), + Genre("Slice of Lif", "773"), + Genre("Slice of Life", "11"), + Genre("Smut", "586"), + Genre("Sports", "103"), + Genre("Super Power", "274"), + Genre("Supernatural", "34"), + Genre("Suspense", "181"), + Genre("Thriller", "170"), + Genre("Tragedy", "92"), + Genre("Urban", "1050"), + Genre("Vampire", "160"), + Genre("Video Games", "1093"), + Genre("Webtoons", "486"), + Genre("Yaoi", "yaoi"), + Genre("Zombies", "377") + ) +} diff --git a/src/all/wpmangastream/src/eu/kanade/tachiyomi/extension/all/wpmangastream/WPMangaStream.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/wpmangastream/WPMangaStream.kt similarity index 98% rename from src/all/wpmangastream/src/eu/kanade/tachiyomi/extension/all/wpmangastream/WPMangaStream.kt rename to multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/wpmangastream/WPMangaStream.kt index 4c21b36ea..05233713d 100644 --- a/src/all/wpmangastream/src/eu/kanade/tachiyomi/extension/all/wpmangastream/WPMangaStream.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/wpmangastream/WPMangaStream.kt @@ -1,10 +1,10 @@ -package eu.kanade.tachiyomi.extension.all.wpmangastream +package eu.kanade.tachiyomi.multisrc.wpmangastream import android.app.Application import android.content.SharedPreferences import android.support.v7.preference.ListPreference import android.support.v7.preference.PreferenceScreen -import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor +//import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor // added to override import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.model.Filter @@ -86,12 +86,12 @@ abstract class WPMangaStream( private fun getShowThumbnail(): Int = preferences.getInt(SHOW_THUMBNAIL_PREF, 0) - private val rateLimitInterceptor = RateLimitInterceptor(4) + //private val rateLimitInterceptor = RateLimitInterceptor(4) override val client: OkHttpClient = network.cloudflareClient.newBuilder() .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) - .addNetworkInterceptor(rateLimitInterceptor) + //.addNetworkInterceptor(rateLimitInterceptor) .build() protected fun Element.imgAttr(): String = if (this.hasAttr("data-src")) this.attr("abs:data-src") else this.attr("abs:src") diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/wpmangastream/WPMangaStreamGenerator.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/wpmangastream/WPMangaStreamGenerator.kt new file mode 100644 index 000000000..1523f3e73 --- /dev/null +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/wpmangastream/WPMangaStreamGenerator.kt @@ -0,0 +1,58 @@ +package eu.kanade.tachiyomi.multisrc.wpmangastream + +import eu.kanade.tachiyomi.multisrc.ThemeSourceData.SingleLang +import eu.kanade.tachiyomi.multisrc.ThemeSourceGenerator + +class WPMangaStreamGenerator : ThemeSourceGenerator { + + override val themePkg = "wpmangastream" + + override val themeClass = "WPMangaStream" + + override val baseVersionCode: Int = 1 + + override val sources = listOf( + SingleLang("Reset Scans", "https://reset-scans.com", "en"), + SingleLang("KlanKomik", "https://klankomik.com", "id"), + SingleLang("ChiOtaku", "https://chiotaku.com", "id"), + SingleLang("MangaShiro", "https://mangashiro.co", "id"), + SingleLang("MasterKomik", "https://masterkomik.com", "id"), + SingleLang("Kaisar Komik", "https://kaisarkomik.com", "id"), + SingleLang("Rawkuma", "https://rawkuma.com/", "ja"), + SingleLang("Flame Scans", "http://flamescans.org", "en"), + SingleLang("KomikTap", "https://komiktap.in/", "id"), + SingleLang("MangaP", "https://mangap.me", "ar"), + SingleLang("Boosei", "https://boosei.com", "id"), + SingleLang("Mangakyo", "https://www.mangakyo.me", "id"), + SingleLang("Sekte Komik", "https://sektekomik.com", "id"), + SingleLang("Komik Station", "https://komikstation.com", "id"), + SingleLang("Komik Indo", "https://www.komikindo.web.id", "id", className = "KomikIndoWPMS"), + SingleLang("Non-Stop Scans", "https://www.nonstopscans.com", "en", className = "NonStopScans"), + SingleLang("KomikIndo.co", "https://komikindo.co", "id", className = "KomikindoCo"), + SingleLang("Readkomik", "https://readkomik.com", "en", className = "ReadKomik"), + SingleLang("MangaIndonesia", "https://mangaindonesia.net", "id"), + SingleLang("Liebe Schnee Hiver", "https://www.liebeschneehiver.com", "tr"), + SingleLang("KomikRu", "https://komikru.com", "id"), + SingleLang("GURU Komik", "https://gurukomik.com", "id"), + SingleLang("Shea Manga", "https://sheamanga.my.id", "id"), + SingleLang("Kiryuu", "https://kiryuu.co", "id"), + SingleLang("Komik AV", "https://komikav.com", "id"), + SingleLang("Komik Cast", "https://komikcast.com", "id"), + SingleLang("West Manga", "https://westmanga.info", "id"), + SingleLang("Komik GO", "https://komikgo.com", "id"), + SingleLang("MangaSwat", "https://mangaswat.com", "ar"), + SingleLang("Manga Raw", "https://mangaraw.org", "ja"), + SingleLang("Matakomik", "https://matakomik.com", "id"), + SingleLang("Manga Pro Z", "https://mangaproz.com", "ar"), + SingleLang("Silence Scan", "https://silencescan.net", "pt-BR"), + SingleLang("Kuma Scans (Kuma Translation)", "https://kumascans.com", "en", className = "KumaScans"), + SingleLang("Tempest Manga", "https://manga.tempestfansub.com", "tr"), + ) + + companion object { + @JvmStatic + fun main(args: Array) { + WPMangaStreamGenerator().createAll() + } + } +} diff --git a/src/all/wpmangastream/AndroidManifest.xml b/src/all/wpmangastream/AndroidManifest.xml deleted file mode 100644 index 30deb7f79..000000000 --- a/src/all/wpmangastream/AndroidManifest.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/src/all/wpmangastream/build.gradle b/src/all/wpmangastream/build.gradle deleted file mode 100644 index 82bf44504..000000000 --- a/src/all/wpmangastream/build.gradle +++ /dev/null @@ -1,16 +0,0 @@ -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' - -ext { - extName = 'WP MangaStream (multiple sources)' - pkgNameSuffix = 'all.wpmangastream' - extClass = '.WPMangaStreamFactory' - extVersionCode = 51 - libVersion = '1.2' -} - -dependencies { - implementation project(':lib-ratelimit') -} - -apply from: "$rootDir/common.gradle" diff --git a/src/all/wpmangastream/src/eu/kanade/tachiyomi/extension/all/wpmangastream/WPMangaStreamFactory.kt b/src/all/wpmangastream/src/eu/kanade/tachiyomi/extension/all/wpmangastream/WPMangaStreamFactory.kt deleted file mode 100644 index 52370596e..000000000 --- a/src/all/wpmangastream/src/eu/kanade/tachiyomi/extension/all/wpmangastream/WPMangaStreamFactory.kt +++ /dev/null @@ -1,773 +0,0 @@ -package eu.kanade.tachiyomi.extension.all.wpmangastream - -import com.github.salomonbrys.kotson.array -import com.github.salomonbrys.kotson.obj -import com.github.salomonbrys.kotson.string -import com.google.gson.JsonParser -import eu.kanade.tachiyomi.network.GET -import eu.kanade.tachiyomi.network.asObservableSuccess -import eu.kanade.tachiyomi.source.Source -import eu.kanade.tachiyomi.source.SourceFactory -import eu.kanade.tachiyomi.source.model.Filter -import eu.kanade.tachiyomi.source.model.FilterList -import eu.kanade.tachiyomi.source.model.Page -import eu.kanade.tachiyomi.source.model.SChapter -import eu.kanade.tachiyomi.source.model.SManga -import eu.kanade.tachiyomi.util.asJsoup -import okhttp3.Headers -import okhttp3.HttpUrl -import okhttp3.Interceptor -import okhttp3.OkHttpClient -import okhttp3.Request -import okhttp3.Response -import org.jsoup.nodes.Document -import org.jsoup.nodes.Element -import rx.Observable -import java.io.IOException -import java.text.SimpleDateFormat -import java.util.Locale - -class WPMangaStreamFactory : SourceFactory { - override fun createSources(): List = listOf( - Kiryuu(), - KomikAV(), - KomikStation(), - KomikCast(), - WestManga(), - KomikGo(), - KomikIndo(), - LiebeSchneeHiver(), - SekteKomik(), - MangaSwat(), - MangaRaw(), - NonStopScans(), - KomikTap(), - Matakomik(), - KomikindoCo(), - ReadKomik(), - MangaP(), - MangaProZ(), - Boosei(), - Mangakyo(), - SilenceScan(), - SheaManga(), - FlameScans(), - GURUKomik(), - Rawkuma(), - KaisarKomik(), - MasterKomik(), - KomikRu(), - MangaShiro(), - ChiOtaku(), - KlanKomik(), - MangaIndonesia(), - ResetScans() - ) -} - -class ResetScans : WPMangaStream("Reset Scans", "https://reset-scans.com", "en") - -class MangaIndonesia : WPMangaStream("MangaIndonesia", "https://mangaindonesia.net", "id") { - override fun popularMangaRequest(page: Int): Request { -// return GET("$baseUrl/popular" + if (page > 1) "/${(page - 1) * 30}" else "", headers) -// return GET("$baseUrl/$popularPath" + if (page > 1) "?page=$page" else "", headers) - return GET("$baseUrl/update/" + if (page > 1) "?page=$page" else "", headers) - } - override fun latestUpdatesRequest(page: Int): Request { - return GET(baseUrl, headers) - } - override fun latestUpdatesSelector() = ".listupd:not(.project) .uta .imgu" - override fun latestUpdatesFromElement(element: Element): SManga { - val manga = SManga.create() - manga.thumbnail_url = element.select("a img").imgAttr() - element.select("a").first().let { - manga.setUrlWithoutDomain(it.attr("href")) - manga.title = it.attr("title") - } - return manga - } - override fun latestUpdatesNextPageSelector(): String? = null - override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { - return GET("$baseUrl/page/$page/$query", headers) - } - override fun chapterListSelector() = "div.bxcl ul li:has(span)" - override fun chapterFromElement(element: Element): SChapter { - val chapter = SChapter.create() - chapter.setUrlWithoutDomain(element.select("a").attr("href")) - chapter.name = element.select("a").text() - chapter.date_upload = element.select("span.dt").firstOrNull()?.text()?.let { parseChapterDate(it) } ?: 0 - return chapter - } -} - -class KlanKomik : WPMangaStream("KlanKomik", "https://klankomik.com", "id") - -class ChiOtaku : WPMangaStream("ChiOtaku", "https://chiotaku.com", "id") - -class LiebeSchneeHiver : WPMangaStream( - "Liebe Schnee Hiver", - "https://www.liebeschneehiver.com", - "tr", - SimpleDateFormat("MMMM dd, yyyy", Locale.forLanguageTag("tr")) -) - -class MangaShiro : WPMangaStream("MangaShiro", "https://mangashiro.co", "id") - -class KomikRu : WPMangaStream("KomikRu", "https://komikru.com", "id", SimpleDateFormat("MMMM dd, yyyy", Locale.forLanguageTag("id"))) - -class MasterKomik : WPMangaStream("MasterKomik", "https://masterkomik.com", "id") - -class KaisarKomik : WPMangaStream("Kaisar Komik", "https://kaisarkomik.com", "id") - -class Rawkuma : WPMangaStream("Rawkuma", "https://rawkuma.com/", "ja") - -class GURUKomik : WPMangaStream("GURU Komik", "https://gurukomik.com", "id", SimpleDateFormat("MMMM dd, yyyy", Locale.forLanguageTag("id"))) - -class FlameScans : WPMangaStream("Flame Scans", "http://flamescans.org", "en") - -class SheaManga : WPMangaStream( - "Shea Manga", - "https://sheamanga.my.id", - "id", - dateFormat = SimpleDateFormat("MMMM dd, yyyy", Locale.forLanguageTag("id")) -) - -class SekteKomik : WPMangaStream("Sekte Komik (WP Manga Stream)", "https://sektekomik.com", "id") - -class Kiryuu : WPMangaStream("Kiryuu (WP Manga Stream)", "https://kiryuu.co", "id") { - override fun pageListParse(document: Document): List { - return document.select("div#readerarea img").map { it.attr("abs:src") } - .filterNot { it.substringAfterLast("/").contains(Regex("""(filerun|photothumb\.db)""")) } - .mapIndexed { i, image -> Page(i, "", image) } - } -} - -class KomikAV : WPMangaStream( - "Komik AV (WP Manga Stream)", - "https://komikav.com", - "id", - dateFormat = SimpleDateFormat("MMMM dd, yyyy", Locale.forLanguageTag("id")) -) { - override fun imageRequest(page: Page): Request { - return GET(page.imageUrl!!, headers) - } -} - -class KomikStation : WPMangaStream("Komik Station (WP Manga Stream)", "https://komikstation.com", "id") - -class KomikCast : WPMangaStream("Komik Cast (WP Manga Stream)", "https://komikcast.com", "id") { - override fun popularMangaRequest(page: Int): Request { - return GET("$baseUrl/daftar-komik/page/$page/?order=popular", headers) - } - - override fun latestUpdatesRequest(page: Int): Request { - return GET("$baseUrl/komik/page/$page/", headers) - } - - override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { - val url = if (query.isNotBlank()) { - val url = HttpUrl.parse("$baseUrl/page/$page")!!.newBuilder() - val pattern = "\\s+".toRegex() - val q = query.replace(pattern, "+") - if (query.isNotEmpty()) { - url.addQueryParameter("s", q) - } else { - url.addQueryParameter("s", "") - } - url.toString() - } else { - val url = HttpUrl.parse("$baseUrl/daftar-komik/page/$page")!!.newBuilder() - var orderBy: String - (if (filters.isEmpty()) getFilterList() else filters).forEach { filter -> - when (filter) { - is StatusFilter -> url.addQueryParameter("status", arrayOf("", "ongoing", "completed")[filter.state]) - is GenreListFilter -> { - val genreInclude = mutableListOf() - filter.state.forEach { - if (it.state == 1) { - genreInclude.add(it.id) - } - } - if (genreInclude.isNotEmpty()) { - genreInclude.forEach { genre -> - url.addQueryParameter("genre[]", genre) - } - } - } - is SortByFilter -> { - orderBy = filter.toUriPart() - url.addQueryParameter("order", orderBy) - } - } - } - url.toString() - } - return GET(url, headers) - } - - override fun popularMangaFromElement(element: Element): SManga { - val manga = SManga.create() - manga.thumbnail_url = element.select("div.limit img").attr("src") - element.select("div.bigor > a").first().let { - manga.setUrlWithoutDomain(it.attr("href")) - manga.title = it.attr("title") - } - return manga - } - - override fun pageListParse(document: Document): List { - return document.select("div#readerarea img.size-full") - .mapIndexed { i, img -> Page(i, "", img.attr("abs:Src")) } - } - - override fun getFilterList() = FilterList( - Filter.Header("NOTE: Ignored if using text search!"), - Filter.Separator(), - SortByFilter(), - Filter.Separator(), - StatusFilter(), - Filter.Separator(), - GenreListFilter(getGenreList()) - ) -} - -class WestManga : WPMangaStream("West Manga (WP Manga Stream)", "https://westmanga.info", "id") { - override fun mangaDetailsParse(document: Document): SManga { - return SManga.create().apply { - document.select(".seriestucontent").firstOrNull()?.let { infoElement -> - genre = infoElement.select(".seriestugenre a").joinToString { it.text() } - status = parseStatus(infoElement.select(".infotable tr:contains(Status) td:last-child").firstOrNull()?.ownText()) - author = infoElement.select(".infotable tr:contains(Author) td:last-child").firstOrNull()?.ownText() - description = infoElement.select(".entry-content-single[itemprop=\"description\"]").joinToString("\n") { it.text() } - thumbnail_url = infoElement.select("div.thumb img").imgAttr() - } - } - } - override fun getGenreList(): List = listOf( - Genre("4 Koma", "344"), - Genre("Action", "13"), - Genre("Adventure", "4"), - Genre("Anthology", "1494"), - Genre("Comedy", "5"), - Genre("Cooking", "54"), - Genre("Crime", "856"), - Genre("Crossdressing", "1306"), - Genre("Demon", "64"), - Genre("Drama", "6"), - Genre("Ecchi", "14"), - Genre("Fantasy", "7"), - Genre("Game", "36"), - Genre("Gender Bender", "149"), - Genre("Genderswap", "157"), - Genre("Gore", "56"), - Genre("Gyaru", "812"), - Genre("Harem", "17"), - Genre("Historical", "44"), - Genre("Horror", "211"), - Genre("Isekai", "20"), - Genre("Isekai Action", "742"), - Genre("Josei", "164"), - Genre("Magic", "65"), - Genre("Manga", "268"), - Genre("Manhua", "32"), - Genre("Martial Art", "754"), - Genre("Martial Arts", "8"), - Genre("Mature", "46"), - Genre("Mecha", "22"), - Genre("Medical", "704"), - Genre("Medy", "1439"), - Genre("Monsters", "91"), - Genre("Music", "457"), - Genre("Mystery", "30"), - Genre("Office Workers", "1501"), - Genre("Oneshot", "405"), - Genre("Project", "313"), - Genre("Psychological", "23"), - Genre("Reincarnation", "57"), - Genre("Reinkarnasi", "1170"), - Genre("Romance", "15"), - Genre("School", "102"), - Genre("School Life", "9"), - Genre("Sci-fi", "33"), - Genre("Seinen", "18"), - Genre("Shotacon", "1070"), - Genre("Shoujo", "110"), - Genre("Shoujo Ai", "113"), - Genre("Shounen", "10"), - Genre("Shounen Ai", "shounen-ai"), - Genre("Si-fi", "776"), - Genre("Slice of Lif", "773"), - Genre("Slice of Life", "11"), - Genre("Smut", "586"), - Genre("Sports", "103"), - Genre("Super Power", "274"), - Genre("Supernatural", "34"), - Genre("Suspense", "181"), - Genre("Thriller", "170"), - Genre("Tragedy", "92"), - Genre("Urban", "1050"), - Genre("Vampire", "160"), - Genre("Video Games", "1093"), - Genre("Webtoons", "486"), - Genre("Yaoi", "yaoi"), - Genre("Zombies", "377") - ) -} - -class KomikGo : WPMangaStream("Komik GO (WP Manga Stream)", "https://komikgo.com", "id") { - - override fun popularMangaRequest(page: Int): Request { - return GET("$baseUrl/page/$page?s&post_type=wp-manga&m_orderby=views", headers) - } - - override fun latestUpdatesRequest(page: Int): Request { - return GET("$baseUrl/page/$page?s&post_type=wp-manga&m_orderby=latest", headers) - } - - override fun popularMangaSelector() = "div.c-tabs-item__content" - - override fun popularMangaFromElement(element: Element): SManga { - val manga = SManga.create() - manga.thumbnail_url = element.select("div.tab-thumb > a > img").attr("data-src") - element.select("div.tab-thumb > a").first().let { - manga.setUrlWithoutDomain(it.attr("href")) - manga.title = it.attr("title") - } - return manga - } - - override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { - val url = HttpUrl.parse("$baseUrl/page/$page")!!.newBuilder() - url.addQueryParameter("post_type", "wp-manga") - val pattern = "\\s+".toRegex() - val q = query.replace(pattern, "+") - if (query.isNotEmpty()) { - url.addQueryParameter("s", q) - } else { - url.addQueryParameter("s", "") - } - - var orderBy: String - - (if (filters.isEmpty()) getFilterList() else filters).forEach { filter -> - when (filter) { -// is Status -> url.addQueryParameter("manga_status", arrayOf("", "completed", "ongoing")[filter.state]) - is GenreListFilter -> { - val genreInclude = mutableListOf() - filter.state.forEach { - if (it.state == 1) { - genreInclude.add(it.id) - } - } - if (genreInclude.isNotEmpty()) { - genreInclude.forEach { genre -> - url.addQueryParameter("genre[]", genre) - } - } - } - is StatusList -> { - val statuses = mutableListOf() - filter.state.forEach { - if (it.state == 1) { - statuses.add(it.id) - } - } - if (statuses.isNotEmpty()) { - statuses.forEach { status -> - url.addQueryParameter("status[]", status) - } - } - } - - is SortBy -> { - orderBy = filter.toUriPart() - url.addQueryParameter("m_orderby", orderBy) - } - is TextField -> url.addQueryParameter(filter.key, filter.state) - } - } - - return GET(url.toString(), headers) - } - - override fun popularMangaNextPageSelector() = "#navigation-ajax" - - override fun mangaDetailsParse(document: Document): SManga { - val infoElement = document.select("div.site-content").first() - - val manga = SManga.create() - manga.author = infoElement.select("div.author-content")?.text() - manga.artist = infoElement.select("div.artist-content")?.text() - - val genres = mutableListOf() - infoElement.select("div.genres-content a").forEach { element -> - val genre = element.text() - genres.add(genre) - } - manga.genre = genres.joinToString(", ") - manga.status = parseStatus(infoElement.select("div.post-status > div:nth-child(2) div").text()) - - manga.description = document.select("div.description-summary")?.text() - manga.thumbnail_url = document.select("div.summary_image > a > img").attr("data-src") - - return manga - } - - override fun chapterListSelector() = "li.wp-manga-chapter" - - override fun chapterFromElement(element: Element): SChapter { - val urlElement = element.select("a").first() - val chapter = SChapter.create() - chapter.setUrlWithoutDomain(urlElement.attr("href")) - chapter.name = urlElement.text() - chapter.date_upload = parseChapterDate(element.select("span.chapter-release-date i").text()) - return chapter - } - - override fun pageListParse(document: Document): List { - return document.select("div.reading-content * img").mapIndexed { i, img -> - Page(i, "", img.imgAttr()) - } - } - - private class TextField(name: String, val key: String) : Filter.Text(name) - - private class SortBy : UriPartFilter( - "Sort by", - arrayOf( - Pair("Relevance", ""), - Pair("Latest", "latest"), - Pair("A-Z", "alphabet"), - Pair("Rating", "rating"), - Pair("Trending", "trending"), - Pair("Most View", "views"), - Pair("New", "new-manga") - ) - ) - - private class Status(name: String, val id: String = name) : Filter.TriState(name) - private class StatusList(statuses: List) : Filter.Group("Status", statuses) - - override fun getFilterList() = FilterList( - TextField("Author", "author"), - TextField("Year", "release"), - SortBy(), - StatusList(getStatusList()), - GenreListFilter(getGenreList()) - ) - - private fun getStatusList() = listOf( - Status("Completed", "end"), - Status("Ongoing", "on-going"), - Status("Canceled", "canceled"), - Status("Onhold", "on-hold") - ) - - override fun getGenreList(): List = 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") - ) -} - -class KomikIndo : WPMangaStream("Komik Indo (WP Manga Stream)", "https://www.komikindo.web.id", "id") - -class MangaSwat : WPMangaStream("MangaSwat", "https://mangaswat.com", "ar") { - /** - * Use IOException or the app crashes! - * x-sucuri-cache header is never present on images; specify webpages or glide won't load images! - */ - private class Sucuri : Interceptor { - override fun intercept(chain: Interceptor.Chain): Response { - val response = chain.proceed(chain.request()) - if (response.header("x-sucuri-cache").isNullOrEmpty() && response.request().url().toString().contains("//mangaswat.com")) - throw IOException("Site protected, open webview | موقع محمي ، عرض ويب مفتوح") - return response - } - } - override val client: OkHttpClient = super.client.newBuilder().addInterceptor(Sucuri()).build() - - override fun headersBuilder(): Headers.Builder = Headers.Builder() - .add("Referer", baseUrl) - .add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0") - .add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3") - - override fun mangaDetailsParse(document: Document): SManga { - return SManga.create().apply { - document.select("div.bigcontent").firstOrNull()?.let { infoElement -> - genre = infoElement.select("span:contains(التصنيف) a").joinToString { it.text() } - status = parseStatus(infoElement.select("span:contains(الحالة)").firstOrNull()?.ownText()) - author = infoElement.select("span:contains(المؤلف) i").firstOrNull()?.ownText() - artist = author - description = infoElement.select("div.desc").text() - thumbnail_url = infoElement.select("img").imgAttr() - } - } - } - override fun pageListRequest(chapter: SChapter): Request { - return GET(baseUrl + chapter.url + "?/", headers) // Bypass "linkvertise" ads - } - - override fun getFilterList() = FilterList( - StatusFilter(), - TypeFilter(), - SortByFilter(), - GenreListFilter(getGenrePairs()) - ) - - private class GenreListFilter(pairs: Array>) : UriPartFilter("Genre", pairs) - - private fun getGenrePairs() = arrayOf( - Pair("<--->", ""), - Pair("آلات", "%d8%a2%d9%84%d8%a7%d8%aa"), - Pair("أكشن", "%d8%a3%d9%83%d8%b4%d9%86"), - Pair("إثارة", "%d8%a5%d8%ab%d8%a7%d8%b1%d8%a9"), - Pair("إعادة", "%d8%a5%d8%b9%d8%a7%d8%af%d8%a9-%d8%a5%d8%ad%d9%8a%d8%a7%d8%a1"), - Pair("الحياة", "%d8%a7%d9%84%d8%ad%d9%8a%d8%a7%d8%a9-%d8%a7%d9%84%d9%85%d8%af%d8%b1%d8%b3%d9%8a%d8%a9"), - Pair("الحياة", "%d8%a7%d9%84%d8%ad%d9%8a%d8%a7%d8%a9-%d8%a7%d9%84%d9%8a%d9%88%d9%85%d9%8a%d8%a9"), - Pair("العاب", "%d8%a7%d9%84%d8%b9%d8%a7%d8%a8-%d9%81%d9%8a%d8%af%d9%8a%d9%88"), - Pair("ايتشي", "%d8%a7%d9%8a%d8%aa%d8%b4%d9%8a"), - Pair("ايسكاي", "%d8%a7%d9%8a%d8%b3%d9%83%d8%a7%d9%8a"), - Pair("بالغ", "%d8%a8%d8%a7%d9%84%d8%ba"), - Pair("تاريخي", "%d8%aa%d8%a7%d8%b1%d9%8a%d8%ae%d9%8a"), - Pair("تراجيدي", "%d8%aa%d8%b1%d8%a7%d8%ac%d9%8a%d8%af%d9%8a"), - Pair("جوسيه", "%d8%ac%d9%88%d8%b3%d9%8a%d9%87"), - Pair("جيندر", "%d8%ac%d9%8a%d9%86%d8%af%d8%b1-%d8%a8%d9%86%d8%af%d8%b1"), - Pair("حربي", "%d8%ad%d8%b1%d8%a8%d9%8a"), - Pair("حريم", "%d8%ad%d8%b1%d9%8a%d9%85"), - Pair("خارق", "%d8%ae%d8%a7%d8%b1%d9%82-%d9%84%d9%84%d8%b7%d8%a8%d9%8a%d8%b9%d8%a9"), - Pair("خيال", "%d8%ae%d9%8a%d8%a7%d9%84"), - Pair("خيال", "%d8%ae%d9%8a%d8%a7%d9%84-%d8%b9%d9%84%d9%85%d9%8a"), - Pair("دراما", "%d8%af%d8%b1%d8%a7%d9%85%d8%a7"), - Pair("دموي", "%d8%af%d9%85%d9%88%d9%8a"), - Pair("رعب", "%d8%b1%d8%b9%d8%a8"), - Pair("رومانسي", "%d8%b1%d9%88%d9%85%d8%a7%d9%86%d8%b3%d9%8a"), - Pair("رياضة", "%d8%b1%d9%8a%d8%a7%d8%b6%d8%a9"), - Pair("زمكاني", "%d8%b2%d9%85%d9%83%d8%a7%d9%86%d9%8a"), - Pair("زومبي", "%d8%b2%d9%88%d9%85%d8%a8%d9%8a"), - Pair("سحر", "%d8%b3%d8%ad%d8%b1"), - Pair("سينين", "%d8%b3%d9%8a%d9%86%d9%8a%d9%86"), - Pair("شريحة", "%d8%b4%d8%b1%d9%8a%d8%ad%d8%a9-%d9%85%d9%86-%d8%a7%d9%84%d8%ad%d9%8a%d8%a7%d8%a9"), - Pair("شوجو", "%d8%b4%d9%88%d8%ac%d9%88"), - Pair("شونين", "%d8%b4%d9%88%d9%86%d9%8a%d9%86"), - Pair("شياطين", "%d8%b4%d9%8a%d8%a7%d8%b7%d9%8a%d9%86"), - Pair("طبخ", "%d8%b7%d8%a8%d8%ae"), - Pair("طبي", "%d8%b7%d8%a8%d9%8a"), - Pair("غموض", "%d8%ba%d9%85%d9%88%d8%b6"), - Pair("فانتازي", "%d9%81%d8%a7%d9%86%d8%aa%d8%a7%d8%b2%d9%8a"), - Pair("فنون", "%d9%81%d9%86%d9%88%d9%86-%d9%82%d8%aa%d8%a7%d9%84%d9%8a%d8%a9"), - Pair("فوق", "%d9%81%d9%88%d9%82-%d8%a7%d9%84%d8%b7%d8%a8%d9%8a%d8%b9%d8%a9"), - Pair("قوى", "%d9%82%d9%88%d9%89-%d8%ae%d8%a7%d8%b1%d9%82%d8%a9"), - Pair("كوميدي", "%d9%83%d9%88%d9%85%d9%8a%d8%af%d9%8a"), - Pair("لعبة", "%d9%84%d8%b9%d8%a8%d8%a9"), - Pair("مافيا", "%d9%85%d8%a7%d9%81%d9%8a%d8%a7"), - Pair("مصاصى", "%d9%85%d8%b5%d8%a7%d8%b5%d9%89-%d8%a7%d9%84%d8%af%d9%85%d8%a7%d8%a1"), - Pair("مغامرات", "%d9%85%d8%ba%d8%a7%d9%85%d8%b1%d8%a7%d8%aa"), - Pair("ميكا", "%d9%85%d9%8a%d9%83%d8%a7"), - Pair("نفسي", "%d9%86%d9%81%d8%b3%d9%8a"), - Pair("وحوش", "%d9%88%d8%ad%d9%88%d8%b4"), - Pair("ويب-تون", "%d9%88%d9%8a%d8%a8-%d8%aa%d9%88%d9%86") - ) -} - -class MangaRaw : WPMangaStream("Manga Raw", "https://mangaraw.org", "ja") { - override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/search?order=popular&page=$page", headers) - override fun popularMangaSelector() = "div.bsx" - override fun popularMangaFromElement(element: Element): SManga { - return SManga.create().apply { - element.select("div.bigor > a").let { - setUrlWithoutDomain(it.attr("href")) - title = it.text() - } - thumbnail_url = element.select("img").attr("abs:src") - } - } - override fun popularMangaNextPageSelector() = "a[rel=next]" - override fun latestUpdatesRequest(page: Int): Request = GET("$baseUrl/search?order=update&page=$page", headers) - override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = - GET("$baseUrl/search?s=$query&page=$page") - override fun searchMangaFromElement(element: Element): SManga = popularMangaFromElement(element) - override fun mangaDetailsParse(document: Document): SManga = super.mangaDetailsParse(document) - .apply { description = document.select("div.bottom").firstOrNull()?.ownText() } - override fun fetchPageList(chapter: SChapter): Observable> { - return client.newCall(pageListRequest(chapter)) - .asObservableSuccess() - .map { response -> - pageListParse(response, baseUrl + chapter.url.removeSuffix("/")) - } - } - private fun pageListParse(response: Response, chapterUrl: String): List { - return response.asJsoup().select("span.page-link").first().ownText().substringAfterLast(" ").toInt() - .let { lastNum -> IntRange(1, lastNum) } - .map { num -> Page(num, "$chapterUrl/$num") } - } - override fun imageUrlParse(document: Document): String = document.select("a.img-block img").attr("abs:src") - override fun getFilterList(): FilterList = FilterList() -} - -class NonStopScans : WPMangaStream("Non-Stop Scans", "https://www.nonstopscans.com", "en") - -class KomikTap : WPMangaStream("KomikTap", "https://komiktap.in/", "id") - -class Matakomik : WPMangaStream("Matakomik", "https://matakomik.com", "id") { - override fun pageListParse(document: Document): List { - return document.select("div#readerarea a").mapIndexed { i, a -> - Page(i, "", a.attr("abs:href")) - } - } -} - -class KomikindoCo : WPMangaStream("Komikindo.co", "https://komikindo.co", "id") - -class ReadKomik : WPMangaStream("Readkomik", "https://readkomik.com", "en") - -class MangaP : WPMangaStream("MangaP", "https://mangap.me", "ar") - -class MangaProZ : WPMangaStream("Manga Pro Z", "https://mangaproz.com", "ar") { - override fun chapterFromElement(element: Element): SChapter = super.chapterFromElement(element).apply { name = name.removeSuffix(" free") } -} - -class Boosei : WPMangaStream("Boosei", "https://boosei.com", "id") - -class Mangakyo : WPMangaStream("Mangakyo", "https://www.mangakyo.me", "id") - -class SilenceScan : WPMangaStream( - "Silence Scan", - "https://silencescan.net", - "pt-BR", - SimpleDateFormat("MMMM dd, yyyy", Locale("pt", "BR")) -) { - - override fun mangaDetailsParse(document: Document): SManga = SManga.create().apply { - val infoEl = document.select("div.bigcontent, div.animefull").first() - - author = infoEl.select("b:contains(Autor) + span").text() - artist = infoEl.select("b:contains(Artista) + span").text() - status = parseStatus(infoEl.select("div.imptdt:contains(Status) i").text()) - description = infoEl.select("h2:contains(Sinopse) + div p").joinToString("\n") { it.text() } - genre = infoEl.select("b:contains(Gêneros) + span a").joinToString { it.text() } - thumbnail_url = infoEl.select("div.thumb img").imgAttr() - } - - override fun chapterFromElement(element: Element): SChapter = SChapter.create().apply { - name = element.select("span.chapternum").text() - scanlator = this@SilenceScan.name - date_upload = element.select("span.chapterdate").firstOrNull()?.text() - ?.let { parseChapterDate(it) } ?: 0 - setUrlWithoutDomain(element.select("div.eph-num > a").attr("href")) - } - - override fun pageListParse(document: Document): List { - val chapterObj = document.select("script:containsData(ts_reader)").first() - .data() - .substringAfter("run(") - .substringBeforeLast(");") - .let { JSON_PARSER.parse(it) } - .obj - - if (chapterObj["sources"].array.size() == 0) { - return emptyList() - } - - val firstServerAvailable = chapterObj["sources"].array[0].obj - - return firstServerAvailable["images"].array - .mapIndexed { i, pageUrl -> Page(i, "", pageUrl.string) } - } - - override fun getGenreList(): List = listOf( - Genre("4-koma", "4-koma"), - Genre("Ação", "acao"), - Genre("Adulto", "adulto"), - Genre("Artes marciais", "artes-marciais"), - Genre("Comédia", "comedia"), - Genre("Comedy", "comedy"), - Genre("Culinária", "culinaria"), - Genre("Drama", "drama"), - Genre("Ecchi", "ecchi"), - Genre("Esporte", "esporte"), - Genre("Fantasia", "fantasia"), - Genre("Gore", "gore"), - Genre("Harém", "harem"), - Genre("Horror", "horror"), - Genre("Isekai", "isekai"), - Genre("Militar", "militar"), - Genre("Mistério", "misterio"), - Genre("Oneshot", "oneshot"), - Genre("Parcialmente Dropado", "parcialmente-dropado"), - Genre("Psicológico", "psicologico"), - Genre("Romance", "romance"), - Genre("School Life", "school-life"), - Genre("Sci-fi", "sci-fi"), - Genre("Seinen", "seinen"), - Genre("Shoujo Ai", "shoujo-ai"), - Genre("Shounen", "shounen"), - Genre("Slice of life", "slice-of-life"), - Genre("Sobrenatural", "sobrenatural"), - Genre("Supernatural", "supernatural"), - Genre("Tragédia", "tragedia"), - Genre("Vida Escolar", "vida-escolar"), - Genre("Violência sexual", "violencia-sexual"), - Genre("Yuri", "yuri") - ) - - companion object { - private val JSON_PARSER by lazy { JsonParser() } - } -} diff --git a/src/id/komikcast/AndroidManifest.xml b/src/id/komikcast/AndroidManifest.xml deleted file mode 100644 index 30deb7f79..000000000 --- a/src/id/komikcast/AndroidManifest.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/src/id/komikcast/build.gradle b/src/id/komikcast/build.gradle deleted file mode 100644 index 5e6ee4525..000000000 --- a/src/id/komikcast/build.gradle +++ /dev/null @@ -1,12 +0,0 @@ -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' - -ext { - extName = 'Komikcast' - pkgNameSuffix = 'id.komikcast' - extClass = '.Komikcast' - extVersionCode = 4 - libVersion = '1.2' -} - -apply from: "$rootDir/common.gradle" diff --git a/src/id/komikcast/res/mipmap-hdpi/ic_launcher.png b/src/id/komikcast/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index 04268e84e..000000000 Binary files a/src/id/komikcast/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/src/id/komikcast/res/mipmap-mdpi/ic_launcher.png b/src/id/komikcast/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index cf1bc9812..000000000 Binary files a/src/id/komikcast/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/src/id/komikcast/res/mipmap-xhdpi/ic_launcher.png b/src/id/komikcast/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 51d53ef34..000000000 Binary files a/src/id/komikcast/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/src/id/komikcast/res/mipmap-xxhdpi/ic_launcher.png b/src/id/komikcast/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 0b0fe6651..000000000 Binary files a/src/id/komikcast/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/id/komikcast/res/mipmap-xxxhdpi/ic_launcher.png b/src/id/komikcast/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index f6857b190..000000000 Binary files a/src/id/komikcast/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/id/komikcast/res/web_hi_res_512.png b/src/id/komikcast/res/web_hi_res_512.png deleted file mode 100644 index 52d59ec72..000000000 Binary files a/src/id/komikcast/res/web_hi_res_512.png and /dev/null differ diff --git a/src/id/komikcast/src/eu/kanade/tachiyomi/extension/id/komikcast/Komikcast.kt b/src/id/komikcast/src/eu/kanade/tachiyomi/extension/id/komikcast/Komikcast.kt deleted file mode 100644 index 654b6e753..000000000 --- a/src/id/komikcast/src/eu/kanade/tachiyomi/extension/id/komikcast/Komikcast.kt +++ /dev/null @@ -1,306 +0,0 @@ -package eu.kanade.tachiyomi.extension.id.komikcast - -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 okhttp3.Headers -import okhttp3.HttpUrl -import okhttp3.OkHttpClient -import okhttp3.Request -import org.jsoup.nodes.Document -import org.jsoup.nodes.Element -import java.util.Calendar - -class Komikcast : ParsedHttpSource() { - - override val name = "Komikcast" - override val baseUrl = "https://komikcast.com" - override val lang = "id" - override val supportsLatest = true - override val client: OkHttpClient = network.cloudflareClient - - override fun popularMangaRequest(page: Int): Request { - return GET("$baseUrl/daftar-komik/page/$page/?order=popular", headers) - } - - override fun latestUpdatesRequest(page: Int): Request { - return GET("$baseUrl/komik/page/$page/", headers) - } - - override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { - val url = if (query.isNotBlank()) { - val url = HttpUrl.parse("$baseUrl/page/$page")!!.newBuilder() - val pattern = "\\s+".toRegex() - val q = query.replace(pattern, "+") - if (query.isNotEmpty()) { - url.addQueryParameter("s", q) - } else { - url.addQueryParameter("s", "") - } - url.toString() - } else { - val url = HttpUrl.parse("$baseUrl/daftar-komik/page/$page")!!.newBuilder() - var orderBy: String - (if (filters.isEmpty()) getFilterList() else filters).forEach { filter -> - when (filter) { - is Status -> url.addQueryParameter("status", arrayOf("", "ongoing", "completed")[filter.state]) - is GenreList -> { - val genreInclude = mutableListOf() - filter.state.forEach { - if (it.state == 1) { - genreInclude.add(it.id) - } - } - if (genreInclude.isNotEmpty()) { - genreInclude.forEach { genre -> - url.addQueryParameter("genre[]", genre) - } - } - } - is SortBy -> { - orderBy = filter.toUriPart() - url.addQueryParameter("order", orderBy) - } - } - } - url.toString() - } - return GET(url, headers) - } - - override fun popularMangaSelector() = "div.bs" - override fun latestUpdatesSelector() = popularMangaSelector() - override fun searchMangaSelector() = popularMangaSelector() - - override fun popularMangaFromElement(element: Element): SManga { - val manga = SManga.create() - manga.thumbnail_url = element.select("div.limit img").attr("src") - element.select("div.bigor > a").first().let { - manga.setUrlWithoutDomain(it.attr("href")) - manga.title = it.attr("title") - } - return manga - } - - override fun searchMangaFromElement(element: Element): SManga = popularMangaFromElement(element) - override fun latestUpdatesFromElement(element: Element): SManga = popularMangaFromElement(element) - - override fun popularMangaNextPageSelector() = "a.next.page-numbers" - override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector() - override fun searchMangaNextPageSelector() = popularMangaNextPageSelector() - - override fun mangaDetailsParse(document: Document): SManga { - val infoElement = document.select("div.spe").first() - val sepName = infoElement.select(".spe > span:nth-child(4)").last() - val manga = SManga.create() - manga.author = sepName.ownText() - manga.artist = sepName.ownText() - val genres = mutableListOf() - infoElement.select(".spe > span:nth-child(1) > a").forEach { element -> - val genre = element.text() - genres.add(genre) - } - manga.genre = genres.joinToString(", ") - manga.status = parseStatus(infoElement.select(".spe > span:nth-child(2)").text()) - manga.description = document.select("div[^itemprop]").last().text() - manga.thumbnail_url = document.select(".thumb > img:nth-child(1)").attr("src") - - return manga - } - - private fun parseStatus(element: String): Int = when { - - element.toLowerCase().contains("ongoing") -> SManga.ONGOING - element.toLowerCase().contains("completed") -> SManga.COMPLETED - else -> SManga.UNKNOWN - } - - override fun chapterListSelector() = "div.cl ul li" - - override fun chapterFromElement(element: Element): SChapter { - val urlElement = element.select("a").first() - val timeElement = element.select("span.rightoff").first() - val chapter = SChapter.create() - chapter.setUrlWithoutDomain(urlElement.attr("href")) - chapter.name = urlElement.text() - chapter.date_upload = parseChapterDate(timeElement.text()) - return chapter - } - - private fun parseChapterDate(date: String): Long { - val value = date.split(' ')[0].toInt() - - return when { - "mins" in date -> Calendar.getInstance().apply { - add(Calendar.MINUTE, value * -1) - }.timeInMillis - "hours" in date -> Calendar.getInstance().apply { - add(Calendar.HOUR_OF_DAY, value * -1) - }.timeInMillis - "days" in date -> Calendar.getInstance().apply { - add(Calendar.DATE, value * -1) - }.timeInMillis - "weeks" in date -> Calendar.getInstance().apply { - add(Calendar.DATE, value * 7 * -1) - }.timeInMillis - "months" in date -> Calendar.getInstance().apply { - add(Calendar.MONTH, value * -1) - }.timeInMillis - "years" in date -> Calendar.getInstance().apply { - add(Calendar.YEAR, value * -1) - }.timeInMillis - "min" in date -> Calendar.getInstance().apply { - add(Calendar.MINUTE, value * -1) - }.timeInMillis - "hour" in date -> Calendar.getInstance().apply { - add(Calendar.HOUR_OF_DAY, value * -1) - }.timeInMillis - "day" in date -> Calendar.getInstance().apply { - add(Calendar.DATE, value * -1) - }.timeInMillis - "week" in date -> Calendar.getInstance().apply { - add(Calendar.DATE, value * 7 * -1) - }.timeInMillis - "month" in date -> Calendar.getInstance().apply { - add(Calendar.MONTH, value * -1) - }.timeInMillis - "year" in date -> Calendar.getInstance().apply { - add(Calendar.YEAR, value * -1) - }.timeInMillis - else -> { - return 0 - } - } - } - - override fun prepareNewChapter(chapter: SChapter, manga: SManga) { - val basic = Regex("""Chapter\s([0-9]+)""") - when { - basic.containsMatchIn(chapter.name) -> { - basic.find(chapter.name)?.let { - chapter.chapter_number = it.groups[1]?.value!!.toFloat() - } - } - } - } - - override fun pageListParse(document: Document): List { - val pages = mutableListOf() - var i = 0 - document.select("div#readerarea img").forEach { element -> - val url = element.attr("src") - i++ - if (url.isNotEmpty()) { - pages.add(Page(i, "", url)) - } - } - return pages - } - - override fun imageUrlParse(document: Document) = "" - - override fun imageRequest(page: Page): Request { - val headers = Headers.Builder() - headers.apply { - add("Referer", baseUrl) - add("User-Agent", "Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.100 Mobile Safari/537.36") - } - - if (page.imageUrl!!.contains("i0.wp.com")) { - headers.apply { - add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3") - } - } - return GET(page.imageUrl!!, headers.build()) - } - - private class SortBy : UriPartFilter( - "Sort by", - arrayOf( - Pair("Default", ""), - Pair("A-Z", "title"), - Pair("Z-A", "titlereverse"), - Pair("Latest Update", "update"), - Pair("Latest Added", "latest"), - Pair("Popular", "popular") - ) - ) - - private class Status : UriPartFilter( - "Status", - arrayOf( - Pair("All", ""), - Pair("Ongoing", "Ongoing"), - Pair("Completed", "Completed") - ) - ) - - private class Genre(name: String, val id: String = name) : Filter.TriState(name) - private class GenreList(genres: List) : Filter.Group("Genres", genres) - - override fun getFilterList() = FilterList( - Filter.Header("NOTE: Ignored if using text search!"), - Filter.Separator(), - SortBy(), - Filter.Separator(), - Status(), - Filter.Separator(), - GenreList(getGenreList()) - ) - - private fun getGenreList() = listOf( - Genre("4-Koma", "4-koma"), - Genre("Action", "action"), - Genre("Adventure", "adventure"), - Genre("Comedy", "comedy"), - Genre("Cooking", "cooking"), - Genre("Demons", "demons"), - 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("Magic", "magic"), - Genre("Martial Arts", "martial-arts"), - Genre("Mature", "mature"), - Genre("Mecha", "mecha"), - Genre("Medical", "medical"), - Genre("Military", "military"), - Genre("Mistery", "mistery"), - Genre("Music", "music"), - Genre("Mystery", "mystery"), - Genre("Psychological", "psychological"), - Genre("Romance", "romance"), - 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("Yuri", "yuri") - ) - - private open class UriPartFilter(displayName: String, val vals: Array>) : - Filter.Select(displayName, vals.map { it.first }.toTypedArray()) { - fun toUriPart() = vals[state].second - } -} diff --git a/src/id/komikindo/AndroidManifest.xml b/src/id/komikindo/AndroidManifest.xml deleted file mode 100644 index 30deb7f79..000000000 --- a/src/id/komikindo/AndroidManifest.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/src/id/komikindo/build.gradle b/src/id/komikindo/build.gradle deleted file mode 100644 index dd43a70e3..000000000 --- a/src/id/komikindo/build.gradle +++ /dev/null @@ -1,12 +0,0 @@ -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' - -ext { - extName = 'Komik Indo' - pkgNameSuffix = 'id.komikindo' - extClass = '.KomikIndo' - extVersionCode = 1 - libVersion = '1.2' -} - -apply from: "$rootDir/common.gradle" diff --git a/src/id/komikindo/src/eu/kanade/tachiyomi/extension/id/komikindo/KomikIndo.kt b/src/id/komikindo/src/eu/kanade/tachiyomi/extension/id/komikindo/KomikIndo.kt deleted file mode 100644 index ec1cdb5f1..000000000 --- a/src/id/komikindo/src/eu/kanade/tachiyomi/extension/id/komikindo/KomikIndo.kt +++ /dev/null @@ -1,235 +0,0 @@ -package eu.kanade.tachiyomi.extension.id.komikindo - -import android.annotation.SuppressLint -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 okhttp3.Headers -import okhttp3.HttpUrl -import okhttp3.OkHttpClient -import okhttp3.Request -import org.jsoup.nodes.Document -import org.jsoup.nodes.Element -import java.text.SimpleDateFormat -import java.util.Calendar - -class KomikIndo : ParsedHttpSource() { - - override val name = "Komik Indo" - override val baseUrl = "https://www.komikindo.web.id" - override val lang = "id" - override val supportsLatest = true - override val client: OkHttpClient = network.cloudflareClient - - override fun popularMangaRequest(page: Int): Request { - val url = if (page == 1) baseUrl else "$baseUrl/page/$page" - return GET(url, headers) - } - - override fun latestUpdatesRequest(page: Int): Request { - val url = if (page == 1) "$baseUrl/manga/" else "$baseUrl/manga/page/$page" - return GET(url, headers) - } - - override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { - var builtUrl = if (page == 1) "$baseUrl/manga/" else "$baseUrl/manga/page/$page/" - if (query != "") { - builtUrl = if (page == 1) "$baseUrl/search/$query/" else "$baseUrl/search/$query/page/$page/" - } else if (filters.size > 0) { - filters.forEach { filter -> - when (filter) { - is GenreListFilter -> { - builtUrl = if (page == 1) "$baseUrl/genres/" + filter.toUriPart() else "$baseUrl/genres/" + filter.toUriPart() + "/page/$page/" - } - } - } - } - val url = HttpUrl.parse(builtUrl)!!.newBuilder() - return GET(url.build().toString(), headers) - } - - override fun popularMangaSelector() = "div.lchap > .lch > .ch" - override fun latestUpdatesSelector() = "div.ctf > div.lsmin > div.chl" - override fun searchMangaSelector() = latestUpdatesSelector() - - override fun popularMangaFromElement(element: Element): SManga { - val manga = SManga.create() - manga.thumbnail_url = element.select("div.thumbnail img").first().attr("src") - element.select("div.l > h3 > a").first().let { - manga.setUrlWithoutDomain(it.attr("href")) - manga.title = it.text() - } - return manga - } - - override fun searchMangaFromElement(element: Element): SManga { - val manga = SManga.create() - manga.thumbnail_url = element.select("div.thumbnail img").first().attr("src") - element.select("div.chlf > h2 > a").first().let { - manga.setUrlWithoutDomain(it.attr("href")) - manga.title = it.text() - } - return manga - } - - override fun latestUpdatesFromElement(element: Element): SManga = searchMangaFromElement(element) - - override fun popularMangaNextPageSelector() = "a.next.page-numbers" - override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector() - override fun searchMangaNextPageSelector() = popularMangaNextPageSelector() - - override fun mangaDetailsParse(document: Document): SManga { - val infoElm = document.select(".listinfo > ul > li") - val manga = SManga.create() - infoElm.forEach { element -> - val infoTitle = element.select("b").text().toLowerCase() - val infoContent = element.text() - when { - infoTitle.contains("status") -> manga.status = parseStatus(infoContent) - infoTitle.contains("author") -> manga.author = infoContent - infoTitle.contains("artist") -> manga.artist = infoContent - infoTitle.contains("genres") -> { - val genres = mutableListOf() - element.select("a").forEach { a -> - val genre = a.text() - genres.add(genre) - } - manga.genre = genres.joinToString(", ") - } - } - } - manga.description = document.select("div.rm > span > p:first-child").text() - manga.thumbnail_url = document.select("div.animeinfo .lm .imgdesc img:first-child").attr("src") - return manga - } - - private fun parseStatus(element: String): Int = when { - element.toLowerCase().contains("completed") -> SManga.COMPLETED - element.toLowerCase().contains("ongoing") -> SManga.ONGOING - else -> SManga.UNKNOWN - } - - override fun chapterListSelector() = "div.cl ul li" - - override fun chapterFromElement(element: Element): SChapter { - val urlElement = element.select(".leftoff > a").first() - val chapter = SChapter.create() - val timeElement = element.select("span.rightoff").first() - chapter.setUrlWithoutDomain(urlElement.attr("href")) - chapter.name = urlElement.text() - chapter.date_upload = parseChapterDate(timeElement.text()) - return chapter - } - - @SuppressLint("SimpleDateFormat") - private fun parseChapterDate(date: String): Long { - val sdf = SimpleDateFormat("MMM dd, yyyy") - val cal = Calendar.getInstance() - cal.time = sdf.parse(date)!! - return cal.timeInMillis - } - - override fun prepareNewChapter(chapter: SChapter, manga: SManga) { - val basic = Regex("""Chapter\s([0-9]+)""") - when { - basic.containsMatchIn(chapter.name) -> { - basic.find(chapter.name)?.let { - chapter.chapter_number = it.groups[1]?.value!!.toFloat() - } - } - } - } - - override fun pageListParse(document: Document): List { - val pages = mutableListOf() - var i = 0 - document.select("div#readerarea img").forEach { element -> - val url = element.attr("src") - i++ - if (url.isNotEmpty()) { - pages.add(Page(i, "", url)) - } - } - return pages - } - - override fun imageUrlParse(document: Document) = "" - - override fun imageRequest(page: Page): Request { - val imgHeader = Headers.Builder().apply { - add("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36") - add("Referer", baseUrl) - }.build() - return GET(page.imageUrl!!, imgHeader) - } - - private class GenreListFilter : UriPartFilter( - "Genre", - arrayOf( - Pair("Default", ""), - Pair("4-Koma", "4-koma"), - Pair("Action", "action"), - Pair("Adventure", "adventure"), - Pair("Comedy", "comedy"), - Pair("Cooking", "cooking"), - Pair("Crime", "crime"), - Pair("Dark Fantasy", "dark-fantasy"), - Pair("Demons", "demons"), - Pair("Drama", "drama"), - Pair("Ecchi", "ecchi"), - Pair("Fantasy", "fantasy"), - Pair("Game", "game"), - Pair("Gender Bender", "gender-bender"), - Pair("Harem", "harem"), - Pair("Historical", "historical"), - Pair("Horor", "horor"), - Pair("Horror", "horror"), - Pair("Isekai", "isekai"), - Pair("Josei", "josei"), - Pair("Komik Tamat", "komik-tamat"), - Pair("Life", "life"), - Pair("Magic", "magic"), - Pair("Manhua", "manhua"), - Pair("Martial Art", "martial-art"), - Pair("Martial Arts", "martial-arts"), - Pair("Mature", "mature"), - Pair("Mecha", "mecha"), - Pair("Military", "military"), - Pair("Music", "music"), - Pair("Mystery", "mystery"), - Pair("Post-Apocalyptic", "post-apocalyptic"), - Pair("Psychological", "psychological"), - Pair("Romance", "romance"), - Pair("School", "school"), - Pair("School Life", "school-life"), - Pair("Sci-Fi", "sci-fi"), - Pair("Seinen", "seinen"), - Pair("Shonen", "shonen"), - Pair("Shoujo", "shoujo"), - Pair("Shounen", "shounen"), - Pair("Slice of Life", "slice-of-life"), - Pair("Sports", "sports"), - Pair("Super Power", "super-power"), - Pair("Superheroes", "superheroes"), - Pair("Supernatural", "supernatural"), - Pair("Survival", "survival"), - Pair("Thriller", "thriller"), - Pair("Tragedy", "tragedy"), - Pair("Zombies", "zombies") - ) - ) - - override fun getFilterList() = FilterList( - Filter.Header("NOTE: filter will be ignored when using text search!"), - GenreListFilter() - ) - - private open class UriPartFilter(displayName: String, val vals: Array>) : - Filter.Select(displayName, vals.map { it.first }.toTypedArray()) { - fun toUriPart() = vals[state].second - } -}