Imperfect Comics: Moved from Madara to wpMangaStream (#11088)
* Remove Imperfect from Madara * Delete multisrc/overrides/madara/imperfectcomics directory * Add icons * Sorted and added Imperfect Comics
|
@ -1,115 +0,0 @@
|
||||||
package eu.kanade.tachiyomi.extension.en.imperfectcomics
|
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
|
||||||
import android.graphics.BitmapFactory
|
|
||||||
import android.graphics.Canvas
|
|
||||||
import android.graphics.ColorMatrix
|
|
||||||
import android.graphics.ColorMatrixColorFilter
|
|
||||||
import android.graphics.Matrix
|
|
||||||
import android.graphics.Paint
|
|
||||||
import eu.kanade.tachiyomi.multisrc.madara.Madara
|
|
||||||
import eu.kanade.tachiyomi.source.model.Page
|
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
|
||||||
import okhttp3.Interceptor
|
|
||||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
|
||||||
import okhttp3.OkHttpClient
|
|
||||||
import okhttp3.Response
|
|
||||||
import okhttp3.ResponseBody.Companion.toResponseBody
|
|
||||||
import org.jsoup.nodes.Document
|
|
||||||
import java.io.ByteArrayOutputStream
|
|
||||||
import java.io.InputStream
|
|
||||||
import java.text.SimpleDateFormat
|
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
|
||||||
class ImperfectComics : Madara("Imperfect Comics", "https://imperfectcomic.com", "en", SimpleDateFormat("yyyy-MM-dd")) {
|
|
||||||
|
|
||||||
override val useNewChapterEndpoint: Boolean = true
|
|
||||||
|
|
||||||
override val client: OkHttpClient = network.cloudflareClient.newBuilder()
|
|
||||||
.connectTimeout(10, TimeUnit.SECONDS)
|
|
||||||
.readTimeout(30, TimeUnit.SECONDS)
|
|
||||||
.addInterceptor(::imageIntercept)
|
|
||||||
.build()
|
|
||||||
|
|
||||||
override fun pageListParse(document: Document): List<Page> {
|
|
||||||
val mangaId = document.select("#manga-reading-nav-head").attr("data-id")
|
|
||||||
val chapterId = document.select("#wp-manga-current-chap").attr("data-id")
|
|
||||||
val mangaRegex = """div\[data-id=\"$mangaId\"(?:.|\n)*?(?=\})""".toRegex()
|
|
||||||
val chapterRegex = """input\[data-id=\"$chapterId\"(?:.|\n)*?(?=\})""".toRegex()
|
|
||||||
val css = document.selectFirst("#wp-custom-css").html()
|
|
||||||
|
|
||||||
// Checking for chapter first to handle mirrored manga with specific un-mirrored chapters
|
|
||||||
val props = chapterRegex.find(css).let { cId ->
|
|
||||||
cId?.value ?: mangaRegex.find(css).let { mId ->
|
|
||||||
mId?.value ?: ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
countViews(document)
|
|
||||||
|
|
||||||
return document.select(pageListParseSelector).mapIndexed { index, element ->
|
|
||||||
val imageUrl = element.selectFirst("img")?.let {
|
|
||||||
it.absUrl(if (it.hasAttr("data-src")) "data-src" else "src")
|
|
||||||
}!!.toHttpUrlOrNull()!!.newBuilder()
|
|
||||||
|
|
||||||
if (props.contains("transform: scaleX(-1)"))
|
|
||||||
imageUrl.addQueryParameter("mirror", "1")
|
|
||||||
if (props.contains("invert"))
|
|
||||||
imageUrl.addQueryParameter("invert", "1")
|
|
||||||
|
|
||||||
Page(index, document.location(), imageUrl.toString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun imageIntercept(chain: Interceptor.Chain): Response {
|
|
||||||
var request = chain.request()
|
|
||||||
val mirror = request.url.queryParameter("mirror") != null
|
|
||||||
val invert = request.url.queryParameter("invert") != null
|
|
||||||
|
|
||||||
if (!(mirror || invert)) {
|
|
||||||
return chain.proceed(request)
|
|
||||||
}
|
|
||||||
|
|
||||||
val newUrl = request.url.newBuilder()
|
|
||||||
.removeAllQueryParameters("mirror")
|
|
||||||
.removeAllQueryParameters("invert")
|
|
||||||
.build()
|
|
||||||
request = request.newBuilder().url(newUrl).build()
|
|
||||||
|
|
||||||
val response = chain.proceed(request)
|
|
||||||
val image = processImage(response.body!!.byteStream(), mirror, invert)
|
|
||||||
val body = image.toResponseBody("image/png".toMediaTypeOrNull())
|
|
||||||
|
|
||||||
response.close()
|
|
||||||
|
|
||||||
return response.newBuilder().body(body).build()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun processImage(image: InputStream, mirror: Boolean, invert: Boolean): ByteArray {
|
|
||||||
var input = BitmapFactory.decodeStream(image)
|
|
||||||
val matrix = Matrix().apply { postScale(-1F, 1F, input.width / 2F, input.height / 2F) }
|
|
||||||
val paint = Paint().apply {
|
|
||||||
colorFilter = ColorMatrixColorFilter(
|
|
||||||
ColorMatrix().apply {
|
|
||||||
set(
|
|
||||||
floatArrayOf(
|
|
||||||
-1f, 0f, 0f, 0f, 255f,
|
|
||||||
0f, -1f, 0f, 0f, 255f,
|
|
||||||
0f, 0f, -1f, 0f, 255f,
|
|
||||||
0f, 0f, 0f, 1f, 0f
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mirror)
|
|
||||||
input = Bitmap.createBitmap(input, 0, 0, input.width, input.height, matrix, true)
|
|
||||||
if (invert)
|
|
||||||
Canvas(input).drawBitmap(input, 0f, 0f, paint)
|
|
||||||
|
|
||||||
val output = ByteArrayOutputStream()
|
|
||||||
input.compress(Bitmap.CompressFormat.PNG, 100, output)
|
|
||||||
return output.toByteArray()
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 127 KiB After Width: | Height: | Size: 127 KiB |
|
@ -133,7 +133,6 @@ class MadaraGenerator : ThemeSourceGenerator {
|
||||||
SingleLang("Ichirin No Hana Yuri", "https://ichirinnohanayuri.com.br", "pt-BR", overrideVersionCode = 3),
|
SingleLang("Ichirin No Hana Yuri", "https://ichirinnohanayuri.com.br", "pt-BR", overrideVersionCode = 3),
|
||||||
SingleLang("Ikifeng", "https://ikifeng.com", "es", isNsfw = true),
|
SingleLang("Ikifeng", "https://ikifeng.com", "es", isNsfw = true),
|
||||||
SingleLang("Immortal Updates", "https://immortalupdates.com", "en", overrideVersionCode = 2),
|
SingleLang("Immortal Updates", "https://immortalupdates.com", "en", overrideVersionCode = 2),
|
||||||
SingleLang("Imperfect Comics", "https://imperfectcomic.com", "en", overrideVersionCode = 4),
|
|
||||||
SingleLang("Império Scans", "https://imperioscans.com.br", "pt-BR", className = "ImperioScans", overrideVersionCode = 1),
|
SingleLang("Império Scans", "https://imperioscans.com.br", "pt-BR", className = "ImperioScans", overrideVersionCode = 1),
|
||||||
SingleLang("InfraFandub", "https://infrafandub.xyz", "es"),
|
SingleLang("InfraFandub", "https://infrafandub.xyz", "es"),
|
||||||
SingleLang("Inmortal Scan", "https://manga.mundodrama.site", "es"),
|
SingleLang("Inmortal Scan", "https://manga.mundodrama.site", "es"),
|
||||||
|
|
|
@ -14,45 +14,46 @@ class WPMangaStreamGenerator : ThemeSourceGenerator {
|
||||||
|
|
||||||
override val sources = listOf(
|
override val sources = listOf(
|
||||||
MultiLang("Asura Scans", "https://www.asurascans.com", listOf("en", "tr"), className = "AsuraScansFactory", pkgName = "asurascans", overrideVersionCode = 11),
|
MultiLang("Asura Scans", "https://www.asurascans.com", listOf("en", "tr"), className = "AsuraScansFactory", pkgName = "asurascans", overrideVersionCode = 11),
|
||||||
|
SingleLang("Boosei", "https://boosei.com", "id", overrideVersionCode = 1),
|
||||||
|
SingleLang("GURU Komik", "https://gurukomik.com", "id"),
|
||||||
|
SingleLang("GoGoManga", "https://gogomanga.org", "en"),
|
||||||
|
SingleLang("Imagine Scan", "https://imaginescan.com.br", "pt-BR", isNsfw = true, overrideVersionCode = 1),
|
||||||
|
SingleLang("Imperfect Comics", "https://imperfectcomic.com", "en", overrideVersionCode = 8),
|
||||||
SingleLang("Infernal Void Scans", "https://infernalvoidscans.com", "en", overrideVersionCode = 3),
|
SingleLang("Infernal Void Scans", "https://infernalvoidscans.com", "en", overrideVersionCode = 3),
|
||||||
|
SingleLang("Kaisar Komik", "https://kaisarkomik.com", "id", overrideVersionCode = 1),
|
||||||
SingleLang("KlanKomik", "https://klankomik.com", "id", overrideVersionCode = 1),
|
SingleLang("KlanKomik", "https://klankomik.com", "id", overrideVersionCode = 1),
|
||||||
SingleLang("Kombatch", "https://kombatch.com", "id"),
|
SingleLang("Kombatch", "https://kombatch.com", "id"),
|
||||||
SingleLang("MasterKomik", "https://masterkomik.com", "id", overrideVersionCode = 1),
|
|
||||||
SingleLang("Kaisar Komik", "https://kaisarkomik.com", "id", overrideVersionCode = 1),
|
|
||||||
SingleLang("Rawkuma", "https://rawkuma.com/", "ja"),
|
|
||||||
SingleLang("Boosei", "https://boosei.com", "id", overrideVersionCode = 1),
|
|
||||||
SingleLang("Mangakyo", "https://www.mangakyo.me", "id"),
|
|
||||||
SingleLang("Sekte Komik", "https://sektekomik.com", "id", overrideVersionCode = 3),
|
|
||||||
SingleLang("Komik Station", "https://komikstation.com", "id", overrideVersionCode = 2),
|
|
||||||
SingleLang("Non-Stop Scans", "https://www.nonstopscans.com", "en", className = "NonStopScans"),
|
|
||||||
SingleLang("KomikIndo.co", "https://komikindo.co", "id", className = "KomikindoCo", overrideVersionCode = 3),
|
|
||||||
SingleLang("Readkomik", "https://readkomik.com", "en", className = "ReadKomik", overrideVersionCode = 1),
|
|
||||||
SingleLang("MangaIndonesia", "https://mangaindonesia.net", "id"),
|
|
||||||
SingleLang("GoGoManga", "https://gogomanga.org", "en"),
|
|
||||||
SingleLang("GURU Komik", "https://gurukomik.com", "id"),
|
|
||||||
SingleLang("Shea Manga", "http://sheamanga.my.id", "id", overrideVersionCode = 3),
|
|
||||||
SingleLang("Komik AV", "https://komikav.com", "id", overrideVersionCode = 1),
|
SingleLang("Komik AV", "https://komikav.com", "id", overrideVersionCode = 1),
|
||||||
SingleLang("Komik Cast", "https://komikcast.com", "id", overrideVersionCode = 9),
|
SingleLang("Komik Cast", "https://komikcast.com", "id", overrideVersionCode = 9),
|
||||||
SingleLang("West Manga", "https://westmanga.info", "id", overrideVersionCode = 1),
|
SingleLang("Komik Station", "https://komikstation.com", "id", overrideVersionCode = 2),
|
||||||
SingleLang("MangaSwat", "https://swatmanga.co", "ar", overrideVersionCode = 6),
|
SingleLang("KomikIndo.co", "https://komikindo.co", "id", className = "KomikindoCo", overrideVersionCode = 3),
|
||||||
SingleLang("Manga Raw.org", "https://mangaraw.org", "ja", className = "MangaRawOrg", overrideVersionCode = 1),
|
|
||||||
SingleLang("Manga Pro Z", "https://mangaprotm.com", "ar", overrideVersionCode = 1),
|
|
||||||
SingleLang("Mihentai", "https://mihentai.com", "en", isNsfw = true, overrideVersionCode = 1),
|
|
||||||
SingleLang("Kuma Scans (Kuma Translation)", "https://kumascans.com", "en", className = "KumaScans", overrideVersionCode = 1),
|
|
||||||
SingleLang("Tempest Manga", "https://manga.tempestfansub.com", "tr"),
|
|
||||||
SingleLang("xCaliBR Scans", "https://xcalibrscans.com", "en", overrideVersionCode = 3),
|
|
||||||
SingleLang("NoxSubs", "https://noxsubs.com", "tr"),
|
|
||||||
SingleLang("The Apollo Team", "https://theapollo.team", "en"),
|
|
||||||
SingleLang("Sekte Doujin", "https://sektedoujin.xyz", "id", isNsfw = true, overrideVersionCode = 2),
|
|
||||||
SingleLang("Phoenix Fansub", "https://phoenixfansub.com", "es", overrideVersionCode = 2),
|
|
||||||
SingleLang("Imagine Scan", "https://imaginescan.com.br", "pt-BR", isNsfw = true, overrideVersionCode = 1),
|
|
||||||
SingleLang("Vapo Scan", "https://vaposcans.com", "pt-BR", overrideVersionCode = 3),
|
|
||||||
SingleLang("Snudae Scans", "https://snudaescans.com", "en", isNsfw = true, className = "BatotoScans", overrideVersionCode = 1),
|
|
||||||
SingleLang("Random Scans", "https://randomscans.xyz", "en"),
|
|
||||||
SingleLang("Phantom Scans", "https://phantomscans.com", "en", overrideVersionCode = 1),
|
|
||||||
SingleLang("Omega Scans", "https://omegascans.org", "en", isNsfw = true),
|
|
||||||
SingleLang("TukangKomik", "https://tukangkomik.com", "id"),
|
|
||||||
SingleLang("Komiksay", "https://komiksay.com", "id"),
|
SingleLang("Komiksay", "https://komiksay.com", "id"),
|
||||||
|
SingleLang("Kuma Scans (Kuma Translation)", "https://kumascans.com", "en", className = "KumaScans", overrideVersionCode = 1),
|
||||||
|
SingleLang("Manga Pro Z", "https://mangaprotm.com", "ar", overrideVersionCode = 1),
|
||||||
|
SingleLang("Manga Raw.org", "https://mangaraw.org", "ja", className = "MangaRawOrg", overrideVersionCode = 1),
|
||||||
|
SingleLang("MangaIndonesia", "https://mangaindonesia.net", "id"),
|
||||||
|
SingleLang("MangaSwat", "https://swatmanga.co", "ar", overrideVersionCode = 6),
|
||||||
|
SingleLang("Mangakyo", "https://www.mangakyo.me", "id"),
|
||||||
|
SingleLang("MasterKomik", "https://masterkomik.com", "id", overrideVersionCode = 1),
|
||||||
|
SingleLang("Mihentai", "https://mihentai.com", "en", isNsfw = true, overrideVersionCode = 1),
|
||||||
|
SingleLang("Non-Stop Scans", "https://www.nonstopscans.com", "en", className = "NonStopScans"),
|
||||||
|
SingleLang("NoxSubs", "https://noxsubs.com", "tr"),
|
||||||
|
SingleLang("Omega Scans", "https://omegascans.org", "en", isNsfw = true),
|
||||||
|
SingleLang("Phantom Scans", "https://phantomscans.com", "en", overrideVersionCode = 1),
|
||||||
|
SingleLang("Phoenix Fansub", "https://phoenixfansub.com", "es", overrideVersionCode = 2),
|
||||||
|
SingleLang("Random Scans", "https://randomscans.xyz", "en"),
|
||||||
|
SingleLang("Rawkuma", "https://rawkuma.com/", "ja"),
|
||||||
|
SingleLang("Readkomik", "https://readkomik.com", "en", className = "ReadKomik", overrideVersionCode = 1),
|
||||||
|
SingleLang("Sekte Doujin", "https://sektedoujin.xyz", "id", isNsfw = true, overrideVersionCode = 2),
|
||||||
|
SingleLang("Sekte Komik", "https://sektekomik.com", "id", overrideVersionCode = 3),
|
||||||
|
SingleLang("Shea Manga", "http://sheamanga.my.id", "id", overrideVersionCode = 3),
|
||||||
|
SingleLang("Snudae Scans", "https://snudaescans.com", "en", isNsfw = true, className = "BatotoScans", overrideVersionCode = 1),
|
||||||
|
SingleLang("Tempest Manga", "https://manga.tempestfansub.com", "tr"),
|
||||||
|
SingleLang("The Apollo Team", "https://theapollo.team", "en"),
|
||||||
|
SingleLang("TukangKomik", "https://tukangkomik.com", "id"),
|
||||||
|
SingleLang("Vapo Scan", "https://vaposcans.com", "pt-BR", overrideVersionCode = 3),
|
||||||
|
SingleLang("West Manga", "https://westmanga.info", "id", overrideVersionCode = 1),
|
||||||
|
SingleLang("xCaliBR Scans", "https://xcalibrscans.com", "en", overrideVersionCode = 3),
|
||||||
)
|
)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|