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' extName = 'MANGA Plus by SHUEISHA'
pkgNameSuffix = 'all.mangaplus' pkgNameSuffix = 'all.mangaplus'
extClass = '.MangaPlusFactory' extClass = '.MangaPlusFactory'
extVersionCode = 49 extVersionCode = 50
} }
dependencies { dependencies {

View File

@ -2,6 +2,11 @@ package eu.kanade.tachiyomi.extension.all.mangaplus
import android.app.Application import android.app.Application
import android.content.SharedPreferences 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.ListPreference
import androidx.preference.PreferenceScreen import androidx.preference.PreferenceScreen
import androidx.preference.SwitchPreferenceCompat import androidx.preference.SwitchPreferenceCompat
@ -234,7 +239,7 @@ class MangaPlus(
.set("Referer", "$baseUrl/titles/$titleId") .set("Referer", "$baseUrl/titles/$titleId")
.build() .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 { override fun mangaDetailsParse(response: Response): SManga {
@ -275,7 +280,6 @@ class MangaPlus(
val titleDetailView = result.success.titleDetailView!! val titleDetailView = result.success.titleDetailView!!
return titleDetailView.chapterList return titleDetailView.chapterList
.filterNot(Chapter::isExpired)
.map(Chapter::toSChapter) .map(Chapter::toSChapter)
.reversed() .reversed()
} }
@ -294,10 +298,17 @@ class MangaPlus(
.set("Referer", "$baseUrl/viewer/$chapterId") .set("Referer", "$baseUrl/viewer/$chapterId")
.build() .build()
val url = "$API_URL/manga_viewer".toHttpUrl().newBuilder() val url = "$APP_API_URL/manga_viewer".toHttpUrl().newBuilder()
.addQueryParameter("chapter_id", chapterId) .addQueryParameter("chapter_id", chapterId)
.addQueryParameter("split", if (preferences.splitImages) "yes" else "no") .addQueryParameter("split", if (preferences.splitImages) "yes" else "no")
.addQueryParameter("img_quality", preferences.imageQuality) .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") .addQueryParameter("format", "json")
.toString() .toString()
@ -360,11 +371,81 @@ class MangaPlus(
summary = intl["split_double_pages_summary"] summary = intl["split_double_pages_summary"]
setDefaultValue(SPLIT_PREF_DEFAULT_VALUE) 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(qualityPref)
screen.addPreference(splitPref) 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 { private fun imageIntercept(chain: Interceptor.Chain): Response {
val request = chain.request() val request = chain.request()
val response = chain.proceed(request) val response = chain.proceed(request)
@ -424,8 +505,15 @@ class MangaPlus(
private val SharedPreferences.splitImages: Boolean private val SharedPreferences.splitImages: Boolean
get() = getBoolean("${SPLIT_PREF_KEY}_$lang", SPLIT_PREF_DEFAULT_VALUE) 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 { companion object {
private const val API_URL = "https://jumpg-webapi.tokyo-cdn.com/api" 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) " + 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" "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_KEY = "splitImage"
private const val SPLIT_PREF_DEFAULT_VALUE = true 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 NOT_FOUND_SUBJECT = "Not Found"
private const val TITLE_THUMBNAIL_PATH = "title_thumbnail_portrait_list" 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 // Doesn't include `midChapterList` by design as their site API returns it
// just for visual representation to redirect users to their app. The extension // 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. // 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 private val isWebtoon: Boolean
@ -102,6 +106,9 @@ data class TitleDetailView(
add("Simulrelease") add("Simulrelease")
} }
// funne hack thing to make the first letter capital
add(titleLabels.planType.substring(0, 1).uppercase() + titleLabels.planType.substring(1))
if (isOneShot) { if (isOneShot) {
add("One-shot") add("One-shot")
} }
@ -151,6 +158,7 @@ data class TitleDetailView(
data class TitleLabels( data class TitleLabels(
val releaseSchedule: ReleaseSchedule = ReleaseSchedule.DISABLED, val releaseSchedule: ReleaseSchedule = ReleaseSchedule.DISABLED,
val isSimulpub: Boolean = false, val isSimulpub: Boolean = false,
val planType: String = "standard",
) )
enum class ReleaseSchedule { enum class ReleaseSchedule {
@ -230,6 +238,7 @@ enum class LabelCode {
@Serializable @Serializable
data class ChapterListGroup( data class ChapterListGroup(
val firstChapterList: List<Chapter> = emptyList(), val firstChapterList: List<Chapter> = emptyList(),
val midChapterList: List<Chapter> = emptyList(),
val lastChapterList: List<Chapter> = emptyList(), val lastChapterList: List<Chapter> = emptyList(),
) )