mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-03 23:58:55 +01:00 
			
		
		
		
	Release v6.1.3
Make search engine synchronous Offload some search engine tasks to background threads Minor search engine speedups
This commit is contained in:
		@@ -11,6 +11,7 @@ import io.realm.Realm
 | 
			
		||||
import io.realm.RealmQuery
 | 
			
		||||
import io.realm.RealmResults
 | 
			
		||||
import rx.Observable
 | 
			
		||||
import timber.log.Timber
 | 
			
		||||
import kotlin.reflect.KClass
 | 
			
		||||
 | 
			
		||||
fun Realm.ehMetaQueryFromUrl(url: String,
 | 
			
		||||
@@ -50,7 +51,7 @@ private fun pervEdenSourceToLang(source: Long)
 | 
			
		||||
 | 
			
		||||
fun Realm.pervEdenMetaQueryFromUrl(url: String,
 | 
			
		||||
                                   source: Long,
 | 
			
		||||
                                   meta: RealmQuery<PervEdenGalleryMetadata>?) =
 | 
			
		||||
                                   meta: RealmQuery<PervEdenGalleryMetadata>? = null) =
 | 
			
		||||
        pervEdenMetadataQuery(
 | 
			
		||||
                PervEdenGalleryMetadata.pvIdFromUrl(url),
 | 
			
		||||
                source,
 | 
			
		||||
@@ -74,7 +75,7 @@ fun Realm.loadPervEdenAsync(pvId: String, source: Long): Observable<PervEdenGall
 | 
			
		||||
        .asObservable()
 | 
			
		||||
 | 
			
		||||
fun Realm.nhentaiMetaQueryFromUrl(url: String,
 | 
			
		||||
                                  meta: RealmQuery<NHentaiMetadata>?) =
 | 
			
		||||
                                  meta: RealmQuery<NHentaiMetadata>? = null) =
 | 
			
		||||
        nhentaiMetadataQuery(
 | 
			
		||||
                NHentaiMetadata.nhIdFromUrl(url),
 | 
			
		||||
                meta
 | 
			
		||||
@@ -95,11 +96,13 @@ fun Realm.loadNhentaiAsync(nhId: Long): Observable<NHentaiMetadata?>
 | 
			
		||||
        .asObservable()
 | 
			
		||||
 | 
			
		||||
fun Realm.loadAllMetadata(): Map<KClass<out SearchableGalleryMetadata>, RealmResults<out SearchableGalleryMetadata>> =
 | 
			
		||||
        mapOf(
 | 
			
		||||
                Pair(ExGalleryMetadata::class, where(ExGalleryMetadata::class.java).findAll()),
 | 
			
		||||
                Pair(NHentaiMetadata::class, where(NHentaiMetadata::class.java).findAll()),
 | 
			
		||||
                Pair(PervEdenGalleryMetadata::class, where(PervEdenGalleryMetadata::class.java).findAll())
 | 
			
		||||
        )
 | 
			
		||||
        listOf<Pair<KClass<out SearchableGalleryMetadata>, RealmQuery<out SearchableGalleryMetadata>>>(
 | 
			
		||||
                Pair(ExGalleryMetadata::class, where(ExGalleryMetadata::class.java)),
 | 
			
		||||
                Pair(NHentaiMetadata::class, where(NHentaiMetadata::class.java)),
 | 
			
		||||
                Pair(PervEdenGalleryMetadata::class, where(PervEdenGalleryMetadata::class.java))
 | 
			
		||||
        ).map {
 | 
			
		||||
            Pair(it.first, it.second.findAllSorted(SearchableGalleryMetadata::mangaId.name))
 | 
			
		||||
        }.toMap()
 | 
			
		||||
 | 
			
		||||
fun Realm.queryMetadataFromManga(manga: Manga,
 | 
			
		||||
                                 meta: RealmQuery<out SearchableGalleryMetadata>? = null): RealmQuery<out SearchableGalleryMetadata> =
 | 
			
		||||
@@ -112,3 +115,21 @@ fun Realm.queryMetadataFromManga(manga: Manga,
 | 
			
		||||
        NHENTAI_SOURCE_ID -> nhentaiMetaQueryFromUrl(manga.url, meta as? RealmQuery<NHentaiMetadata>)
 | 
			
		||||
        else -> throw IllegalArgumentException("Unknown source type!")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
fun Realm.syncMangaIds(mangas: List<Manga>) {
 | 
			
		||||
    Timber.d("--> EH: Begin syncing ${mangas.size} manga IDs...")
 | 
			
		||||
    executeTransaction {
 | 
			
		||||
        mangas.filter {
 | 
			
		||||
            isLewdSource(it.source)
 | 
			
		||||
        }.forEach { manga ->
 | 
			
		||||
            try {
 | 
			
		||||
                queryMetadataFromManga(manga).findFirst()?.let { meta ->
 | 
			
		||||
                    meta.mangaId = manga.id
 | 
			
		||||
                }
 | 
			
		||||
            } catch(e: Exception) {
 | 
			
		||||
                Timber.w(e, "Error syncing manga IDs! Ignoring...")
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    Timber.d("--> EH: Finish syncing ${mangas.size} manga IDs!")
 | 
			
		||||
}
 | 
			
		||||
@@ -56,10 +56,10 @@ open class ExGalleryMetadata : RealmObject(), SearchableGalleryMetadata {
 | 
			
		||||
    override fun getTitles() = listOf(title, altTitle).filterNotNull()
 | 
			
		||||
 | 
			
		||||
    @Ignore
 | 
			
		||||
    override val titleFields = listOf(
 | 
			
		||||
            ExGalleryMetadata::title.name,
 | 
			
		||||
            ExGalleryMetadata::altTitle.name
 | 
			
		||||
    )
 | 
			
		||||
    override val titleFields = TITLE_FIELDS
 | 
			
		||||
 | 
			
		||||
    @Index
 | 
			
		||||
    override var mangaId: Long? = null
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
        private fun splitGalleryUrl(url: String)
 | 
			
		||||
@@ -72,5 +72,10 @@ open class ExGalleryMetadata : RealmObject(), SearchableGalleryMetadata {
 | 
			
		||||
 | 
			
		||||
        fun galleryToken(url: String) =
 | 
			
		||||
                splitGalleryUrl(url).last()
 | 
			
		||||
 | 
			
		||||
        val TITLE_FIELDS = listOf(
 | 
			
		||||
                ExGalleryMetadata::title.name,
 | 
			
		||||
                ExGalleryMetadata::altTitle.name
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -53,11 +53,10 @@ open class NHentaiMetadata : RealmObject(), SearchableGalleryMetadata {
 | 
			
		||||
    override fun getTitles() = listOf(japaneseTitle, englishTitle, shortTitle).filterNotNull()
 | 
			
		||||
 | 
			
		||||
    @Ignore
 | 
			
		||||
    override val titleFields = listOf(
 | 
			
		||||
            NHentaiMetadata::japaneseTitle.name,
 | 
			
		||||
            NHentaiMetadata::englishTitle.name,
 | 
			
		||||
            NHentaiMetadata::shortTitle.name
 | 
			
		||||
    )
 | 
			
		||||
    override val titleFields = TITLE_FIELDS
 | 
			
		||||
 | 
			
		||||
    @Index
 | 
			
		||||
    override var mangaId: Long? = null
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
        val BASE_URL = "https://nhentai.net"
 | 
			
		||||
@@ -71,6 +70,12 @@ open class NHentaiMetadata : RealmObject(), SearchableGalleryMetadata {
 | 
			
		||||
 | 
			
		||||
        fun nhIdFromUrl(url: String)
 | 
			
		||||
            = url.split("/").last { it.isNotBlank() }.toLong()
 | 
			
		||||
 | 
			
		||||
        val TITLE_FIELDS = listOf(
 | 
			
		||||
                NHentaiMetadata::japaneseTitle.name,
 | 
			
		||||
                NHentaiMetadata::englishTitle.name,
 | 
			
		||||
                NHentaiMetadata::shortTitle.name
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -45,10 +45,10 @@ open class PervEdenGalleryMetadata : RealmObject(), SearchableGalleryMetadata {
 | 
			
		||||
    }).filterNotNull()
 | 
			
		||||
 | 
			
		||||
    @Ignore
 | 
			
		||||
    override val titleFields = listOf(
 | 
			
		||||
            //TODO Somehow include altTitles
 | 
			
		||||
            PervEdenGalleryMetadata::title.name
 | 
			
		||||
    )
 | 
			
		||||
    override val titleFields = TITLE_FIELDS
 | 
			
		||||
 | 
			
		||||
    @Index
 | 
			
		||||
    override var mangaId: Long? = null
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
        private fun splitGalleryUrl(url: String)
 | 
			
		||||
@@ -57,6 +57,11 @@ open class PervEdenGalleryMetadata : RealmObject(), SearchableGalleryMetadata {
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
        fun pvIdFromUrl(url: String) = splitGalleryUrl(url).last()
 | 
			
		||||
 | 
			
		||||
        val TITLE_FIELDS = listOf(
 | 
			
		||||
                //TODO Somehow include altTitles
 | 
			
		||||
                PervEdenGalleryMetadata::title.name
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -21,4 +21,6 @@ interface SearchableGalleryMetadata: RealmModel {
 | 
			
		||||
    fun getTitles(): List<String>
 | 
			
		||||
 | 
			
		||||
    val titleFields: List<String>
 | 
			
		||||
 | 
			
		||||
    var mangaId: Long?
 | 
			
		||||
}
 | 
			
		||||
@@ -2,18 +2,17 @@ package exh.search
 | 
			
		||||
 | 
			
		||||
import exh.metadata.models.SearchableGalleryMetadata
 | 
			
		||||
import exh.metadata.models.Tag
 | 
			
		||||
import exh.util.beginLog
 | 
			
		||||
import io.realm.Case
 | 
			
		||||
import io.realm.RealmResults
 | 
			
		||||
import io.realm.RealmQuery
 | 
			
		||||
 | 
			
		||||
class SearchEngine {
 | 
			
		||||
 | 
			
		||||
    private val queryCache = mutableMapOf<String, List<QueryComponent>>()
 | 
			
		||||
 | 
			
		||||
    fun filterResults(metadata: RealmResults<out SearchableGalleryMetadata>, query: List<QueryComponent>):
 | 
			
		||||
            RealmResults<out SearchableGalleryMetadata> {
 | 
			
		||||
        val first = metadata.firstOrNull() ?: return metadata
 | 
			
		||||
        val rQuery = metadata.where()//.beginLog(SearchableGalleryMetadata::class.java)
 | 
			
		||||
    fun <T : SearchableGalleryMetadata> filterResults(rQuery: RealmQuery<T>,
 | 
			
		||||
                                                      query: List<QueryComponent>,
 | 
			
		||||
                                                      titleFields: List<String>):
 | 
			
		||||
            RealmQuery<T> {
 | 
			
		||||
        var queryEmpty = true
 | 
			
		||||
 | 
			
		||||
        fun matchTagList(namespace: String?,
 | 
			
		||||
@@ -59,14 +58,13 @@ class SearchEngine {
 | 
			
		||||
                rQuery.beginGroup()
 | 
			
		||||
 | 
			
		||||
                //Match title
 | 
			
		||||
                first.titleFields
 | 
			
		||||
                        .forEachIndexed { index, s ->
 | 
			
		||||
                            queryEmpty = false
 | 
			
		||||
                            if(index > 0)
 | 
			
		||||
                                rQuery.or()
 | 
			
		||||
                titleFields.forEachIndexed { index, s ->
 | 
			
		||||
                    queryEmpty = false
 | 
			
		||||
                    if(index > 0)
 | 
			
		||||
                        rQuery.or()
 | 
			
		||||
 | 
			
		||||
                            rQuery.like(s, component.asLenientTitleQuery(), Case.INSENSITIVE)
 | 
			
		||||
                        }
 | 
			
		||||
                    rQuery.like(s, component.asLenientTitleQuery(), Case.INSENSITIVE)
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                //Match tags
 | 
			
		||||
                matchTagList(null, component, false) //We already deal with exclusions here
 | 
			
		||||
@@ -89,7 +87,7 @@ class SearchEngine {
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return rQuery.findAll()
 | 
			
		||||
        return rQuery
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun parseQuery(query: String) = queryCache.getOrPut(query, {
 | 
			
		||||
 
 | 
			
		||||
@@ -88,7 +88,6 @@ class MetadataFetchDialog {
 | 
			
		||||
        db.getLibraryMangas().asRxSingle().subscribe {
 | 
			
		||||
            if(!explicit && it.isEmpty()) {
 | 
			
		||||
                //Do not open dialog on startup if no manga
 | 
			
		||||
                preferenceHelper.migrateLibraryAsked2().set(true)
 | 
			
		||||
            } else {
 | 
			
		||||
                //Not logged in but have ExHentai galleries
 | 
			
		||||
                if (!preferenceHelper.enableExhentai().getOrDefault()) {
 | 
			
		||||
@@ -109,9 +108,7 @@ class MetadataFetchDialog {
 | 
			
		||||
                            .onNegative({ _, _ -> adviseMigrationLater(activity) })
 | 
			
		||||
                            .cancelable(false)
 | 
			
		||||
                            .canceledOnTouchOutside(false)
 | 
			
		||||
                            .dismissListener {
 | 
			
		||||
                                preferenceHelper.migrateLibraryAsked2().set(true)
 | 
			
		||||
                            }.show()
 | 
			
		||||
                            .show()
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user