Convert E-Hentai Update helper to Flows
This commit is contained in:
parent
1a0109df1d
commit
c049ce9018
@ -53,7 +53,12 @@ import exh.util.asObservable
|
|||||||
import exh.util.await
|
import exh.util.await
|
||||||
import exh.util.shouldDeleteChapters
|
import exh.util.shouldDeleteChapters
|
||||||
import exh.util.trimOrNull
|
import exh.util.trimOrNull
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.NonCancellable
|
import kotlinx.coroutines.NonCancellable
|
||||||
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import rx.Subscription
|
import rx.Subscription
|
||||||
@ -77,6 +82,8 @@ class MangaPresenter(
|
|||||||
private val sourceManager: SourceManager = Injekt.get()
|
private val sourceManager: SourceManager = Injekt.get()
|
||||||
) : BasePresenter<MangaController>() {
|
) : BasePresenter<MangaController>() {
|
||||||
|
|
||||||
|
val scope = CoroutineScope(Job() + Dispatchers.IO)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscription to update the manga from the source.
|
* Subscription to update the manga from the source.
|
||||||
*/
|
*/
|
||||||
@ -116,7 +123,7 @@ class MangaPresenter(
|
|||||||
|
|
||||||
private val updateHelper: EHentaiUpdateHelper by injectLazy()
|
private val updateHelper: EHentaiUpdateHelper by injectLazy()
|
||||||
|
|
||||||
val redirectUserRelay = BehaviorRelay.create<EXHRedirect>()
|
val redirectUserRelay: BehaviorRelay<EXHRedirect> = BehaviorRelay.create<EXHRedirect>()
|
||||||
|
|
||||||
data class EXHRedirect(val manga: Manga, val update: Boolean)
|
data class EXHRedirect(val manga: Manga, val update: Boolean)
|
||||||
|
|
||||||
@ -185,25 +192,22 @@ class MangaPresenter(
|
|||||||
if (chapters.isNotEmpty() && (source.isEhBasedSource()) && DebugToggles.ENABLE_EXH_ROOT_REDIRECT.enabled) {
|
if (chapters.isNotEmpty() && (source.isEhBasedSource()) && 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
|
||||||
add(
|
updateHelper.findAcceptedRootAndDiscardOthers(manga.source, chapters)
|
||||||
updateHelper.findAcceptedRootAndDiscardOthers(manga.source, chapters)
|
.onEach { (acceptedChain, _) ->
|
||||||
.subscribeOn(Schedulers.io())
|
// Redirect if we are not the accepted root
|
||||||
.subscribe { (acceptedChain, _) ->
|
if (manga.id != acceptedChain.manga.id) {
|
||||||
// Redirect if we are not the accepted root
|
// Update if any of our chapters are not in accepted manga's chapters
|
||||||
if (manga.id != acceptedChain.manga.id) {
|
val ourChapterUrls = chapters.map { it.url }.toSet()
|
||||||
// Update if any of our chapters are not in accepted manga's chapters
|
val acceptedChapterUrls = acceptedChain.chapters.map { it.url }.toSet()
|
||||||
val ourChapterUrls = chapters.map { it.url }.toSet()
|
val update = (ourChapterUrls - acceptedChapterUrls).isNotEmpty()
|
||||||
val acceptedChapterUrls = acceptedChain.chapters.map { it.url }.toSet()
|
redirectUserRelay.call(
|
||||||
val update = (ourChapterUrls - acceptedChapterUrls).isNotEmpty()
|
EXHRedirect(
|
||||||
redirectUserRelay.call(
|
acceptedChain.manga,
|
||||||
EXHRedirect(
|
update
|
||||||
acceptedChain.manga,
|
|
||||||
update
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
)
|
}.launchIn(scope)
|
||||||
}
|
}
|
||||||
// SY <--
|
// SY <--
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,10 @@ import eu.kanade.tachiyomi.data.database.models.Manga
|
|||||||
import eu.kanade.tachiyomi.data.database.models.MangaCategory
|
import eu.kanade.tachiyomi.data.database.models.MangaCategory
|
||||||
import exh.metadata.metadata.EHentaiSearchMetadata
|
import exh.metadata.metadata.EHentaiSearchMetadata
|
||||||
import exh.metadata.metadata.base.getFlatMetadataForManga
|
import exh.metadata.metadata.base.getFlatMetadataForManga
|
||||||
import rx.Observable
|
import exh.util.await
|
||||||
import rx.Single
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.asFlow
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
@ -29,31 +31,25 @@ class EHentaiUpdateHelper(context: Context) {
|
|||||||
*
|
*
|
||||||
* @return Triple<Accepted, Discarded, HasNew>
|
* @return Triple<Accepted, Discarded, HasNew>
|
||||||
*/
|
*/
|
||||||
fun findAcceptedRootAndDiscardOthers(sourceId: Long, chapters: List<Chapter>): Single<Triple<ChapterChain, List<ChapterChain>, Boolean>> {
|
fun findAcceptedRootAndDiscardOthers(sourceId: Long, chapters: List<Chapter>): Flow<Triple<ChapterChain, List<ChapterChain>, Boolean>> {
|
||||||
// Find other chains
|
// Find other chains
|
||||||
val chainsObservable = Observable.merge(
|
val chainsFlow = chapters.asFlow()
|
||||||
chapters.map { chapter ->
|
.map { chapter ->
|
||||||
db.getChapters(chapter.url).asRxSingle().toObservable()
|
db.getChapters(chapter.url).await().mapNotNull { it.manga_id }.distinct()
|
||||||
}
|
}
|
||||||
).toList().map { allChapters ->
|
.map { mangaIds ->
|
||||||
allChapters.flatMap { innerChapters -> innerChapters.map { it.manga_id!! } }.distinct()
|
mangaIds
|
||||||
}.flatMap { mangaIds ->
|
.mapNotNull { mangaId ->
|
||||||
Observable.merge(
|
(db.getManga(mangaId).await() ?: return@mapNotNull null) to db.getChapters(mangaId).await()
|
||||||
mangaIds.map { mangaId ->
|
|
||||||
Single.zip(
|
|
||||||
db.getManga(mangaId).asRxSingle(),
|
|
||||||
db.getChapters(mangaId).asRxSingle()
|
|
||||||
) { manga, chapters ->
|
|
||||||
ChapterChain(manga, chapters)
|
|
||||||
}.toObservable().filter {
|
|
||||||
it.manga.source == sourceId
|
|
||||||
}
|
}
|
||||||
}
|
.map {
|
||||||
)
|
ChapterChain(it.first, it.second)
|
||||||
}.toList()
|
}
|
||||||
|
.filter { it.manga.source == sourceId }
|
||||||
|
}
|
||||||
|
|
||||||
// Accept oldest chain
|
// Accept oldest chain
|
||||||
val chainsWithAccepted = chainsObservable.map { chains ->
|
val chainsWithAccepted = chainsFlow.map { chains ->
|
||||||
val acceptedChain = chains.minByOrNull { it.manga.id!! }!!
|
val acceptedChain = chains.minByOrNull { it.manga.id!! }!!
|
||||||
|
|
||||||
acceptedChain to chains
|
acceptedChain to chains
|
||||||
@ -160,7 +156,7 @@ class EHentaiUpdateHelper(context: Context) {
|
|||||||
|
|
||||||
Triple(newAccepted, toDiscard, new)
|
Triple(newAccepted, toDiscard, new)
|
||||||
} else Triple(accepted, emptyList(), false)
|
} else Triple(accepted, emptyList(), false)
|
||||||
}.toSingle()
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,12 +29,12 @@ import exh.util.cancellable
|
|||||||
import exh.util.jobScheduler
|
import exh.util.jobScheduler
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.FlowPreview
|
import kotlinx.coroutines.FlowPreview
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.cancelAndJoin
|
import kotlinx.coroutines.cancelAndJoin
|
||||||
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.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
@ -228,7 +228,7 @@ class EHentaiUpdateWorker : JobService(), CoroutineScope {
|
|||||||
|
|
||||||
// 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).await()
|
updateHelper.findAcceptedRootAndDiscardOthers(manga.source, chapters).single()
|
||||||
|
|
||||||
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