Simplify EHentaiUpdateHelper
This commit is contained in:
parent
755f3377ad
commit
a280a5ed77
@ -263,8 +263,9 @@ class MangaInfoScreenModel(
|
|||||||
if (chapters.isNotEmpty() && manga.isEhBasedManga() && DebugToggles.ENABLE_EXH_ROOT_REDIRECT.enabled) {
|
if (chapters.isNotEmpty() && manga.isEhBasedManga() && DebugToggles.ENABLE_EXH_ROOT_REDIRECT.enabled) {
|
||||||
// Check for gallery in library and accept manga with lowest id
|
// Check for gallery in library and accept manga with lowest id
|
||||||
// Find chapters sharing same root
|
// Find chapters sharing same root
|
||||||
updateHelper.findAcceptedRootAndDiscardOthers(manga.source, chapters)
|
launchIO {
|
||||||
.onEach { (acceptedChain, _) ->
|
try {
|
||||||
|
val (acceptedChain) = updateHelper.findAcceptedRootAndDiscardOthers(manga.source, chapters)
|
||||||
// Redirect if we are not the accepted root
|
// Redirect if we are not the accepted root
|
||||||
if (manga.id != acceptedChain.manga.id && acceptedChain.manga.favorite) {
|
if (manga.id != acceptedChain.manga.id && acceptedChain.manga.favorite) {
|
||||||
// Update if any of our chapters are not in accepted manga's chapters
|
// Update if any of our chapters are not in accepted manga's chapters
|
||||||
@ -273,7 +274,10 @@ class MangaInfoScreenModel(
|
|||||||
EXHRedirect(acceptedChain.manga.id),
|
EXHRedirect(acceptedChain.manga.id),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}.launchIn(coroutineScope)
|
} catch (e: Exception) {
|
||||||
|
logcat(LogPriority.ERROR, e) { "Error loading accepted chapter chain" }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.combine(
|
.combine(
|
||||||
|
@ -20,9 +20,6 @@ import eu.kanade.domain.manga.model.MangaUpdate
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.coroutineScope
|
import kotlinx.coroutines.coroutineScope
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
import kotlinx.coroutines.flow.flowOf
|
|
||||||
import kotlinx.coroutines.flow.map
|
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@ -50,111 +47,101 @@ class EHentaiUpdateHelper(context: Context) {
|
|||||||
*
|
*
|
||||||
* @return Triple<Accepted, Discarded, HasNew>
|
* @return Triple<Accepted, Discarded, HasNew>
|
||||||
*/
|
*/
|
||||||
fun findAcceptedRootAndDiscardOthers(sourceId: Long, chapters: List<Chapter>): Flow<Triple<ChapterChain, List<ChapterChain>, Boolean>> {
|
suspend fun findAcceptedRootAndDiscardOthers(sourceId: Long, chapters: List<Chapter>): Triple<ChapterChain, List<ChapterChain>, Boolean> {
|
||||||
// Find other chains
|
// Find other chains
|
||||||
val chainsFlow = flowOf(chapters)
|
val chains = chapters
|
||||||
.map { chapterList ->
|
.flatMap { chapter ->
|
||||||
chapterList.flatMap { chapter ->
|
getChapterByUrl.await(chapter.url).map { it.mangaId }
|
||||||
getChapterByUrl.await(chapter.url).map { it.mangaId }
|
|
||||||
}.distinct()
|
|
||||||
}
|
}
|
||||||
.map { mangaIds ->
|
.distinct()
|
||||||
mangaIds
|
.mapNotNull { mangaId ->
|
||||||
.mapNotNull { mangaId ->
|
coroutineScope {
|
||||||
coroutineScope {
|
val manga = async(Dispatchers.IO) {
|
||||||
val manga = async(Dispatchers.IO) {
|
getManga.await(mangaId)
|
||||||
getManga.await(mangaId)
|
|
||||||
}
|
|
||||||
val chapterList = async(Dispatchers.IO) {
|
|
||||||
getChapterByMangaId.await(mangaId)
|
|
||||||
}
|
|
||||||
val history = async(Dispatchers.IO) {
|
|
||||||
getHistoryByMangaId.await(mangaId)
|
|
||||||
}
|
|
||||||
ChapterChain(
|
|
||||||
manga.await() ?: return@coroutineScope null,
|
|
||||||
chapterList.await(),
|
|
||||||
history.await(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.filter { it.manga.source == sourceId }
|
val chapterList = async(Dispatchers.IO) {
|
||||||
|
getChapterByMangaId.await(mangaId)
|
||||||
|
}
|
||||||
|
val history = async(Dispatchers.IO) {
|
||||||
|
getHistoryByMangaId.await(mangaId)
|
||||||
|
}
|
||||||
|
ChapterChain(
|
||||||
|
manga.await() ?: return@coroutineScope null,
|
||||||
|
chapterList.await(),
|
||||||
|
history.await(),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
.filter { it.manga.source == sourceId }
|
||||||
|
|
||||||
// Accept oldest chain
|
// Accept oldest chain
|
||||||
val chainsWithAccepted = chainsFlow.map { chains ->
|
val accepted = chains.minBy { it.manga.id }
|
||||||
val acceptedChain = chains.minBy { it.manga.id }
|
|
||||||
|
|
||||||
acceptedChain to chains
|
val toDiscard = chains.filter { it.manga.favorite && it.manga.id != accepted.manga.id }
|
||||||
}
|
val mangaUpdates = mutableListOf<MangaUpdate>()
|
||||||
|
|
||||||
return chainsWithAccepted.map { (accepted, chains) ->
|
val chainsAsChapters = chains.flatMap { it.chapters }
|
||||||
val toDiscard = chains.filter { it.manga.favorite && it.manga.id != accepted.manga.id }
|
val chainsAsHistory = chains.flatMap { it.history }
|
||||||
val mangaUpdates = mutableListOf<MangaUpdate>()
|
|
||||||
|
|
||||||
val chainsAsChapters = chains.flatMap { it.chapters }
|
return if (toDiscard.isNotEmpty()) {
|
||||||
val chainsAsHistory = chains.flatMap { it.history }
|
// Copy chain chapters to curChapters
|
||||||
|
val (chapterUpdates, newChapters, new) = getChapterList(accepted, toDiscard, chainsAsChapters)
|
||||||
|
|
||||||
if (toDiscard.isNotEmpty()) {
|
toDiscard.forEach {
|
||||||
// Copy chain chapters to curChapters
|
mangaUpdates += MangaUpdate(
|
||||||
val (chapterUpdates, newChapters, new) = getChapterList(accepted, toDiscard, chainsAsChapters)
|
id = it.manga.id,
|
||||||
|
favorite = false,
|
||||||
toDiscard.forEach {
|
dateAdded = 0,
|
||||||
mangaUpdates += MangaUpdate(
|
)
|
||||||
id = it.manga.id,
|
|
||||||
favorite = false,
|
|
||||||
dateAdded = 0,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (!accepted.manga.favorite) {
|
|
||||||
mangaUpdates += MangaUpdate(
|
|
||||||
id = accepted.manga.id,
|
|
||||||
favorite = true,
|
|
||||||
dateAdded = System.currentTimeMillis(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
val newAccepted = ChapterChain(accepted.manga, newChapters, emptyList())
|
|
||||||
val rootsToMutate = toDiscard + newAccepted
|
|
||||||
|
|
||||||
// Apply changes to all manga
|
|
||||||
updateManga.awaitAll(mangaUpdates)
|
|
||||||
// Insert new chapters for accepted manga
|
|
||||||
chapterRepository.updateAll(chapterUpdates)
|
|
||||||
chapterRepository.addAll(newChapters)
|
|
||||||
|
|
||||||
val (newHistory, deleteHistory) = getHistory(getChapterByMangaId.await(accepted.manga.id), chainsAsChapters, chainsAsHistory)
|
|
||||||
|
|
||||||
// Delete the duplicate history first
|
|
||||||
deleteHistory.forEach {
|
|
||||||
removeHistory.awaitById(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert new history
|
|
||||||
newHistory.forEach {
|
|
||||||
upsertHistory.await(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy categories from all chains to accepted manga
|
|
||||||
|
|
||||||
val newCategories = rootsToMutate.flatMap { chapterChain ->
|
|
||||||
getCategories.await(chapterChain.manga.id).map { it.id }
|
|
||||||
}.distinct()
|
|
||||||
rootsToMutate.forEach {
|
|
||||||
setMangaCategories.await(it.manga.id, newCategories)
|
|
||||||
}
|
|
||||||
|
|
||||||
Triple(newAccepted, toDiscard, new)
|
|
||||||
} else {
|
|
||||||
/*val notNeeded = chains.filter { it.manga.id != accepted.manga.id }
|
|
||||||
val (newChapters, new) = getChapterList(accepted, notNeeded, chainsAsChapters)
|
|
||||||
val newAccepted = ChapterChain(accepted.manga, newChapters)
|
|
||||||
|
|
||||||
// Insert new chapters for accepted manga
|
|
||||||
db.insertChapters(newAccepted.chapters).await()*/
|
|
||||||
|
|
||||||
Triple(accepted, emptyList(), false)
|
|
||||||
}
|
}
|
||||||
|
if (!accepted.manga.favorite) {
|
||||||
|
mangaUpdates += MangaUpdate(
|
||||||
|
id = accepted.manga.id,
|
||||||
|
favorite = true,
|
||||||
|
dateAdded = System.currentTimeMillis(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val newAccepted = ChapterChain(accepted.manga, newChapters, emptyList())
|
||||||
|
val rootsToMutate = toDiscard + newAccepted
|
||||||
|
|
||||||
|
// Apply changes to all manga
|
||||||
|
updateManga.awaitAll(mangaUpdates)
|
||||||
|
// Insert new chapters for accepted manga
|
||||||
|
chapterRepository.updateAll(chapterUpdates)
|
||||||
|
chapterRepository.addAll(newChapters)
|
||||||
|
|
||||||
|
val (newHistory, deleteHistory) = getHistory(getChapterByMangaId.await(accepted.manga.id), chainsAsChapters, chainsAsHistory)
|
||||||
|
|
||||||
|
// Delete the duplicate history first
|
||||||
|
deleteHistory.forEach {
|
||||||
|
removeHistory.awaitById(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert new history
|
||||||
|
newHistory.forEach {
|
||||||
|
upsertHistory.await(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy categories from all chains to accepted manga
|
||||||
|
|
||||||
|
val newCategories = rootsToMutate.flatMap { chapterChain ->
|
||||||
|
getCategories.await(chapterChain.manga.id).map { it.id }
|
||||||
|
}.distinct()
|
||||||
|
rootsToMutate.forEach {
|
||||||
|
setMangaCategories.await(it.manga.id, newCategories)
|
||||||
|
}
|
||||||
|
|
||||||
|
Triple(newAccepted, toDiscard, new)
|
||||||
|
} else {
|
||||||
|
/*val notNeeded = chains.filter { it.manga.id != accepted.manga.id }
|
||||||
|
val (newChapters, new) = getChapterList(accepted, notNeeded, chainsAsChapters)
|
||||||
|
val newAccepted = ChapterChain(accepted.manga, newChapters)
|
||||||
|
|
||||||
|
// Insert new chapters for accepted manga
|
||||||
|
db.insertChapters(newAccepted.chapters).await()*/
|
||||||
|
|
||||||
|
Triple(accepted, emptyList(), false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,6 @@ import exh.metadata.metadata.EHentaiSearchMetadata
|
|||||||
import exh.util.cancellable
|
import exh.util.cancellable
|
||||||
import kotlinx.coroutines.flow.asFlow
|
import kotlinx.coroutines.flow.asFlow
|
||||||
import kotlinx.coroutines.flow.mapNotNull
|
import kotlinx.coroutines.flow.mapNotNull
|
||||||
import kotlinx.coroutines.flow.single
|
|
||||||
import kotlinx.coroutines.flow.toList
|
import kotlinx.coroutines.flow.toList
|
||||||
import kotlinx.serialization.encodeToString
|
import kotlinx.serialization.encodeToString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
@ -165,7 +164,7 @@ class EHentaiUpdateWorker(private val context: Context, workerParams: WorkerPara
|
|||||||
|
|
||||||
// Find accepted root and discard others
|
// Find accepted root and discard others
|
||||||
val (acceptedRoot, discardedRoots, hasNew) =
|
val (acceptedRoot, discardedRoots, hasNew) =
|
||||||
updateHelper.findAcceptedRootAndDiscardOthers(manga.source, chapters).single()
|
updateHelper.findAcceptedRootAndDiscardOthers(manga.source, chapters)
|
||||||
|
|
||||||
if ((new.isNotEmpty() && manga.id == acceptedRoot.manga.id) ||
|
if ((new.isNotEmpty() && manga.id == acceptedRoot.manga.id) ||
|
||||||
(hasNew && updatedManga.none { it.first.id == acceptedRoot.manga.id })
|
(hasNew && updatedManga.none { it.first.id == acceptedRoot.manga.id })
|
||||||
|
Loading…
x
Reference in New Issue
Block a user