add information about content client provider to readme

This commit is contained in:
2022-03-18 00:04:04 +06:00
parent 1dafe0a679
commit 709e7a8583
11 changed files with 122 additions and 56 deletions
features
common
README.md
server
src
jvmMain
kotlin
dev
inmo
postssystem
features
content
README.md
binary
server
src
jvmMain
kotlin
dev
inmo
postssystem
features
text
server
src
jvmMain
kotlin
dev
inmo
postssystem
features
publicators/simple/server/src/jvmMain/kotlin/dev/inmo/postssystem/publicators/simple/server
server
src
main
java
dev
inmo
postssystem
test.config.json
targets/telegram/loader/server/src/jvmMain/kotlin/dev/inmo/postssystem/targets/telegram/loader/server

26
features/common/README.md Normal file

@ -0,0 +1,26 @@
# Common
In that readme will be stored several notes about working with common parts in all your modules
## ModuleLoader
This module has been created to allow your plugins to load dynamically after build of the server and client
### Server
To declare your module loader you should create **_class_** realization of `ServerModuleLoader` and put the classname of that
realization into the `modules` section as a string.
### Client
On the client side you also should create your own realization of `ModuleLoader`, but instead of some config you will
need to create some `private val` property on the top level in your `ModuleLoader` realization file. Example:
```kotlin
object SomeModuleLoader : ModuleLoader {
// body
}
private val someModuleLoaderProperty = AdditionalModules.addModule(SomeModuleLoader) // that is important part
```

@ -0,0 +1,15 @@
package dev.inmo.postssystem.features.common.server.sessions
import org.koin.core.qualifier.StringQualifier
object Qualifiers {
val binaryFilesFolderQualifier = StringQualifier("binaryFilesFolder")
val originalFilesMetasKeyValueRepoQualifier = StringQualifier("OriginalFilesMetaKV")
val binaryOriginalFilesMetasKeyValueRepoQualifier = StringQualifier("BinaryOriginalFilesMetaKV")
val commonFilesMetasKeyValueRepoQualifier = StringQualifier("CommonFilesMetaKV")
val binaryFilesMetasKeyValueRepoQualifier = StringQualifier("BinaryFilesMetaKV")
val filesFolderQualifier = StringQualifier("rootFilesFolder")
val commonFilesFolderQualifier = StringQualifier("commonFilesFolder")
val usersRolesKeyValueFactoryQualifier = StringQualifier("usersRolesKeyValueFactory")
val binaryStorageFilesQualifier = StringQualifier("binaryContentFiles")
}

