Edit mangaplus extension to allow for auth

This commit is contained in:
Draff 2024-01-09 00:42:59 +00:00
parent 88ada96212
commit c0271a4046
3 changed files with 109 additions and 6 deletions

View File

@ -6,7 +6,7 @@ ext {
extName = 'MANGA Plus by SHUEISHA'
pkgNameSuffix = 'all.mangaplus'
extClass = '.MangaPlusFactory'
extVersionCode = 49
extVersionCode = 50
}
dependencies {

View File

@ -2,6 +2,11 @@ package eu.kanade.tachiyomi.extension.all.mangaplus
import android.app.Application
import android.content.SharedPreferences
import android.text.Editable
import android.text.TextWatcher
import android.widget.Button
import android.widget.Toast
import androidx.preference.EditTextPreference
import androidx.preference.ListPreference
import androidx.preference.PreferenceScreen
import androidx.preference.SwitchPreferenceCompat
@ -234,7 +239,7 @@ class MangaPlus(
.set("Referer", "$baseUrl/titles/$titleId")
.build()
return GET("$API_URL/title_detailV3?title_id=$titleId&format=json", newHeaders)
return GET("$APP_API_URL/title_detailV3?title_id=$titleId&lang=eng&os=android&os_ver=30&app_ver=${preferences.appVersion}&secret=${preferences.accountSecret}&format=json", newHeaders)
}
override fun mangaDetailsParse(response: Response): SManga {
@ -275,7 +280,6 @@ class MangaPlus(
val titleDetailView = result.success.titleDetailView!!
return titleDetailView.chapterList
.filterNot(Chapter::isExpired)
.map(Chapter::toSChapter)
.reversed()
}
@ -294,10 +298,17 @@ class MangaPlus(
.set("Referer", "$baseUrl/viewer/$chapterId")
.build()
val url = "$API_URL/manga_viewer".toHttpUrl().newBuilder()
val url = "$APP_API_URL/manga_viewer".toHttpUrl().newBuilder()
.addQueryParameter("chapter_id", chapterId)
.addQueryParameter("split", if (preferences.splitImages) "yes" else "no")
.addQueryParameter("img_quality", preferences.imageQuality)
.addQueryParameter("ticket_reading", "no")
.addQueryParameter("free_reading", "yes")
.addQueryParameter("subscription_reading", "no")
.addQueryParameter("os", "android")
.addQueryParameter("os_ver", "30")
.addQueryParameter("app_ver", preferences.appVersion)
.addQueryParameter("secret", preferences.accountSecret)
.addQueryParameter("format", "json")
.toString()
@ -360,11 +371,81 @@ class MangaPlus(
summary = intl["split_double_pages_summary"]
setDefaultValue(SPLIT_PREF_DEFAULT_VALUE)
}
screen.addEditTextPreference(
title = "Secret",
default = SECRET_PREF_DEFAULT_VALUE,
summary = preferences.accountSecret?.ifBlank { "The user secret" } ?: "",
key = "${SECRET_PREF_KEY}_$lang",
)
screen.addEditTextPreference(
title = "App Version",
default = VER_PREF_DEFAULT_VALUE,
summary = preferences.appVersion?.ifBlank { "The current app version" } ?: "",
key = "${VER_PREF_KEY}_$lang",
)
screen.addPreference(qualityPref)
screen.addPreference(splitPref)
}
private fun PreferenceScreen.addEditTextPreference(
title: String,
default: String,
summary: String,
inputType: Int? = null,
validate: ((String) -> Boolean)? = null,
validationMessage: String? = null,
key: String = title,
) {
val preference = EditTextPreference(context).apply {
this.key = key
this.title = title
this.summary = summary
this.setDefaultValue(default)
dialogTitle = title
setOnBindEditTextListener { editText ->
if (inputType != null) {
editText.inputType = inputType
}
if (validate != null) {
editText.addTextChangedListener(
object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
override fun afterTextChanged(editable: Editable?) {
requireNotNull(editable)
val text = editable.toString()
val isValid = text.isBlank() || validate(text)
editText.error = if (!isValid) validationMessage else null
editText.rootView.findViewById<Button>(android.R.id.button1)
?.isEnabled = editText.error == null
}
},
)
}
}
setOnPreferenceChangeListener { _, newValue ->
try {
val res = preferences.edit().putString(this.key, newValue as String).commit()
Toast.makeText(context, "Restart Tachiyomi to apply new setting.", Toast.LENGTH_LONG).show()
res
} catch (e: Exception) {
e.printStackTrace()
false
}
}
}
addPreference(preference)
}
private fun imageIntercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val response = chain.proceed(request)
@ -424,8 +505,15 @@ class MangaPlus(
private val SharedPreferences.splitImages: Boolean
get() = getBoolean("${SPLIT_PREF_KEY}_$lang", SPLIT_PREF_DEFAULT_VALUE)
private val SharedPreferences.appVersion: String?
get() = getString("${VER_PREF_KEY}_$lang", VER_PREF_DEFAULT_VALUE)
private val SharedPreferences.accountSecret: String?
get() = getString("${SECRET_PREF_KEY}_$lang", SECRET_PREF_DEFAULT_VALUE)
companion object {
private const val API_URL = "https://jumpg-webapi.tokyo-cdn.com/api"
private const val APP_API_URL = "https://jumpg-api.tokyo-cdn.com/api"
private const val USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"
@ -438,6 +526,12 @@ class MangaPlus(
private const val SPLIT_PREF_KEY = "splitImage"
private const val SPLIT_PREF_DEFAULT_VALUE = true
private const val VER_PREF_KEY = "appVer"
private const val VER_PREF_DEFAULT_VALUE = ""
private const val SECRET_PREF_KEY = "accountSecret"
private const val SECRET_PREF_DEFAULT_VALUE = ""
private const val NOT_FOUND_SUBJECT = "Not Found"
private const val TITLE_THUMBNAIL_PATH = "title_thumbnail_portrait_list"

View File

@ -73,7 +73,11 @@ data class TitleDetailView(
// Doesn't include `midChapterList` by design as their site API returns it
// just for visual representation to redirect users to their app. The extension
// intends to allow users to read only what they can already read in their site.
chapterListGroup.flatMap { it.firstChapterList + it.lastChapterList }
if (titleLabels.planType != "standard") {
chapterListGroup.flatMap { it.firstChapterList + it.lastChapterList }
} else {
chapterListGroup.flatMap { it.firstChapterList + it.midChapterList + it.lastChapterList }
}
}
private val isWebtoon: Boolean
@ -102,6 +106,9 @@ data class TitleDetailView(
add("Simulrelease")
}
// funne hack thing to make the first letter capital
add(titleLabels.planType.substring(0, 1).uppercase() + titleLabels.planType.substring(1))
if (isOneShot) {
add("One-shot")
}
@ -151,6 +158,7 @@ data class TitleDetailView(
data class TitleLabels(
val releaseSchedule: ReleaseSchedule = ReleaseSchedule.DISABLED,
val isSimulpub: Boolean = false,
val planType: String = "standard",
)
enum class ReleaseSchedule {
@ -230,6 +238,7 @@ enum class LabelCode {
@Serializable
data class ChapterListGroup(
val firstChapterList: List<Chapter> = emptyList(),
val midChapterList: List<Chapter> = emptyList(),
val lastChapterList: List<Chapter> = emptyList(),
)