Mangadex support completed status

This commit is contained in:
Jobobby04 2021-11-13 22:46:03 -05:00
parent 508f025092
commit 0df5376545
5 changed files with 76 additions and 47 deletions

View File

@ -56,7 +56,7 @@ import kotlin.reflect.KClass
@Suppress("OverridingDeprecatedMember")
class MangaDex(delegate: HttpSource, val context: Context) :
DelegatedHttpSource(delegate),
MetadataSource<MangaDexSearchMetadata, MangaDto>,
MetadataSource<MangaDexSearchMetadata, Pair<MangaDto, List<String>>>,
UrlImportableSource,
FollowsSource,
LoginSource,
@ -193,8 +193,8 @@ class MangaDex(delegate: HttpSource, val context: Context) :
return MangaDexDescriptionAdapter(controller)
}
override suspend fun parseIntoMetadata(metadata: MangaDexSearchMetadata, input: MangaDto) {
apiMangaParser.parseIntoMetadata(metadata, input)
override suspend fun parseIntoMetadata(metadata: MangaDexSearchMetadata, input: Pair<MangaDto, List<String>>) {
apiMangaParser.parseIntoMetadata(metadata, input.first, input.second)
}
// LoginSource methods

View File

@ -122,3 +122,22 @@ data class CoverDataDto(
data class CoverAttributesDto(
val fileName: String,
)
@Serializable
data class AggregateDto(
val result: String,
val volumes: Map<String, AggregateVolume>,
)
@Serializable
data class AggregateVolume(
val volume: String,
val count: String,
val chapters: Map<String, AggregateChapter>,
)
@Serializable
data class AggregateChapter(
val chapter: String,
val count: String,
)

View File

@ -36,14 +36,14 @@ class ApiMangaParser(
}?.call()
?: error("Could not find no-args constructor for meta class: ${metaClass.qualifiedName}!")
fun parseToManga(manga: MangaInfo, input: MangaDto, sourceId: Long): MangaInfo {
fun parseToManga(manga: MangaInfo, input: MangaDto, simpleChapters: List<String>, sourceId: Long): MangaInfo {
val mangaId = db.getManga(manga.key, sourceId).executeAsBlocking()?.id
val metadata = if (mangaId != null) {
val flatMetadata = db.getFlatMetadataForManga(mangaId).executeAsBlocking()
flatMetadata?.raise(metaClass) ?: newMetaInstance()
} else newMetaInstance()
parseIntoMetadata(metadata, input)
parseIntoMetadata(metadata, input, simpleChapters)
if (mangaId != null) {
metadata.mangaId = mangaId
db.insertFlatMetadata(metadata.flatten())
@ -52,7 +52,7 @@ class ApiMangaParser(
return metadata.createMangaInfo(manga)
}
fun parseIntoMetadata(metadata: MangaDexSearchMetadata, mangaDto: MangaDto) {
fun parseIntoMetadata(metadata: MangaDexSearchMetadata, mangaDto: MangaDto, simpleChapters: List<String>) {
with(metadata) {
try {
val mangaAttributesDto = mangaDto.data.attributes
@ -73,11 +73,11 @@ class ApiMangaParser(
authors = mangaRelationshipsDto.filter { relationshipDto ->
relationshipDto.type.equals(MdConstants.Types.author, true)
}.mapNotNull { it.attributes!!.name }.distinct()
}.mapNotNull { it.attributes?.name }.distinct()
artists = mangaRelationshipsDto.filter { relationshipDto ->
relationshipDto.type.equals(MdConstants.Types.artist, true)
}.mapNotNull { it.attributes!!.name }.distinct()
}.mapNotNull { it.attributes?.name }.distinct()
langFlag = mangaAttributesDto.originalLanguage
val lastChapter = mangaAttributesDto.lastChapter?.toFloatOrNull()
@ -98,15 +98,17 @@ class ApiMangaParser(
// val filteredChapters = filterChapterForChecking(networkApiManga)
val tempStatus = parseStatus(mangaAttributesDto.status ?: "")
/*val publishedOrCancelled =
tempStatus == SManga.PUBLICATION_COMPLETE || tempStatus == SManga.CANCELLED
if (publishedOrCancelled && isMangaCompleted(networkApiManga, filteredChapters)) {
manga.status = SManga.COMPLETED
manga.missing_chapters = null
} else {*/
status = tempStatus
// }
val tempStatus = parseStatus(mangaAttributesDto.status)
val publishedOrCancelled = tempStatus == SManga.PUBLICATION_COMPLETE || tempStatus == SManga.CANCELLED
status = if (
mangaAttributesDto.lastChapter != null &&
publishedOrCancelled &&
mangaAttributesDto.lastChapter in simpleChapters
) {
SManga.COMPLETED
} else {
tempStatus
}
// things that will go with the genre tags but aren't actually genre
val nonGenres = listOfNotNull(
@ -134,34 +136,6 @@ class ApiMangaParser(
}
}
/**
* If chapter title is oneshot or a chapter exists which matches the last chapter in the required language
* return manga is complete
*/
/*private fun isMangaCompleted(
serializer: ApiMangaSerializer,
filteredChapters: List<ChapterSerializer>
): Boolean {
if (filteredChapters.isEmpty() || serializer.data.manga.lastChapter.isNullOrEmpty()) {
return false
}
val finalChapterNumber = serializer.data.manga.lastChapter!!
if (MdUtil.validOneShotFinalChapters.contains(finalChapterNumber)) {
filteredChapters.firstOrNull()?.let {
if (isOneShot(it, finalChapterNumber)) {
return true
}
}
}
val removeOneshots = filteredChapters.asSequence()
.map { it.chapter!!.toDoubleOrNull() }
.filter { it != null }
.map { floor(it!!).toInt() }
.filter { it != 0 }
.toList().distinctBy { it }
return removeOneshots.toList().size == floor(finalChapterNumber.toDouble()).toInt()
}*/
/* private fun filterChapterForChecking(serializer: ApiMangaSerializer): List<ChapterSerializer> {
serializer.data.chapters ?: return emptyList()
return serializer.data.chapters.asSequence()
@ -182,7 +156,7 @@ class ApiMangaParser(
((chapter.chapter.isNullOrEmpty() || chapter.chapter == "0") && MdUtil.validOneShotFinalChapters.contains(finalChapterNumber))
}*/
private fun parseStatus(status: String) = when (status) {
private fun parseStatus(status: String?) = when (status) {
"ongoing" -> SManga.ONGOING
"completed" -> SManga.PUBLICATION_COMPLETE
"cancelled" -> SManga.CANCELLED

View File

@ -14,6 +14,7 @@ import exh.md.utils.MdConstants
import exh.md.utils.MdUtil
import exh.md.utils.mdListCall
import exh.metadata.metadata.MangaDexSearchMetadata
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.async
import rx.Observable
import tachiyomi.source.model.ChapterInfo
@ -27,7 +28,8 @@ class MangaHandler(
) {
suspend fun getMangaDetails(manga: MangaInfo, sourceId: Long, forceLatestCovers: Boolean): MangaInfo {
val response = withIOContext { service.viewManga(MdUtil.getMangaId(manga.key)) }
return apiMangaParser.parseToManga(manga, response, sourceId)
val simpleChapters = withIOContext { getSimpleChapters(manga) }
return apiMangaParser.parseToManga(manga, response, simpleChapters, sourceId)
}
fun fetchMangaDetailsObservable(manga: SManga, sourceId: Long, forceLatestCovers: Boolean): Observable<SManga> {
@ -88,4 +90,17 @@ class MangaHandler(
apiMangaParser.chapterParseForMangaId(service.viewChapter(chapterId))
}
}
private suspend fun getSimpleChapters(manga: MangaInfo): List<String> {
return runCatching { service.aggregateChapters(MdUtil.getMangaId(manga.key), lang) }
.onFailure {
if (it is CancellationException) throw it
}
.map { dto ->
dto.volumes.values
.flatMap { it.chapters.values }
.map { it.chapter }
}
.getOrDefault(emptyList())
}
}

View File

@ -4,6 +4,7 @@ import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.parseAs
import exh.md.dto.AggregateDto
import exh.md.dto.AtHomeDto
import exh.md.dto.AtHomeImageReportDto
import exh.md.dto.ChapterDto
@ -64,6 +65,26 @@ class MangaDexService(
).await().parseAs(MdUtil.jsonParser)
}
suspend fun aggregateChapters(
id: String,
translatedLanguage: String
): AggregateDto {
return client.newCall(
GET(
MdApi.manga.toHttpUrl()
.newBuilder()
.apply {
addPathSegment(id)
addPathSegment("aggregate")
addQueryParameter("translatedLanguage[]", translatedLanguage)
}
.build()
.toString(),
cache = CacheControl.FORCE_NETWORK
)
).await().parseAs(MdUtil.jsonParser)
}
suspend fun viewChapters(
id: String,
translatedLanguage: String,