Prevent duplicated chapter pages (#1353)

In case "ChapterForDownload#asDownloadReady" was called in quick succession, the page list got inserted twice.

This caused problems with getting the images from the rest endpoint, because they are selected by sorting them by asc index and selecting the page by using the provided index as an offset.

This, however, only works as long as there are no duplicates, otherwise, page indexes 1, 2; 3, 4; 5, 6; ... will just return the same page.
This commit is contained in:
schroda
2025-04-28 00:54:54 +02:00
committed by GitHub
parent 1cc2a05f90
commit 59d2151c92
2 changed files with 45 additions and 3 deletions

View File

@@ -11,6 +11,9 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import io.github.oshai.kotlinlogging.KLogger
import io.github.oshai.kotlinlogging.KotlinLogging
import io.github.reactivecircus.cache4k.Cache
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import org.jetbrains.exposed.sql.ResultRow
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.jetbrains.exposed.sql.and
@@ -26,6 +29,7 @@ import suwayomi.tachidesk.manga.model.table.ChapterTable
import suwayomi.tachidesk.manga.model.table.MangaTable
import suwayomi.tachidesk.manga.model.table.PageTable
import suwayomi.tachidesk.manga.model.table.toDataClass
import kotlin.time.Duration.Companion.minutes
suspend fun getChapterDownloadReady(
chapterId: Int? = null,
@@ -43,6 +47,12 @@ suspend fun getChapterDownloadReadyByIndex(
mangaId: Int,
): ChapterDataClass = getChapterDownloadReady(chapterIndex = chapterIndex, mangaId = mangaId)
private val mutexByChapterId: Cache<Int, Mutex> =
Cache
.Builder<Int, Mutex>()
.expireAfterAccess(10.minutes)
.build()
private class ChapterForDownload(
optChapterId: Int? = null,
optChapterIndex: Int? = null,
@@ -69,9 +79,7 @@ private class ChapterForDownload(
markAsNotDownloaded()
val pageList = fetchPageList()
updateDatabasePages(pageList)
updatePageList()
}
return asDataClass()
@@ -109,6 +117,14 @@ private class ChapterForDownload(
}.first()
}
private suspend fun updatePageList() {
val mutex = mutexByChapterId.get(chapterId) { Mutex() }
mutex.withLock {
val pageList = fetchPageList()
updateDatabasePages(pageList)
}
}
private suspend fun fetchPageList(): List<Page> {
val mangaEntry = transaction { MangaTable.selectAll().where { MangaTable.id eq mangaId }.first() }
val source = getCatalogueSourceOrStub(mangaEntry[MangaTable.sourceReference])