From ea6bf80d486d25b239b53a1e447596e743ffdb50 Mon Sep 17 00:00:00 2001 From: Eyre_S Date: Sat, 22 Feb 2025 01:13:31 +0800 Subject: [PATCH] MornyInformation adds sub-commands, move BuildConfig to morny-core - add Info_EventStatistic in MornyReport, registers to MornyInformation. This refactors the old /info event that hard-coded to MornyInformation class. - change SimpleCommandManager's `execute()` to `emitCommands()`, for not conflict to ISimpleCommand - deleted MornyInformationOlds, its functionality has been completely implemented by the original MornyInformation The BuildConfig series is still not completed yet. --- build.sbt | 47 +++-- .../sukazyo/cono/morny/reporter/Module.scala | 7 + .../command/Info_EventStatistic.scala | 32 +++ .../cc/sukazyo/cono/morny/BuildConfig.scala | 40 ---- .../cc/sukazyo/cono/morny/IBuildInfo.scala | 20 ++ .../sukazyo/cono/morny/core/MornyCoeur.scala | 7 +- .../core/bot/api/MornyCommandManager.scala | 9 +- .../core/bot/api/SimpleCommandManager.scala | 26 ++- .../core/bot/command/MornyInformation.scala | 184 ++++++++++-------- .../bot/command/MornyInformationOlds.scala | 18 -- .../bot/event/MornyOnTelegramCommand.scala | 2 +- .../telegram_api/command/InputCommand.scala | 35 +++- 12 files changed, 256 insertions(+), 171 deletions(-) create mode 100644 morny-coeur/src/main/scala/cc/sukazyo/cono/morny/reporter/command/Info_EventStatistic.scala delete mode 100644 morny-core/src/main/scala/cc/sukazyo/cono/morny/BuildConfig.scala create mode 100644 morny-core/src/main/scala/cc/sukazyo/cono/morny/IBuildInfo.scala delete mode 100644 morny-core/src/main/scala/cc/sukazyo/cono/morny/core/bot/command/MornyInformationOlds.scala diff --git a/build.sbt b/build.sbt index 8e6d5b9..9f390fa 100644 --- a/build.sbt +++ b/build.sbt @@ -70,6 +70,7 @@ lazy val morny_system_lib = (project in file (MornyProject.morny_system_lib.id)) ) lazy val morny_core = (project in file(MornyProject.morny_core.id)) + .enablePlugins(BuildInfoPlugin) .dependsOn(morny_system_lib) .settings( @@ -78,23 +79,9 @@ lazy val morny_core = (project in file(MornyProject.morny_core.id)) libraryDependencies ++= MornyProject.morny_core.dependencies, - ) - -lazy val morny_coeur = (project in file(MornyProject.morny_coeur.id)) - .enablePlugins(BuildInfoPlugin) - .dependsOn(morny_core) - .dependsOn(morny_system_lib) - .settings( - - name := MornyProject.morny_coeur.name, - moduleName := MornyProject.morny_coeur.id, - - Compile / mainClass := Some(MornyProject.morny_coeur.main_class), - - libraryDependencies ++= MornyProject.morny_coeur.dependencies, - buildInfoPackage := MornyProject.morny_coeur.root_package, buildInfoObject := "BuildConfig", + buildInfoOptions += BuildInfoOption.Traits("cc.sukazyo.cono.morny.IBuildInfo"), buildInfoKeys ++= Seq( BuildInfoKey[String]("VERSION", MornyProject.version), BuildInfoKey[String]("VERSION_FULL", MornyProject.version_full), @@ -108,6 +95,36 @@ lazy val morny_coeur = (project in file(MornyProject.morny_coeur.id)) BuildInfoKey[String]("COMMIT_PATH", MornyProject.git_store_path), ), + ) + +lazy val morny_coeur = (project in file(MornyProject.morny_coeur.id)) + .dependsOn(morny_core) + .dependsOn(morny_system_lib) + .settings( + + name := MornyProject.morny_coeur.name, + moduleName := MornyProject.morny_coeur.id, + + Compile / mainClass := Some(MornyProject.morny_coeur.main_class), + + libraryDependencies ++= MornyProject.morny_coeur.dependencies, + +// buildInfoPackage := MornyProject.morny_coeur.root_package, +// buildInfoObject := "BuildConfig", +// buildInfoOptions += BuildInfoOption.Traits("cc.sukazyo.cono.morny.IBuildInfo"), +// buildInfoKeys ++= Seq( +// BuildInfoKey[String]("VERSION", MornyProject.version), +// BuildInfoKey[String]("VERSION_FULL", MornyProject.version_full), +// BuildInfoKey[String]("VERSION_BASE", MornyProject.version_base), +// BuildInfoKey[Option[String]]("VERSION_DELTA", MornyProject.version_delta), +// BuildInfoKey[String]("CODENAME", MornyProject.version_codename), +// BuildInfoKey.action[Long]("CODE_TIMESTAMP") { MornyProject.code_time }, +// BuildInfoKey.action[String]("COMMIT") { MornyProject.git_commit }, +// BuildInfoKey.action[Boolean]("CLEAN_BUILD") { MornyProject.git_is_clean }, +// BuildInfoKey[String]("CODE_STORE", MornyProject.git_store), +// BuildInfoKey[String]("COMMIT_PATH", MornyProject.git_store_path), +// ), + assemblyMergeStrategy := { case module if module endsWith "module-info.class" => MergeStrategy.concat case module_kt if module_kt endsWith ".kotlin_module" => MergeStrategy.concat diff --git a/morny-coeur/src/main/scala/cc/sukazyo/cono/morny/reporter/Module.scala b/morny-coeur/src/main/scala/cc/sukazyo/cono/morny/reporter/Module.scala index 2b4b42c..4962b36 100644 --- a/morny-coeur/src/main/scala/cc/sukazyo/cono/morny/reporter/Module.scala +++ b/morny-coeur/src/main/scala/cc/sukazyo/cono/morny/reporter/Module.scala @@ -3,6 +3,7 @@ package cc.sukazyo.cono.morny.reporter import cc.sukazyo.cono.morny.core.internal.MornyInternalModule import cc.sukazyo.cono.morny.core.Log.logger import cc.sukazyo.cono.morny.core.MornyCoeur +import cc.sukazyo.cono.morny.core.bot.command.MornyInformation import cc.sukazyo.cono.morny.core.event.{TelegramBotEvents, TelegramCoreCommandEvents} class Module extends MornyInternalModule { @@ -28,8 +29,14 @@ class Module extends MornyInternalModule { import cxt.* externalContext >> { (instance: MornyReport) => + given MornyReport = instance + logger `info` "MornyReport will now collect your bot event statistics." eventManager register instance.EventStatistics.EventInfoCatcher + + import command.* + MornyInformation.inCoeur register Info_EventStatistic() + } || { logger `warn` "There seems no reporter instance is provided; skipped register events for it." } diff --git a/morny-coeur/src/main/scala/cc/sukazyo/cono/morny/reporter/command/Info_EventStatistic.scala b/morny-coeur/src/main/scala/cc/sukazyo/cono/morny/reporter/command/Info_EventStatistic.scala new file mode 100644 index 0000000..7e4e1a7 --- /dev/null +++ b/morny-coeur/src/main/scala/cc/sukazyo/cono/morny/reporter/command/Info_EventStatistic.scala @@ -0,0 +1,32 @@ +package cc.sukazyo.cono.morny.reporter.command + +import cc.sukazyo.cono.morny.reporter.MornyReport +import cc.sukazyo.cono.morny.system.telegram_api.command.{ICommandAlias, InputCommand, ISimpleCommand} +import cc.sukazyo.cono.morny.system.telegram_api.TelegramExtensions.Requests.unsafeExecute +import cc.sukazyo.cono.morny.util.var_text.VarText +import com.pengrad.telegrambot.model.Update +import com.pengrad.telegrambot.model.request.ParseMode +import com.pengrad.telegrambot.request.SendMessage + +class Info_EventStatistic (using reporter: MornyReport) extends ISimpleCommand { + import reporter.coeur.dsl.given + + override val name: String = "event" + override val aliases: List[ICommandAlias] = Nil + + override def execute (using command: InputCommand, event: Update): Unit = { + SendMessage( + event.message.chat.id, + VarText( + // language=html + """Event Statistics : + |in today + |{event_statistics}""".stripMargin + ).render( + "event_statistics" -> reporter.EventStatistics.eventStatisticsHTML + ) + ).parseMode(ParseMode.HTML).replyToMessageId(event.message.messageId) + .unsafeExecute + } + +} diff --git a/morny-core/src/main/scala/cc/sukazyo/cono/morny/BuildConfig.scala b/morny-core/src/main/scala/cc/sukazyo/cono/morny/BuildConfig.scala deleted file mode 100644 index 6304e9a..0000000 --- a/morny-core/src/main/scala/cc/sukazyo/cono/morny/BuildConfig.scala +++ /dev/null @@ -1,40 +0,0 @@ -// $COVERAGE-OFF$ -package cc.sukazyo.cono.morny - -/** This object was generated by sbt-buildinfo. */ -case object BuildConfig { - /** The value is "Morny Coeur". */ - val name: String = "Morny Coeur" - /** The value is "2.0.0-alpha21-SNAPSHOT". */ - val version: String = "2.0.0-alpha21-SNAPSHOT" - /** The value is "3.4.1". */ - val scalaVersion: String = "3.4.1" - /** The value is "1.10.0". */ - val sbtVersion: String = "1.10.0" - /** The value is "2.0.0-alpha21-SNAPSHOT". */ - val VERSION: String = "2.0.0-alpha21-SNAPSHOT" - /** The value is "2.0.0-alpha21-SNAPSHOT+gitbd958708.δ". */ - val VERSION_FULL: String = "2.0.0-alpha21-SNAPSHOT+gitbd958708.δ" - /** The value is "2.0.0-alpha21". */ - val VERSION_BASE: String = "2.0.0-alpha21" - /** The value is scala.None. */ - val VERSION_DELTA: scala.Option[String] = scala.None - /** The value is "xinzheng". */ - val CODENAME: String = "xinzheng" - /** The value is 1739975193572L. */ - val CODE_TIMESTAMP: scala.Long = 1739975193572L - /** The value is "bd95870864075e9921257e14bf446f53d4bc5e02". */ - val COMMIT: String = "bd95870864075e9921257e14bf446f53d4bc5e02" - /** The value is false. */ - val CLEAN_BUILD: scala.Boolean = false - /** The value is "https://github.com/Eyre-S/Coeur-Morny-Cono". */ - val CODE_STORE: String = "https://github.com/Eyre-S/Coeur-Morny-Cono" - /** The value is "https://github.com/Eyre-S/Coeur-Morny-Cono/commit/%s". */ - val COMMIT_PATH: String = "https://github.com/Eyre-S/Coeur-Morny-Cono/commit/%s" - override val toString: String = { - "name: %s, version: %s, scalaVersion: %s, sbtVersion: %s, VERSION: %s, VERSION_FULL: %s, VERSION_BASE: %s, VERSION_DELTA: %s, CODENAME: %s, CODE_TIMESTAMP: %s, COMMIT: %s, CLEAN_BUILD: %s, CODE_STORE: %s, COMMIT_PATH: %s".format( - name, version, scalaVersion, sbtVersion, VERSION, VERSION_FULL, VERSION_BASE, VERSION_DELTA, CODENAME, CODE_TIMESTAMP, COMMIT, CLEAN_BUILD, CODE_STORE, COMMIT_PATH - ) - } -} -// $COVERAGE-ON$ diff --git a/morny-core/src/main/scala/cc/sukazyo/cono/morny/IBuildInfo.scala b/morny-core/src/main/scala/cc/sukazyo/cono/morny/IBuildInfo.scala new file mode 100644 index 0000000..36de514 --- /dev/null +++ b/morny-core/src/main/scala/cc/sukazyo/cono/morny/IBuildInfo.scala @@ -0,0 +1,20 @@ +package cc.sukazyo.cono.morny + +trait IBuildInfo { + + val name : String + val version : String + val scalaVersion : String + val sbtVersion : String + val VERSION : String + val VERSION_FULL : String + val VERSION_BASE : String + val VERSION_DELTA : Option[String] + val CODENAME : String + val CODE_TIMESTAMP: Long + val COMMIT : String + val CLEAN_BUILD : Boolean + val CODE_STORE : String + val COMMIT_PATH : String + +} diff --git a/morny-core/src/main/scala/cc/sukazyo/cono/morny/core/MornyCoeur.scala b/morny-core/src/main/scala/cc/sukazyo/cono/morny/core/MornyCoeur.scala index 76ae768..3bd5953 100644 --- a/morny-core/src/main/scala/cc/sukazyo/cono/morny/core/MornyCoeur.scala +++ b/morny-core/src/main/scala/cc/sukazyo/cono/morny/core/MornyCoeur.scala @@ -194,6 +194,8 @@ class MornyCoeur (modules: List[MornyModule])(using val config: MornyConfig)(tes _httpServerContext, initializeContext))) + import bot.command.MornyInformation + private[core] val $MornyInformation = MornyInformation() { // register core/api events @@ -206,8 +208,6 @@ class MornyCoeur (modules: List[MornyModule])(using val config: MornyConfig)(tes import bot.command.* val $MornyHellos = MornyHellos() - val $MornyInformation = MornyInformation() - val $MornyInformationOlds = MornyInformationOlds(using $MornyInformation) val $MornyManagers = MornyManagers() commands.register( @@ -216,8 +216,6 @@ class MornyCoeur (modules: List[MornyModule])(using val config: MornyConfig)(tes MornyInfoOnStart(), $MornyInformation, - $MornyInformationOlds.Version, - $MornyInformationOlds.Runtime, $MornyManagers.SaveData, $MornyManagers.Reload, $MornyManagers.Exit, @@ -227,6 +225,7 @@ class MornyCoeur (modules: List[MornyModule])(using val config: MornyConfig)(tes errorMessageManager.ShowErrorMessageCommand, ) + commands.register($MornyInformation.toplevelCommands*) // register core utils events eventManager register $MornyHellos.PrivateChat_O diff --git a/morny-core/src/main/scala/cc/sukazyo/cono/morny/core/bot/api/MornyCommandManager.scala b/morny-core/src/main/scala/cc/sukazyo/cono/morny/core/bot/api/MornyCommandManager.scala index d3ca87e..cbc22ca 100644 --- a/morny-core/src/main/scala/cc/sukazyo/cono/morny/core/bot/api/MornyCommandManager.scala +++ b/morny-core/src/main/scala/cc/sukazyo/cono/morny/core/bot/api/MornyCommandManager.scala @@ -19,14 +19,7 @@ object MornyCommandManager: class MornyCommandManager (using coeur: MornyCoeur) extends SimpleCommandManager { private given TelegramBot = coeur.account - def execute (using command: InputCommand, event: Update): Boolean = { - if (commands contains command.command) - commands(command.command) execute; - true - else nonCommandExecutable - } - - private def nonCommandExecutable (using command: InputCommand, event: Update): Boolean = { + protected override def nonCommandExecutable (using command: InputCommand, event: Update): Boolean = { if command.target eq null then false else SendSticker( diff --git a/morny-core/src/main/scala/cc/sukazyo/cono/morny/core/bot/api/SimpleCommandManager.scala b/morny-core/src/main/scala/cc/sukazyo/cono/morny/core/bot/api/SimpleCommandManager.scala index 158f041..63db233 100644 --- a/morny-core/src/main/scala/cc/sukazyo/cono/morny/core/bot/api/SimpleCommandManager.scala +++ b/morny-core/src/main/scala/cc/sukazyo/cono/morny/core/bot/api/SimpleCommandManager.scala @@ -1,10 +1,19 @@ package cc.sukazyo.cono.morny.core.bot.api import cc.sukazyo.cono.morny.core.bot.api.MornyCommandManager.CommandMap -import cc.sukazyo.cono.morny.system.telegram_api.command.ISimpleCommand +import cc.sukazyo.cono.morny.system.telegram_api.command.{InputCommand, ISimpleCommand} +import com.pengrad.telegrambot.model.Update import scala.collection.mutable +/** The most basic command manager for Telegram commands. + * + * This manager contains numbers [[ISimpleCommand]], also provides methods to register them. + * Also, it provides a method to execute a command. + * + * If the command is not found, this manager will do nothing in default. + * You can customize the behavior by overriding the method [[nonCommandExecutable]]. + */ trait SimpleCommandManager { protected val commands: CommandMap = mutable.SeqMap.empty @@ -19,4 +28,19 @@ trait SimpleCommandManager { def register [T <: ISimpleCommand] (commands: T*): Unit = for (command <- commands) doRegister(command) + def emitCommands (using command: InputCommand, event: Update): Boolean = { + if (commands contains command.command) + commands(command.command) execute; + true + else nonCommandExecutable + } + + protected def nonCommandExecutable (using command: InputCommand, event: Update): Boolean = { + false + } + +} + +object SimpleCommandManager { + def apply (): SimpleCommandManager = new SimpleCommandManager {} } diff --git a/morny-core/src/main/scala/cc/sukazyo/cono/morny/core/bot/command/MornyInformation.scala b/morny-core/src/main/scala/cc/sukazyo/cono/morny/core/bot/command/MornyInformation.scala index fb527df..52eac61 100644 --- a/morny-core/src/main/scala/cc/sukazyo/cono/morny/core/bot/command/MornyInformation.scala +++ b/morny-core/src/main/scala/cc/sukazyo/cono/morny/core/bot/command/MornyInformation.scala @@ -2,11 +2,13 @@ package cc.sukazyo.cono.morny.core.bot.command import cc.sukazyo.cono.morny.core.{MornyCoeur, MornySystem} import cc.sukazyo.cono.morny.core.bot.api.messages.{ErrorMessage, MessagingContext} +import cc.sukazyo.cono.morny.core.bot.api.SimpleCommandManager import cc.sukazyo.cono.morny.data.MornyInformation.* import cc.sukazyo.cono.morny.data.TelegramStickers import cc.sukazyo.cono.morny.system.telegram_api.formatting.TelegramParseEscape.escapeHtml as h import cc.sukazyo.cono.morny.system.telegram_api.TelegramExtensions.Requests.unsafeExecute -import cc.sukazyo.cono.morny.system.telegram_api.command.{ICommandAlias, InputCommand, ITelegramCommand} +import cc.sukazyo.cono.morny.system.telegram_api.command.{ICommandAlias, InputCommand, ISimpleCommand, ITelegramCommand} +import cc.sukazyo.cono.morny.system.telegram_api.command.ICommandAlias.HiddenAlias import cc.sukazyo.cono.morny.util.CommonFormat.{formatDate, formatDuration} import cc.sukazyo.cono.morny.util.var_text import cc.sukazyo.cono.morny.util.var_text.VarText @@ -16,43 +18,39 @@ import com.pengrad.telegrambot.request.{SendMessage, SendPhoto, SendSticker} import java.lang.System -class MornyInformation (using coeur: MornyCoeur) extends ITelegramCommand { +class MornyInformation (using coeur: MornyCoeur) extends SimpleCommandManager with ITelegramCommand { import coeur.dsl.{*, given} - private case object Subs { - val STICKERS = "stickers" - val RUNTIME = "runtime" - val VERSION = "version" - val VERSION_2 = "v" - val TASKS = "tasks" - val EVENTS = "event" - } - override val name: String = "info" override val aliases: List[ICommandAlias] = Nil override val paramRule: String = "[(version|runtime|stickers[.IDs]|tasks|event)]" override val description: String = "输出当前 Morny 的各种信息" + this.register(Info, Version, _Runtime, TasksStatus) + private[core] val toplevelCommands: List[ISimpleCommand] = List(Version_Toplevel, _Runtime) + override def execute (using command: InputCommand, event: Update): Unit = { - if (command.args isEmpty) { - echoInfo(event) - return - } + command.args.headOption match + // due to the complex of stickers.XXX subcommands + // matches all the commands that starts with "stickers" + case Some(s) if s.startsWith(Stickers.name) => + Stickers.execute + case _ => - val action: String = command.args(0) - - action match { - case s if s `startsWith` Subs.STICKERS => echoStickers - case Subs.RUNTIME => echoRuntime - case Subs.VERSION | Subs.VERSION_2 => echoVersion - case Subs.TASKS => echoTasksStatus - case Subs.EVENTS => echoEventStatistics - case _ => echo404 - } + this.emitCommands(using command.subcommand, event) } + override protected def nonCommandExecutable (using command: InputCommand, event: Update): Boolean = + echo404 + true + + private case object Info extends ISimpleCommand: + override val name: String = "" + override val aliases: List[ICommandAlias] = Nil + override def execute (using command: InputCommand, event: Update): Unit = + echoInfo(event) private def echoInfo (update: Update): Unit = { val cxt = MessagingContext.extract(using update.message) val cxtReplied = Option(update.message.replyToMessage).map(MessagingContext.extract(using _)) @@ -82,44 +80,77 @@ class MornyInformation (using coeur: MornyCoeur) extends ITelegramCommand { } - private def echoStickers (using command: InputCommand, event: Update): Unit = { - val mid: String|Null = - if (command.args(0) == Subs.STICKERS) { - if (command.args.length == 1) "" - else if (command.args.length == 2) command.args(1) - else null - } else if (command.args.length == 1) { - if ((command.args(0) `startsWith` s"${Subs.STICKERS}.") || (command.args(0) `startsWith` s"${Subs.STICKERS}#")) { - command.args(0) `substring` Subs.STICKERS.length+1 + private case object Stickers extends ISimpleCommand { + + override val name: String = "stickers" + override val aliases: List[ICommandAlias] = Nil + + /** Process the parameter, to find the sticker name hidden in params. + * + * Supports: + * - args is `stickers`, send all stickers + * - args is `stickers.xxx`, send the sticker named `xxx` + * - args is `stickers#xxx`, send the sticker named `xxx` + * - args is `stickers` `xxx`, send the sticker named `xxx` + * - args is `xxx`, send the sticker named `xxx` + */ + override def execute (using command: InputCommand, event: Update): Unit = { + val mid: String | Null = + if (command.args(0) == this.name) { + if (command.args.length == 1) "" + else if (command.args.length == 2) command.args(1) + else null + } else if (command.args.length == 1) { + if ((command.args(0) `startsWith` s"${this.name}.") || (command.args(0) `startsWith` s"${this.name}#")) { + command.args(0) `substring` this.name.length + 1 + } else command.args(0) } else null - } else null - if (mid == null) echo404 - else echoStickers(mid)(using event.message.chat.id, event.message.messageId) - } - - private def echoStickers (mid: String)(using send_chat: Long, send_replyTo: Int)(using Update): Unit = { - import scala.jdk.CollectionConverters.* - if (mid isEmpty) for ((_key, _file_id) <- TelegramStickers.map asScala) - echoSticker(_key, _file_id) - else { - try { - val sticker = TelegramStickers `getById` mid - echoSticker(sticker.getKey, sticker.getValue) - } catch case _: NoSuchFieldException => { - echo404 + if (mid == null) echo404 + else echoStickers(mid)(using event.message.chat.id, event.message.messageId) + } + + /** Send the sticker named mid, or send all stickers if mid is not set. + * + * - If mid is set and is a sticker name, send the specific one sticker. + * - If mid is set and is not a sticker name, send 404. + * - If mid is not set, send all stickers that available in [[TelegramStickers]]. + */ + private def echoStickers (mid: String)(using send_chat: Long, send_replyTo: Int)(using Update): Unit = { + import scala.jdk.CollectionConverters.* + if (mid isEmpty) for ((_key, _file_id) <- TelegramStickers.map asScala) + sent(_key, _file_id) + else { + try { + val sticker = TelegramStickers `getById` mid + sent(sticker.getKey, sticker.getValue) + } catch case _: NoSuchFieldException => { + echo404 + } } } + + /** Send the specific sticker to telegram. */ + private def sent (mid: String, file_id: String)(using send_chat: Long, send_replyTo: Int): Unit = { + val send_mid = SendMessage(send_chat, mid) + val send_sticker = SendSticker(send_chat, file_id) + if (send_replyTo != -1) send_mid.replyToMessageId(send_replyTo) + val result_send_mid = send_mid.unsafeExecute + send_sticker.replyToMessageId(result_send_mid.message.messageId) + send_sticker.unsafeExecute + } + } - private def echoSticker (mid: String, file_id: String)(using send_chat: Long, send_replyTo: Int): Unit = { - val send_mid = SendMessage(send_chat, mid) - val send_sticker = SendSticker(send_chat, file_id) - if (send_replyTo != -1) send_mid.replyToMessageId(send_replyTo) - val result_send_mid = send_mid.unsafeExecute - send_sticker.replyToMessageId(result_send_mid.message.messageId) - send_sticker.unsafeExecute - } - + case object Version extends ISimpleCommand: + override val name: String = "version" + override val aliases: List[ICommandAlias] = List(HiddenAlias("v")) + override def execute (using command: InputCommand, event: Update): Unit = + echoVersion + private case object Version_Toplevel extends ISimpleCommand: + override val name: String = "version" + override val aliases: List[ICommandAlias] = Nil + override def execute (using command: InputCommand, event: Update): Unit = + echoVersion private[command] def echoVersion (using event: Update): Unit = { val versionDeltaHTML = MornySystem.VERSION_DELTA match {case Some(d) => s"-δ${h(d)}" case None => ""} val versionGitHTML = if (MornySystem.GIT_COMMIT nonEmpty) s"git $getVersionGitTagHTML" else "" @@ -149,6 +180,11 @@ class MornyInformation (using coeur: MornyCoeur) extends ITelegramCommand { .unsafeExecute } + private case object _Runtime extends ISimpleCommand: + override val name: String = "runtime" + override val aliases: List[ICommandAlias] = Nil + override def execute (using command: InputCommand, event: Update): Unit = + echoRuntime private[command] def echoRuntime (using event: Update): Unit = { def sysprop (p: String): String = System.getProperty(p) SendMessage( @@ -199,6 +235,11 @@ class MornyInformation (using coeur: MornyCoeur) extends ITelegramCommand { .unsafeExecute } + private case object TasksStatus extends ISimpleCommand: + override val name: String = "tasks" + override val aliases: List[ICommandAlias] = Nil + override def execute (using command: InputCommand, event: Update): Unit = + echoTasksStatus private def echoTasksStatus (using update: Update): Unit = { // if !coeur.trusted.isTrusted(update.message.from.id) then return; SendMessage( @@ -217,26 +258,6 @@ class MornyInformation (using coeur: MornyCoeur) extends ITelegramCommand { ) ).parseMode(ParseMode.HTML).replyToMessageId(update.message.messageId) .unsafeExecute - } - - // todo: fix this - private def echoEventStatistics (using update: Update): Unit = { -// coeur.externalContext >> { (reporter: MornyReport) => -// SendMessage( -// update.message.chat.id, -// VarText( -// // language=html -// """Event Statistics : -// |in today -// |{event_statistics}""".stripMargin -// ).render( -// "event_statistics" -> reporter.EventStatistics.eventStatisticsHTML -// ) -// ).parseMode(ParseMode.HTML).replyToMessageId(update.message.messageId) -// .unsafeExecute -// } || { -// echo404 -// } } private def echo404 (using event: Update): Unit = @@ -247,3 +268,10 @@ class MornyInformation (using coeur: MornyCoeur) extends ITelegramCommand { .unsafeExecute } + +object MornyInformation { + + def inCoeur (using coeur: MornyCoeur): MornyInformation = + coeur.$MornyInformation + +} diff --git a/morny-core/src/main/scala/cc/sukazyo/cono/morny/core/bot/command/MornyInformationOlds.scala b/morny-core/src/main/scala/cc/sukazyo/cono/morny/core/bot/command/MornyInformationOlds.scala deleted file mode 100644 index b919957..0000000 --- a/morny-core/src/main/scala/cc/sukazyo/cono/morny/core/bot/command/MornyInformationOlds.scala +++ /dev/null @@ -1,18 +0,0 @@ -package cc.sukazyo.cono.morny.core.bot.command - -import cc.sukazyo.cono.morny.system.telegram_api.command.{ICommandAlias, InputCommand, ISimpleCommand} -import com.pengrad.telegrambot.model.Update - -class MornyInformationOlds (using base: MornyInformation) { - - object Version extends ISimpleCommand: - override val name: String = "version" - override val aliases: List[ICommandAlias] = Nil - override def execute (using command: InputCommand, event: Update): Unit = base.echoVersion - - object Runtime extends ISimpleCommand: - override val name: String = "runtime" - override val aliases: List[ICommandAlias] = Nil - override def execute (using command: InputCommand, event: Update): Unit = base.echoRuntime - -} diff --git a/morny-core/src/main/scala/cc/sukazyo/cono/morny/core/bot/event/MornyOnTelegramCommand.scala b/morny-core/src/main/scala/cc/sukazyo/cono/morny/core/bot/event/MornyOnTelegramCommand.scala index c95d915..77de756 100644 --- a/morny-core/src/main/scala/cc/sukazyo/cono/morny/core/bot/event/MornyOnTelegramCommand.scala +++ b/morny-core/src/main/scala/cc/sukazyo/cono/morny/core/bot/event/MornyOnTelegramCommand.scala @@ -30,7 +30,7 @@ class MornyOnTelegramCommand (using commandManager: MornyCommandManager) (using logger `debug` "not morny command" else logger `debug` "is command" - if commandManager.execute(using inputCommand) then + if commandManager.emitCommands(using inputCommand) then setEventOk } diff --git a/morny-system-lib/src/main/scala/cc/sukazyo/cono/morny/system/telegram_api/command/InputCommand.scala b/morny-system-lib/src/main/scala/cc/sukazyo/cono/morny/system/telegram_api/command/InputCommand.scala index 2082cc8..81d706b 100644 --- a/morny-system-lib/src/main/scala/cc/sukazyo/cono/morny/system/telegram_api/command/InputCommand.scala +++ b/morny-system-lib/src/main/scala/cc/sukazyo/cono/morny/system/telegram_api/command/InputCommand.scala @@ -9,13 +9,40 @@ class InputCommand private ( ) { override def toString: String = - s"{{$command}@{$target}#{${args.mkString}}" +// s"{{$command}@{$target}#{${args.mkString}}" + s"/$command${if target != null then s"@$target" else ""} ${args.mkString(" ")}" + + def subcommand: InputCommand = + InputCommand(args, target) } object InputCommand { - def apply (input: Array[String]): InputCommand = { + private final val TARGET_DEFAULT: String|Null = null + + def apply (input: Array[String], target: String|Null): InputCommand = { + new InputCommand( + target, + input.headOption.getOrElse(""), + input drop 1 + ) + } + + def apply (input: Array[String]): InputCommand = + InputCommand(input, TARGET_DEFAULT) + + def apply (input: String): InputCommand = + InputCommand(UniversalCommand.Lossy(input)) + + def apply (input: String, target: String|Null): InputCommand = + InputCommand(UniversalCommand.Lossy(input), target) + + def inTelegram (input: String): InputCommand = { + inTelegram(UniversalCommand.Lossy(input)) + } + + def inTelegram (input: Array[String]): InputCommand = { val _ex = if input.nonEmpty then input(0).split("@", 2) else Array.empty[String] val _args = input drop 1 new InputCommand( @@ -25,8 +52,4 @@ object InputCommand { ) } - //noinspection NoTailRecursionAnnotation - def apply (input: String): InputCommand = - InputCommand(UniversalCommand.Lossy(input)) - }