diff --git a/.github/workflows/issue_moderator.yml b/.github/workflows/issue_moderator.yml index c2351752d..47eecb5de 100644 --- a/.github/workflows/issue_moderator.yml +++ b/.github/workflows/issue_moderator.yml @@ -50,7 +50,7 @@ jobs: }, { "type": "both", - "regex": ".*(komiktap|gourmet\\s*scans|mangawow|hikari\\s*scans|mangagegecesi|knightnoscanlations|ahstudios|mangagecesi|nartag|xxx\\s*yaoi|yaoi\\s*fan\\s*clube|luminous|dragontea|hunters\\s*scan|reset(?:\\s*|-)scan|astra\\s*scans|manganoon|manga(?:-|\\s*)pro|coven\\s*scans?|shinobiscans|plot ?twist ?no ?fansub(?: ?scans?)?|plot-twistnf-scans(?:\\.com)?|mhscans|aresmanga|realm ?scans?).*", + "regex": ".*(komiktap|gourmet\\s*scans|mangawow|hikari\\s*scans|mangagegecesi|knightnoscanlations|ahstudios|mangagecesi|nartag|xxx\\s*yaoi|yaoi\\s*fan\\s*clube|luminous|hunters\\s*scan|reset(?:\\s*|-)scan|astra\\s*scans|manganoon|manga(?:-|\\s*)pro|coven\\s*scans?|shinobiscans|plot ?twist ?no ?fansub(?: ?scans?)?|plot-twistnf-scans(?:\\.com)?|mhscans|aresmanga|realm ?scans?).*", "ignoreCase": true, "labels": ["invalid"], "message": "{match} will not be added back as the scanlator team has requested it to be removed. Read #3475 for more information." diff --git a/REMOVED_SOURCES.md b/REMOVED_SOURCES.md index 7aebfd951..365f776f7 100644 --- a/REMOVED_SOURCES.md +++ b/REMOVED_SOURCES.md @@ -30,7 +30,6 @@ - ARES Manga https://github.com/tachiyomiorg/tachiyomi-extensions/issues/15396 - Astra Scans https://github.com/tachiyomiorg/tachiyomi-extensions/issues/13845 - Coven Scan https://github.com/tachiyomiorg/tachiyomi-extensions/issues/14499 -- Dragontea https://github.com/tachiyomiorg/tachiyomi-extensions/issues/10103 - Gourmet Scans https://github.com/tachiyomiorg/tachiyomi-extensions/issues/6192 - Hikari Scans https://github.com/tachiyomiorg/tachiyomi-extensions/issues/6611 - Hunter Scans https://github.com/tachiyomiorg/tachiyomi-extensions/issues/12392 diff --git a/multisrc/overrides/madara/dragontea/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/madara/dragontea/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..4a0a1be93 Binary files /dev/null and b/multisrc/overrides/madara/dragontea/res/mipmap-hdpi/ic_launcher.png differ diff --git a/multisrc/overrides/madara/dragontea/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/madara/dragontea/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..b98556d7b Binary files /dev/null and b/multisrc/overrides/madara/dragontea/res/mipmap-mdpi/ic_launcher.png differ diff --git a/multisrc/overrides/madara/dragontea/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/madara/dragontea/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..b88025065 Binary files /dev/null and b/multisrc/overrides/madara/dragontea/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/madara/dragontea/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/madara/dragontea/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..025bf31d4 Binary files /dev/null and b/multisrc/overrides/madara/dragontea/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/madara/dragontea/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/madara/dragontea/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..f271a3464 Binary files /dev/null and b/multisrc/overrides/madara/dragontea/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/madara/dragontea/res/web_hi_res_512.png b/multisrc/overrides/madara/dragontea/res/web_hi_res_512.png new file mode 100644 index 000000000..845fde910 Binary files /dev/null and b/multisrc/overrides/madara/dragontea/res/web_hi_res_512.png differ diff --git a/multisrc/overrides/madara/dragontea/src/DragonTea.kt b/multisrc/overrides/madara/dragontea/src/DragonTea.kt new file mode 100644 index 000000000..d8502af46 --- /dev/null +++ b/multisrc/overrides/madara/dragontea/src/DragonTea.kt @@ -0,0 +1,126 @@ +package eu.kanade.tachiyomi.extension.en.dragontea + +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.graphics.Canvas +import android.graphics.Rect +import eu.kanade.tachiyomi.multisrc.madara.Madara +import eu.kanade.tachiyomi.network.interceptor.rateLimit +import eu.kanade.tachiyomi.source.model.Page +import okhttp3.Interceptor +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.OkHttpClient +import okhttp3.Protocol +import okhttp3.Response +import okhttp3.ResponseBody.Companion.toResponseBody +import org.jsoup.nodes.Document +import java.io.ByteArrayOutputStream +import java.text.SimpleDateFormat +import java.util.Locale + +class DragonTea : Madara( + "DragonTea", + "https://dragontea.ink", + "en", + dateFormat = SimpleDateFormat("MM/dd/yyyy", Locale.US), +) { + override val client: OkHttpClient = super.client.newBuilder() + .addInterceptor(::begonepeconIntercept) + .rateLimit(1) + .build() + + override val mangaSubString = "novel" + + override val useNewChapterEndpoint = true + + override fun searchPage(page: Int): String { + return if (page > 1) { + "page/$page/" + } else { + "" + } + } + + private val begonepeconSelector: String = "div.begonepecon" + + private val peconholderSelector: String = "div.peconholder" + + override fun pageListParse(document: Document): List { + countViews(document) + + val hasSplitImages = document + .select(begonepeconSelector) + .firstOrNull() != null + + if (!hasSplitImages) { + return super.pageListParse(document) + } + + return document.select("div.page-break, li.blocks-gallery-item, $begonepeconSelector") + .mapIndexed { index, element -> + val imageUrl = if (element.select(peconholderSelector).firstOrNull() == null) { + element.select("img").first()?.let { it.absUrl(if (it.hasAttr("data-src")) "data-src" else "src") } + } else { + element.select("img").joinToString("|") { it.absUrl(if (it.hasAttr("data-src")) "data-src" else "src") } + BEGONEPECON_SUFFIX + } + Page(index, document.location(), imageUrl) + } + } + + private fun begonepeconIntercept(chain: Interceptor.Chain): Response { + if (!chain.request().url.toString().endsWith(BEGONEPECON_SUFFIX)) { + return chain.proceed(chain.request()) + } + + val imageUrls = chain.request().url.toString() + .removeSuffix(BEGONEPECON_SUFFIX) + .split("%7C") + + var width = 0 + var height = 0 + + val imageBitmaps = imageUrls.map { imageUrl -> + val request = chain.request().newBuilder().url(imageUrl).build() + val response = chain.proceed(request) + + val bitmap = BitmapFactory.decodeStream(response.body.byteStream()) + + width += bitmap.width + height = bitmap.height + + bitmap + } + + val result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) + val canvas = Canvas(result) + + var left = 0 + + imageBitmaps.forEach { bitmap -> + val srcRect = Rect(0, 0, bitmap.width, bitmap.height) + val dstRect = Rect(left, 0, left + bitmap.width, bitmap.height) + + canvas.drawBitmap(bitmap, srcRect, dstRect, null) + + left += bitmap.width + } + + val output = ByteArrayOutputStream() + result.compress(Bitmap.CompressFormat.PNG, 100, output) + + val responseBody = output.toByteArray().toResponseBody(PNG_MEDIA_TYPE) + + return Response.Builder() + .code(200) + .protocol(Protocol.HTTP_1_1) + .request(chain.request()) + .message("OK") + .body(responseBody) + .build() + } + + companion object { + private const val BEGONEPECON_SUFFIX = "?begonepecon" + private val PNG_MEDIA_TYPE = "image/png".toMediaType() + } +} diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/madara/MadaraGenerator.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/madara/MadaraGenerator.kt index 80a405a67..d07785acb 100644 --- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/madara/MadaraGenerator.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/madara/MadaraGenerator.kt @@ -81,6 +81,7 @@ class MadaraGenerator : ThemeSourceGenerator { SingleLang("DokkoManga", "https://dokkomanga.com", "es", overrideVersionCode = 1), SingleLang("Doodmanga", "https://www.doodmanga.com", "th"), SingleLang("DoujinHentai", "https://doujinhentai.net", "es", isNsfw = true, overrideVersionCode = 1), + SingleLang("DragonTea", "https://dragontea.ink", "en"), SingleLang("DragonTranslation.net", "https://dragontranslation.net", "es", isNsfw = true, className = "DragonTranslationNet"), SingleLang("Drake Scans", "https://drakescans.com", "en", overrideVersionCode = 3), SingleLang("Dream Manga", "https://www.swarmmanga.com", "en", overrideVersionCode = 3),