From e2ee93b8a8d49cdc288291120dc990478d58c9e3 Mon Sep 17 00:00:00 2001 From: NGB-Was-Taken <76197326+NGB-Was-Taken@users.noreply.github.com> Date: Sun, 25 Aug 2024 18:11:25 +0545 Subject: [PATCH] Respect `thumbnailQuality` and `tryUsingFirstVolumeCover` preferences. (MD) --- .../tachiyomi/source/online/all/MangaDex.kt | 20 +++++++++++++--- app/src/main/java/exh/md/dto/MangaDto.kt | 8 ++----- .../java/exh/md/handlers/ApiMangaParser.kt | 24 ++++++++++++------- .../main/java/exh/md/handlers/MangaHandler.kt | 23 ++++++++++++++---- .../java/exh/md/service/MangaDexService.kt | 20 ++++++++++++++++ app/src/main/java/exh/md/utils/MdApi.kt | 1 + 6 files changed, 75 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MangaDex.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MangaDex.kt index 357bd2f7f34d..8e422e7957fa 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MangaDex.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MangaDex.kt @@ -87,6 +87,8 @@ class MangaDex(delegate: HttpSource, val context: Context) : private fun usePort443Only() = sourcePreferences.getBoolean(getStandardHttpsPreferenceKey(mdLang.lang), false) private fun blockedGroups() = sourcePreferences.getString(getBlockedGroupsPrefKey(mdLang.lang), "").orEmpty() private fun blockedUploaders() = sourcePreferences.getString(getBlockedUploaderPrefKey(mdLang.lang), "").orEmpty() + private fun coverQuality() = sourcePreferences.getString(getCoverQualityPrefKey(mdLang.lang), "").orEmpty() + private fun tryUsingFirstVolumeCover() = sourcePreferences.getBoolean(getTryUsingFirstVolumeCoverKey(mdLang.lang), false) private val mangadexService by lazy { MangaDexService(client) @@ -189,11 +191,11 @@ class MangaDex(delegate: HttpSource, val context: Context) : @Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getMangaDetails")) override fun fetchMangaDetails(manga: SManga): Observable { - return mangaHandler.fetchMangaDetailsObservable(manga, id) + return mangaHandler.fetchMangaDetailsObservable(manga, id, coverQuality(), tryUsingFirstVolumeCover()) } override suspend fun getMangaDetails(manga: SManga): SManga { - return mangaHandler.getMangaDetails(manga, id) + return mangaHandler.getMangaDetails(manga, id, coverQuality(), tryUsingFirstVolumeCover()) } @Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getChapterList")) @@ -239,7 +241,7 @@ class MangaDex(delegate: HttpSource, val context: Context) : override fun newMetaInstance() = MangaDexSearchMetadata() override suspend fun parseIntoMetadata(metadata: MangaDexSearchMetadata, input: Triple, StatisticsMangaDto>) { - apiMangaParser.parseIntoMetadata(metadata, input.first, input.second, input.third) + apiMangaParser.parseIntoMetadata(metadata, input.first, input.second, input.third, null, coverQuality()) } // LoginSource methods @@ -334,5 +336,17 @@ class MangaDex(delegate: HttpSource, val context: Context) : fun getBlockedUploaderPrefKey(dexLang: String): String { return "${blockedUploaderPref}_$dexLang" } + + private const val coverQualityPref = "thumbnailQuality" + + fun getCoverQualityPrefKey(dexLang: String): String { + return "${coverQualityPref}_$dexLang" + } + + private const val tryUsingFirstVolumeCover = "tryUsingFirstVolumeCover" + + fun getTryUsingFirstVolumeCoverKey(dexLang: String): String { + return "${tryUsingFirstVolumeCover}_$dexLang" + } } } diff --git a/app/src/main/java/exh/md/dto/MangaDto.kt b/app/src/main/java/exh/md/dto/MangaDto.kt index 43fa77d9d522..f12071938346 100644 --- a/app/src/main/java/exh/md/dto/MangaDto.kt +++ b/app/src/main/java/exh/md/dto/MangaDto.kt @@ -104,16 +104,12 @@ data class ReadChapterDto( @Serializable data class CoverListDto( - val results: List, + val data: List, ) @Serializable data class CoverDto( - val data: CoverDataDto, -) - -@Serializable -data class CoverDataDto( + val id: String, val attributes: CoverAttributesDto, val relationships: List, ) diff --git a/app/src/main/java/exh/md/handlers/ApiMangaParser.kt b/app/src/main/java/exh/md/handlers/ApiMangaParser.kt index 6b3ebe6468f3..5467335aadf0 100644 --- a/app/src/main/java/exh/md/handlers/ApiMangaParser.kt +++ b/app/src/main/java/exh/md/handlers/ApiMangaParser.kt @@ -41,6 +41,8 @@ class ApiMangaParser( input: MangaDto, simpleChapters: List, statistics: StatisticsMangaDto?, + coverFileName: String?, + coverQuality: String, ): SManga { val mangaId = getManga.await(manga.url, sourceId)?.id val metadata = if (mangaId != null) { @@ -50,7 +52,7 @@ class ApiMangaParser( newMetaInstance() } - parseIntoMetadata(metadata, input, simpleChapters, statistics) + parseIntoMetadata(metadata, input, simpleChapters, statistics, coverFileName, coverQuality) if (mangaId != null) { metadata.mangaId = mangaId insertFlatMetadata.await(metadata.flatten()) @@ -64,6 +66,8 @@ class ApiMangaParser( mangaDto: MangaDto, simpleChapters: List, statistics: StatisticsMangaDto?, + coverFileName: String?, + coverQuality: String, ) { with(metadata) { try { @@ -73,13 +77,17 @@ class ApiMangaParser( altTitles = mangaAttributesDto.altTitles.mapNotNull { it[lang] }.nullIfEmpty() val mangaRelationshipsDto = mangaDto.data.relationships - mangaRelationshipsDto - .firstOrNull { relationshipDto -> relationshipDto.type == MdConstants.Types.coverArt } - ?.attributes - ?.fileName - ?.let { coverFileName -> - cover = MdUtil.cdnCoverUrl(mangaDto.data.id, coverFileName) - } + cover = if (!coverFileName.isNullOrEmpty()) { + MdUtil.cdnCoverUrl(mangaDto.data.id, "$coverFileName$coverQuality") + } else { + mangaRelationshipsDto + .firstOrNull { relationshipDto -> relationshipDto.type == MdConstants.Types.coverArt } + ?.attributes + ?.fileName + ?.let { coverFileName -> + MdUtil.cdnCoverUrl(mangaDto.data.id, "$coverFileName$coverQuality") + } + } description = MdUtil.cleanDescription( MdUtil.getFromLangMap( diff --git a/app/src/main/java/exh/md/handlers/MangaHandler.kt b/app/src/main/java/exh/md/handlers/MangaHandler.kt index 7efe1b0cdb30..90163daa551e 100644 --- a/app/src/main/java/exh/md/handlers/MangaHandler.kt +++ b/app/src/main/java/exh/md/handlers/MangaHandler.kt @@ -23,7 +23,12 @@ class MangaHandler( private val apiMangaParser: ApiMangaParser, private val followsHandler: FollowsHandler, ) { - suspend fun getMangaDetails(manga: SManga, sourceId: Long): SManga { + suspend fun getMangaDetails( + manga: SManga, + sourceId: Long, + coverQuality: String, + tryUsingFirstVolumeCover: Boolean, + ): SManga { return coroutineScope { val mangaId = MdUtil.getMangaId(manga.url) val response = async(Dispatchers.IO) { service.viewManga(mangaId) } @@ -32,19 +37,29 @@ class MangaHandler( async(Dispatchers.IO) { kotlin.runCatching { service.mangasRating(mangaId) }.getOrNull()?.statistics?.get(mangaId) } + val responseData = response.await() + val coverFileName = if (tryUsingFirstVolumeCover) { + async(Dispatchers.IO) { + service.fetchFirstVolumeCover(responseData) + } + } else { + null + } apiMangaParser.parseToManga( manga, sourceId, - response.await(), + responseData, simpleChapters.await(), statistics.await(), + coverFileName?.await(), + coverQuality, ) } } - fun fetchMangaDetailsObservable(manga: SManga, sourceId: Long): Observable { + fun fetchMangaDetailsObservable(manga: SManga, sourceId: Long, coverQuality: String, tryUsingFirstVolumeCover: Boolean): Observable { return runAsObservable { - getMangaDetails(manga, sourceId) + getMangaDetails(manga, sourceId, coverQuality, tryUsingFirstVolumeCover) } } diff --git a/app/src/main/java/exh/md/service/MangaDexService.kt b/app/src/main/java/exh/md/service/MangaDexService.kt index 60f4f75857fa..fea6ebfa6936 100644 --- a/app/src/main/java/exh/md/service/MangaDexService.kt +++ b/app/src/main/java/exh/md/service/MangaDexService.kt @@ -9,6 +9,7 @@ import exh.md.dto.AtHomeDto import exh.md.dto.AtHomeImageReportDto import exh.md.dto.ChapterDto import exh.md.dto.ChapterListDto +import exh.md.dto.CoverListDto import exh.md.dto.MangaDto import exh.md.dto.MangaListDto import exh.md.dto.RelationListDto @@ -209,4 +210,23 @@ class MangaDexService( ).awaitSuccess().parseAs() } } + + suspend fun fetchFirstVolumeCover(mangaDto: MangaDto): String? { + val mangaData = mangaDto.data + val result: CoverListDto = with(MdUtil.jsonParser) { + client.newCall( + GET( + MdApi.cover.toHttpUrl().newBuilder() + .apply { + addQueryParameter("order[volume]", "asc") + addQueryParameter("manga[]", mangaData.id) + addQueryParameter("locales[]", mangaData.attributes.originalLanguage) + addQueryParameter("limit", "1") + } + .build(), + ), + ).awaitSuccess().parseAs() + } + return result.data.firstOrNull()?.attributes?.fileName + } } diff --git a/app/src/main/java/exh/md/utils/MdApi.kt b/app/src/main/java/exh/md/utils/MdApi.kt index 1e441d7e07cc..58b6f27204fe 100644 --- a/app/src/main/java/exh/md/utils/MdApi.kt +++ b/app/src/main/java/exh/md/utils/MdApi.kt @@ -3,6 +3,7 @@ package exh.md.utils object MdApi { const val baseUrl = "https://api.mangadex.org" const val manga = "$baseUrl/manga" + const val cover = "$baseUrl/cover" const val chapter = "$baseUrl/chapter" const val group = "$baseUrl/group" const val author = "$baseUrl/author"