1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2024-12-22 16:47:13 +00:00

start adding events generator

This commit is contained in:
InsanusMokrassar 2024-12-05 18:00:39 +06:00
parent 5559923339
commit 819982473a
6 changed files with 296 additions and 0 deletions

View File

@ -0,0 +1 @@
data object {{$event_name_uppercase}} : EventType("{{$event_name}}")

View File

@ -0,0 +1,2 @@
@JsName("onEvent")
internal fun on{{$event_name_uppercase}}(type: String, callback: ({{$callback_args}}) -> Unit)

View File

@ -0,0 +1,22 @@
// Part for callback typealias
typealias {{$callback_typealias_name}} = WebApp.({{$callback_args}}) -> Unit
// Part for outside of WebApp
/**
* @return The callback which should be used in case you want to turn off events handling
*/
fun WebApp.onEvent(type: EventType.{{$event_name_uppercase}}, eventHandler: {{$callback_typealias_name}}) = { it: {{$callback_typealias_name}} ->
eventHandler(js("this").unsafeCast<WebApp>(), it)
}.also {
on{{$event_name_uppercase}}(
type.typeName,
callback = it
)
}
/**
* @return The callback which should be used in case you want to turn off events handling
*/
fun WebApp.on{{$event_name_uppercase}}(eventHandler: {{$callback_typealias_name}}) = onEvent(EventType.{{$event_name_uppercase}}, eventHandler)

View File

