add partially working native sample

This commit is contained in:
InsanusMokrassar 2023-04-04 01:01:22 +06:00
parent 0f0ad5a1af
commit d3cb8a32ef
3 changed files with 163 additions and 0 deletions

View File

@ -0,0 +1,9 @@
# 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

@ -0,0 +1,45 @@
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
plugins {
id "org.jetbrains.kotlin.multiplatform"
}
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.")
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

@ -0,0 +1,109 @@
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()
}