Respect thumbnailQuality and tryUsingFirstVolumeCover preferences. (MD) (#1260)

This commit is contained in:
NGB-Was-Taken 2024-09-01 20:30:01 +05:45 committed by GitHub
parent fbac29e0cd
commit bdb8553e28
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 75 additions and 21 deletions

View File

@ -87,6 +87,8 @@ class MangaDex(delegate: HttpSource, val context: Context) :
private fun usePort443Only() = sourcePreferences.getBoolean(getStandardHttpsPreferenceKey(mdLang.lang), false) private fun usePort443Only() = sourcePreferences.getBoolean(getStandardHttpsPreferenceKey(mdLang.lang), false)
private fun blockedGroups() = sourcePreferences.getString(getBlockedGroupsPrefKey(mdLang.lang), "").orEmpty() private fun blockedGroups() = sourcePreferences.getString(getBlockedGroupsPrefKey(mdLang.lang), "").orEmpty()
private fun blockedUploaders() = sourcePreferences.getString(getBlockedUploaderPrefKey(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 { private val mangadexService by lazy {
MangaDexService(client) MangaDexService(client)
@ -189,11 +191,11 @@ class MangaDex(delegate: HttpSource, val context: Context) :
@Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getMangaDetails")) @Deprecated("Use the 1.x API instead", replaceWith = ReplaceWith("getMangaDetails"))
override fun fetchMangaDetails(manga: SManga): Observable<SManga> { override fun fetchMangaDetails(manga: SManga): Observable<SManga> {
return mangaHandler.fetchMangaDetailsObservable(manga, id) return mangaHandler.fetchMangaDetailsObservable(manga, id, coverQuality(), tryUsingFirstVolumeCover())
} }
override suspend fun getMangaDetails(manga: SManga): SManga { 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")) @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 fun newMetaInstance() = MangaDexSearchMetadata()
override suspend fun parseIntoMetadata(metadata: MangaDexSearchMetadata, input: Triple<MangaDto, List<String>, StatisticsMangaDto>) { override suspend fun parseIntoMetadata(metadata: MangaDexSearchMetadata, input: Triple<MangaDto, List<String>, StatisticsMangaDto>) {
apiMangaParser.parseIntoMetadata(metadata, input.first, input.second, input.third) apiMangaParser.parseIntoMetadata(metadata, input.first, input.second, input.third, null, coverQuality())
} }
// LoginSource methods // LoginSource methods
@ -334,5 +336,17 @@ class MangaDex(delegate: HttpSource, val context: Context) :
fun getBlockedUploaderPrefKey(dexLang: String): String { fun getBlockedUploaderPrefKey(dexLang: String): String {
return "${blockedUploaderPref}_$dexLang" 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"
}
} }
} }

View File

@ -104,16 +104,12 @@ data class ReadChapterDto(
@Serializable @Serializable
data class CoverListDto( data class CoverListDto(
val results: List<CoverDto>, val data: List<CoverDto>,
) )
@Serializable @Serializable
data class CoverDto( data class CoverDto(
val data: CoverDataDto, val id: String,
)
@Serializable
data class CoverDataDto(
val attributes: CoverAttributesDto, val attributes: CoverAttributesDto,
val relationships: List<RelationshipDto>, val relationships: List<RelationshipDto>,
) )

View File

@ -41,6 +41,8 @@ class ApiMangaParser(
input: MangaDto, input: MangaDto,
simpleChapters: List<String>, simpleChapters: List<String>,
statistics: StatisticsMangaDto?, statistics: StatisticsMangaDto?,
coverFileName: String?,
coverQuality: String,
): SManga { ): SManga {
val mangaId = getManga.await(manga.url, sourceId)?.id val mangaId = getManga.await(manga.url, sourceId)?.id
val metadata = if (mangaId != null) { val metadata = if (mangaId != null) {
@ -50,7 +52,7 @@ class ApiMangaParser(
newMetaInstance() newMetaInstance()
} }
parseIntoMetadata(metadata, input, simpleChapters, statistics) parseIntoMetadata(metadata, input, simpleChapters, statistics, coverFileName, coverQuality)
if (mangaId != null) { if (mangaId != null) {
metadata.mangaId = mangaId metadata.mangaId = mangaId
insertFlatMetadata.await(metadata.flatten()) insertFlatMetadata.await(metadata.flatten())
@ -64,6 +66,8 @@ class ApiMangaParser(
mangaDto: MangaDto, mangaDto: MangaDto,
simpleChapters: List<String>, simpleChapters: List<String>,
statistics: StatisticsMangaDto?, statistics: StatisticsMangaDto?,
coverFileName: String?,
coverQuality: String,
) { ) {
with(metadata) { with(metadata) {
try { try {
@ -73,13 +77,17 @@ class ApiMangaParser(
altTitles = mangaAttributesDto.altTitles.mapNotNull { it[lang] }.nullIfEmpty() altTitles = mangaAttributesDto.altTitles.mapNotNull { it[lang] }.nullIfEmpty()
val mangaRelationshipsDto = mangaDto.data.relationships val mangaRelationshipsDto = mangaDto.data.relationships
mangaRelationshipsDto cover = if (!coverFileName.isNullOrEmpty()) {
.firstOrNull { relationshipDto -> relationshipDto.type == MdConstants.Types.coverArt } MdUtil.cdnCoverUrl(mangaDto.data.id, "$coverFileName$coverQuality")
?.attributes } else {
?.fileName mangaRelationshipsDto
?.let { coverFileName -> .firstOrNull { relationshipDto -> relationshipDto.type == MdConstants.Types.coverArt }
cover = MdUtil.cdnCoverUrl(mangaDto.data.id, coverFileName) ?.attributes
} ?.fileName
?.let { coverFileName ->
MdUtil.cdnCoverUrl(mangaDto.data.id, "$coverFileName$coverQuality")
}
}
description = MdUtil.cleanDescription( description = MdUtil.cleanDescription(
MdUtil.getFromLangMap( MdUtil.getFromLangMap(

View File

@ -23,7 +23,12 @@ class MangaHandler(
private val apiMangaParser: ApiMangaParser, private val apiMangaParser: ApiMangaParser,
private val followsHandler: FollowsHandler, 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 { return coroutineScope {
val mangaId = MdUtil.getMangaId(manga.url) val mangaId = MdUtil.getMangaId(manga.url)
val response = async(Dispatchers.IO) { service.viewManga(mangaId) } val response = async(Dispatchers.IO) { service.viewManga(mangaId) }
@ -32,19 +37,29 @@ class MangaHandler(
async(Dispatchers.IO) { async(Dispatchers.IO) {
kotlin.runCatching { service.mangasRating(mangaId) }.getOrNull()?.statistics?.get(mangaId) 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( apiMangaParser.parseToManga(
manga, manga,
sourceId, sourceId,
response.await(), responseData,
simpleChapters.await(), simpleChapters.await(),
statistics.await(), statistics.await(),
coverFileName?.await(),
coverQuality,
) )
} }
} }
fun fetchMangaDetailsObservable(manga: SManga, sourceId: Long): Observable<SManga> { fun fetchMangaDetailsObservable(manga: SManga, sourceId: Long, coverQuality: String, tryUsingFirstVolumeCover: Boolean): Observable<SManga> {
return runAsObservable { return runAsObservable {
getMangaDetails(manga, sourceId) getMangaDetails(manga, sourceId, coverQuality, tryUsingFirstVolumeCover)
} }
} }

View File

@ -9,6 +9,7 @@ import exh.md.dto.AtHomeDto
import exh.md.dto.AtHomeImageReportDto import exh.md.dto.AtHomeImageReportDto
import exh.md.dto.ChapterDto import exh.md.dto.ChapterDto
import exh.md.dto.ChapterListDto import exh.md.dto.ChapterListDto
import exh.md.dto.CoverListDto
import exh.md.dto.MangaDto import exh.md.dto.MangaDto
import exh.md.dto.MangaListDto import exh.md.dto.MangaListDto
import exh.md.dto.RelationListDto import exh.md.dto.RelationListDto
@ -209,4 +210,23 @@ class MangaDexService(
).awaitSuccess().parseAs() ).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
}
} }

View File

@ -3,6 +3,7 @@ package exh.md.utils
object MdApi { object MdApi {
const val baseUrl = "https://api.mangadex.org" const val baseUrl = "https://api.mangadex.org"
const val manga = "$baseUrl/manga" const val manga = "$baseUrl/manga"
const val cover = "$baseUrl/cover"
const val chapter = "$baseUrl/chapter" const val chapter = "$baseUrl/chapter"
const val group = "$baseUrl/group" const val group = "$baseUrl/group"
const val author = "$baseUrl/author" const val author = "$baseUrl/author"