From d7418f4b5fb1caa526e61c14dc73092c983821d1 Mon Sep 17 00:00:00 2001 From: bapeey <90949336+bapeey@users.noreply.github.com> Date: Thu, 24 Oct 2024 06:43:24 -0500 Subject: [PATCH] Keyoapp: Update cdn of sources and add paid chapters preference (#5666) * update cdn and move preference to theme * lint --- .../assets/i18n/messages_en.properties | 3 + lib-multisrc/keyoapp/build.gradle.kts | 6 +- .../tachiyomi/multisrc/keyoapp/Keyoapp.kt | 54 ++++++++++++-- .../tachiyomi/extension/ar/scans4u/Scans4u.kt | 10 ++- .../extension/en/arvencomics/ArvenComics.kt | 2 + .../tachiyomi/extension/en/ezmanga/EZmanga.kt | 2 + .../extension/en/luascans/LuaScans.kt | 2 +- .../extension/en/magusmanga/MagusManga.kt | 6 +- .../extension/en/necroscans/NecroScans.kt | 8 ++- .../extension/en/rezoscans/RezoScans.kt | 4 +- .../extension/en/suryascans/GenzToons.kt | 70 ++----------------- 11 files changed, 87 insertions(+), 80 deletions(-) create mode 100644 lib-multisrc/keyoapp/assets/i18n/messages_en.properties diff --git a/lib-multisrc/keyoapp/assets/i18n/messages_en.properties b/lib-multisrc/keyoapp/assets/i18n/messages_en.properties new file mode 100644 index 000000000..bb835eafb --- /dev/null +++ b/lib-multisrc/keyoapp/assets/i18n/messages_en.properties @@ -0,0 +1,3 @@ +pref_show_paid_chapter_title=Display paid chapters +pref_show_paid_chapter_summary_on=Paid chapters will appear. +pref_show_paid_chapter_summary_off=Only free chapters will be displayed. diff --git a/lib-multisrc/keyoapp/build.gradle.kts b/lib-multisrc/keyoapp/build.gradle.kts index f0ad544d5..7ef91ecaf 100644 --- a/lib-multisrc/keyoapp/build.gradle.kts +++ b/lib-multisrc/keyoapp/build.gradle.kts @@ -2,4 +2,8 @@ plugins { id("lib-multisrc") } -baseVersionCode = 7 +baseVersionCode = 8 + +dependencies { + api(project(":lib:i18n")) +} diff --git a/lib-multisrc/keyoapp/src/eu/kanade/tachiyomi/multisrc/keyoapp/Keyoapp.kt b/lib-multisrc/keyoapp/src/eu/kanade/tachiyomi/multisrc/keyoapp/Keyoapp.kt index b7c0d3a08..73bab2b48 100644 --- a/lib-multisrc/keyoapp/src/eu/kanade/tachiyomi/multisrc/keyoapp/Keyoapp.kt +++ b/lib-multisrc/keyoapp/src/eu/kanade/tachiyomi/multisrc/keyoapp/Keyoapp.kt @@ -1,6 +1,12 @@ package eu.kanade.tachiyomi.multisrc.keyoapp +import android.app.Application +import android.content.SharedPreferences +import androidx.preference.PreferenceScreen +import androidx.preference.SwitchPreferenceCompat +import eu.kanade.tachiyomi.lib.i18n.Intl import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.model.Filter import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.MangasPage @@ -17,6 +23,8 @@ import okhttp3.Request import okhttp3.Response import org.jsoup.nodes.Document import org.jsoup.nodes.Element +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get import uy.kohesive.injekt.injectLazy import java.text.ParseException import java.text.SimpleDateFormat @@ -27,7 +35,12 @@ abstract class Keyoapp( override val name: String, override val baseUrl: String, final override val lang: String, -) : ParsedHttpSource() { +) : ParsedHttpSource(), ConfigurableSource { + + protected val preferences: SharedPreferences by lazy { + Injekt.get().getSharedPreferences("source_$id", 0x0000) + } + override val supportsLatest = true override val client = network.cloudflareClient @@ -39,6 +52,13 @@ abstract class Keyoapp( private val dateFormat = SimpleDateFormat("MMM d, yyyy", Locale.ENGLISH) + protected val intl = Intl( + language = lang, + baseLanguage = "en", + availableLanguages = setOf("en", "pt-BR", "es"), + classLoader = this::class.java.classLoader!!, + ) + // Popular override fun popularMangaRequest(page: Int): Request = GET(baseUrl, headers) @@ -218,7 +238,12 @@ abstract class Keyoapp( // Chapter list - override fun chapterListSelector(): String = "#chapters > a:not(:has(.text-sm span:matches(Upcoming)))" + override fun chapterListSelector(): String { + if (!preferences.showPaidChapters) { + return "#chapters > a:not(:has(.text-sm span:matches(Upcoming))):not(:has(img[src*=Coin.svg]))" + } + return "#chapters > a:not(:has(.text-sm span:matches(Upcoming)))" + } override fun chapterFromElement(element: Element): SChapter = SChapter.create().apply { setUrlWithoutDomain(element.selectFirst("a[href]")!!.attr("href")) @@ -226,6 +251,9 @@ abstract class Keyoapp( element.selectFirst(".text-xs")?.run { date_upload = text().trim().parseDate() } + if (element.select("img[src*=Coin.svg]").isNotEmpty()) { + name = "🔒 $name" + } } // Image list @@ -235,7 +263,7 @@ abstract class Keyoapp( .map { it.attr("uid") } .filter { it.isNotEmpty() } .mapIndexed { index, img -> - Page(index, document.location(), "$cdnUrl/uploads/$img") + Page(index, document.location(), "$cdnUrl/$img") } .takeIf { it.isNotEmpty() } ?.also { return it } @@ -249,7 +277,7 @@ abstract class Keyoapp( } } - protected val cdnUrl = "https://cdn.igniscans.com" + protected open val cdnUrl = "https://2xffbs-cn8.is1.buzz/uploads" private val oldImgCdnRegex = Regex("""^(https?:)?//cdn\d*\.keyoapp\.com""") @@ -315,4 +343,22 @@ abstract class Keyoapp( } return now.timeInMillis } + + override fun setupPreferenceScreen(screen: PreferenceScreen) { + SwitchPreferenceCompat(screen.context).apply { + key = SHOW_PAID_CHAPTERS_PREF + title = intl["pref_show_paid_chapter_title"] + summaryOn = intl["pref_show_paid_chapter_summary_on"] + summaryOff = intl["pref_show_paid_chapter_summary_off"] + setDefaultValue(SHOW_PAID_CHAPTERS_DEFAULT) + }.also(screen::addPreference) + } + + protected val SharedPreferences.showPaidChapters: Boolean + get() = getBoolean(SHOW_PAID_CHAPTERS_PREF, SHOW_PAID_CHAPTERS_DEFAULT) + + companion object { + private const val SHOW_PAID_CHAPTERS_PREF = "pref_show_paid_chap" + private const val SHOW_PAID_CHAPTERS_DEFAULT = false + } } diff --git a/src/ar/scans4u/src/eu/kanade/tachiyomi/extension/ar/scans4u/Scans4u.kt b/src/ar/scans4u/src/eu/kanade/tachiyomi/extension/ar/scans4u/Scans4u.kt index 5503daa42..1760fb79e 100644 --- a/src/ar/scans4u/src/eu/kanade/tachiyomi/extension/ar/scans4u/Scans4u.kt +++ b/src/ar/scans4u/src/eu/kanade/tachiyomi/extension/ar/scans4u/Scans4u.kt @@ -2,4 +2,12 @@ package eu.kanade.tachiyomi.extension.ar.scans4u import eu.kanade.tachiyomi.multisrc.keyoapp.Keyoapp -class Scans4u : Keyoapp("Scans 4u", "https://4uscans.com", "ar") +class Scans4u : Keyoapp("Scans 4u", "https://4uscans.com", "ar") { + + override fun chapterListSelector(): String { + if (!preferences.showPaidChapters) { + return "#chapters > a:not(:has(.text-sm span:matches(قادم))):not(:has(img[src*=Coin.svg]))" + } + return "#chapters > a:not(:has(.text-sm span:matches(قادم)))" + } +} diff --git a/src/en/arvencomics/src/eu/kanade/tachiyomi/extension/en/arvencomics/ArvenComics.kt b/src/en/arvencomics/src/eu/kanade/tachiyomi/extension/en/arvencomics/ArvenComics.kt index b52b1b65e..84c412bf7 100644 --- a/src/en/arvencomics/src/eu/kanade/tachiyomi/extension/en/arvencomics/ArvenComics.kt +++ b/src/en/arvencomics/src/eu/kanade/tachiyomi/extension/en/arvencomics/ArvenComics.kt @@ -9,4 +9,6 @@ class ArvenComics : Keyoapp( ) { // migrated from Mangathemesia to Keyoapp override val versionId = 2 + + override val cdnUrl = "https://3xfsjdlc.is1.buzz/uploads" } diff --git a/src/en/ezmanga/src/eu/kanade/tachiyomi/extension/en/ezmanga/EZmanga.kt b/src/en/ezmanga/src/eu/kanade/tachiyomi/extension/en/ezmanga/EZmanga.kt index a52a663fb..e88e036ee 100644 --- a/src/en/ezmanga/src/eu/kanade/tachiyomi/extension/en/ezmanga/EZmanga.kt +++ b/src/en/ezmanga/src/eu/kanade/tachiyomi/extension/en/ezmanga/EZmanga.kt @@ -9,4 +9,6 @@ class EZmanga : Keyoapp( ) { // Migrated from Madara to Keyoapp override val versionId = 2 + + override val cdnUrl = "https://3xfsjdlc.is1.buzz/uploads" } diff --git a/src/en/luascans/src/eu/kanade/tachiyomi/extension/en/luascans/LuaScans.kt b/src/en/luascans/src/eu/kanade/tachiyomi/extension/en/luascans/LuaScans.kt index 632c0d540..3ffea0d33 100644 --- a/src/en/luascans/src/eu/kanade/tachiyomi/extension/en/luascans/LuaScans.kt +++ b/src/en/luascans/src/eu/kanade/tachiyomi/extension/en/luascans/LuaScans.kt @@ -10,5 +10,5 @@ class LuaScans : Keyoapp( // migrated from MangaThemesia to Keyoapp override val versionId = 2 - override fun chapterListSelector() = "${super.chapterListSelector()}:not(:has(img[src^='/assets/images/Coin.svg']))" + override val cdnUrl = "https://3xfsjdlc.is1.buzz/uploads" } diff --git a/src/en/magusmanga/src/eu/kanade/tachiyomi/extension/en/magusmanga/MagusManga.kt b/src/en/magusmanga/src/eu/kanade/tachiyomi/extension/en/magusmanga/MagusManga.kt index ea0cabef2..f8cab15eb 100644 --- a/src/en/magusmanga/src/eu/kanade/tachiyomi/extension/en/magusmanga/MagusManga.kt +++ b/src/en/magusmanga/src/eu/kanade/tachiyomi/extension/en/magusmanga/MagusManga.kt @@ -15,6 +15,8 @@ class MagusManga : Keyoapp( ) { override val versionId = 2 + override val cdnUrl = "https://3xfsjdlc.is1.buzz/uploads" + override val client = network.cloudflareClient.newBuilder() .addInterceptor(::captchaInterceptor) .rateLimitHost(baseUrl.toHttpUrl(), 1) @@ -39,8 +41,4 @@ class MagusManga : Keyoapp( return response } - - override fun chapterListSelector(): String { - return "${super.chapterListSelector()}:not(:has(img[src*=coin]))" - } } diff --git a/src/en/necroscans/src/eu/kanade/tachiyomi/extension/en/necroscans/NecroScans.kt b/src/en/necroscans/src/eu/kanade/tachiyomi/extension/en/necroscans/NecroScans.kt index 69fedc3c0..74e955e35 100644 --- a/src/en/necroscans/src/eu/kanade/tachiyomi/extension/en/necroscans/NecroScans.kt +++ b/src/en/necroscans/src/eu/kanade/tachiyomi/extension/en/necroscans/NecroScans.kt @@ -2,4 +2,10 @@ package eu.kanade.tachiyomi.extension.en.necroscans import eu.kanade.tachiyomi.multisrc.keyoapp.Keyoapp -class NecroScans : Keyoapp("Necro Scans", "https://necroscans.com", "en") +class NecroScans : Keyoapp( + "Necro Scans", + "https://necroscans.com", + "en", +) { + override val cdnUrl = "https://3xfsjdlc.is1.buzz/uploads" +} diff --git a/src/en/rezoscans/src/eu/kanade/tachiyomi/extension/en/rezoscans/RezoScans.kt b/src/en/rezoscans/src/eu/kanade/tachiyomi/extension/en/rezoscans/RezoScans.kt index 5d28f77ae..6af18a08b 100644 --- a/src/en/rezoscans/src/eu/kanade/tachiyomi/extension/en/rezoscans/RezoScans.kt +++ b/src/en/rezoscans/src/eu/kanade/tachiyomi/extension/en/rezoscans/RezoScans.kt @@ -6,6 +6,4 @@ class RezoScans : Keyoapp( "Rezo Scans", "https://rezoscans.com", "en", -) { - override fun chapterListSelector() = "${super.chapterListSelector()}:not(:has(img[src^='/assets/images/Coin.svg']))" -} +) diff --git a/src/en/suryascans/src/eu/kanade/tachiyomi/extension/en/suryascans/GenzToons.kt b/src/en/suryascans/src/eu/kanade/tachiyomi/extension/en/suryascans/GenzToons.kt index 81d84fdf2..a8aa4f674 100644 --- a/src/en/suryascans/src/eu/kanade/tachiyomi/extension/en/suryascans/GenzToons.kt +++ b/src/en/suryascans/src/eu/kanade/tachiyomi/extension/en/suryascans/GenzToons.kt @@ -1,30 +1,14 @@ package eu.kanade.tachiyomi.extension.en.suryascans -import android.app.Application -import android.content.SharedPreferences -import androidx.preference.PreferenceScreen -import androidx.preference.SwitchPreferenceCompat import eu.kanade.tachiyomi.multisrc.keyoapp.Keyoapp import eu.kanade.tachiyomi.network.interceptor.rateLimit -import eu.kanade.tachiyomi.source.ConfigurableSource -import eu.kanade.tachiyomi.source.model.Page -import eu.kanade.tachiyomi.source.model.SChapter -import org.jsoup.nodes.Document -import org.jsoup.nodes.Element -import uy.kohesive.injekt.Injekt -import uy.kohesive.injekt.api.get import java.util.concurrent.TimeUnit -class GenzToons : - Keyoapp( - "Genz Toons", - "https://genzupdates.com", - "en", - ), - ConfigurableSource { - - private val preferences: SharedPreferences = - Injekt.get().getSharedPreferences("source_$id", 0x0000) +class GenzToons : Keyoapp( + "Genz Toons", + "https://genzupdates.com", + "en", +) { override val client = super.client.newBuilder() .rateLimit(3) @@ -32,48 +16,4 @@ class GenzToons : .writeTimeout(90, TimeUnit.SECONDS) .readTimeout(90, TimeUnit.SECONDS) .build() - - override fun chapterListSelector(): String { - if (!preferences.showPaidChapters) { - return "#chapters > a:not(:has(.text-sm span:matches(Upcoming))):not(:has(img[src*=Coin.svg]))" - } - return "#chapters > a:not(:has(.text-sm span:matches(Upcoming)))" - } - - override fun chapterFromElement(element: Element): SChapter { - return super.chapterFromElement(element).apply { - if (element.select("img[src*=Coin.svg]").isNotEmpty()) { - name = "🔒 $name" - } - } - } - - override fun pageListParse(document: Document): List { - val script = document.select("#pages > script").joinToString("\n") { it.data() } - val realCdnUrl = CDN_URL_REGEX.find(script)?.groupValues?.get(1)?.takeIf { it.startsWith("http") } - ?: "$baseUrl/uploads/" - return document.select("#pages > img") - .mapIndexed { index, img -> - Page(index, document.location(), realCdnUrl + img.attr("uid")) - } - } - - override fun setupPreferenceScreen(screen: PreferenceScreen) { - SwitchPreferenceCompat(screen.context).apply { - key = SHOW_PAID_CHAPTERS_PREF - title = "Display paid chapters" - summaryOn = "Paid chapters will appear." - summaryOff = "Only free chapters will be displayed." - setDefaultValue(SHOW_PAID_CHAPTERS_DEFAULT) - }.also(screen::addPreference) - } - - private val SharedPreferences.showPaidChapters: Boolean - get() = getBoolean(SHOW_PAID_CHAPTERS_PREF, SHOW_PAID_CHAPTERS_DEFAULT) - - companion object { - private const val SHOW_PAID_CHAPTERS_PREF = "pref_show_paid_chap" - private const val SHOW_PAID_CHAPTERS_DEFAULT = false - private val CDN_URL_REGEX = """realUrl\s*=\s*`([^`]+?)\$""".toRegex() - } }