@ -0,0 +1,238 @@
#!/usr/bin/env kotlin
/**
* Generates files and folders as they have been put in the folder. Envs uses common syntax, but
* values may contains {{${'$'}sampleVariable}} parts, where {{${'$'}sampleVariable}} will be replaced with variable value.
* Example:
*
* .env:
* sampleVariable=${'$'}prompt # require request from command line
* sampleVariable2=just some value
* sampleVariable3=${'$'}{sampleVariable}.${'$'}{sampleVariable2}
*
* Result variables:
* sampleVariable=your input in console # lets imagine you typed it
* sampleVariable2=just some value
* sampleVariable3=your input in console.just some value
*
* To use these variables in template, you will need to write {{${'$'}sampleVariable}}.
* You may use it in text of files as well as in files/folders names.
*
* Usage: kotlin generator.kts [args] folders...
* Args:
* -e, --env: Path to file with args for generation; Use "${'$'}prompt" as values to read variable value from console
* -o, --outputFolder: Folder where templates should be used. Folder of calling by default
* folders: Folders-templates
* -s, --skip: Skip variables setup
* -a, --args: Pass several for several args. Use with syntax `--args a=b` or `-a a=b` to set variable with key `a` to value `b`
*/
import java.io.File
val console = System.console()
var envFile: File? = null
var outputFolder: File = File("./") // current folder by default
val templatesFolders = mutableListOf<File>()
var extensions: List<String>? = null
var skipPrompts: Boolean = false
val commandLineArgs = mutableMapOf<String, String>()
val globalEnvs = System.getenv()
fun String.replaceWithVariables(envs: Map<String, String>): String {
var currentString = this
var changed = false
do {
changed = false
envs.forEach { (k, v) ->
val previousString = currentString
currentString = currentString.replace("{{$${k}}}", v)
changed = changed || currentString != previousString
}
} while (changed)
return currentString
}
fun requestVariable(variableName: String, defaultValue: String?): String {
console.printf("Enter value for variable $variableName${defaultValue ?.let { " [$it]" } ?: ""}: ")
return console.readLine().ifEmpty { defaultValue } ?: ""
}
fun readEnvs(content: String, presets: Map<String, String>?): Map<String, String> {
val initialEnvs = mutableMapOf<String, String>()
val contentAsMap = mutableMapOf<String, String>()
content.split("\n").forEach {
val withoutComment = it.replace(Regex("\\#.*"), "")
runCatching {
val (key, value) = withoutComment.split("=")
contentAsMap[key] = value
}
}
if (skipPrompts) {
initialEnvs.putAll(
contentAsMap + (presets ?: emptyMap()) + globalEnvs + commandLineArgs
)
} else {
contentAsMap.forEach { (key, value) ->
val existsValue = presets ?.get(key) ?: commandLineArgs[key] ?: globalEnvs[key]
initialEnvs[key] = when {
value == "\$prompt" -> requestVariable(key, existsValue)
else -> requestVariable(key, value.replaceWithVariables(initialEnvs))
}
}
}
var i = 0
val readEnvs = initialEnvs.toMutableMap()
while (i < readEnvs.size) {
val key = readEnvs.keys.elementAt(i)
val currentValue = readEnvs.getValue(key)
val withReplaced = currentValue.replaceWithVariables(readEnvs)
var changed = false
if (withReplaced != currentValue) {
i = 0
readEnvs[key] = withReplaced
} else {
i++
}
}
return (presets ?: emptyMap()) + readEnvs
}
fun readParameters() {
var i = 0
while (i < args.size) {
val arg = args[i]
when (arg) {
"--env",
"-e" -> {
i++
envFile = File(args[i])
}
"--skip",
"-s" -> {
skipPrompts = true
}
"--extensions",
"-ex" -> {
i++
extensions = args[i].split(",")
}
"--outputFolder",
"-o" -> {
i++
outputFolder = File(args[i])
}
"--args",
"-a" -> {
i++
val subarg = args[i]
val key = subarg.takeWhile { it != '=' }
val value = subarg.dropWhile { it != '=' }.removePrefix("=")
commandLineArgs[key] = value
}
"--help",
"-h" -> {
println("""
Generates files and folders as the have been put in the folder. Envs uses common syntax, but
values may contains {{${'$'}sampleVariable}} parts, where {{${'$'}sampleVariable}} will be replaced with variable value.
Example:
.env:
sampleVariable=${'$'}prompt # require request from command line
sampleVariable2=just some value
sampleVariable3=${'$'}{sampleVariable}.${'$'}{sampleVariable2}
Result variables:
sampleVariable=your input in console # lets imagine you typed it
sampleVariable2=just some value
sampleVariable3=your input in console.just some value
To use these variables in template, you will need to write {{${'$'}sampleVariable}}.
You may use it in text of files as well as in files/folders names.
Usage: kotlin generator.kts [args] folders...
Args:
-e, --env: Path to file with args for generation; Use "${'$'}prompt" as values to read variable value from console
-o, --outputFolder: Folder where templates should be used. Folder of calling by default
folders: Folders-templates
-s, --skip: Skip variables setup
-a, --args: Pass several for several args. Use with syntax `--args a=b` or `-a a=b` to set variable with key `a` to value `b`
""".trimIndent())
Runtime.getRuntime().exit(0)
}
else -> {
val potentialFile = File(arg)
println("Potential file/folder as template: ${potentialFile.absolutePath}")
runCatching {
if (potentialFile.exists()) {
println("Adding file/folder as template: ${potentialFile.absolutePath}")
templatesFolders.add(potentialFile)
}
}.onFailure { e ->
println("Unable to use folder $arg as template folder")
e.printStackTrace()
}
}
}
i++
}
}
readParameters()
val envs: MutableMap<String, String> = envFile ?.let { readEnvs(it.readText(), null) } ?.toMutableMap() ?: mutableMapOf()
println(
"""
Result environments:
${envs.toList().joinToString("\n ") { (k, v) -> "$k=$v" }}
Result extensions:
${extensions ?.joinToString()}
Input folders:
${templatesFolders.joinToString("\n ") { it.absolutePath }}
Output folder:
${outputFolder.absolutePath}
""".trimIndent()
)
fun File.handleTemplate(targetFolder: File, envs: Map<String, String>) {
println("Handling $absolutePath")
val localEnvs = File(absolutePath, ".env").takeIf { it.exists() } ?.let {
println("Reading .env in ${absolutePath}")
readEnvs(it.readText(), envs)
} ?: envs
println(
"""
Local environments:
${localEnvs.toList().joinToString("\n ") { (k, v) -> "$k=$v" }}
""".trimIndent()
)
val newName = name.replaceWithVariables(localEnvs)
println("New name $newName")
when {
!exists() -> return
isFile -> {
val content = useLines {
it.map { it.replaceWithVariables(localEnvs) }.toList()
}.joinToString("\n")
val targetFile = File(targetFolder, newName)
targetFile.writeText(content)
println("Target file: ${targetFile.absolutePath}")
}
else -> {
val folder = File(targetFolder, newName)
println("Target folder: ${folder.absolutePath}")
folder.mkdirs()
listFiles() ?.forEach { fileOrFolder ->
fileOrFolder.handleTemplate(folder, localEnvs)
}
}
}
}
templatesFolders.forEach { folderOrFile ->
folderOrFile.handleTemplate(outputFolder, envs)
}

View File

@ -0,0 +1,6 @@
[
{
"event_name": "activated",
"callback_args": ""
}
]

View File

@ -0,0 +1,27 @@
#!/usr/bin/env kotlin
@file:DependsOn("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")
import kotlinx.serialization.json.*
import java.io.File
import java.lang.Runtime
val rootFolder = File("../../../../../../../../")
val rfAbsolutePath = rootFolder.absolutePath
fun generateEvent(eventName: String, callbacks: String) {
val uppercaseEventName = eventName.take(1).uppercase() + eventName.drop(1)
val command = "${rfAbsolutePath}/.templates/generator.kts -s -a \"event_name=$eventName\" -a \"event_name_uppercase=$uppercaseEventName\" -a \"callback_args=$callbacks\" --env \"${rfAbsolutePath}/.templates/events/.env\" -o \"./\" -ex \"kt\" \"${rfAbsolutePath}/.templates/events/\""
Runtime.getRuntime().exec(command).waitFor()
}
val eventsList: JsonArray = Json.parseToJsonElement(File("EventsList.json").readText()).jsonArray
eventsList.forEach {
generateEvent(
it.jsonObject["event_name"]!!.jsonPrimitive.content,
it.jsonObject["callback"] ?.jsonPrimitive ?.content ?: ""
)
}
println(eventsList.toString())