HeanCMS: Added paid chapter preference (#19006)
* Added paid chapter preference
* Added requested changes and fixed a warning
* Paid chapters now have a 🔒 next to it
* Added Spanish translations
* Converted protected into private functions
* Improved the error message for unavailable paid chapters.
* Revert "Converted protected into private functions"
This reverts commit 864186d7b1f96b867c2d26e4410a6578e53223d5.
* Added spanish translation for error message
* Fixed: paidStatus would be set if price was 0
* Fixed: paidStatus would be set if price was null
* Fixed: chapterId retrieval from url in pageListRequest
This commit is contained in:
parent
496f8d26f3
commit
ac077880f9
|
@ -2,8 +2,11 @@ package eu.kanade.tachiyomi.multisrc.heancms
|
|||
|
||||
import android.app.Application
|
||||
import android.content.SharedPreferences
|
||||
import androidx.preference.PreferenceScreen
|
||||
import androidx.preference.SwitchPreferenceCompat
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.POST
|
||||
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
|
||||
|
@ -25,6 +28,7 @@ import okhttp3.Response
|
|||
import rx.Observable
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.io.IOException
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
|
@ -33,12 +37,28 @@ abstract class HeanCms(
|
|||
override val baseUrl: String,
|
||||
override val lang: String,
|
||||
protected val apiUrl: String = baseUrl.replace("://", "://api."),
|
||||
) : HttpSource() {
|
||||
) : ConfigurableSource, HttpSource() {
|
||||
|
||||
private val preferences: SharedPreferences by lazy {
|
||||
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
|
||||
}
|
||||
|
||||
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
||||
SwitchPreferenceCompat(screen.context).apply {
|
||||
key = SHOW_PAID_CHAPTERS_PREF
|
||||
title = intl.prefShowPaidChapterTitle
|
||||
summaryOn = intl.prefShowPaidChapterSummaryOn
|
||||
summaryOff = intl.prefShowPaidChapterSummaryOff
|
||||
setDefaultValue(SHOW_PAID_CHAPTERS_DEFAULT)
|
||||
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
preferences.edit()
|
||||
.putBoolean(SHOW_PAID_CHAPTERS_PREF, newValue as Boolean)
|
||||
.commit()
|
||||
}
|
||||
}.also(screen::addPreference)
|
||||
}
|
||||
|
||||
override val supportsLatest = true
|
||||
|
||||
override val client: OkHttpClient = network.cloudflareClient
|
||||
|
@ -402,16 +422,18 @@ abstract class HeanCms(
|
|||
|
||||
val currentTimestamp = System.currentTimeMillis()
|
||||
|
||||
val showPaidChapters = preferences.showPaidChapters
|
||||
|
||||
if (useNewQueryEndpoint) {
|
||||
return result.seasons.orEmpty()
|
||||
.flatMap { it.chapters.orEmpty() }
|
||||
.filter { it.price == 0 }
|
||||
.filter { it.price == 0 || showPaidChapters }
|
||||
.map { it.toSChapter(result.slug, mangaSubDirectory, dateFormat, slugStrategy) }
|
||||
.filter { it.date_upload <= currentTimestamp }
|
||||
}
|
||||
|
||||
return result.chapters.orEmpty()
|
||||
.filter { it.price == 0 }
|
||||
.filter { it.price == 0 || showPaidChapters }
|
||||
.map { it.toSChapter(result.slug, mangaSubDirectory, dateFormat, slugStrategy) }
|
||||
.filter { it.date_upload <= currentTimestamp }
|
||||
.reversed()
|
||||
|
@ -442,7 +464,7 @@ abstract class HeanCms(
|
|||
return GET(baseUrl + chapter.url, headers)
|
||||
}
|
||||
|
||||
val chapterId = chapter.url.substringAfterLast("#")
|
||||
val chapterId = chapter.url.substringAfterLast("#").substringBefore("-paid")
|
||||
|
||||
val apiHeaders = headersBuilder()
|
||||
.add("Accept", ACCEPT_JSON)
|
||||
|
@ -453,18 +475,30 @@ abstract class HeanCms(
|
|||
|
||||
override fun pageListParse(response: Response): List<Page> {
|
||||
if (useNewQueryEndpoint) {
|
||||
val paidChapter = response.request.url.fragment?.contains("-paid")
|
||||
|
||||
val document = response.asJsoup()
|
||||
|
||||
val images = document.selectFirst("div.min-h-screen > div.container > p.items-center")
|
||||
|
||||
if (images == null && paidChapter == true) {
|
||||
throw IOException(intl.paidChapterError)
|
||||
}
|
||||
|
||||
return images?.select("img").orEmpty().mapIndexed { i, img ->
|
||||
val imageUrl = if (img.hasClass("lazy")) img.absUrl("data-src") else img.absUrl("src")
|
||||
Page(i, "", imageUrl)
|
||||
}
|
||||
}
|
||||
|
||||
return response.parseAs<HeanCmsReaderDto>().content?.images.orEmpty()
|
||||
.filterNot { imageUrl ->
|
||||
val images = response.parseAs<HeanCmsReaderDto>().content?.images.orEmpty()
|
||||
val paidChapter = response.request.url.fragment?.contains("-paid")
|
||||
|
||||
if (images.isEmpty() && paidChapter == true) {
|
||||
throw IOException(intl.paidChapterError)
|
||||
}
|
||||
|
||||
return images.filterNot { imageUrl ->
|
||||
// Their image server returns HTTP 403 for hidden files that starts
|
||||
// with a dot in the file name. To avoid download errors, these are removed.
|
||||
imageUrl
|
||||
|
@ -639,9 +673,12 @@ abstract class HeanCms(
|
|||
set(newSlugMap) {
|
||||
edit()
|
||||
.putString(PREF_URL_MAP_SLUG, json.encodeToString(newSlugMap))
|
||||
.commit()
|
||||
.apply()
|
||||
}
|
||||
|
||||
private val SharedPreferences.showPaidChapters: Boolean
|
||||
get() = getBoolean(SHOW_PAID_CHAPTERS_PREF, SHOW_PAID_CHAPTERS_DEFAULT)
|
||||
|
||||
companion object {
|
||||
private const val ACCEPT_IMAGE = "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8"
|
||||
private const val ACCEPT_JSON = "application/json, text/plain, */*"
|
||||
|
@ -655,5 +692,8 @@ abstract class HeanCms(
|
|||
const val SEARCH_PREFIX = "slug:"
|
||||
|
||||
private const val PREF_URL_MAP_SLUG = "pref_url_map"
|
||||
|
||||
private const val SHOW_PAID_CHAPTERS_PREF = "pref_show_paid_chap"
|
||||
private const val SHOW_PAID_CHAPTERS_DEFAULT = false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -120,9 +120,17 @@ data class HeanCmsChapterDto(
|
|||
): SChapter = SChapter.create().apply {
|
||||
val seriesSlugOnly = seriesSlug.toPermSlugIfNeeded(slugStrategy)
|
||||
name = this@HeanCmsChapterDto.name.trim()
|
||||
|
||||
if (price != 0) {
|
||||
name += " \uD83D\uDD12"
|
||||
}
|
||||
|
||||
date_upload = runCatching { dateFormat.parse(createdAt)?.time }
|
||||
.getOrNull() ?: 0L
|
||||
url = "/$mangaSubDirectory/$seriesSlugOnly/$slug#$id"
|
||||
|
||||
val paidStatus = if (price != 0 && price != null) "-paid" else ""
|
||||
|
||||
url = "/$mangaSubDirectory/$seriesSlugOnly/$slug#$id$paidStatus"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ class HeanCmsGenerator : ThemeSourceGenerator {
|
|||
|
||||
override val themeClass = "HeanCms"
|
||||
|
||||
override val baseVersionCode: Int = 19
|
||||
override val baseVersionCode: Int = 20
|
||||
|
||||
override val sources = listOf(
|
||||
SingleLang("Glorious Scan", "https://gloriousscan.com", "pt-BR", overrideVersionCode = 17),
|
||||
|
|
|
@ -76,6 +76,26 @@ class HeanCmsIntl(lang: String) {
|
|||
else -> "Filters will be ignored if the search is not empty."
|
||||
}
|
||||
|
||||
val prefShowPaidChapterTitle: String = when (availableLang) {
|
||||
SPANISH -> "Mostrar capítulos de pago"
|
||||
else -> "Display paid chapters"
|
||||
}
|
||||
|
||||
val prefShowPaidChapterSummaryOn: String = when (availableLang) {
|
||||
SPANISH -> "Se mostrarán capítulos de pago. Deberá iniciar sesión"
|
||||
else -> "Paid chapters will appear. A login might be needed!"
|
||||
}
|
||||
|
||||
val prefShowPaidChapterSummaryOff: String = when (availableLang) {
|
||||
SPANISH -> "Solo se mostrarán los capítulos gratuitos"
|
||||
else -> "Only free chapters will be displayed."
|
||||
}
|
||||
|
||||
val paidChapterError: String = when (availableLang) {
|
||||
SPANISH -> "Capítulo no disponible. Debe iniciar sesión en Webview y tener el capítulo comprado."
|
||||
else -> "Paid chapter unavailable.\nA login/purchase might be needed (using webview)."
|
||||
}
|
||||
|
||||
fun urlChangedError(sourceName: String): String = when (availableLang) {
|
||||
BRAZILIAN_PORTUGUESE ->
|
||||
"A URL da série mudou. Migre de $sourceName " +
|
||||
|
|
Loading…
Reference in New Issue