complete sample with native

This commit is contained in:
InsanusMokrassar 2023-04-19 20:20:11 +06:00
parent 7b996fe1de
commit c6019b1862
15 changed files with 100 additions and 158 deletions

View File

@ -1,9 +0,0 @@
# RandomFileSenderBot
This bot will send random file from input folder OR from bot working folder
## Launch
```bash
../gradlew run --args="BOT_TOKEN[ optional/folder/path]"
```

View File

@ -1,109 +0,0 @@
import dev.inmo.micro_utils.common.MPPFile
import dev.inmo.micro_utils.common.filesize
import dev.inmo.micro_utils.coroutines.runCatchingSafely
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.tgbotapi.bot.ktor.telegramBot
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.api.bot.getMe
import dev.inmo.tgbotapi.extensions.api.bot.setMyCommands
import dev.inmo.tgbotapi.extensions.api.send.*
import dev.inmo.tgbotapi.extensions.api.send.media.sendDocument
import dev.inmo.tgbotapi.extensions.api.send.media.sendDocumentsGroup
import dev.inmo.tgbotapi.extensions.behaviour_builder.buildBehaviourWithLongPolling
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommandWithArgs
import dev.inmo.tgbotapi.requests.abstracts.asMultipartFile
import dev.inmo.tgbotapi.types.BotCommand
import dev.inmo.tgbotapi.types.chat.Chat
import dev.inmo.tgbotapi.types.files.DocumentFile
import dev.inmo.tgbotapi.types.media.TelegramMediaDocument
import dev.inmo.tgbotapi.types.mediaCountInMediaGroup
import kotlinx.coroutines.runBlocking
import okio.FileSystem
import okio.Path.Companion.toPath
private const val command = "send_file"
/**
* This bot will send files inside of working directory OR from directory in the second argument.
* You may send /send_file command to this bot to get random file from the directory OR
* `/send_file $number` when you want to receive required number of files. For example,
* /send_file and `/send_file 1` will have the same effect - bot will send one random file.
* But if you will send `/send_file 5` it will choose 5 random files and send them as group
*/
fun main(args: Array<String>) = runBlocking {
val botToken = args.first()
val directoryOrFile = args.getOrNull(1) ?.toPath() ?: "".toPath()
fun pickFile(currentRoot: MPPFile = directoryOrFile): MPPFile? {
if (FileSystem.SYSTEM.exists(currentRoot) && FileSystem.SYSTEM.listOrNull(currentRoot) == null) {
return currentRoot
} else {
return pickFile(FileSystem.SYSTEM.list(currentRoot).takeIf { it.isNotEmpty() } ?.random() ?: return null)
}
}
suspend fun TelegramBot.sendFiles(chat: Chat, files: List<MPPFile>) {
when (files.size) {
1 -> {
sendDocument(
chat.id,
files.first().asMultipartFile(),
protectContent = true
)
}
else -> sendDocumentsGroup(
chat,
files.map { TelegramMediaDocument(it.asMultipartFile()) },
protectContent = true
)
}
}
val bot = telegramBot(botToken)
bot.buildBehaviourWithLongPolling (defaultExceptionsHandler = { it.printStackTrace() }) {
onCommandWithArgs(command) { message, args ->
withUploadDocumentAction(message.chat) {
val count = args.firstOrNull() ?.toIntOrNull() ?: 1
var sent = false
var left = count
val chosen = mutableListOf<MPPFile>()
while (left > 0) {
val picked = pickFile() ?.takeIf { it.filesize > 0 } ?: continue
chosen.add(picked)
left--
if (chosen.size >= mediaCountInMediaGroup.last) {
runCatchingSafely {
sendFiles(message.chat, chosen)
}.onFailure {
it.printStackTrace()
}
chosen.clear()
sent = true
}
}
if (chosen.isNotEmpty()) {
sendFiles(message.chat, chosen)
sent = true
}
if (!sent) {
reply(message, "Nothing selected :(")
}
}
}
setMyCommands(
BotCommand(command, "Send some random file in picker directory")
)
allUpdatesFlow.subscribeSafelyWithoutExceptions(this) {
println(it)
}
println(getMe())
}.join()
}

View File

@ -8,14 +8,45 @@ buildscript {
} }
} }
apply plugin: 'kotlin' plugins {
id "org.jetbrains.kotlin.multiplatform"
}
apply plugin: 'application' apply plugin: 'application'
mainClassName="RandomFileSenderBotKt" mainClassName="RandomFileSenderBotKt"
dependencies { kotlin {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" def hostOs = System.getProperty("os.name")
def isMingwX64 = hostOs.startsWith("Windows")
def nativeTarget
if (hostOs == "Linux") nativeTarget = linuxX64("native") { binaries { executable() } }
else if (isMingwX64) nativeTarget = mingwX64("native") { binaries { executable() } }
else throw new GradleException("Host OS is not supported in Kotlin/Native.")
implementation "dev.inmo:tgbotapi:$telegram_bot_api_version" jvm()
sourceSets {
commonMain {
dependencies {
implementation kotlin('stdlib')
api "dev.inmo:tgbotapi:$telegram_bot_api_version"
}
}
nativeMain {
dependencies {
def engine
if (hostOs == "Linux") engine = "curl"
else if (isMingwX64) engine = "winhttp"
else throw new GradleException("Host OS is not supported in Kotlin/Native.")
api "io.ktor:ktor-client-$engine:$ktor_version"
}
}
}
} }

