diff --git a/app/src/main/java/exh/search/Namespace.kt b/app/src/main/java/exh/search/Namespace.kt index 8c939ac96..e23a0e722 100644 --- a/app/src/main/java/exh/search/Namespace.kt +++ b/app/src/main/java/exh/search/Namespace.kt @@ -1,4 +1,4 @@ package exh.search -class Namespace(var namespace: Text, +class Namespace(var namespace: String, var tag: Text? = null) : QueryComponent() diff --git a/app/src/main/java/exh/search/SearchEngine.kt b/app/src/main/java/exh/search/SearchEngine.kt index cf7eaecf1..962fdbe4c 100644 --- a/app/src/main/java/exh/search/SearchEngine.kt +++ b/app/src/main/java/exh/search/SearchEngine.kt @@ -2,22 +2,18 @@ package exh.search import exh.metadata.models.ExGalleryMetadata import exh.metadata.models.Tag -import ru.lanwen.verbalregex.VerbalExpression -import java.util.* class SearchEngine { //TODO Namespace alias fun matches(metadata: ExGalleryMetadata, query: List): Boolean { fun matchTagList(tags: List, - component: Text, - builder: VerbalExpression.Builder, - built: VerbalExpression): Boolean { + component: Text): Boolean { //Match tags val tagMatcher = if(!component.exact) - builder.anything().build() + component.asLenientRegex() else - built + component.asRegex() //Match beginning of tag if (tags.find { tagMatcher.testExact(it.name) @@ -32,28 +28,21 @@ class SearchEngine { for(component in query) { if(component is Text) { - val builder = component.asRegex() - val built = builder.build() //Match title - if (built.test(metadata.title?.toLowerCase()) - || built.test(metadata.altTitle?.toLowerCase())) { + if (component.asRegex().test(metadata.title?.toLowerCase()) + || component.asRegex().test(metadata.altTitle?.toLowerCase())) { continue } //Match tags - if(!matchTagList(metadata.tags.entries.flatMap(MutableMap.MutableEntry>::value), - component, - builder, - built)) - return false + if(!matchTagList(metadata.tags.entries.flatMap { it.value }, + component)) return false } else if(component is Namespace) { //Match namespace val ns = metadata.tags.entries.filter { - it.key == component.namespace.rawTextOnly() + it.key == component.namespace }.flatMap { it.value } //Match tags - val builder = component.tag!!.asRegex() - val built = builder.build() - if(!matchTagList(ns, component.tag!!, builder, built)) + if(!matchTagList(ns, component.tag!!)) return false } } @@ -110,7 +99,20 @@ class SearchEngine { nextIsExact = true } else if(char == ':') { flushText() - namespace = Namespace(flushToText(), null) + var flushed = flushToText().rawTextOnly() + //Map tag aliases + flushed = when(flushed) { + "a" -> "artist" + "c", "char" -> "character" + "f" -> "female" + "g", "creator", "circle" -> "group" + "l", "lang" -> "language" + "m" -> "male" + "p", "series" -> "parody" + "r" -> "reclass" + else -> flushed + } + namespace = Namespace(flushed, null) } else if(char == ' ' && !inQuotes) { flushAll() } else { diff --git a/app/src/main/java/exh/search/Text.kt b/app/src/main/java/exh/search/Text.kt index 210bde398..5db17ae01 100644 --- a/app/src/main/java/exh/search/Text.kt +++ b/app/src/main/java/exh/search/Text.kt @@ -6,7 +6,24 @@ import ru.lanwen.verbalregex.VerbalExpression class Text: QueryComponent() { val components = mutableListOf() - fun asRegex(): VerbalExpression.Builder { + private var regex: VerbalExpression? = null + private var lenientRegex: VerbalExpression? = null + + fun asRegex(): VerbalExpression { + if(regex == null) { + regex = baseBuilder().build() + } + return regex!! + } + + fun asLenientRegex(): VerbalExpression { + if(lenientRegex == null) { + lenientRegex = baseBuilder().anything().build() + } + return lenientRegex!! + } + + fun baseBuilder(): VerbalExpression.Builder { val builder = VerbalExpression.regex() for(component in components) { when(component) {