@ -3,6 +3,6 @@ package dev.inmo.postssystem.features.common.server.sessions
import kotlinx.serialization.json.JsonObject
import org.koin.core.module.Module
interface ModuleLoader {
interface ServerModuleLoader {
fun Module.load(config: JsonObject)
}

@ -35,3 +35,14 @@ For example, you want to create content named `MyFormat`. To do this, you must p
```kotlin
singleWithRandomQualifier<ContentSerializersModuleConfigurator.Element> { MyFormatContentSerializerModuleConfigurator }
```
## Client
**Currently, this information is actual only for JS (browser) clients. Other client platforms will be added later**
Besides, you may (and it is strongly recommended to) create your own client `ContentClientProvider` realization.
This realization will contain all main functions for drawing of content on the client side.
## Server
On the server side it is required to

@ -0,0 +1,20 @@
package dev.inmo.postssystem.features.content.binary.server
import dev.inmo.postssystem.features.common.common.singleWithRandomQualifier
import dev.inmo.postssystem.features.common.server.sessions.Qualifiers
import dev.inmo.postssystem.features.common.server.sessions.ServerModuleLoader
import dev.inmo.postssystem.features.content.common.BinaryContent
import dev.inmo.postssystem.features.content.server.ServerContentStorageWrapper
import kotlinx.serialization.json.JsonObject
import org.koin.core.module.Module
class BinaryContentServerModuleLoader : ServerModuleLoader {
override fun Module.load(config: JsonObject) {
singleWithRandomQualifier {
ServerContentStorageWrapper(
BinaryServerContentStorage(get(Qualifiers.binaryStorageFilesQualifier)),
BinaryContent::class
)
}
}
}

@ -0,0 +1,22 @@
package dev.inmo.postssystem.features.content.text.server
import dev.inmo.postssystem.features.common.common.singleWithRandomQualifier
import dev.inmo.postssystem.features.common.server.sessions.ServerModuleLoader
import dev.inmo.postssystem.features.content.common.ContentSerializersModuleConfigurator
import dev.inmo.postssystem.features.content.server.ServerContentStorageWrapper
import dev.inmo.postssystem.features.content.text.common.TextContent
import dev.inmo.postssystem.features.content.text.common.TextContentSerializerModuleConfigurator
import kotlinx.serialization.json.JsonObject
import org.koin.core.module.Module
class TextContentServerModuleLoader : ServerModuleLoader {
override fun Module.load(config: JsonObject) {
singleWithRandomQualifier<ContentSerializersModuleConfigurator.Element> { TextContentSerializerModuleConfigurator }
singleWithRandomQualifier {
ServerContentStorageWrapper(
TextServerContentStorage(get()),
TextContent::class
)
}
}
}

@ -2,11 +2,11 @@ package dev.inmo.postssystem.publicators.simple.server
import dev.inmo.micro_utils.ktor.server.configurators.ApplicationRoutingConfigurator
import dev.inmo.postssystem.features.common.common.singleWithRandomQualifier
import dev.inmo.postssystem.features.common.server.sessions.ModuleLoader
import dev.inmo.postssystem.features.common.server.sessions.ServerModuleLoader
import kotlinx.serialization.json.JsonObject
import org.koin.core.module.Module
class SimplePublicationTriggerLoader : ModuleLoader {
class SimplePublicationTriggerLoaderServer : ServerModuleLoader {
override fun Module.load(config: JsonObject) {
singleWithRandomQualifier<ApplicationRoutingConfigurator.Element> {
SimplePublicatorRoutingConfigurator(

@ -1,6 +1,6 @@
package dev.inmo.postssystem.server
import dev.inmo.postssystem.features.common.server.sessions.ModuleLoader
import dev.inmo.postssystem.features.common.server.sessions.ServerModuleLoader
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import java.io.File
@ -25,7 +25,7 @@ data class Config(
val modules by lazy {
modulesClassPaths.mapNotNull { moduleClassPath ->
runCatching {
Class.forName(moduleClassPath).constructors.firstOrNull { it.parameterCount == 0 } ?.newInstance() as ModuleLoader
Class.forName(moduleClassPath).constructors.firstOrNull { it.parameterCount == 0 } ?.newInstance() as ServerModuleLoader
}.onFailure {
println("Unable to load $moduleClassPath")
it.printStackTrace()

@ -25,19 +25,13 @@ import dev.inmo.micro_utils.ktor.server.createKtorServer
import dev.inmo.micro_utils.repos.exposed.keyvalue.ExposedKeyValueRepo
import dev.inmo.micro_utils.repos.exposed.onetomany.ExposedOneToManyKeyValueRepo
import dev.inmo.postssystem.features.common.common.*
import dev.inmo.postssystem.features.content.binary.server.BinaryServerContentStorage
import dev.inmo.postssystem.features.common.server.sessions.Qualifiers
import dev.inmo.postssystem.features.content.common.*
import dev.inmo.postssystem.features.content.server.ServerContentStorageAggregator
import dev.inmo.postssystem.features.content.server.ServerContentStorageWrapper
import dev.inmo.postssystem.features.content.server.storage.*
import dev.inmo.postssystem.features.content.text.common.TextContent
import dev.inmo.postssystem.features.content.text.common.TextContentSerializerModuleConfigurator
import dev.inmo.postssystem.features.content.text.server.TextServerContentStorage
import dev.inmo.postssystem.features.posts.server.*
import dev.inmo.postssystem.features.publication.server.PublicationManager
import dev.inmo.postssystem.features.publication.server.PublicationTarget
import dev.inmo.postssystem.services.posts.server.*
import dev.inmo.postssystem.targets.telegram.publication.server.PublicationTargetTelegram
import io.ktor.application.featureOrNull
import io.ktor.application.log
import io.ktor.routing.Route
@ -56,7 +50,6 @@ import org.koin.core.module.Module
import org.koin.core.parameter.ParametersHolder
import org.koin.core.qualifier.StringQualifier
import org.koin.dsl.*
import org.w3c.dom.Text
import java.io.File
private fun Route.print() {
@ -77,18 +70,8 @@ fun getDIModule(
val configJsonElement = configJson.decodeFromString(JsonObject.serializer(), File(args.first()).readText())
val config = configJson.decodeFromJsonElement(Config.serializer(), configJsonElement)
val originalFilesMetasKeyValueRepoQualifier = StringQualifier("OriginalFilesMetaKV")
val binaryOriginalFilesMetasKeyValueRepoQualifier = StringQualifier("BinaryOriginalFilesMetaKV")
val commonFilesMetasKeyValueRepoQualifier = StringQualifier("CommonFilesMetaKV")
val binaryFilesMetasKeyValueRepoQualifier = StringQualifier("BinaryFilesMetaKV")
val filesFolderQualifier = StringQualifier("rootFilesFolder")
val commonFilesFolderQualifier = StringQualifier("commonFilesFolder")
val binaryFilesFolderQualifier = StringQualifier("binaryFilesFolder")
val usersRolesKeyValueFactoryQualifier = StringQualifier("usersRolesKeyValueFactory")
return module {
singleWithRandomQualifier<ContentSerializersModuleConfigurator.Element> { OtherContentSerializerModuleConfigurator }
singleWithRandomQualifier<ContentSerializersModuleConfigurator.Element> { TextContentSerializerModuleConfigurator }
singleWithRandomQualifier<SerializersModuleConfigurator.Element> { ContentSerializersModuleConfigurator(getAll()) }
single { SerializersModuleConfigurator(getAll()) }
@ -110,34 +93,34 @@ fun getDIModule(
singleWithBinds { config }
singleWithBinds { get<Config>().databaseConfig }
singleWithBinds { get<Config>().authConfig }
singleWithBinds(filesFolderQualifier) { get<Config>().filesFolderFile }
singleWithBinds(commonFilesFolderQualifier) { get<Config>().commonFilesFolder }
singleWithBinds(binaryFilesFolderQualifier) { get<Config>().binaryFilesFolder }
singleWithBinds(Qualifiers.filesFolderQualifier) { get<Config>().filesFolderFile }
singleWithBinds(Qualifiers.commonFilesFolderQualifier) { get<Config>().commonFilesFolder }
singleWithBinds(Qualifiers.binaryFilesFolderQualifier) { get<Config>().binaryFilesFolder }
singleWithBinds { get<DatabaseConfig>().database }
singleWithBinds(originalFilesMetasKeyValueRepoQualifier) {
singleWithBinds(Qualifiers.originalFilesMetasKeyValueRepoQualifier) {
ExposedKeyValueRepo(get(), { text("fileid") }, { text("metaInfo") }, "FileIdsToMetas")
}
singleWithBinds(binaryOriginalFilesMetasKeyValueRepoQualifier) {
singleWithBinds(Qualifiers.binaryOriginalFilesMetasKeyValueRepoQualifier) {
ExposedKeyValueRepo(get(), { text("fileid") }, { text("metaInfo") }, "BinaryContentFileIdsToMetas")
}
singleWithBinds(commonFilesMetasKeyValueRepoQualifier) {
singleWithBinds(Qualifiers.commonFilesMetasKeyValueRepoQualifier) {
MetasKeyValueRepo(
get(),
get(originalFilesMetasKeyValueRepoQualifier)
get(Qualifiers.originalFilesMetasKeyValueRepoQualifier)
)
}
single<ReadFilesStorage> { DiskReadFilesStorage(get(commonFilesFolderQualifier), get(commonFilesMetasKeyValueRepoQualifier)) }
single<WriteFilesStorage> { WriteDistFilesStorage(get(commonFilesFolderQualifier), get(commonFilesMetasKeyValueRepoQualifier)) }
single<ReadFilesStorage> { DiskReadFilesStorage(get(Qualifiers.commonFilesFolderQualifier), get(Qualifiers.commonFilesMetasKeyValueRepoQualifier)) }
single<WriteFilesStorage> { WriteDistFilesStorage(get(Qualifiers.commonFilesFolderQualifier), get(Qualifiers.commonFilesMetasKeyValueRepoQualifier)) }
single<FilesStorage> { DefaultFilesStorage(get(), get()) }
singleWithBinds { ExposedUsersStorage(get()) }
singleWithBinds { exposedUsersAuthenticator(get(), get()) }
factory<KeyValuesRolesOriginalRepo>(usersRolesKeyValueFactoryQualifier) { (tableName: String) ->
factory<KeyValuesRolesOriginalRepo>(Qualifiers.usersRolesKeyValueFactoryQualifier) { (tableName: String) ->
ExposedOneToManyKeyValueRepo(get(), { text("subject") }, { text("role") }, tableName)
}
single {
RolesManagerRoleStorage(get(usersRolesKeyValueFactoryQualifier) { ParametersHolder(mutableListOf("rolesManager")) })
RolesManagerRoleStorage(get(Qualifiers.usersRolesKeyValueFactoryQualifier) { ParametersHolder(mutableListOf("rolesManager")) })
}
single<RolesStorage<RolesManagerRole>>(StringQualifier("RolesManagerRoleStorage")) { get<RolesManagerRoleStorage>() }
singleWithBinds {
@ -156,29 +139,16 @@ fun getDIModule(
factory<CoroutineScope> { baseScope.LinkedSupervisorScope() }
// Content storages
val binaryStorageFilesQualifier = StringQualifier("binaryContentFiles")
singleWithBinds(binaryFilesMetasKeyValueRepoQualifier) {
singleWithBinds(Qualifiers.binaryFilesMetasKeyValueRepoQualifier) {
MetasKeyValueRepo(
get(),
get(binaryOriginalFilesMetasKeyValueRepoQualifier)
get(Qualifiers.binaryOriginalFilesMetasKeyValueRepoQualifier)
)
}
single<FilesStorage>(binaryStorageFilesQualifier) {
single<FilesStorage>(Qualifiers.binaryStorageFilesQualifier) {
DefaultFilesStorage(
DiskReadFilesStorage(get(binaryFilesFolderQualifier), get(binaryFilesMetasKeyValueRepoQualifier)),
WriteDistFilesStorage(get(binaryFilesFolderQualifier), get(binaryFilesMetasKeyValueRepoQualifier))
)
}
singleWithRandomQualifier {
ServerContentStorageWrapper(
BinaryServerContentStorage(get(binaryStorageFilesQualifier)),
BinaryContent::class
)
}
singleWithRandomQualifier {
ServerContentStorageWrapper(
TextServerContentStorage(get()),
TextContent::class
DiskReadFilesStorage(get(Qualifiers.binaryFilesFolderQualifier), get(Qualifiers.binaryFilesMetasKeyValueRepoQualifier)),
WriteDistFilesStorage(get(Qualifiers.binaryFilesFolderQualifier), get(Qualifiers.binaryFilesMetasKeyValueRepoQualifier))
)
}

@ -7,8 +7,10 @@
"filesFolder": "/tmp/files",
"debugMode": true,
"modules": [
"dev.inmo.postssystem.targets.telegram.loader.server.TelegramTargetModuleLoader",
"dev.inmo.postssystem.publicators.simple.server.SimplePublicationTriggerLoader"
"dev.inmo.postssystem.features.content.text.server.TextContentServerModuleLoader",
"dev.inmo.postssystem.features.content.binary.server.BinaryContentServerModuleLoader",
"dev.inmo.postssystem.targets.telegram.loader.server.TelegramTargetServerModuleLoader",
"dev.inmo.postssystem.publicators.simple.server.SimplePublicationTriggerLoaderServer"
],
"telegram": {
"botToken": "YOUR BOT TOKEN",

@ -1,7 +1,7 @@
package dev.inmo.postssystem.targets.telegram.loader.server
import dev.inmo.postssystem.features.common.common.singleWithRandomQualifier
import dev.inmo.postssystem.features.common.server.sessions.ModuleLoader
import dev.inmo.postssystem.features.common.server.sessions.ServerModuleLoader
import dev.inmo.postssystem.features.content.common.ContentSerializersModuleConfigurator
import dev.inmo.postssystem.features.publication.server.PublicationTarget
import dev.inmo.postssystem.targets.telegram.content.polls.common.PollContent
@ -16,7 +16,7 @@ import org.koin.core.qualifier.StringQualifier
/**
* Expects to get a config from a field "telegram" of your config
*/
class TelegramTargetModuleLoader : ModuleLoader {
class TelegramTargetServerModuleLoader : ServerModuleLoader {
override fun Module.load(config: JsonObject) {
val configJson = config["telegram"]