diff --git a/project/MornyConfiguration.scala b/project/MornyConfiguration.scala
index 98ea059..772a4d1 100644
--- a/project/MornyConfiguration.scala
+++ b/project/MornyConfiguration.scala
@@ -8,7 +8,7 @@ object MornyConfiguration {
val MORNY_CODE_STORE = "https://github.com/Eyre-S/Coeur-Morny-Cono"
val MORNY_COMMIT_PATH = "https://github.com/Eyre-S/Coeur-Morny-Cono/commit/%s"
- val VERSION = "2.0.0-alpha7"
+ val VERSION = "2.0.0-alpha8"
val VERSION_DELTA: Option[String] = None
val CODENAME = "guanggu"
diff --git a/src/main/scala/cc/sukazyo/cono/morny/MornyCoeur.scala b/src/main/scala/cc/sukazyo/cono/morny/MornyCoeur.scala
index bde5b4f..bbadf99 100644
--- a/src/main/scala/cc/sukazyo/cono/morny/MornyCoeur.scala
+++ b/src/main/scala/cc/sukazyo/cono/morny/MornyCoeur.scala
@@ -1,12 +1,12 @@
package cc.sukazyo.cono.morny
import cc.sukazyo.cono.morny.bot.command.MornyCommandManager
-import cc.sukazyo.cono.morny.daemon.MornyDaemons
import cc.sukazyo.cono.morny.Log.{exceptionLog, logger}
import cc.sukazyo.cono.morny.MornyCoeur.*
import cc.sukazyo.cono.morny.bot.api.EventListenerManager
import cc.sukazyo.cono.morny.bot.event.{MornyOnInlineQuery, MornyOnTelegramCommand, MornyOnUpdateTimestampOffsetLock}
import cc.sukazyo.cono.morny.bot.query.MornyQueryManager
+import cc.sukazyo.cono.morny.reporter.MornyReport
import cc.sukazyo.cono.morny.util.schedule.Scheduler
import cc.sukazyo.cono.morny.util.EpochDateTime.EpochMillis
import cc.sukazyo.cono.morny.util.time.WatchDog
@@ -111,6 +111,14 @@ class MornyCoeur (modules: List[MornyModule])(using val config: MornyConfig)(tes
given MornyCoeur = this
val externalContext: GivenContext = GivenContext()
+ import util.dataview.Table.format as fmtTable
+ logger info
+ s"""The following Modules have been added to current Morny:
+ |${fmtTable(
+ ("Module ID" :: "Module Name" :: "Module Version" :: Nil)::Nil :::
+ modules.map(f => f.id :: f.name :: f.version :: Nil)
+ ).replaceAll("\n", "\n|")}
+ |""".stripMargin
///>>> BLOCK START instance configure & startup stage 1
@@ -156,8 +164,6 @@ class MornyCoeur (modules: List[MornyModule])(using val config: MornyConfig)(tes
/** current Morny's [[MornyTrusted]] instance */
val trusted: MornyTrusted = MornyTrusted()
- val daemons: MornyDaemons = MornyDaemons()
- initializeContext << daemons
val eventManager: EventListenerManager = EventListenerManager()
val commands: MornyCommandManager = MornyCommandManager()
val queries: MornyQueryManager = MornyQueryManager()
@@ -192,7 +198,7 @@ class MornyCoeur (modules: List[MornyModule])(using val config: MornyConfig)(tes
$MornyManagers.Exit,
DirectMsgClear(),
-
+
)
}
@@ -203,7 +209,6 @@ class MornyCoeur (modules: List[MornyModule])(using val config: MornyConfig)(tes
eventManager, commands, queries,
initializeContext)))
- eventManager register daemons.reporter.EventStatistics.EventInfoCatcher
val watchDog: WatchDog = WatchDog("watch-dog", 1000, 1500, { (consumed, _) =>
import cc.sukazyo.cono.morny.util.CommonFormat.formatDuration as f
logger warn
@@ -234,7 +239,6 @@ class MornyCoeur (modules: List[MornyModule])(using val config: MornyConfig)(tes
modules.foreach(it => it.onStarting(OnStartingContext(
initializeContext)))
- daemons.start()
logger info "start telegram event listening"
import com.pengrad.telegrambot.TelegramException
account.setUpdatesListener(eventManager, (e: TelegramException) => {
@@ -254,7 +258,7 @@ class MornyCoeur (modules: List[MornyModule])(using val config: MornyConfig)(tes
| server responses:
|${GsonBuilder().setPrettyPrinting().create.toJson(e.response) indent 4}
|""".stripMargin
- this.daemons.reporter.exception(e, "Failed get updates.")
+ externalContext.consume[MornyReport](_.exception(e, "Failed get updates."))
}
if (e.getCause != null) {
@@ -278,7 +282,7 @@ class MornyCoeur (modules: List[MornyModule])(using val config: MornyConfig)(tes
logger error
s"""Failed get updates:
|${exceptionLog(e_other) indent 3}""".stripMargin
- this.daemons.reporter.exception(e_other, "Failed get updates.")
+ externalContext.consume[MornyReport](_.exception(e_other, "Failed get updates."))
}
})
@@ -291,7 +295,6 @@ class MornyCoeur (modules: List[MornyModule])(using val config: MornyConfig)(tes
logger info "resetting telegram command list"
commands.automaticTGListUpdate()
- daemons.reporter.reportCoeurMornyLogin()
initializeContext = null
logger info "Coeur start complete."
@@ -303,17 +306,26 @@ class MornyCoeur (modules: List[MornyModule])(using val config: MornyConfig)(tes
}
private def exitCleanup (): Unit = {
- daemons.reporter.reportCoeurExit()
+
+ // Morny Exiting
modules.foreach(it => it.onExiting)
- account.shutdown()
- logger info "stopped bot account"
- daemons.stop()
+
+ account.removeGetUpdatesListener()
+ logger info "stopped bot update listener"
tasks.waitForStop()
logger info s"morny tasks stopped: remains ${tasks.amount} tasks not be executed"
+
+ // Morny Exiting Post
if config.commandLogoutClear then
commands.automaticTGListRemove()
+ modules.foreach(it => it.onExitingPost)
+
+ account.shutdown()
+ logger info "stopped bot account"
+ // Morny Exited
modules.foreach(it => it.onExited)
- logger info "done exit cleanup"
+ logger info "done exit cleanup\nMorny will EXIT now"
+
}
private def configure_exitCleanup (): Unit = {
diff --git a/src/main/scala/cc/sukazyo/cono/morny/MornyModule.scala b/src/main/scala/cc/sukazyo/cono/morny/MornyModule.scala
index d50b1f2..d0d6b43 100644
--- a/src/main/scala/cc/sukazyo/cono/morny/MornyModule.scala
+++ b/src/main/scala/cc/sukazyo/cono/morny/MornyModule.scala
@@ -20,6 +20,7 @@ trait MornyModule {
def onRoutineSavingData (using MornyCoeur): Unit = {}
def onExiting (using MornyCoeur): Unit = {}
+ def onExitingPost (using MornyCoeur): Unit = {}
def onExited (using MornyCoeur): Unit = {}
}
diff --git a/src/main/scala/cc/sukazyo/cono/morny/ServerMain.scala b/src/main/scala/cc/sukazyo/cono/morny/ServerMain.scala
index 383277b..06f0335 100644
--- a/src/main/scala/cc/sukazyo/cono/morny/ServerMain.scala
+++ b/src/main/scala/cc/sukazyo/cono/morny/ServerMain.scala
@@ -9,7 +9,7 @@ import java.util.TimeZone
import scala.collection.mutable.ArrayBuffer
import scala.language.postfixOps
-object ServerMain {
+object ServerMain {
val tz: TimeZone = TimeZone getDefault
val tz_offset: ZoneOffset = ZoneOffset ofTotalSeconds (tz.getRawOffset/1000)
diff --git a/src/main/scala/cc/sukazyo/cono/morny/ServerModulesLoader.scala b/src/main/scala/cc/sukazyo/cono/morny/ServerModulesLoader.scala
index 8625440..28f168b 100644
--- a/src/main/scala/cc/sukazyo/cono/morny/ServerModulesLoader.scala
+++ b/src/main/scala/cc/sukazyo/cono/morny/ServerModulesLoader.scala
@@ -16,7 +16,8 @@ object ServerModulesLoader {
social_share.ModuleSocialShare(),
medication_timer.ModuleMedicationTimer(),
morny_misc.ModuleMornyMisc(),
- uni_meow.ModuleUniMeow()
+ uni_meow.ModuleUniMeow(),
+ reporter.Module()
)
diff --git a/src/main/scala/cc/sukazyo/cono/morny/bot/api/EventListenerManager.scala b/src/main/scala/cc/sukazyo/cono/morny/bot/api/EventListenerManager.scala
index 7a810f4..dab29d9 100644
--- a/src/main/scala/cc/sukazyo/cono/morny/bot/api/EventListenerManager.scala
+++ b/src/main/scala/cc/sukazyo/cono/morny/bot/api/EventListenerManager.scala
@@ -2,6 +2,7 @@ package cc.sukazyo.cono.morny.bot.api
import cc.sukazyo.cono.morny.{Log, MornyCoeur}
import cc.sukazyo.cono.morny.Log.{exceptionLog, logger}
+import cc.sukazyo.cono.morny.reporter.MornyReport
import cc.sukazyo.cono.morny.util.tgapi.event.EventRuntimeException
import com.google.gson.GsonBuilder
import com.pengrad.telegrambot.model.Update
@@ -87,7 +88,7 @@ class EventListenerManager (using coeur: MornyCoeur) extends UpdatesListener {
) indent 4) ++= "\n"
case _ =>
logger error errorMessage.toString
- coeur.daemons.reporter.exception(e, "on event running")
+ coeur.externalContext.consume[MornyReport](_.exception(e, "on event running"))
}
}
diff --git a/src/main/scala/cc/sukazyo/cono/morny/bot/command/MornyInformation.scala b/src/main/scala/cc/sukazyo/cono/morny/bot/command/MornyInformation.scala
index fb683ad..36f9e2e 100644
--- a/src/main/scala/cc/sukazyo/cono/morny/bot/command/MornyInformation.scala
+++ b/src/main/scala/cc/sukazyo/cono/morny/bot/command/MornyInformation.scala
@@ -3,6 +3,7 @@ package cc.sukazyo.cono.morny.bot.command
import cc.sukazyo.cono.morny.{MornyCoeur, MornySystem}
import cc.sukazyo.cono.morny.data.MornyInformation.*
import cc.sukazyo.cono.morny.data.TelegramStickers
+import cc.sukazyo.cono.morny.reporter.MornyReport
import cc.sukazyo.cono.morny.util.CommonFormat.{formatDate, formatDuration}
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h
import cc.sukazyo.cono.morny.util.tgapi.InputCommand
@@ -162,13 +163,17 @@ class MornyInformation (using coeur: MornyCoeur) extends ITelegramCommand {
}
private def echoEventStatistics (using update: Update): Unit = {
- coeur.account exec SendMessage(
- update.message.chat.id,
- // language=html
- s"""Event Statistics :
- |in today
- |${coeur.daemons.reporter.EventStatistics.eventStatisticsHTML}""".stripMargin
- ).parseMode(ParseMode.HTML).replyToMessageId(update.message.messageId)
+ coeur.externalContext >> { (reporter: MornyReport) =>
+ coeur.account exec SendMessage(
+ update.message.chat.id,
+ // language=html
+ s"""Event Statistics :
+ |in today
+ |${reporter.EventStatistics.eventStatisticsHTML}""".stripMargin
+ ).parseMode(ParseMode.HTML).replyToMessageId(update.message.messageId)
+ } || {
+ echo404
+ }
}
private def echo404 (using event: Update): Unit =
diff --git a/src/main/scala/cc/sukazyo/cono/morny/bot/command/MornyManagers.scala b/src/main/scala/cc/sukazyo/cono/morny/bot/command/MornyManagers.scala
index 2dc8f60..e833843 100644
--- a/src/main/scala/cc/sukazyo/cono/morny/bot/command/MornyManagers.scala
+++ b/src/main/scala/cc/sukazyo/cono/morny/bot/command/MornyManagers.scala
@@ -3,7 +3,7 @@ import cc.sukazyo.cono.morny.bot.command.ICommandAlias.HiddenAlias
import cc.sukazyo.cono.morny.MornyCoeur
import cc.sukazyo.cono.morny.data.TelegramStickers
import cc.sukazyo.cono.morny.Log.logger
-import cc.sukazyo.cono.morny.daemon.MornyReport
+import cc.sukazyo.cono.morny.reporter.MornyReport
import cc.sukazyo.cono.morny.util.tgapi.InputCommand
import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramFormatter.*
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
@@ -41,7 +41,7 @@ class MornyManagers (using coeur: MornyCoeur) {
TelegramStickers ID_403
).replyToMessageId(event.message.messageId)
logger attention s"403 exit caught from user ${user toLogTag}"
- coeur.daemons.reporter.unauthenticatedAction("/exit", user)
+ coeur.externalContext.consume[MornyReport](_.unauthenticatedAction("/exit", user))
}
@@ -76,7 +76,7 @@ class MornyManagers (using coeur: MornyCoeur) {
TelegramStickers ID_403
).replyToMessageId(event.message.messageId)
logger attention s"403 save caught from user ${user toLogTag}"
- coeur.daemons.reporter.unauthenticatedAction("/save", user)
+ coeur.externalContext.consume[MornyReport](_.unauthenticatedAction("/save", user))
}
diff --git a/src/main/scala/cc/sukazyo/cono/morny/daemon/MornyDaemons.scala b/src/main/scala/cc/sukazyo/cono/morny/daemon/MornyDaemons.scala
deleted file mode 100644
index cfef7b8..0000000
--- a/src/main/scala/cc/sukazyo/cono/morny/daemon/MornyDaemons.scala
+++ /dev/null
@@ -1,29 +0,0 @@
-package cc.sukazyo.cono.morny.daemon
-
-import cc.sukazyo.cono.morny.Log.logger
-import cc.sukazyo.cono.morny.MornyCoeur
-
-class MornyDaemons (using val coeur: MornyCoeur) {
-
- val reporter: MornyReport = MornyReport()
-
- def start (): Unit = {
-
- logger notice "ALL Morny Daemons starting..."
-
- reporter.start()
-
- logger notice "Morny Daemons started."
-
- }
-
- def stop (): Unit = {
-
- logger notice "stopping All Morny Daemons..."
-
- reporter.stop()
-
- logger notice "stopped ALL Morny Daemons."
- }
-
-}
diff --git a/src/main/scala/cc/sukazyo/cono/morny/data/TelegramImages.scala b/src/main/scala/cc/sukazyo/cono/morny/data/TelegramImages.scala
index ac45039..e6362d4 100644
--- a/src/main/scala/cc/sukazyo/cono/morny/data/TelegramImages.scala
+++ b/src/main/scala/cc/sukazyo/cono/morny/data/TelegramImages.scala
@@ -1,8 +1,6 @@
package cc.sukazyo.cono.morny.data
-import cc.sukazyo.cono.morny.Log.{exceptionLog, logger}
import cc.sukazyo.cono.morny.MornyAssets
-import cc.sukazyo.cono.morny.daemon.MornyReport
import cc.sukazyo.cono.morny.MornyAssets.AssetsException
import java.io.IOException
diff --git a/src/main/scala/cc/sukazyo/cono/morny/encrypt_tool/Encryptor.scala b/src/main/scala/cc/sukazyo/cono/morny/encrypt_tool/Encryptor.scala
index 5fb9989..1292b87 100644
--- a/src/main/scala/cc/sukazyo/cono/morny/encrypt_tool/Encryptor.scala
+++ b/src/main/scala/cc/sukazyo/cono/morny/encrypt_tool/Encryptor.scala
@@ -5,6 +5,7 @@ import cc.sukazyo.cono.morny.MornyCoeur
import cc.sukazyo.cono.morny.bot.command.{ICommandAlias, ITelegramCommand}
import cc.sukazyo.cono.morny.bot.command.ICommandAlias.ListedAlias
import cc.sukazyo.cono.morny.data.TelegramStickers
+import cc.sukazyo.cono.morny.reporter.MornyReport
import cc.sukazyo.cono.morny.util.tgapi.InputCommand
import cc.sukazyo.cono.morny.util.CommonEncrypt
import cc.sukazyo.cono.morny.util.CommonEncrypt.*
@@ -81,7 +82,7 @@ class Encryptor (using coeur: MornyCoeur) extends ITelegramCommand {
_r.document.fileName
)} catch case e: IOException =>
logger warn s"NetworkRequest error: TelegramFileAPI:\n\t${e.getMessage}"
- coeur.daemons.reporter.exception(e, "NetworkRequest error: TelegramFileAPI")
+ coeur.externalContext.consume[MornyReport](_.exception(e, "NetworkRequest error: TelegramFileAPI"))
return
} else if ((_r ne null) && (_r.photo ne null)) {
try {
@@ -102,11 +103,11 @@ class Encryptor (using coeur: MornyCoeur) extends ITelegramCommand {
case e: IOException =>
//noinspection DuplicatedCode
logger warn s"NetworkRequest error: TelegramFileAPI:\n\t${e.getMessage}"
- coeur.daemons.reporter.exception(e, "NetworkRequest error: TelegramFileAPI")
+ coeur.externalContext.consume[MornyReport](_.exception(e, "NetworkRequest error: TelegramFileAPI"))
return
case e: IllegalArgumentException =>
logger warn s"FileProcess error: PhotoSize:\n\t${e.getMessage}"
- coeur.daemons.reporter.exception(e, "FileProcess error: PhotoSize")
+ coeur.externalContext.consume[MornyReport](_.exception(e, "FileProcess error: PhotoSize"))
return
} else if ((_r ne null) && (_r.text ne null)) {
XText(_r.text)
diff --git a/src/main/scala/cc/sukazyo/cono/morny/reporter/Module.scala b/src/main/scala/cc/sukazyo/cono/morny/reporter/Module.scala
new file mode 100644
index 0000000..22a6fde
--- /dev/null
+++ b/src/main/scala/cc/sukazyo/cono/morny/reporter/Module.scala
@@ -0,0 +1,70 @@
+package cc.sukazyo.cono.morny.reporter
+
+import cc.sukazyo.cono.morny.internal.MornyInternalModule
+import cc.sukazyo.cono.morny.Log.logger
+import cc.sukazyo.cono.morny.MornyCoeur
+
+class Module extends MornyInternalModule {
+
+ override val id: String = "morny.report"
+ override val name: String = "Morny/Coeur Reporter"
+ override val description: String | Null =
+ """Report crucial messages to a Telegram channel.
+ |""".stripMargin
+
+ description.take(description.indexOf("\n"))
+
+ override def onInitializingPre (using MornyCoeur)(cxt: MornyCoeur.OnInitializingPreContext): Unit = {
+ import cxt.*
+
+ val instance = MornyReport()
+ externalContext << instance
+ givenCxt << instance
+
+ }
+
+ override def onInitializing (using MornyCoeur)(cxt: MornyCoeur.OnInitializingContext): Unit = {
+ import cxt.*
+
+ externalContext >> { (instance: MornyReport) =>
+ logger info "MornyReport will now collect your bot event statistics."
+ eventManager register instance.EventStatistics.EventInfoCatcher
+ } || {
+ logger warn "There seems no reporter instance is provided; skipped register events for it."
+ }
+
+ }
+
+ override def onStarting (using coeur: MornyCoeur)(cxt: MornyCoeur.OnStartingContext): Unit = {
+ import coeur.externalContext
+ externalContext >> { (instance: MornyReport) =>
+ instance.start()
+ } || {
+ logger warn "There seems no reporter instance is provided; skipped start it."
+ }
+ }
+
+ override def onStartingPost (using coeur: MornyCoeur)(cxt: MornyCoeur.OnStartingPostContext): Unit = {
+ import coeur.externalContext
+ externalContext >> { (instance: MornyReport) =>
+ instance.reportCoeurMornyLogin()
+ }
+ }
+
+ override def onExiting (using coeur: MornyCoeur): Unit = {
+ import coeur.externalContext
+ externalContext >> { (instance: MornyReport) =>
+ instance.stop()
+ } || {
+ logger warn "There seems no reporter instance need to be stop."
+ }
+ }
+
+ override def onExitingPost (using coeur: MornyCoeur): Unit = {
+ import coeur.externalContext
+ externalContext >> { (instance: MornyReport) =>
+ instance.reportCoeurExit()
+ }
+ }
+
+}
diff --git a/src/main/scala/cc/sukazyo/cono/morny/daemon/MornyReport.scala b/src/main/scala/cc/sukazyo/cono/morny/reporter/MornyReport.scala
similarity index 99%
rename from src/main/scala/cc/sukazyo/cono/morny/daemon/MornyReport.scala
rename to src/main/scala/cc/sukazyo/cono/morny/reporter/MornyReport.scala
index 0fd7a2e..00c888e 100644
--- a/src/main/scala/cc/sukazyo/cono/morny/daemon/MornyReport.scala
+++ b/src/main/scala/cc/sukazyo/cono/morny/reporter/MornyReport.scala
@@ -1,4 +1,4 @@
-package cc.sukazyo.cono.morny.daemon
+package cc.sukazyo.cono.morny.reporter
import cc.sukazyo.cono.morny.{MornyCoeur, MornyConfig}
import cc.sukazyo.cono.morny.Log.{exceptionLog, logger}
diff --git a/src/main/scala/cc/sukazyo/cono/morny/social_share/event/OnGetSocial.scala b/src/main/scala/cc/sukazyo/cono/morny/social_share/event/OnGetSocial.scala
index b0775ad..726fe21 100644
--- a/src/main/scala/cc/sukazyo/cono/morny/social_share/event/OnGetSocial.scala
+++ b/src/main/scala/cc/sukazyo/cono/morny/social_share/event/OnGetSocial.scala
@@ -6,6 +6,7 @@ import cc.sukazyo.cono.morny.data.TelegramStickers
import cc.sukazyo.cono.morny.social_share.event.OnGetSocial.tryFetchSocial
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec
import cc.sukazyo.cono.morny.Log.{exceptionLog, logger}
+import cc.sukazyo.cono.morny.reporter.MornyReport
import cc.sukazyo.cono.morny.social_share.api.{SocialTwitterParser, SocialWeiboParser}
import cc.sukazyo.cono.morny.social_share.external.{twitter, weibo}
import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Message.entitiesSafe
@@ -87,7 +88,7 @@ object OnGetSocial {
).replyToMessageId(replyToMessage)
logger error
"Error on requesting FixTweet API\n" + exceptionLog(e)
- coeur.daemons.reporter.exception(e, "Error on requesting FixTweet API")
+ coeur.externalContext.consume[MornyReport](_.exception(e, "Error on requesting FixTweet API"))
def tryFetchSocialOfWeibo (url: weibo.StatusUrlInfo)(using replyChat: Long, replyToMessage: Int)(using coeur: MornyCoeur) =
import cc.sukazyo.cono.morny.social_share.external.weibo.MApi
@@ -111,6 +112,6 @@ object OnGetSocial {
).replyToMessageId(replyToMessage)
logger error
"Error on requesting Weibo m.API\n" + exceptionLog(e)
- coeur.daemons.reporter.exception(e, "Error on requesting Weibo m.API")
+ coeur.externalContext.consume[MornyReport](_.exception(e, "Error on requesting Weibo m.API"))
}
diff --git a/src/main/scala/cc/sukazyo/cono/morny/social_share/query/ShareToolBilibili.scala b/src/main/scala/cc/sukazyo/cono/morny/social_share/query/ShareToolBilibili.scala
index 6ba9ba2..c44483d 100644
--- a/src/main/scala/cc/sukazyo/cono/morny/social_share/query/ShareToolBilibili.scala
+++ b/src/main/scala/cc/sukazyo/cono/morny/social_share/query/ShareToolBilibili.scala
@@ -4,6 +4,7 @@ import cc.sukazyo.cono.morny.MornyCoeur
import cc.sukazyo.cono.morny.util.tgapi.formatting.NamingUtils.inlineQueryId
import cc.sukazyo.cono.morny.Log.{exceptionLog, logger}
import cc.sukazyo.cono.morny.bot.query.{InlineQueryUnit, ITelegramQuery}
+import cc.sukazyo.cono.morny.reporter.MornyReport
import com.pengrad.telegrambot.model.Update
import com.pengrad.telegrambot.model.request.{InlineQueryResultArticle, InputTextMessageContent, ParseMode}
@@ -17,7 +18,6 @@ class ShareToolBilibili (using coeur: MornyCoeur) extends ITelegramQuery {
private val ID_PREFIX_BILI_AV = "[morny/share/bili/av]"
private val ID_PREFIX_BILI_BV = "[morny/share/bili/bv]"
private val LINK_PREFIX = "https://bilibili.com/video/"
- private val REGEX_BILI_VIDEO: Regex = "^(?:(?:https?://)?(?:www\\.)?bilibili\\.com(?:/s)?/video/((?:av|AV)(\\d{1,12})|(?:bv|BV)([A-HJ-NP-Za-km-z1-9]{10}))/?(\\?(?:p=(\\d+))?.*)?|(?:av|AV)(\\d{1,12})|(?:bv|BV)([A-HJ-NP-Za-km-z1-9]{10}))$"r
private val SHARE_FORMAT_HTML = "%s"
override def query (event: Update): List[InlineQueryUnit[_]] | Null = {
@@ -37,7 +37,7 @@ class ShareToolBilibili (using coeur: MornyCoeur) extends ITelegramQuery {
return null;
case e: IllegalStateException =>
logger error exceptionLog(e)
- coeur.daemons.reporter.exception(e)
+ coeur.externalContext.consume[MornyReport](_.exception(e))
return null;
val av = result.av
diff --git a/src/main/scala/cc/sukazyo/cono/morny/util/dataview/Table.scala b/src/main/scala/cc/sukazyo/cono/morny/util/dataview/Table.scala
new file mode 100644
index 0000000..f4a31e9
--- /dev/null
+++ b/src/main/scala/cc/sukazyo/cono/morny/util/dataview/Table.scala
@@ -0,0 +1,20 @@
+package cc.sukazyo.cono.morny.util.dataview
+
+object Table {
+
+ def format (table: Seq[Seq[Any]]): String = {
+ if (table.isEmpty) ""
+ else {
+ // Get column widths based on the maximum cell width in each column (+2 for a one character padding on each side)
+ val colWidths = table.transpose.map(_.map(cell => if (cell == null) 0 else cell.toString.length).max + 2)
+ // Format each row
+ val rows = table.map(_.zip(colWidths).map { case (item, size) => (" %-" + (size - 1) + "s").format(item) }
+ .mkString("|", "|", "|"))
+ // Formatted separator row, used to separate the header and draw table borders
+ val separator = colWidths.map("-" * _).mkString("+", "+", "+")
+ // Put the table together and return
+ (separator +: rows.head +: separator +: rows.tail :+ separator).mkString("\n")
+ }
+ }
+
+}