Better handle the API errors in MangaPlus. (#13094)

This commit is contained in:
Alessandro Jean 2022-08-19 22:29:02 -03:00 committed by GitHub
parent 6fb71ea1a9
commit 05070ea80b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 73 additions and 40 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 = 35 extVersionCode = 36
} }
apply from: "$rootDir/common.gradle" apply from: "$rootDir/common.gradle"

View File

@ -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:"

View File

@ -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 }
) )
} }

View File

@ -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)

View File

@ -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."
}
} }