Refactor network to local manga logic

Maybe fixes #8289

(cherry picked from commit d5b4bb49b1)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/SearchPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourcePresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/globalsearch/GlobalSearchPresenter.kt
This commit is contained in:
arkon
2022-10-26 23:01:21 -04:00
committed by Jobobby04
parent 9b28b65e62
commit b5ae4c0d43
17 changed files with 157 additions and 277 deletions
+9 -11
View File
@@ -6,7 +6,7 @@ import eu.kanade.domain.chapter.interactor.GetChapter
import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
import eu.kanade.domain.chapter.model.Chapter
import eu.kanade.domain.manga.interactor.GetManga
import eu.kanade.domain.manga.interactor.InsertManga
import eu.kanade.domain.manga.interactor.NetworkToLocalManga
import eu.kanade.domain.manga.interactor.UpdateManga
import eu.kanade.domain.manga.model.Manga
import eu.kanade.domain.source.service.SourcePreferences
@@ -22,7 +22,7 @@ import uy.kohesive.injekt.api.get
class GalleryAdder(
private val getManga: GetManga = Injekt.get(),
private val updateManga: UpdateManga = Injekt.get(),
private val insertManga: InsertManga = Injekt.get(),
private val networkToLocalManga: NetworkToLocalManga = Injekt.get(),
private val getChapter: GetChapter = Injekt.get(),
private val syncChaptersWithSource: SyncChaptersWithSource = Injekt.get(),
private val sourceManager: SourceManager = Injekt.get(),
@@ -129,15 +129,13 @@ class GalleryAdder(
// Use manga in DB if possible, otherwise, make a new manga
var manga = getManga.await(cleanedMangaUrl, source.id)
?: run {
insertManga.await(
Manga.create().copy(
source = source.id,
url = cleanedMangaUrl,
),
)
getManga.await(cleanedMangaUrl, source.id)!!
}
?: networkToLocalManga.await(
Manga.create().copy(
source = source.id,
url = cleanedMangaUrl,
),
source.id,
)
// Fetch and copy details
val newManga = source.getMangaDetails(manga.toSManga())
@@ -1,9 +1,7 @@
package exh.smartsearch
import eu.kanade.domain.manga.interactor.GetManga
import eu.kanade.domain.manga.interactor.InsertManga
import eu.kanade.domain.manga.model.Manga
import eu.kanade.tachiyomi.data.database.models.toDomainManga
import eu.kanade.domain.manga.model.toDomainManga
import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.SManga
@@ -12,19 +10,14 @@ import info.debatty.java.stringsimilarity.NormalizedLevenshtein
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.supervisorScope
import uy.kohesive.injekt.injectLazy
import java.util.Locale
import eu.kanade.tachiyomi.data.database.models.Manga.Companion as DbManga
class SmartSearchEngine(
private val extraSearchParams: String? = null,
) {
private val getManga: GetManga by injectLazy()
private val insertManga: InsertManga by injectLazy()
private val normalizedLevenshtein = NormalizedLevenshtein()
suspend fun smartSearch(source: CatalogueSource, title: String): SManga? {
suspend fun smartSearch(source: CatalogueSource, title: String): Manga? {
val cleanedTitle = cleanSmartSearchTitle(title)
val queries = getSmartSearchQueries(cleanedTitle)
@@ -51,10 +44,10 @@ class SmartSearchEngine(
}.flatMap { it.await() }
}
return eligibleManga.maxByOrNull { it.dist }?.manga
return eligibleManga.maxByOrNull { it.dist }?.manga?.toDomainManga()
}
suspend fun normalSearch(source: CatalogueSource, title: String): SManga? {
suspend fun normalSearch(source: CatalogueSource, title: String): Manga? {
val eligibleManga = supervisorScope {
val searchQuery = if (extraSearchParams != null) {
"$title ${extraSearchParams.trim()}"
@@ -75,7 +68,7 @@ class SmartSearchEngine(
}
}
return eligibleManga.maxByOrNull { it.dist }?.manga
return eligibleManga.maxByOrNull { it.dist }?.manga?.toDomainManga()
}
private fun getSmartSearchQueries(cleanedTitle: String): List<String> {
@@ -169,32 +162,6 @@ class SmartSearchEngine(
return result.toString()
}
/**
* Returns a manga from the database for the given manga from network. It creates a new entry
* if the manga is not yet in the database.
*
* @param sManga the manga from the source.
* @return a manga from the database.
*/
suspend fun networkToLocalManga(sManga: SManga, sourceId: Long): Manga {
var localManga = getManga.await(sManga.url, sourceId)
if (localManga == null) {
val newManga = DbManga.create(sManga.url, sManga.title, sourceId)
newManga.copyFrom(sManga)
newManga.id = -1
val result = run {
val id = insertManga.await(newManga.toDomainManga()!!)
getManga.await(id!!)
}
localManga = result
} else if (!localManga.favorite) {
// if the manga isn't a favorite, set its display title from source
// if it later becomes a favorite, updated title will go to db
localManga = localManga.copy(ogTitle = sManga.title)
}
return localManga!!
}
companion object {
const val MIN_SMART_ELIGIBLE_THRESHOLD = 0.4
const val MIN_NORMAL_ELIGIBLE_THRESHOLD = 0.4
@@ -1,6 +1,7 @@
package exh.ui.smartsearch
import android.os.Bundle
import eu.kanade.domain.manga.interactor.NetworkToLocalManga
import eu.kanade.domain.manga.model.Manga
import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
@@ -10,8 +11,14 @@ import exh.smartsearch.SmartSearchEngine
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
class SmartSearchPresenter(private val source: CatalogueSource, private val config: SourcesController.SmartSearchConfig) :
class SmartSearchPresenter(
private val source: CatalogueSource,
private val config: SourcesController.SmartSearchConfig,
private val networkToLocalManga: NetworkToLocalManga = Injekt.get(),
) :
BasePresenter<SmartSearchController>() {
private val _smartSearchFlow = MutableSharedFlow<SearchResults>()
@@ -26,7 +33,7 @@ class SmartSearchPresenter(private val source: CatalogueSource, private val conf
val result = try {
val resultManga = smartSearchEngine.smartSearch(source, config.origTitle)
if (resultManga != null) {
val localManga = smartSearchEngine.networkToLocalManga(resultManga, source.id)
val localManga = networkToLocalManga.await(resultManga, source.id)
SearchResults.Found(localManga)
} else {
SearchResults.NotFound