Keyoapp: Update cdn of sources and add paid chapters preference (#5666)
* update cdn and move preference to theme * lint
This commit is contained in:
parent
b1c2054428
commit
d7418f4b5f
|
@ -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.
|
|
@ -2,4 +2,8 @@ plugins {
|
||||||
id("lib-multisrc")
|
id("lib-multisrc")
|
||||||
}
|
}
|
||||||
|
|
||||||
baseVersionCode = 7
|
baseVersionCode = 8
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
api(project(":lib:i18n"))
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
package eu.kanade.tachiyomi.multisrc.keyoapp
|
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.network.GET
|
||||||
|
import eu.kanade.tachiyomi.source.ConfigurableSource
|
||||||
import eu.kanade.tachiyomi.source.model.Filter
|
import eu.kanade.tachiyomi.source.model.Filter
|
||||||
import eu.kanade.tachiyomi.source.model.FilterList
|
import eu.kanade.tachiyomi.source.model.FilterList
|
||||||
import eu.kanade.tachiyomi.source.model.MangasPage
|
import eu.kanade.tachiyomi.source.model.MangasPage
|
||||||
|
@ -17,6 +23,8 @@ import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
import org.jsoup.nodes.Element
|
import org.jsoup.nodes.Element
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.text.ParseException
|
import java.text.ParseException
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
|
@ -27,7 +35,12 @@ abstract class Keyoapp(
|
||||||
override val name: String,
|
override val name: String,
|
||||||
override val baseUrl: String,
|
override val baseUrl: String,
|
||||||
final override val lang: String,
|
final override val lang: String,
|
||||||
) : ParsedHttpSource() {
|
) : ParsedHttpSource(), ConfigurableSource {
|
||||||
|
|
||||||
|
protected val preferences: SharedPreferences by lazy {
|
||||||
|
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
|
||||||
|
}
|
||||||
|
|
||||||
override val supportsLatest = true
|
override val supportsLatest = true
|
||||||
|
|
||||||
override val client = network.cloudflareClient
|
override val client = network.cloudflareClient
|
||||||
|
@ -39,6 +52,13 @@ abstract class Keyoapp(
|
||||||
|
|
||||||
private val dateFormat = SimpleDateFormat("MMM d, yyyy", Locale.ENGLISH)
|
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
|
// Popular
|
||||||
|
|
||||||
override fun popularMangaRequest(page: Int): Request = GET(baseUrl, headers)
|
override fun popularMangaRequest(page: Int): Request = GET(baseUrl, headers)
|
||||||
|
@ -218,7 +238,12 @@ abstract class Keyoapp(
|
||||||
|
|
||||||
// Chapter list
|
// 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 {
|
override fun chapterFromElement(element: Element): SChapter = SChapter.create().apply {
|
||||||
setUrlWithoutDomain(element.selectFirst("a[href]")!!.attr("href"))
|
setUrlWithoutDomain(element.selectFirst("a[href]")!!.attr("href"))
|
||||||
|
@ -226,6 +251,9 @@ abstract class Keyoapp(
|
||||||
element.selectFirst(".text-xs")?.run {
|
element.selectFirst(".text-xs")?.run {
|
||||||
date_upload = text().trim().parseDate()
|
date_upload = text().trim().parseDate()
|
||||||
}
|
}
|
||||||
|
if (element.select("img[src*=Coin.svg]").isNotEmpty()) {
|
||||||
|
name = "🔒 $name"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Image list
|
// Image list
|
||||||
|
@ -235,7 +263,7 @@ abstract class Keyoapp(
|
||||||
.map { it.attr("uid") }
|
.map { it.attr("uid") }
|
||||||
.filter { it.isNotEmpty() }
|
.filter { it.isNotEmpty() }
|
||||||
.mapIndexed { index, img ->
|
.mapIndexed { index, img ->
|
||||||
Page(index, document.location(), "$cdnUrl/uploads/$img")
|
Page(index, document.location(), "$cdnUrl/$img")
|
||||||
}
|
}
|
||||||
.takeIf { it.isNotEmpty() }
|
.takeIf { it.isNotEmpty() }
|
||||||
?.also { return it }
|
?.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""")
|
private val oldImgCdnRegex = Regex("""^(https?:)?//cdn\d*\.keyoapp\.com""")
|
||||||
|
|
||||||
|
@ -315,4 +343,22 @@ abstract class Keyoapp(
|
||||||
}
|
}
|
||||||
return now.timeInMillis
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,4 +2,12 @@ package eu.kanade.tachiyomi.extension.ar.scans4u
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.multisrc.keyoapp.Keyoapp
|
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(قادم)))"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -9,4 +9,6 @@ class ArvenComics : Keyoapp(
|
||||||
) {
|
) {
|
||||||
// migrated from Mangathemesia to Keyoapp
|
// migrated from Mangathemesia to Keyoapp
|
||||||
override val versionId = 2
|
override val versionId = 2
|
||||||
|
|
||||||
|
override val cdnUrl = "https://3xfsjdlc.is1.buzz/uploads"
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,4 +9,6 @@ class EZmanga : Keyoapp(
|
||||||
) {
|
) {
|
||||||
// Migrated from Madara to Keyoapp
|
// Migrated from Madara to Keyoapp
|
||||||
override val versionId = 2
|
override val versionId = 2
|
||||||
|
|
||||||
|
override val cdnUrl = "https://3xfsjdlc.is1.buzz/uploads"
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,5 +10,5 @@ class LuaScans : Keyoapp(
|
||||||
// migrated from MangaThemesia to Keyoapp
|
// migrated from MangaThemesia to Keyoapp
|
||||||
override val versionId = 2
|
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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@ class MagusManga : Keyoapp(
|
||||||
) {
|
) {
|
||||||
override val versionId = 2
|
override val versionId = 2
|
||||||
|
|
||||||
|
override val cdnUrl = "https://3xfsjdlc.is1.buzz/uploads"
|
||||||
|
|
||||||
override val client = network.cloudflareClient.newBuilder()
|
override val client = network.cloudflareClient.newBuilder()
|
||||||
.addInterceptor(::captchaInterceptor)
|
.addInterceptor(::captchaInterceptor)
|
||||||
.rateLimitHost(baseUrl.toHttpUrl(), 1)
|
.rateLimitHost(baseUrl.toHttpUrl(), 1)
|
||||||
|
@ -39,8 +41,4 @@ class MagusManga : Keyoapp(
|
||||||
|
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun chapterListSelector(): String {
|
|
||||||
return "${super.chapterListSelector()}:not(:has(img[src*=coin]))"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,4 +2,10 @@ package eu.kanade.tachiyomi.extension.en.necroscans
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.multisrc.keyoapp.Keyoapp
|
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"
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,4 @@ class RezoScans : Keyoapp(
|
||||||
"Rezo Scans",
|
"Rezo Scans",
|
||||||
"https://rezoscans.com",
|
"https://rezoscans.com",
|
||||||
"en",
|
"en",
|
||||||
) {
|
)
|
||||||
override fun chapterListSelector() = "${super.chapterListSelector()}:not(:has(img[src^='/assets/images/Coin.svg']))"
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,30 +1,14 @@
|
||||||
package eu.kanade.tachiyomi.extension.en.suryascans
|
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.multisrc.keyoapp.Keyoapp
|
||||||
import eu.kanade.tachiyomi.network.interceptor.rateLimit
|
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
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
class GenzToons :
|
class GenzToons : Keyoapp(
|
||||||
Keyoapp(
|
"Genz Toons",
|
||||||
"Genz Toons",
|
"https://genzupdates.com",
|
||||||
"https://genzupdates.com",
|
"en",
|
||||||
"en",
|
) {
|
||||||
),
|
|
||||||
ConfigurableSource {
|
|
||||||
|
|
||||||
private val preferences: SharedPreferences =
|
|
||||||
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
|
|
||||||
|
|
||||||
override val client = super.client.newBuilder()
|
override val client = super.client.newBuilder()
|
||||||
.rateLimit(3)
|
.rateLimit(3)
|
||||||
|
@ -32,48 +16,4 @@ class GenzToons :
|
||||||
.writeTimeout(90, TimeUnit.SECONDS)
|
.writeTimeout(90, TimeUnit.SECONDS)
|
||||||
.readTimeout(90, TimeUnit.SECONDS)
|
.readTimeout(90, TimeUnit.SECONDS)
|
||||||
.build()
|
.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<Page> {
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue