Skip to content

Commit

Permalink
Merge pull request #5 from Paulanerus/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
Paulanerus authored Jan 9, 2025
2 parents 279c990 + ba77ac7 commit 9f139b3
Show file tree
Hide file tree
Showing 18 changed files with 580 additions and 98 deletions.
3 changes: 3 additions & 0 deletions api/src/main/kotlin/dev/paulee/api/data/Data.kt
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,6 @@ annotation class NullValue(val values: Array<String>)

@Target(AnnotationTarget.VALUE_PARAMETER)
annotation class Link(val clazz: KClass<*>)

@Target(AnnotationTarget.FUNCTION)
annotation class ViewFilter(val name: String, val fields: Array<String>, val global: Boolean = true)
14 changes: 14 additions & 0 deletions api/src/main/kotlin/dev/paulee/api/data/DiffService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package dev.paulee.api.data

data class Change(val str: String, val tokens: List<Pair<String, IntRange>>)

interface DiffService {

fun getDiff(strings: List<String>): Set<Change>

fun getDiff(original: String, str: String): Change?

fun oldValue(change: Change): String

fun newValue(change: Change): String
}
4 changes: 3 additions & 1 deletion api/src/main/kotlin/dev/paulee/api/data/IDataService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ interface IDataService : Closeable {

fun loadDataPools(path: Path, dataInfo: Set<RequiresData>): Int

fun selectDataPool(pool: String)
fun selectDataPool(selection: String)

fun getSelectedPool(): String

fun getAvailablePools(): Set<String>

fun getPage(query: String, pageCount: Int): Pair<List<Map<String, String>>, Map<String, List<Map<String, String>>>>

fun getPageCount(query: String): Pair<Long, Set<String>>
Expand Down
5 changes: 5 additions & 0 deletions api/src/main/kotlin/dev/paulee/api/plugin/IPluginService.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.paulee.api.plugin

import dev.paulee.api.data.RequiresData
import dev.paulee.api.data.ViewFilter
import java.nio.file.Path

interface IPluginService {
Expand All @@ -20,4 +21,8 @@ interface IPluginService {
fun getAllDataInfos(): Set<RequiresData>

fun getDataSources(dataInfo: String): Set<String>

fun tagFields(plugin: IPlugin, field: String, value: String): Map<String, Tag>

fun getViewFilter(plugin: IPlugin): ViewFilter?
}
10 changes: 9 additions & 1 deletion api/src/main/kotlin/dev/paulee/api/plugin/Plugin.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package dev.paulee.api.plugin

import java.awt.Color

@Target(AnnotationTarget.CLASS)
annotation class PluginOrder(val order: Int)

Expand All @@ -8,9 +10,15 @@ annotation class PluginMetadata(
val name: String,
val version: String = "",
val author: String = "",
val description: String = ""
val description: String = "",
)

interface IPlugin {
fun init()
}

data class Tag(val name: String, val color: Color)

interface Taggable {
fun tag(field: String, value: String): Map<String, Tag>
}
2 changes: 2 additions & 0 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ dependencies {

implementation("org.xerial:sqlite-jdbc:3.47.0.0")

implementation("io.github.java-diff-utils:java-diff-utils:4.15")

implementation("org.apache.lucene:lucene-core:${rootProject.extra["lucene.version"]}")
implementation("org.apache.lucene:lucene-analysis-common:${rootProject.extra["lucene.version"]}")
implementation("org.apache.lucene:lucene-analysis-kuromoji:${rootProject.extra["lucene.version"]}")
Expand Down
30 changes: 27 additions & 3 deletions core/src/main/kotlin/dev/paulee/core/data/DataServiceImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,21 @@ private class DataPool(val indexer: Indexer, dataInfo: RequiresData) {
}
}

if (defaultIndexField.isNullOrEmpty()) println("${dataInfo.name} has no default index field")
if (this.defaultIndexField.isNullOrEmpty()) {
println("${dataInfo.name} has no default index field.")

this.fields.filter { it.value }
.entries
.firstOrNull()?.key
.let {
if (it == null) {
println("${dataInfo.name} has no indexable fields.")
} else {
println("'$it' was chosen instead.")
this.defaultIndexField = it
}
}
}
}

fun search(query: String): IndexSearchResult {
Expand Down Expand Up @@ -235,12 +249,22 @@ class DataServiceImpl(private val storageProvider: IStorageProvider) : IDataServ
return dataPools.size
}

override fun selectDataPool(pool: String) {
TODO("Not yet implemented")
override fun selectDataPool(selection: String) {
if (!selection.contains(".")) return

val (pool, field) = selection.split(".", limit = 2)

this.currentPool = pool
this.currentField = field
}

override fun getSelectedPool(): String = "${this.currentPool}.${this.currentField}"

override fun getAvailablePools(): Set<String> = dataPools.filter { it.value.fields.any { it.value } }
.flatMap { entry ->
entry.value.fields.filter { it.value }.map { "${entry.key}.${it.key.substringBefore(".")}" }
}.toSet()

override fun getPage(query: String, pageCount: Int): PageResult {

if (this.currentPool == null || this.currentField == null) return Pair(emptyList(), emptyMap())
Expand Down
53 changes: 53 additions & 0 deletions core/src/main/kotlin/dev/paulee/core/data/DiffServiceImpl.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package dev.paulee.core.data

import com.github.difflib.text.DiffRowGenerator
import dev.paulee.api.data.Change
import dev.paulee.api.data.DiffService

class DiffServiceImpl : DiffService {

private val generator =
DiffRowGenerator.create().mergeOriginalRevised(true).showInlineDiffs(true).oldTag { f -> "~~" }
.newTag { f -> "**" }.build()

override fun getDiff(strings: List<String>): Set<Change> {

if (strings.size <= 1) return emptySet()

val first = listOf(strings[0])

return (1 until strings.size).map {
val output = generator.generateDiffRows(first, listOf(strings[it]))

val oldLine = output.first().oldLine

Change(oldLine, extractToken(oldLine))
}.toSet()
}

override fun getDiff(original: String, str: String): Change? = this.getDiff(listOf(original, str)).firstOrNull()

override fun oldValue(change: Change): String = with(change) {
tokens.fold(str) { acc, token ->
if (token.first.startsWith("**")) acc.replace(token.first, "")
else acc.replace(token.first, token.first.trim('~'))
}
}

override fun newValue(change: Change): String = with(change) {
tokens.fold(str) { acc, token ->
if (token.first.startsWith("~~")) acc.replace(token.first, "")
else acc.replace(token.first, token.first.trim('*'))
}
}

private fun extractToken(str: String): List<Pair<String, IntRange>> {
val patternOld = Regex("~~([^~]*)~~")
val patternNew = Regex("\\*\\*([^*]*)\\*\\*")

val entriesOld = patternOld.findAll(str).map { it.groupValues[0] to it.range }.toList()
val entriesNew = patternNew.findAll(str).map { it.groupValues[0] to it.range }.toList()

return entriesOld + entriesNew
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import kotlin.io.path.bufferedReader

internal class BufferedCSVReader(path: Path, private val delimiter: Char = ',') {

var lineCount: Long = 0
var errorCount: Long = 0

private var reader = path.bufferedReader()
Expand All @@ -30,9 +29,9 @@ internal class BufferedCSVReader(path: Path, private val delimiter: Char = ',')
if (split.size == this.headSize) {
val headToValue = mutableMapOf<String, String>()

split.forEachIndexed { index, entry -> headToValue[header[index]] = entry }
split.forEachIndexed { index, entry -> headToValue[header[index]] = entry.trim('"') }

batch.add(headToValue).also { lineCount++ }
batch.add(headToValue)
} else errorCount++

if (batch.size == 100) callback(batch).also { batch.clear() }
Expand Down
18 changes: 14 additions & 4 deletions core/src/main/kotlin/dev/paulee/core/plugin/PluginServiceImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ package dev.paulee.core.plugin

import dev.paulee.api.data.DataSource
import dev.paulee.api.data.RequiresData
import dev.paulee.api.plugin.IPlugin
import dev.paulee.api.plugin.IPluginService
import dev.paulee.api.plugin.PluginMetadata
import dev.paulee.api.plugin.PluginOrder
import dev.paulee.api.data.ViewFilter
import dev.paulee.api.plugin.*
import dev.paulee.core.normalizeDataSource
import java.net.URLClassLoader
import java.nio.file.Path
Expand All @@ -15,6 +13,7 @@ import kotlin.io.path.extension
import kotlin.io.path.isDirectory
import kotlin.io.path.walk
import kotlin.reflect.full.findAnnotation
import kotlin.reflect.full.functions

class PluginServiceImpl : IPluginService {

Expand Down Expand Up @@ -79,6 +78,17 @@ class PluginServiceImpl : IPluginService {
return dataSources
}

override fun tagFields(plugin: IPlugin, field: String, value: String): Map<String, Tag> =
(plugin as? Taggable)?.tag(field, value) ?: emptyMap()

override fun getViewFilter(plugin: IPlugin): ViewFilter? {
val taggable = plugin as? Taggable ?: return null

val func = taggable::class.functions.find { it.name == "tag" } ?: return null

return func.findAnnotation<ViewFilter>()
}

private fun getPluginEntryPoint(path: Path): String? =
JarFile(path.toFile()).use { return it.manifest.mainAttributes.getValue("Main-Class") }

Expand Down
8 changes: 4 additions & 4 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ kotlin.version=2.1.0
compose.version=1.7.1
lucene.version=10.0.0

api.version=0.24.0
core.version=0.24.0
ui.version=0.14.1
app.version=1.5.0
api.version=0.32.1
core.version=0.30.1
ui.version=0.20.4
app.version=1.6.0
6 changes: 5 additions & 1 deletion src/main/kotlin/dev/paulee/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ package dev.paulee

import dev.paulee.api.data.provider.StorageType
import dev.paulee.core.data.DataServiceImpl
import dev.paulee.core.data.DiffServiceImpl
import dev.paulee.core.data.provider.StorageProvider
import dev.paulee.core.plugin.PluginServiceImpl
import dev.paulee.ui.TextExplorerUI

fun main() {
val explorerUI = TextExplorerUI(PluginServiceImpl(), DataServiceImpl(StorageProvider.of(StorageType.SQLITE)))
val explorerUI = TextExplorerUI(
PluginServiceImpl(),
DataServiceImpl(StorageProvider.of(StorageType.SQLITE)),
DiffServiceImpl())
explorerUI.start()
}
2 changes: 2 additions & 0 deletions ui/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ repositories {
}

dependencies {
implementation(kotlin("reflect"))

implementation(project(":api"))

testImplementation(kotlin("test"))
Expand Down
68 changes: 68 additions & 0 deletions ui/src/main/kotlin/dev/paulee/ui/Config.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package dev.paulee.ui

import java.nio.file.Path
import kotlin.io.path.Path
import kotlin.io.path.bufferedReader
import kotlin.io.path.bufferedWriter
import kotlin.io.path.notExists
import kotlin.reflect.KMutableProperty
import kotlin.reflect.KVisibility
import kotlin.reflect.full.memberProperties

object Config {

var noWidthRestriction = false

private var configFile = "config"

private var configPath = Path(configFile)

fun save() {
this.configPath.bufferedWriter().use { writer ->

this::class.memberProperties
.filter { it.visibility == KVisibility.PUBLIC && it is KMutableProperty<*> }
.forEach {
val value = it.getter.call(this)

writer.write("${it.name} = $value\n")
writer.newLine()
}
}
}

fun load(path: Path) {
this.configPath = path.resolve(configFile)

if(this.configPath.notExists()) return

this.configPath.bufferedReader().useLines { lines ->
lines.filter { it.contains("=") }.forEach {
val (field, value) = it.split("=", limit = 2).map { it.trim() }

val member = this::class.memberProperties.find { it.name == field }

if (member != null && member is KMutableProperty<*>) {
val converted: Any = when (member.returnType.classifier) {
Boolean::class -> value.toBooleanStrictOrNull() ?: false
Short::class -> value.toShortOrNull() ?: 0
Int::class -> value.toIntOrNull() ?: 0
Long::class -> value.toLongOrNull() ?: 0L
Float::class -> value.toFloatOrNull() ?: 0f
Double::class -> value.toDoubleOrNull() ?: 0
else -> value
}

runCatching {
member.setter.call(
this,
converted
)
}.onFailure { e -> println("Failed to set value for $field (${e.message}).") }
} else {
//TODO
}
}
}
}
}
Loading

0 comments on commit 9f139b3

Please sign in to comment.