Better handle the API errors in MangaPlus. (#13094)
This commit is contained in:
parent
6fb71ea1a9
commit
05070ea80b
|
@ -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 = 35
|
extVersionCode = 36
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
apply from: "$rootDir/common.gradle"
|
||||||
|
|
|
@ -32,17 +32,17 @@ import uy.kohesive.injekt.api.get
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
abstract class MangaPlus(
|
class MangaPlus(
|
||||||
override val lang: String,
|
override val lang: String,
|
||||||
private val internalLang: String,
|
private val internalLang: String,
|
||||||
private val langCode: Language
|
private val langCode: Language
|
||||||
) : HttpSource(), ConfigurableSource {
|
) : HttpSource(), ConfigurableSource {
|
||||||
|
|
||||||
final override val name = "MANGA Plus by SHUEISHA"
|
override val name = "MANGA Plus by SHUEISHA"
|
||||||
|
|
||||||
final override val baseUrl = "https://mangaplus.shueisha.co.jp"
|
override val baseUrl = "https://mangaplus.shueisha.co.jp"
|
||||||
|
|
||||||
final override val supportsLatest = true
|
override val supportsLatest = true
|
||||||
|
|
||||||
override fun headersBuilder(): Headers.Builder = Headers.Builder()
|
override fun headersBuilder(): Headers.Builder = Headers.Builder()
|
||||||
.add("Origin", baseUrl)
|
.add("Origin", baseUrl)
|
||||||
|
@ -84,7 +84,9 @@ abstract class MangaPlus(
|
||||||
override fun popularMangaParse(response: Response): MangasPage {
|
override fun popularMangaParse(response: Response): MangasPage {
|
||||||
val result = response.asMangaPlusResponse()
|
val result = response.asMangaPlusResponse()
|
||||||
|
|
||||||
checkNotNull(result.success) { result.error!!.langPopup(langCode).body }
|
checkNotNull(result.success) {
|
||||||
|
result.error!!.langPopup(langCode)?.body ?: intl.unknownError
|
||||||
|
}
|
||||||
|
|
||||||
titleList = result.success.titleRankingView!!.titles
|
titleList = result.success.titleRankingView!!.titles
|
||||||
.filter { it.language == langCode }
|
.filter { it.language == langCode }
|
||||||
|
@ -111,7 +113,9 @@ abstract class MangaPlus(
|
||||||
override fun latestUpdatesParse(response: Response): MangasPage {
|
override fun latestUpdatesParse(response: Response): MangasPage {
|
||||||
val result = response.asMangaPlusResponse()
|
val result = response.asMangaPlusResponse()
|
||||||
|
|
||||||
checkNotNull(result.success) { result.error!!.langPopup(langCode).body }
|
checkNotNull(result.success) {
|
||||||
|
result.error!!.langPopup(langCode)?.body ?: intl.unknownError
|
||||||
|
}
|
||||||
|
|
||||||
// Fetch all titles to get newer thumbnail URLs in the interceptor.
|
// Fetch all titles to get newer thumbnail URLs in the interceptor.
|
||||||
val popularResponse = client.newCall(popularMangaRequest(1)).execute()
|
val popularResponse = client.newCall(popularMangaRequest(1)).execute()
|
||||||
|
@ -160,7 +164,9 @@ abstract class MangaPlus(
|
||||||
override fun searchMangaParse(response: Response): MangasPage {
|
override fun searchMangaParse(response: Response): MangasPage {
|
||||||
val result = response.asMangaPlusResponse()
|
val result = response.asMangaPlusResponse()
|
||||||
|
|
||||||
checkNotNull(result.success) { result.error!!.langPopup(langCode).body }
|
checkNotNull(result.success) {
|
||||||
|
result.error!!.langPopup(langCode)?.body ?: intl.unknownError
|
||||||
|
}
|
||||||
|
|
||||||
if (result.success.titleDetailView != null) {
|
if (result.success.titleDetailView != null) {
|
||||||
val mangaPlusTitle = result.success.titleDetailView.title
|
val mangaPlusTitle = result.success.titleDetailView.title
|
||||||
|
@ -192,7 +198,9 @@ abstract class MangaPlus(
|
||||||
val titleRequest = titleDetailsRequest(titleId.toString())
|
val titleRequest = titleDetailsRequest(titleId.toString())
|
||||||
val titleResult = client.newCall(titleRequest).execute().asMangaPlusResponse()
|
val titleResult = client.newCall(titleRequest).execute().asMangaPlusResponse()
|
||||||
|
|
||||||
checkNotNull(titleResult.success) { titleResult.error!!.langPopup(langCode).body }
|
checkNotNull(titleResult.success) {
|
||||||
|
titleResult.error!!.langPopup(langCode)?.body ?: intl.unknownError
|
||||||
|
}
|
||||||
|
|
||||||
titleDetailsParse(titleResult.success.titleDetailView!!)
|
titleDetailsParse(titleResult.success.titleDetailView!!)
|
||||||
}
|
}
|
||||||
|
@ -248,7 +256,15 @@ abstract class MangaPlus(
|
||||||
override fun mangaDetailsParse(response: Response): SManga {
|
override fun mangaDetailsParse(response: Response): SManga {
|
||||||
val result = response.asMangaPlusResponse()
|
val result = response.asMangaPlusResponse()
|
||||||
|
|
||||||
checkNotNull(result.success) { result.error!!.langPopup(langCode).body }
|
checkNotNull(result.success) {
|
||||||
|
val error = result.error!!.langPopup(langCode)
|
||||||
|
|
||||||
|
when {
|
||||||
|
error?.subject == NOT_FOUND_SUBJECT -> intl.titleRemoved
|
||||||
|
!error?.body.isNullOrEmpty() -> error!!.body
|
||||||
|
else -> intl.unknownError
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return titleDetailsParse(result.success.titleDetailView!!)
|
return titleDetailsParse(result.success.titleDetailView!!)
|
||||||
?: throw Exception(intl.notAvailable)
|
?: throw Exception(intl.notAvailable)
|
||||||
|
@ -263,7 +279,7 @@ abstract class MangaPlus(
|
||||||
artist = author
|
artist = author
|
||||||
description = details.overview + "\n\n" + details.viewingPeriodDescription
|
description = details.overview + "\n\n" + details.viewingPeriodDescription
|
||||||
status = if (details.isCompleted) SManga.COMPLETED else SManga.ONGOING
|
status = if (details.isCompleted) SManga.COMPLETED else SManga.ONGOING
|
||||||
genre = details.genres.filter(String::isNotEmpty).joinToString()
|
genre = details.genres.joinToString()
|
||||||
thumbnail_url = titleObj.portraitImageUrl
|
thumbnail_url = titleObj.portraitImageUrl
|
||||||
url = "#/titles/${titleObj.titleId}"
|
url = "#/titles/${titleObj.titleId}"
|
||||||
}
|
}
|
||||||
|
@ -276,7 +292,15 @@ abstract class MangaPlus(
|
||||||
override fun chapterListParse(response: Response): List<SChapter> {
|
override fun chapterListParse(response: Response): List<SChapter> {
|
||||||
val result = response.asMangaPlusResponse()
|
val result = response.asMangaPlusResponse()
|
||||||
|
|
||||||
checkNotNull(result.success) { result.error!!.langPopup(langCode).body }
|
checkNotNull(result.success) {
|
||||||
|
val error = result.error!!.langPopup(langCode)
|
||||||
|
|
||||||
|
when {
|
||||||
|
error?.subject == NOT_FOUND_SUBJECT -> intl.titleRemoved
|
||||||
|
!error?.body.isNullOrEmpty() -> error!!.body
|
||||||
|
else -> intl.unknownError
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val titleDetailView = result.success.titleDetailView!!
|
val titleDetailView = result.success.titleDetailView!!
|
||||||
|
|
||||||
|
@ -319,7 +343,15 @@ abstract class MangaPlus(
|
||||||
override fun pageListParse(response: Response): List<Page> {
|
override fun pageListParse(response: Response): List<Page> {
|
||||||
val result = response.asMangaPlusResponse()
|
val result = response.asMangaPlusResponse()
|
||||||
|
|
||||||
checkNotNull(result.success) { result.error!!.langPopup(langCode).body }
|
checkNotNull(result.success) {
|
||||||
|
val error = result.error!!.langPopup(langCode)
|
||||||
|
|
||||||
|
when {
|
||||||
|
error?.subject == NOT_FOUND_SUBJECT -> intl.chapterExpired
|
||||||
|
!error?.body.isNullOrEmpty() -> error!!.body
|
||||||
|
else -> intl.unknownError
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val referer = response.request.header("Referer")!!
|
val referer = response.request.header("Referer")!!
|
||||||
|
|
||||||
|
@ -451,7 +483,7 @@ abstract class MangaPlus(
|
||||||
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 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/102.0.0.0 Safari/537.36"
|
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36"
|
||||||
|
|
||||||
private const val QUALITY_PREF_KEY = "imageResolution"
|
private const val QUALITY_PREF_KEY = "imageResolution"
|
||||||
private val QUALITY_PREF_ENTRY_VALUES = arrayOf("low", "high", "super_high")
|
private val QUALITY_PREF_ENTRY_VALUES = arrayOf("low", "high", "super_high")
|
||||||
|
@ -463,6 +495,8 @@ abstract class MangaPlus(
|
||||||
val COMPLETED_REGEX = "completado|complete|completo".toRegex()
|
val COMPLETED_REGEX = "completado|complete|completo".toRegex()
|
||||||
val REEDITION_REGEX = "revival|remasterizada".toRegex()
|
val REEDITION_REGEX = "revival|remasterizada".toRegex()
|
||||||
|
|
||||||
|
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"
|
||||||
|
|
||||||
const val PREFIX_ID_SEARCH = "id:"
|
const val PREFIX_ID_SEARCH = "id:"
|
||||||
|
|
|
@ -10,13 +10,10 @@ data class MangaPlusResponse(
|
||||||
)
|
)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class ErrorResult(
|
data class ErrorResult(val popups: List<Popup> = emptyList()) {
|
||||||
val englishPopup: Popup,
|
|
||||||
val popups: List<Popup> = emptyList()
|
|
||||||
) {
|
|
||||||
|
|
||||||
fun langPopup(lang: Language): Popup =
|
fun langPopup(lang: Language): Popup? =
|
||||||
popups.firstOrNull { it.language == lang } ?: englishPopup
|
popups.firstOrNull { it.language == lang }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
|
@ -85,11 +82,11 @@ data class TitleDetailView(
|
||||||
get() = nonAppearanceInfo.contains(MangaPlus.COMPLETED_REGEX) || isOneShot
|
get() = nonAppearanceInfo.contains(MangaPlus.COMPLETED_REGEX) || isOneShot
|
||||||
|
|
||||||
val genres: List<String>
|
val genres: List<String>
|
||||||
get() = listOf(
|
get() = listOfNotNull(
|
||||||
if (isSimulReleased && !isReEdition) "Simulrelease" else "",
|
"Simulrelease".takeIf { isSimulReleased && !isReEdition && !isOneShot },
|
||||||
if (isOneShot) "One-shot" else "",
|
"One-shot".takeIf { isOneShot },
|
||||||
if (isReEdition) "Re-edition" else "",
|
"Re-edition".takeIf { isReEdition },
|
||||||
if (isWebtoon) "Webtoon" else ""
|
"Webtoon".takeIf { isWebtoon }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,20 +5,12 @@ import eu.kanade.tachiyomi.source.SourceFactory
|
||||||
|
|
||||||
class MangaPlusFactory : SourceFactory {
|
class MangaPlusFactory : SourceFactory {
|
||||||
override fun createSources(): List<Source> = listOf(
|
override fun createSources(): List<Source> = listOf(
|
||||||
MangaPlusEnglish(),
|
MangaPlus("en", "eng", Language.ENGLISH),
|
||||||
MangaPlusIndonesian(),
|
MangaPlus("es", "esp", Language.SPANISH),
|
||||||
MangaPlusPortuguese(),
|
MangaPlus("fr", "fra", Language.FRENCH),
|
||||||
MangaPlusRussian(),
|
MangaPlus("id", "ind", Language.INDONESIAN),
|
||||||
MangaPlusSpanish(),
|
MangaPlus("pt-BR", "ptb", Language.PORTUGUESE_BR),
|
||||||
MangaPlusThai(),
|
MangaPlus("ru", "rus", Language.RUSSIAN),
|
||||||
MangaPlusFrench()
|
MangaPlus("th", "tha", Language.THAI)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
class MangaPlusEnglish : MangaPlus("en", "eng", Language.ENGLISH)
|
|
||||||
class MangaPlusIndonesian : MangaPlus("id", "ind", Language.INDONESIAN)
|
|
||||||
class MangaPlusPortuguese : MangaPlus("pt-BR", "ptb", Language.PORTUGUESE_BR)
|
|
||||||
class MangaPlusRussian : MangaPlus("ru", "rus", Language.RUSSIAN)
|
|
||||||
class MangaPlusSpanish : MangaPlus("es", "esp", Language.SPANISH)
|
|
||||||
class MangaPlusThai : MangaPlus("th", "tha", Language.THAI)
|
|
||||||
class MangaPlusFrench : MangaPlus("fr", "fra", Language.FRENCH)
|
|
||||||
|
|
|
@ -41,4 +41,14 @@ class MangaPlusIntl(lang: Language) {
|
||||||
Language.PORTUGUESE_BR -> "Título não disponível neste idioma."
|
Language.PORTUGUESE_BR -> "Título não disponível neste idioma."
|
||||||
else -> "Title not available in this language."
|
else -> "Title not available in this language."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val unknownError: String = when (lang) {
|
||||||
|
Language.PORTUGUESE_BR -> "Um erro desconhecido ocorreu."
|
||||||
|
else -> "An unknown error happened."
|
||||||
|
}
|
||||||
|
|
||||||
|
val titleRemoved: String = when (lang) {
|
||||||
|
Language.PORTUGUESE_BR -> "Este título foi removido do catálogo do MANGA Plus."
|
||||||
|
else -> "This title was removed from the MANGA Plus catalogue."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue