add target and telegram target
This commit is contained in:
parent
6171eb3c40
commit
3661c1ca73
@ -12,6 +12,7 @@ kotlin {
|
|||||||
dependencies {
|
dependencies {
|
||||||
api project(":postssystem.features.common.common")
|
api project(":postssystem.features.common.common")
|
||||||
api project(":postssystem.features.content.common")
|
api project(":postssystem.features.content.common")
|
||||||
|
api "dev.inmo:micro_utils.mime_types:$microutils_version"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
package dev.inmo.postssystem.features.content.binary.common
|
package dev.inmo.postssystem.features.content.binary.common
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.common.ByteArrayAllocator
|
||||||
|
import dev.inmo.micro_utils.common.FileName
|
||||||
|
import dev.inmo.micro_utils.mime_types.MimeType
|
||||||
import dev.inmo.postssystem.features.content.common.Content
|
import dev.inmo.postssystem.features.content.common.Content
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class BinaryContent(
|
data class BinaryContent(
|
||||||
val bytes: ByteArray
|
val filename: FileName,
|
||||||
|
val mimeType: MimeType,
|
||||||
|
val bytesAllocator: ByteArrayAllocator
|
||||||
) : Content
|
) : Content
|
@ -2,7 +2,8 @@ package dev.inmo.postssystem.features.content.common
|
|||||||
|
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
typealias ContentId = String
|
@Serializable
|
||||||
|
value class ContentId(val string: String)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Content which is planned to be registered in database
|
* Content which is planned to be registered in database
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
package dev.inmo.postssystem.features.content.server
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.repos.CRUDRepo
|
||||||
|
import dev.inmo.postssystem.features.content.common.*
|
||||||
|
|
||||||
|
interface ServerContentStorage : ServerReadContentStorage, ServerWriteContentStorage, CRUDRepo<RegisteredContent, ContentId, Content>
|
@ -0,0 +1,7 @@
|
|||||||
|
package dev.inmo.postssystem.features.content.server
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.repos.ReadCRUDRepo
|
||||||
|
import dev.inmo.postssystem.features.content.common.ContentId
|
||||||
|
import dev.inmo.postssystem.features.content.common.RegisteredContent
|
||||||
|
|
||||||
|
interface ServerReadContentStorage : ReadCRUDRepo<RegisteredContent, ContentId>
|
@ -0,0 +1,6 @@
|
|||||||
|
package dev.inmo.postssystem.features.content.server
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.repos.WriteCRUDRepo
|
||||||
|
import dev.inmo.postssystem.features.content.common.*
|
||||||
|
|
||||||
|
interface ServerWriteContentStorage : WriteCRUDRepo<RegisteredContent, ContentId, Content>
|
18
features/publication/client/build.gradle
Normal file
18
features/publication/client/build.gradle
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
plugins {
|
||||||
|
id "org.jetbrains.kotlin.multiplatform"
|
||||||
|
id "org.jetbrains.kotlin.plugin.serialization"
|
||||||
|
id "com.android.library"
|
||||||
|
}
|
||||||
|
|
||||||
|
apply from: "$mppProjectWithSerializationPresetPath"
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
sourceSets {
|
||||||
|
commonMain {
|
||||||
|
dependencies {
|
||||||
|
api project(":postssystem.features.publication.common")
|
||||||
|
api project(":postssystem.features.common.client")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1
features/publication/client/src/main/AndroidManifest.xml
Normal file
1
features/publication/client/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1 @@
|
|||||||
|
<manifest package="dev.inmo.postssystem.features.publication.client"/>
|
19
features/publication/common/build.gradle
Normal file
19
features/publication/common/build.gradle
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
plugins {
|
||||||
|
id "org.jetbrains.kotlin.multiplatform"
|
||||||
|
id "org.jetbrains.kotlin.plugin.serialization"
|
||||||
|
id "com.android.library"
|
||||||
|
}
|
||||||
|
|
||||||
|
apply from: "$mppProjectWithSerializationPresetPath"
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
sourceSets {
|
||||||
|
commonMain {
|
||||||
|
dependencies {
|
||||||
|
api project(":postssystem.features.common.common")
|
||||||
|
api project(":postssystem.features.content.common")
|
||||||
|
api project(":postssystem.features.posts.common")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1
features/publication/common/src/main/AndroidManifest.xml
Normal file
1
features/publication/common/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1 @@
|
|||||||
|
<manifest package="dev.inmo.postssystem.features.publication.common"/>
|
19
features/publication/server/build.gradle
Normal file
19
features/publication/server/build.gradle
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
plugins {
|
||||||
|
id "org.jetbrains.kotlin.multiplatform"
|
||||||
|
id "org.jetbrains.kotlin.plugin.serialization"
|
||||||
|
}
|
||||||
|
|
||||||
|
apply from: "$mppJavaProjectPresetPath"
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
sourceSets {
|
||||||
|
commonMain {
|
||||||
|
dependencies {
|
||||||
|
api project(":postssystem.features.publication.common")
|
||||||
|
api project(":postssystem.features.common.server")
|
||||||
|
api project(":postssystem.features.content.server")
|
||||||
|
api project(":postssystem.features.posts.server")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package dev.inmo.postssystem.features.publication.server
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.coroutines.asyncSafelyWithoutExceptions
|
||||||
|
import dev.inmo.postssystem.features.content.server.ServerReadContentStorage
|
||||||
|
import dev.inmo.postssystem.features.posts.common.PostId
|
||||||
|
import dev.inmo.postssystem.features.posts.server.ServerReadPostsStorage
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
|
||||||
|
class PublicationManager (
|
||||||
|
private val targets: List<PublicationTarget>,
|
||||||
|
private val postsRepo: ServerReadPostsStorage,
|
||||||
|
private val contentRepo: ServerReadContentStorage,
|
||||||
|
private val scope: CoroutineScope
|
||||||
|
) {
|
||||||
|
suspend fun publish(
|
||||||
|
postId: PostId
|
||||||
|
) {
|
||||||
|
val post = postsRepo.getById(postId) ?: return
|
||||||
|
val content = post.content.map {
|
||||||
|
scope.async {
|
||||||
|
contentRepo.getById(it)
|
||||||
|
}
|
||||||
|
}.awaitAll().filterNotNull()
|
||||||
|
|
||||||
|
val publicationPost = PublicationPost(post, content)
|
||||||
|
|
||||||
|
targets.map {
|
||||||
|
scope.asyncSafelyWithoutExceptions {
|
||||||
|
it.publish(publicationPost)
|
||||||
|
}
|
||||||
|
}.awaitAll()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package dev.inmo.postssystem.features.publication.server
|
||||||
|
|
||||||
|
import dev.inmo.postssystem.features.content.common.RegisteredContent
|
||||||
|
import dev.inmo.postssystem.features.posts.common.RegisteredPost
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class PublicationPost(
|
||||||
|
val post: RegisteredPost,
|
||||||
|
val content: List<RegisteredContent>
|
||||||
|
)
|
@ -0,0 +1,5 @@
|
|||||||
|
package dev.inmo.postssystem.features.publication.server
|
||||||
|
|
||||||
|
fun interface PublicationTarget {
|
||||||
|
suspend fun publish(post: PublicationPost)
|
||||||
|
}
|
@ -19,6 +19,8 @@ logback_version=1.2.10
|
|||||||
uuid_version=0.3.1
|
uuid_version=0.3.1
|
||||||
klock_version=2.4.10
|
klock_version=2.4.10
|
||||||
|
|
||||||
|
tgbotapi_version=0.38.1
|
||||||
|
|
||||||
# Server
|
# Server
|
||||||
|
|
||||||
kotlin_exposed_version=0.37.2
|
kotlin_exposed_version=0.37.2
|
||||||
|
@ -21,6 +21,10 @@ dependencies {
|
|||||||
api project(":postssystem.features.content.server")
|
api project(":postssystem.features.content.server")
|
||||||
api project(":postssystem.features.content.text.server")
|
api project(":postssystem.features.content.text.server")
|
||||||
api project(":postssystem.features.content.binary.server")
|
api project(":postssystem.features.content.binary.server")
|
||||||
|
api project(":postssystem.features.publication.server")
|
||||||
|
|
||||||
|
api project(":postssystem.targets.telegram.publication.server")
|
||||||
|
|
||||||
api "io.ktor:ktor-server-netty:$ktor_version"
|
api "io.ktor:ktor-server-netty:$ktor_version"
|
||||||
api "io.ktor:ktor-websockets:$ktor_version"
|
api "io.ktor:ktor-websockets:$ktor_version"
|
||||||
api "org.jetbrains.exposed:exposed-jdbc:$kotlin_exposed_version"
|
api "org.jetbrains.exposed:exposed-jdbc:$kotlin_exposed_version"
|
||||||
|
@ -29,6 +29,9 @@ import dev.inmo.postssystem.features.content.binary.common.BinaryContentSerializ
|
|||||||
import dev.inmo.postssystem.features.content.common.ContentSerializersModuleConfigurator
|
import dev.inmo.postssystem.features.content.common.ContentSerializersModuleConfigurator
|
||||||
import dev.inmo.postssystem.features.content.common.OtherContentSerializerModuleConfigurator
|
import dev.inmo.postssystem.features.content.common.OtherContentSerializerModuleConfigurator
|
||||||
import dev.inmo.postssystem.features.content.text.common.TextContentSerializerModuleConfigurator
|
import dev.inmo.postssystem.features.content.text.common.TextContentSerializerModuleConfigurator
|
||||||
|
import dev.inmo.postssystem.features.publication.server.PublicationManager
|
||||||
|
import dev.inmo.postssystem.features.publication.server.PublicationTarget
|
||||||
|
import dev.inmo.postssystem.targets.telegram.publication.server.PublicationTargetTelegram
|
||||||
import io.ktor.application.featureOrNull
|
import io.ktor.application.featureOrNull
|
||||||
import io.ktor.application.log
|
import io.ktor.application.log
|
||||||
import io.ktor.routing.Route
|
import io.ktor.routing.Route
|
||||||
@ -129,6 +132,11 @@ fun getDIModule(
|
|||||||
}
|
}
|
||||||
singleWithBinds<RolesStorage<Role>> { RolesAggregator(getAll()) }
|
singleWithBinds<RolesStorage<Role>> { RolesAggregator(getAll()) }
|
||||||
|
|
||||||
|
// Publication targets
|
||||||
|
singleWithRandomQualifier<PublicationTarget> { PublicationTargetTelegram(get(), get()) }
|
||||||
|
|
||||||
|
single { PublicationManager(getAll(), get(), get(), get()) }
|
||||||
|
|
||||||
// Roles checkers
|
// Roles checkers
|
||||||
single<RolesChecker<Role>>(StringQualifier(RolesManagerRolesChecker.key)) { RolesManagerRolesChecker }
|
single<RolesChecker<Role>>(StringQualifier(RolesManagerRolesChecker.key)) { RolesManagerRolesChecker }
|
||||||
|
|
||||||
|
@ -45,6 +45,12 @@ String[] includes = [
|
|||||||
":features:posts:client",
|
":features:posts:client",
|
||||||
":features:posts:server",
|
":features:posts:server",
|
||||||
|
|
||||||
|
":features:publication:common",
|
||||||
|
":features:publication:client",
|
||||||
|
":features:publication:server",
|
||||||
|
|
||||||
|
":targets:telegram:publication:server",
|
||||||
|
|
||||||
":server",
|
":server",
|
||||||
":client",
|
":client",
|
||||||
]
|
]
|
||||||
|
22
targets/telegram/publication/server/build.gradle
Normal file
22
targets/telegram/publication/server/build.gradle
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
plugins {
|
||||||
|
id "org.jetbrains.kotlin.multiplatform"
|
||||||
|
id "org.jetbrains.kotlin.plugin.serialization"
|
||||||
|
}
|
||||||
|
|
||||||
|
apply from: "$mppJavaProjectPresetPath"
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
sourceSets {
|
||||||
|
commonMain {
|
||||||
|
dependencies {
|
||||||
|
api project(":postssystem.features.common.server")
|
||||||
|
api project(":postssystem.features.publication.server")
|
||||||
|
|
||||||
|
api project(":postssystem.features.content.binary.server")
|
||||||
|
api project(":postssystem.features.content.text.server")
|
||||||
|
|
||||||
|
api "dev.inmo:tgbotapi:$tgbotapi_version"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
package dev.inmo.postssystem.targets.telegram.publication.server
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.mime_types.KnownMimeTypes
|
||||||
|
import dev.inmo.postssystem.features.content.binary.common.BinaryContent
|
||||||
|
import dev.inmo.postssystem.features.content.text.common.TextContent
|
||||||
|
import dev.inmo.postssystem.features.publication.server.PublicationPost
|
||||||
|
import dev.inmo.postssystem.features.publication.server.PublicationTarget
|
||||||
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
|
import dev.inmo.tgbotapi.extensions.utils.shortcuts.executeUnsafe
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.MultipartFile
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.asMultipartFile
|
||||||
|
import dev.inmo.tgbotapi.requests.send.SendTextMessage
|
||||||
|
import dev.inmo.tgbotapi.requests.send.media.*
|
||||||
|
import dev.inmo.tgbotapi.types.ChatId
|
||||||
|
import dev.inmo.tgbotapi.utils.StorageFile
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
|
||||||
|
class PublicationTargetTelegram(
|
||||||
|
private val bot: TelegramBot,
|
||||||
|
private val targetChatId: ChatId
|
||||||
|
) : PublicationTarget {
|
||||||
|
override suspend fun publish(post: PublicationPost) {
|
||||||
|
post.content.mapNotNull {
|
||||||
|
val content = it.content
|
||||||
|
when (content) {
|
||||||
|
is BinaryContent -> {
|
||||||
|
val storageFile by lazy {
|
||||||
|
StorageFile(content.filename.name, content.bytesAllocator()).asMultipartFile()
|
||||||
|
}
|
||||||
|
when (content.mimeType) {
|
||||||
|
is KnownMimeTypes.Image.Jpeg,
|
||||||
|
is KnownMimeTypes.Image.Png -> {
|
||||||
|
SendPhoto(targetChatId, storageFile)
|
||||||
|
}
|
||||||
|
is KnownMimeTypes.Video.Mp4 -> {
|
||||||
|
SendVideo(targetChatId, storageFile)
|
||||||
|
}
|
||||||
|
is KnownMimeTypes.Audio.Mpeg -> {
|
||||||
|
SendAudio(targetChatId, storageFile)
|
||||||
|
}
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is TextContent -> {
|
||||||
|
SendTextMessage(targetChatId, content.text)
|
||||||
|
}
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}.forEach { request ->
|
||||||
|
bot.executeUnsafe(request, 3, 1000L)
|
||||||
|
delay(100L)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user