* [#1496] First conversion attempt * [#1496] Configurable conversion * Fix: allow nested configs (map) * [#1496] Support explicit `none` conversion * Use MimeUtils for provided download * [1496] Support image conversion on load for downloaded images * Lint * [#1496] Support conversion on fresh download as well Previous commit was only for already downloaded images, now also for fresh and cached * [#1496] Refactor: Move where conversion for download happens * Rewrite config handling, improve custom types * Lint * Add format to pages mutation * Lint * Standardize url encode * Lint * Config: Allow additional conversion parameters * Implement conversion quality parameter * Lint * Implement a conversion util to allow fallback readers * Add downloadConversions to api and backup, fix updateValue issues * Lint * Minor cleanup * Update libs.versions.toml --------- Co-authored-by: Syer10 <syer10@users.noreply.github.com>
This commit is contained in:
@@ -10,10 +10,11 @@ package xyz.nulldev.ts.config
|
||||
import ch.qos.logback.classic.Level
|
||||
import com.typesafe.config.Config
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import com.typesafe.config.ConfigObject
|
||||
import com.typesafe.config.ConfigValue
|
||||
import com.typesafe.config.ConfigValueFactory
|
||||
import com.typesafe.config.parser.ConfigDocument
|
||||
import com.typesafe.config.parser.ConfigDocumentFactory
|
||||
import io.github.config4k.toConfig
|
||||
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
@@ -113,7 +114,7 @@ open class ConfigManager {
|
||||
) {
|
||||
mutex.withLock {
|
||||
val actualValue = if (value is Enum<*>) value.name else value
|
||||
val configValue = ConfigValueFactory.fromAnyRef(actualValue)
|
||||
val configValue = actualValue.toConfig("internal").getValue("internal")
|
||||
|
||||
updateUserConfigFile(path, configValue)
|
||||
internalConfig = internalConfig.withValue(path, configValue)
|
||||
@@ -142,8 +143,13 @@ open class ConfigManager {
|
||||
val serverConfig = ConfigFactory.parseResources("server-reference.conf")
|
||||
val userConfig = getUserConfig()
|
||||
|
||||
val hasMissingSettings = serverConfig.entrySet().any { !userConfig.hasPath(it.key) }
|
||||
val hasOutdatedSettings = userConfig.entrySet().any { !serverConfig.hasPath(it.key) }
|
||||
// NOTE: if more than 1 dot is included, that's a nested setting, which we need to filter out here
|
||||
val refKeys =
|
||||
serverConfig.root().entries.flatMap {
|
||||
(it.value as? ConfigObject)?.entries?.map { e -> "${it.key}.${e.key}" }.orEmpty()
|
||||
}
|
||||
val hasMissingSettings = refKeys.any { !userConfig.hasPath(it) }
|
||||
val hasOutdatedSettings = userConfig.entrySet().any { !refKeys.contains(it.key) && it.key.count { c -> c == '.' } <= 1 }
|
||||
val isUserConfigOutdated = hasMissingSettings || hasOutdatedSettings
|
||||
if (!isUserConfigOutdated) {
|
||||
return
|
||||
@@ -159,7 +165,8 @@ open class ConfigManager {
|
||||
.filter {
|
||||
serverConfig.hasPath(
|
||||
it.key,
|
||||
)
|
||||
) ||
|
||||
it.key.count { c -> c == '.' } > 1
|
||||
}.forEach { newUserConfigDoc = newUserConfigDoc.withValue(it.key, it.value) }
|
||||
|
||||
newUserConfigDoc =
|
||||
|
||||
@@ -8,9 +8,13 @@ package xyz.nulldev.ts.config
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import com.typesafe.config.Config
|
||||
import com.typesafe.config.ConfigException
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import com.typesafe.config.ConfigValueFactory
|
||||
import io.github.config4k.ClassContainer
|
||||
import io.github.config4k.TypeReference
|
||||
import io.github.config4k.getValue
|
||||
import io.github.config4k.readers.SelectReader
|
||||
import io.github.config4k.toConfig
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
/**
|
||||
@@ -26,7 +30,7 @@ abstract class ConfigModule(
|
||||
*/
|
||||
abstract class SystemPropertyOverridableConfigModule(
|
||||
getConfig: () -> Config,
|
||||
moduleName: String,
|
||||
val moduleName: String,
|
||||
) : ConfigModule(getConfig) {
|
||||
val overridableConfig = SystemPropertyOverrideDelegate(getConfig, moduleName)
|
||||
}
|
||||
@@ -46,20 +50,31 @@ class SystemPropertyOverrideDelegate(
|
||||
val combined =
|
||||
System.getProperty(
|
||||
"$CONFIG_PREFIX.$moduleName.${property.name}",
|
||||
if (T::class.simpleName == "List") {
|
||||
ConfigValueFactory.fromAnyRef(configValue).render()
|
||||
} else {
|
||||
configValue.toString()
|
||||
},
|
||||
configValue!!
|
||||
.toConfig("internal")
|
||||
.root()
|
||||
.render()
|
||||
.removePrefix("internal="),
|
||||
)
|
||||
val combinedConfig =
|
||||
try {
|
||||
ConfigFactory.parseString(combined)
|
||||
} catch (_: ConfigException) {
|
||||
ConfigFactory.parseString("internal=$combined")
|
||||
}
|
||||
|
||||
return when (T::class.simpleName) {
|
||||
"Int" -> combined.toInt()
|
||||
"Boolean" -> combined.toBoolean()
|
||||
"Double" -> combined.toDouble()
|
||||
"List" -> ConfigFactory.parseString("internal=" + combined).getStringList("internal").orEmpty()
|
||||
// add more types as needed
|
||||
else -> combined // covers String
|
||||
} as T
|
||||
val genericType = object : TypeReference<T>() {}.genericType()
|
||||
val clazz = ClassContainer(T::class, genericType)
|
||||
val reader = SelectReader.getReader(clazz)
|
||||
val path = property.name
|
||||
|
||||
val result = reader(combinedConfig, "internal")
|
||||
return try {
|
||||
result as T
|
||||
} catch (e: Exception) {
|
||||
throw result
|
||||
?.let { e }
|
||||
?: ConfigException.BadPath(path, "take a look at your config")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,5 +47,5 @@ dependencies {
|
||||
|
||||
// OpenJDK lacks native JPEG encoder and native WEBP decoder
|
||||
implementation(libs.bundles.twelvemonkeys)
|
||||
implementation(libs.sejda.webp)
|
||||
implementation(libs.imageio.webp)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user