From c6019b1862f718ebd1710a41697eb567b9283bab Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Wed, 19 Apr 2023 20:20:11 +0600 Subject: [PATCH] complete sample with native --- NativeRandomFileSenderBot/README.md | 9 -- .../nativeMain/kotlin/RandomFileSenderBot.kt | 109 ------------------ RandomFileSenderBot/build.gradle | 39 ++++++- .../kotlin/Bot.kt} | 31 ++--- .../src/commonMain/kotlin/PickFile.kt | 0 .../src/jvmMain/kotlin/ActualPickFile.kt | 10 ++ .../src/jvmMain/kotlin/RandomFileSenderBot.kt | 5 + .../src/nativeMain/kotlin/ActualPickFile.kt | 10 ++ .../nativeMain/kotlin/RandomFileSenderBot.kt | 8 ++ ResenderBot/ResenderBotLib/build.gradle | 2 + .../src/commonMain/kotlin/ResenderBot.kt | 9 +- .../native_launcher}/build.gradle | 7 +- .../src/nativeMain/kotlin/ResenderBot.kt | 9 ++ gradle.properties | 8 +- settings.gradle | 2 +- 15 files changed, 100 insertions(+), 158 deletions(-) delete mode 100644 NativeRandomFileSenderBot/README.md delete mode 100644 NativeRandomFileSenderBot/src/nativeMain/kotlin/RandomFileSenderBot.kt rename RandomFileSenderBot/src/{main/kotlin/RandomFileSenderBot.kt => commonMain/kotlin/Bot.kt} (77%) create mode 100644 RandomFileSenderBot/src/commonMain/kotlin/PickFile.kt create mode 100644 RandomFileSenderBot/src/jvmMain/kotlin/ActualPickFile.kt create mode 100644 RandomFileSenderBot/src/jvmMain/kotlin/RandomFileSenderBot.kt create mode 100644 RandomFileSenderBot/src/nativeMain/kotlin/ActualPickFile.kt create mode 100644 RandomFileSenderBot/src/nativeMain/kotlin/RandomFileSenderBot.kt rename {NativeRandomFileSenderBot => ResenderBot/native_launcher}/build.gradle (87%) create mode 100644 ResenderBot/native_launcher/src/nativeMain/kotlin/ResenderBot.kt diff --git a/NativeRandomFileSenderBot/README.md b/NativeRandomFileSenderBot/README.md deleted file mode 100644 index 4765c04..0000000 --- a/NativeRandomFileSenderBot/README.md +++ /dev/null @@ -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]" -``` diff --git a/NativeRandomFileSenderBot/src/nativeMain/kotlin/RandomFileSenderBot.kt b/NativeRandomFileSenderBot/src/nativeMain/kotlin/RandomFileSenderBot.kt deleted file mode 100644 index 29bf284..0000000 --- a/NativeRandomFileSenderBot/src/nativeMain/kotlin/RandomFileSenderBot.kt +++ /dev/null @@ -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) = 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) { - 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() - - 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() -} diff --git a/RandomFileSenderBot/build.gradle b/RandomFileSenderBot/build.gradle index 946ccfc..70327df 100644 --- a/RandomFileSenderBot/build.gradle +++ b/RandomFileSenderBot/build.gradle @@ -8,14 +8,45 @@ buildscript { } } -apply plugin: 'kotlin' +plugins { + id "org.jetbrains.kotlin.multiplatform" +} + apply plugin: 'application' mainClassName="RandomFileSenderBotKt" -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" +kotlin { + 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" + } + } + } } + diff --git a/RandomFileSenderBot/src/main/kotlin/RandomFileSenderBot.kt b/RandomFileSenderBot/src/commonMain/kotlin/Bot.kt similarity index 77% rename from RandomFileSenderBot/src/main/kotlin/RandomFileSenderBot.kt rename to RandomFileSenderBot/src/commonMain/kotlin/Bot.kt index 302200e..671d843 100644 --- a/RandomFileSenderBot/src/main/kotlin/RandomFileSenderBot.kt +++ b/RandomFileSenderBot/src/commonMain/kotlin/Bot.kt @@ -1,23 +1,25 @@ +import dev.inmo.micro_utils.common.MPPFile import dev.inmo.micro_utils.common.filesize -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.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.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 java.io.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. * 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. * But if you will send `/send_file 5` it will choose 5 random files and send them as group */ -suspend fun main(args: Array) { - val botToken = args.first() - val directoryOrFile = args.getOrNull(1) ?.let { File(it) } ?: File("") +suspend fun doRandomFileSenderBot(token: String, folder: MPPFile) { + val bot = telegramBot(token) - fun pickFile(currentRoot: File = directoryOrFile): File? { - if (currentRoot.isFile) { - return currentRoot - } else { - return pickFile(currentRoot.listFiles() ?.takeIf { it.isNotEmpty() } ?.random() ?: return null) - } - } - - suspend fun TelegramBot.sendFiles(chat: Chat, files: List) { + suspend fun TelegramBot.sendFiles(chat: Chat, files: List) { when (files.size) { 1 -> sendDocument( chat.id, @@ -52,8 +45,6 @@ suspend fun main(args: Array) { } } - val bot = telegramBot(botToken) - bot.buildBehaviourWithLongPolling (defaultExceptionsHandler = { it.printStackTrace() }) { onCommandWithArgs(command) { message, args -> @@ -62,10 +53,10 @@ suspend fun main(args: Array) { var sent = false var left = count - val chosen = mutableListOf() + val chosen = mutableListOf() while (left > 0) { - val picked = pickFile() ?.takeIf { it.filesize > 0 } ?: continue + val picked = pickFile(folder) ?.takeIf { it.filesize > 0 } ?: continue chosen.add(picked) left-- if (chosen.size >= mediaCountInMediaGroup.last) { diff --git a/RandomFileSenderBot/src/commonMain/kotlin/PickFile.kt b/RandomFileSenderBot/src/commonMain/kotlin/PickFile.kt new file mode 100644 index 0000000..e69de29 diff --git a/RandomFileSenderBot/src/jvmMain/kotlin/ActualPickFile.kt b/RandomFileSenderBot/src/jvmMain/kotlin/ActualPickFile.kt new file mode 100644 index 0000000..f453694 --- /dev/null +++ b/RandomFileSenderBot/src/jvmMain/kotlin/ActualPickFile.kt @@ -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) + } +} diff --git a/RandomFileSenderBot/src/jvmMain/kotlin/RandomFileSenderBot.kt b/RandomFileSenderBot/src/jvmMain/kotlin/RandomFileSenderBot.kt new file mode 100644 index 0000000..52d0e06 --- /dev/null +++ b/RandomFileSenderBot/src/jvmMain/kotlin/RandomFileSenderBot.kt @@ -0,0 +1,5 @@ +import dev.inmo.micro_utils.common.MPPFile + +suspend fun main(args: Array) { + doRandomFileSenderBot(args.first(), MPPFile(args.getOrNull(1) ?: "")) +} diff --git a/RandomFileSenderBot/src/nativeMain/kotlin/ActualPickFile.kt b/RandomFileSenderBot/src/nativeMain/kotlin/ActualPickFile.kt new file mode 100644 index 0000000..1b6386d --- /dev/null +++ b/RandomFileSenderBot/src/nativeMain/kotlin/ActualPickFile.kt @@ -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) + } +} diff --git a/RandomFileSenderBot/src/nativeMain/kotlin/RandomFileSenderBot.kt b/RandomFileSenderBot/src/nativeMain/kotlin/RandomFileSenderBot.kt new file mode 100644 index 0000000..4ef7710 --- /dev/null +++ b/RandomFileSenderBot/src/nativeMain/kotlin/RandomFileSenderBot.kt @@ -0,0 +1,8 @@ +import kotlinx.coroutines.runBlocking +import okio.Path.Companion.toPath + +fun main(args: Array) { + runBlocking { + doRandomFileSenderBot(args.first(), args.getOrNull(1) ?.toPath() ?: "".toPath()) + } +} diff --git a/ResenderBot/ResenderBotLib/build.gradle b/ResenderBot/ResenderBotLib/build.gradle index 1d40c3e..0530296 100644 --- a/ResenderBot/ResenderBotLib/build.gradle +++ b/ResenderBot/ResenderBotLib/build.gradle @@ -20,6 +20,8 @@ kotlin { browser() binaries.executable() } + linuxX64() + mingwX64() sourceSets { commonMain { diff --git a/ResenderBot/ResenderBotLib/src/commonMain/kotlin/ResenderBot.kt b/ResenderBot/ResenderBotLib/src/commonMain/kotlin/ResenderBot.kt index cec4079..fe604d8 100644 --- a/ResenderBot/ResenderBotLib/src/commonMain/kotlin/ResenderBot.kt +++ b/ResenderBot/ResenderBotLib/src/commonMain/kotlin/ResenderBot.kt @@ -15,11 +15,7 @@ suspend fun activateResenderBot( token: String, print: (Any) -> Unit ) { - val bot = telegramBot(token) - - print(bot.getMe()) - - bot.buildBehaviourWithLongPolling(CoroutineScope(currentCoroutineContext() + SupervisorJob())) { + telegramBotWithBehaviourAndLongPolling(token, scope = CoroutineScope(currentCoroutineContext() + SupervisorJob())) { onContentMessage( subcontextUpdatesFilter = MessageFilterByChat, ) { @@ -43,5 +39,6 @@ suspend fun activateResenderBot( allUpdatesFlow.subscribeSafelyWithoutExceptions(this) { println(it) } - }.join() + print(bot.getMe()) + }.second.join() } diff --git a/NativeRandomFileSenderBot/build.gradle b/ResenderBot/native_launcher/build.gradle similarity index 87% rename from NativeRandomFileSenderBot/build.gradle rename to ResenderBot/native_launcher/build.gradle index 0f5d51a..fa67557 100644 --- a/NativeRandomFileSenderBot/build.gradle +++ b/ResenderBot/native_launcher/build.gradle @@ -12,10 +12,6 @@ plugins { id "org.jetbrains.kotlin.multiplatform" } -repositories { - maven { url "https://maven.pkg.jetbrains.space/public/p/ktor/eap/" } -} - kotlin { def hostOs = System.getProperty("os.name") @@ -30,7 +26,7 @@ kotlin { dependencies { implementation kotlin('stdlib') - api "dev.inmo:tgbotapi:$telegram_bot_api_version" + api project(":ResenderBot:ResenderBotLib") } } @@ -47,3 +43,4 @@ kotlin { } } } + diff --git a/ResenderBot/native_launcher/src/nativeMain/kotlin/ResenderBot.kt b/ResenderBot/native_launcher/src/nativeMain/kotlin/ResenderBot.kt new file mode 100644 index 0000000..29e16b1 --- /dev/null +++ b/ResenderBot/native_launcher/src/nativeMain/kotlin/ResenderBot.kt @@ -0,0 +1,9 @@ +import kotlinx.coroutines.runBlocking + +fun main(vararg args: String) { + runBlocking { + activateResenderBot(args.first()) { + println(it) + } + } +} diff --git a/gradle.properties b/gradle.properties index ffb21b7..823884b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,11 +1,11 @@ kotlin.code.style=official org.gradle.parallel=true # 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 -telegram_bot_api_version=7.0.2-branch_7.0.2-build1583 -micro_utils_version=0.17.6 +telegram_bot_api_version=7.0.2 +micro_utils_version=0.17.8 serialization_version=1.5.0 -ktor_version=2.2.4 +ktor_version=2.3.0 diff --git a/settings.gradle b/settings.gradle index ab1214f..a665bb3 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,7 +1,6 @@ include ":ForwardInfoSenderBot" include ":RandomFileSenderBot" -include ":NativeRandomFileSenderBot" include ":HelloBot" @@ -13,6 +12,7 @@ include ":FilesLoaderBot" include ":ResenderBot:ResenderBotLib" include ":ResenderBot:jvm_launcher" +include ":ResenderBot:native_launcher" include ":KeyboardsBot:KeyboardsBotLib" include ":KeyboardsBot:jvm_launcher"