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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user