View File

@ -1,23 +1,25 @@
import dev.inmo.micro_utils.common.MPPFile
import dev.inmo.micro_utils.common.filesize import dev.inmo.micro_utils.common.filesize
import dev.inmo.tgbotapi.bot.ktor.telegramBot
import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.api.bot.getMe import dev.inmo.tgbotapi.extensions.api.bot.getMe
import dev.inmo.tgbotapi.extensions.api.bot.setMyCommands import dev.inmo.tgbotapi.extensions.api.bot.setMyCommands
import dev.inmo.tgbotapi.extensions.api.send.*
import dev.inmo.tgbotapi.extensions.api.send.media.sendDocument import dev.inmo.tgbotapi.extensions.api.send.media.sendDocument
import dev.inmo.tgbotapi.extensions.api.send.media.sendDocumentsGroup import dev.inmo.tgbotapi.extensions.api.send.media.sendDocumentsGroup
import dev.inmo.tgbotapi.extensions.api.send.reply
import dev.inmo.tgbotapi.extensions.api.send.withUploadDocumentAction
import dev.inmo.tgbotapi.extensions.api.telegramBot
import dev.inmo.tgbotapi.extensions.behaviour_builder.buildBehaviourWithLongPolling import dev.inmo.tgbotapi.extensions.behaviour_builder.buildBehaviourWithLongPolling
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommandWithArgs import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommandWithArgs
import dev.inmo.tgbotapi.requests.abstracts.asMultipartFile import dev.inmo.tgbotapi.requests.abstracts.asMultipartFile
import dev.inmo.tgbotapi.types.BotCommand import dev.inmo.tgbotapi.types.BotCommand
import dev.inmo.tgbotapi.types.chat.Chat import dev.inmo.tgbotapi.types.chat.Chat
import dev.inmo.tgbotapi.types.files.DocumentFile
import dev.inmo.tgbotapi.types.media.TelegramMediaDocument import dev.inmo.tgbotapi.types.media.TelegramMediaDocument
import dev.inmo.tgbotapi.types.mediaCountInMediaGroup import dev.inmo.tgbotapi.types.mediaCountInMediaGroup
import java.io.File
private const val command = "send_file" private const val command = "send_file"
expect fun pickFile(currentRoot: MPPFile): MPPFile?
/** /**
* This bot will send files inside of working directory OR from directory in the second argument. * This bot will send files inside of working directory OR from directory in the second argument.
* You may send /send_file command to this bot to get random file from the directory OR * You may send /send_file command to this bot to get random file from the directory OR
@ -25,19 +27,10 @@ private const val command = "send_file"
* /send_file and `/send_file 1` will have the same effect - bot will send one random file. * /send_file and `/send_file 1` will have the same effect - bot will send one random file.
* But if you will send `/send_file 5` it will choose 5 random files and send them as group * But if you will send `/send_file 5` it will choose 5 random files and send them as group
*/ */
suspend fun main(args: Array<String>) { suspend fun doRandomFileSenderBot(token: String, folder: MPPFile) {
val botToken = args.first() val bot = telegramBot(token)
val directoryOrFile = args.getOrNull(1) ?.let { File(it) } ?: File("")
fun pickFile(currentRoot: File = directoryOrFile): File? { suspend fun TelegramBot.sendFiles(chat: Chat, files: List<MPPFile>) {
if (currentRoot.isFile) {
return currentRoot
} else {
return pickFile(currentRoot.listFiles() ?.takeIf { it.isNotEmpty() } ?.random() ?: return null)
}
}
suspend fun TelegramBot.sendFiles(chat: Chat, files: List<File>) {
when (files.size) { when (files.size) {
1 -> sendDocument( 1 -> sendDocument(
chat.id, chat.id,
@ -52,8 +45,6 @@ suspend fun main(args: Array<String>) {
} }
} }
val bot = telegramBot(botToken)
bot.buildBehaviourWithLongPolling (defaultExceptionsHandler = { it.printStackTrace() }) { bot.buildBehaviourWithLongPolling (defaultExceptionsHandler = { it.printStackTrace() }) {
onCommandWithArgs(command) { message, args -> onCommandWithArgs(command) { message, args ->
@ -62,10 +53,10 @@ suspend fun main(args: Array<String>) {
var sent = false var sent = false
var left = count var left = count
val chosen = mutableListOf<File>() val chosen = mutableListOf<MPPFile>()
while (left > 0) { while (left > 0) {
val picked = pickFile() ?.takeIf { it.filesize > 0 } ?: continue val picked = pickFile(folder) ?.takeIf { it.filesize > 0 } ?: continue
chosen.add(picked) chosen.add(picked)
left-- left--
if (chosen.size >= mediaCountInMediaGroup.last) { if (chosen.size >= mediaCountInMediaGroup.last) {

View File

@ -0,0 +1,10 @@
import dev.inmo.micro_utils.common.MPPFile
import java.io.File
actual fun pickFile(currentRoot: MPPFile): File? {
if (currentRoot.isFile) {
return currentRoot
} else {
return pickFile(currentRoot.listFiles() ?.takeIf { it.isNotEmpty() } ?.random() ?: return null)
}
}

View File

@ -0,0 +1,5 @@
import dev.inmo.micro_utils.common.MPPFile
suspend fun main(args: Array<String>) {
doRandomFileSenderBot(args.first(), MPPFile(args.getOrNull(1) ?: ""))
}

View File

@ -0,0 +1,10 @@
import dev.inmo.micro_utils.common.MPPFile
import okio.FileSystem
actual fun pickFile(currentRoot: MPPFile): MPPFile? {
if (FileSystem.SYSTEM.exists(currentRoot) && FileSystem.SYSTEM.listOrNull(currentRoot) == null) {
return currentRoot
} else {
return pickFile(FileSystem.SYSTEM.list(currentRoot).takeIf { it.isNotEmpty() } ?.random() ?: return null)
}
}

View File

@ -0,0 +1,8 @@
import kotlinx.coroutines.runBlocking
import okio.Path.Companion.toPath
fun main(args: Array<String>) {
runBlocking {
doRandomFileSenderBot(args.first(), args.getOrNull(1) ?.toPath() ?: "".toPath())
}
}

View File

@ -20,6 +20,8 @@ kotlin {
browser() browser()
binaries.executable() binaries.executable()
} }
linuxX64()
mingwX64()
sourceSets { sourceSets {
commonMain { commonMain {

View File

@ -15,11 +15,7 @@ suspend fun activateResenderBot(
token: String, token: String,
print: (Any) -> Unit print: (Any) -> Unit
) { ) {
val bot = telegramBot(token) telegramBotWithBehaviourAndLongPolling(token, scope = CoroutineScope(currentCoroutineContext() + SupervisorJob())) {
print(bot.getMe())
bot.buildBehaviourWithLongPolling(CoroutineScope(currentCoroutineContext() + SupervisorJob())) {
onContentMessage( onContentMessage(
subcontextUpdatesFilter = MessageFilterByChat, subcontextUpdatesFilter = MessageFilterByChat,
) { ) {
@ -43,5 +39,6 @@ suspend fun activateResenderBot(
allUpdatesFlow.subscribeSafelyWithoutExceptions(this) { allUpdatesFlow.subscribeSafelyWithoutExceptions(this) {
println(it) println(it)
} }
}.join() print(bot.getMe())
}.second.join()
} }

View File

@ -12,10 +12,6 @@ plugins {
id "org.jetbrains.kotlin.multiplatform" id "org.jetbrains.kotlin.multiplatform"
} }
repositories {
maven { url "https://maven.pkg.jetbrains.space/public/p/ktor/eap/" }
}
kotlin { kotlin {
def hostOs = System.getProperty("os.name") def hostOs = System.getProperty("os.name")
@ -30,7 +26,7 @@ kotlin {
dependencies { dependencies {
implementation kotlin('stdlib') implementation kotlin('stdlib')
api "dev.inmo:tgbotapi:$telegram_bot_api_version" api project(":ResenderBot:ResenderBotLib")
} }
} }
@ -47,3 +43,4 @@ kotlin {
} }
} }
} }

View File

@ -0,0 +1,9 @@
import kotlinx.coroutines.runBlocking
fun main(vararg args: String) {
runBlocking {
activateResenderBot(args.first()) {
println(it)
}
}
}

View File

@ -1,11 +1,11 @@
kotlin.code.style=official kotlin.code.style=official
org.gradle.parallel=true org.gradle.parallel=true
# Due to parallel compilation project require next amount of memory on full build # Due to parallel compilation project require next amount of memory on full build
org.gradle.jvmargs=-Xmx1g org.gradle.jvmargs=-Xmx2g
kotlin_version=1.8.20 kotlin_version=1.8.20
telegram_bot_api_version=7.0.2-branch_7.0.2-build1583 telegram_bot_api_version=7.0.2
micro_utils_version=0.17.6 micro_utils_version=0.17.8
serialization_version=1.5.0 serialization_version=1.5.0
ktor_version=2.2.4 ktor_version=2.3.0

View File

@ -1,7 +1,6 @@
include ":ForwardInfoSenderBot" include ":ForwardInfoSenderBot"
include ":RandomFileSenderBot" include ":RandomFileSenderBot"
include ":NativeRandomFileSenderBot"
include ":HelloBot" include ":HelloBot"
@ -13,6 +12,7 @@ include ":FilesLoaderBot"
include ":ResenderBot:ResenderBotLib" include ":ResenderBot:ResenderBotLib"
include ":ResenderBot:jvm_launcher" include ":ResenderBot:jvm_launcher"
include ":ResenderBot:native_launcher"
include ":KeyboardsBot:KeyboardsBotLib" include ":KeyboardsBot:KeyboardsBotLib"
include ":KeyboardsBot:jvm_launcher" include ":KeyboardsBot:jvm_launcher"