Skip to content

Commit

Permalink
[[release 1.2.0*xiongan]]
Browse files Browse the repository at this point in the history
## 📇 Function & Mechanisms

- add for /encrypt
  - add urlencode / urldecode sub-command: they process text input only
  - add alias /enc
- add for InlineBilibiliShare
  - add b23.tv share-link parse
  - add b23.tv video link parse

## 🔩 for self-hosted/developer

- cha EventListener use EventEnv instead of Update
- new LogLevel NOTICE(notice) and ATTION(attention)
  - with new formatter
  • Loading branch information
Eyre-S committed Oct 18, 2023
2 parents 1b3a847 + 40bdbec commit 69e9459
Show file tree
Hide file tree
Showing 35 changed files with 603 additions and 260 deletions.
6 changes: 3 additions & 3 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@ MORNY_ARCHIVE_NAME = morny-coeur
MORNY_CODE_STORE = https://github.com/Eyre-S/Coeur-Morny-Cono
MORNY_COMMIT_PATH = https://github.com/Eyre-S/Coeur-Morny-Cono/commit/%s

VERSION = 1.1.1
VERSION = 1.2.0

USE_DELTA = false
VERSION_DELTA =

CODENAME = nanchang
CODENAME = xiongan

# dependencies

lib_spotbugs_v = 4.7.3
lib_scalamodule_xml_v = 2.2.0

lib_messiva_v = 0.1.1
lib_messiva_v = 0.2.0
lib_resourcetools_v = 0.2.2

lib_javatelegramapi_v = 6.2.0
Expand Down
2 changes: 1 addition & 1 deletion settings.gradle
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
rootProject.name = 'Coeur Morny Cono'
rootProject.name = "Coeur Morny Cono"

16 changes: 9 additions & 7 deletions src/main/scala/cc/sukazyo/cono/morny/Log.scala
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
package cc.sukazyo.cono.morny

import cc.sukazyo.cono.morny.internal.logging.{MornyFormatterConsole, MornyLoggerBase}
import cc.sukazyo.messiva.appender.ConsoleAppender
import cc.sukazyo.messiva.formatter.SimpleFormatter
import cc.sukazyo.messiva.log.LogLevel
import cc.sukazyo.messiva.log.LogLevels
import cc.sukazyo.messiva.logger.Logger

import java.io.{PrintWriter, StringWriter}

object Log {

val logger: Logger = Logger(
val logger: MornyLoggerBase = MornyLoggerBase(
ConsoleAppender(
SimpleFormatter()
MornyFormatterConsole()
)
).minLevel(LogLevel.INFO)
)
logger minLevel LogLevels.INFO

def debug: Boolean = logger.levelSetting.minLevel.level <= LogLevel.DEBUG.level
def debug: Boolean = logger.levelSetting.minLevel.level <= LogLevels.DEBUG.level

def debug(is: Boolean): Unit =
if is then logger.minLevel(LogLevel.ALL)
else logger.minLevel(LogLevel.INFO)
if is then logger.minLevel(LogLevels.ALL)
else logger.minLevel(LogLevels.INFO)

def exceptionLog (e: Throwable): String =
val stackTrace = StringWriter()
Expand Down
5 changes: 3 additions & 2 deletions src/main/scala/cc/sukazyo/cono/morny/MornyCoeur.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ class MornyCoeur (using val config: MornyConfig) {

logger info "Coeur starting..."

logger info s"args key:\n ${config.telegramBotKey}"
import cc.sukazyo.cono.morny.util.StringEnsure.deSensitive
logger info s"args key:\n ${config.telegramBotKey deSensitive 4}"
if config.telegramBotUsername ne null then
logger info s"login as:\n ${config.telegramBotUsername}"

Expand Down Expand Up @@ -92,7 +93,7 @@ class MornyCoeur (using val config: MornyConfig) {

def saveDataAll(): Unit = {
// nothing to do
logger info "done all save action."
logger notice "done all save action."
}

private def exitCleanup (): Unit = {
Expand Down
7 changes: 7 additions & 0 deletions src/main/scala/cc/sukazyo/cono/morny/ServerMain.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@ import cc.sukazyo.cono.morny.MornyConfig.CheckFailure
import cc.sukazyo.cono.morny.util.CommonFormat

import java.time.ZoneOffset
import java.util.TimeZone
import scala.collection.mutable.ArrayBuffer
import scala.language.postfixOps

object ServerMain {

val tz: TimeZone = TimeZone getDefault
val tz_offset: ZoneOffset = ZoneOffset ofTotalSeconds (tz.getRawOffset/1000)

private val THREAD_MORNY_INIT: String = "morny-init"

def main (args: Array[String]): Unit = {
Expand Down Expand Up @@ -135,6 +139,9 @@ object ServerMain {
|- Morny ${MornySystem.CODENAME toUpperCase}
|- <${MornySystem.getJarMD5}> [${BuildConfig.CODE_TIMESTAMP}]""".stripMargin

// due to [[MornyFormatterConsole]] will use a localized time, it will output to the log
logger info s"logging time will use time-zone ${tz.getID} ($tz_offset)"

///
/// Check Coeur arguments
/// finally start Coeur Program
Expand Down
37 changes: 37 additions & 0 deletions src/main/scala/cc/sukazyo/cono/morny/bot/api/EventEnv.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package cc.sukazyo.cono.morny.bot.api

import com.pengrad.telegrambot.model.Update

import scala.collection.mutable

class EventEnv (

val update: Update

) {

private var _isOk: Int = 0
private val variables: mutable.HashMap[Class[?], Any] = mutable.HashMap.empty

def isEventOk: Boolean = _isOk > 0

//noinspection UnitMethodIsParameterless
def setEventOk: Unit =
_isOk = _isOk + 1

def provide (i: Any): Unit =
variables += (i.getClass -> i)

def consume [T] (t: Class[T]) (consumer: T => Unit): ConsumeResult = {
variables get t match
case Some(i) => consumer(i.asInstanceOf[T]); ConsumeResult(true)
case None => ConsumeResult(false)
}

class ConsumeResult (success: Boolean) {
def onfail (processor: => Unit): Unit = {
if !success then processor
}
}

}
30 changes: 14 additions & 16 deletions src/main/scala/cc/sukazyo/cono/morny/bot/api/EventListener.scala
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
package cc.sukazyo.cono.morny.bot.api

import com.pengrad.telegrambot.model.Update

trait EventListener () {

def onMessage (using Update): Boolean = false
def onEditedMessage (using Update): Boolean = false
def onChannelPost (using Update): Boolean = false
def onEditedChannelPost (using Update): Boolean = false
def onInlineQuery (using Update): Boolean = false
def onChosenInlineResult (using Update): Boolean = false
def onCallbackQuery (using Update): Boolean = false
def onShippingQuery (using Update): Boolean = false
def onPreCheckoutQuery (using Update): Boolean = false
def onPoll (using Update): Boolean = false
def onPollAnswer (using Update): Boolean = false
def onMyChatMemberUpdated (using Update): Boolean = false
def onChatMemberUpdated (using Update): Boolean = false
def onChatJoinRequest (using Update): Boolean = false
def onMessage (using EventEnv): Unit = {}
def onEditedMessage (using EventEnv): Unit = {}
def onChannelPost (using EventEnv): Unit = {}
def onEditedChannelPost (using EventEnv): Unit = {}
def onInlineQuery (using EventEnv): Unit = {}
def onChosenInlineResult (using EventEnv): Unit = {}
def onCallbackQuery (using EventEnv): Unit = {}
def onShippingQuery (using EventEnv): Unit = {}
def onPreCheckoutQuery (using EventEnv): Unit = {}
def onPoll (using EventEnv): Unit = {}
def onPollAnswer (using EventEnv): Unit = {}
def onMyChatMemberUpdated (using EventEnv): Unit = {}
def onChatMemberUpdated (using EventEnv): Unit = {}
def onChatJoinRequest (using EventEnv): Unit = {}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import com.pengrad.telegrambot.UpdatesListener

import scala.collection.mutable
import scala.language.postfixOps
import scala.util.boundary

/** Contains a [[mutable.Queue]] of [[EventListener]], and delivery telegram [[Update]].
*
Expand All @@ -23,46 +24,43 @@ class EventListenerManager (using coeur: MornyCoeur) extends UpdatesListener {
def register (listeners: EventListener*): Unit =
this.listeners ++= listeners

private class EventRunner (using event: Update) extends Thread {
this setName s"evt-${event.updateId()}-nn"
private class EventRunner (using update: Update) extends Thread {
this setName s"upd-${update.updateId()}-nn"
private def updateThreadName (t: String): Unit =
this setName s"evt-${event.updateId()}-$t"
this setName s"upd-${update.updateId()}-$t"

override def run (): Unit = {
for (i <- listeners) {
object status:
var _status = 0
def isOk: Boolean = _status > 0
def check (u: Boolean): Unit = if u then _status = _status + 1
given env: EventEnv = EventEnv(update)
boundary { for (i <- listeners) {
try {
updateThreadName("message")
if event.message ne null then status check i.onMessage
if update.message ne null then i.onMessage
updateThreadName("edited-message")
if event.editedMessage ne null then status check i.onEditedMessage
if update.editedMessage ne null then i.onEditedMessage
updateThreadName("channel-post")
if event.channelPost ne null then status check i.onChannelPost
if update.channelPost ne null then i.onChannelPost
updateThreadName("edited-channel-post")
if event.editedChannelPost ne null then status check i.onEditedChannelPost
if update.editedChannelPost ne null then i.onEditedChannelPost
updateThreadName("inline-query")
if event.inlineQuery ne null then status check i.onInlineQuery
if update.inlineQuery ne null then i.onInlineQuery
updateThreadName("chosen-inline-result")
if event.chosenInlineResult ne null then status check i.onChosenInlineResult
if update.chosenInlineResult ne null then i.onChosenInlineResult
updateThreadName("callback-query")
if event.callbackQuery ne null then status check i.onCallbackQuery
if update.callbackQuery ne null then i.onCallbackQuery
updateThreadName("shipping-query")
if event.shippingQuery ne null then status check i.onShippingQuery
if update.shippingQuery ne null then i.onShippingQuery
updateThreadName("pre-checkout-query")
if event.preCheckoutQuery ne null then status check i.onPreCheckoutQuery
if update.preCheckoutQuery ne null then i.onPreCheckoutQuery
updateThreadName("poll")
if event.poll ne null then status check i.onPoll
if update.poll ne null then i.onPoll
updateThreadName("poll-answer")
if event.pollAnswer ne null then status check i.onPollAnswer
if update.pollAnswer ne null then i.onPollAnswer
updateThreadName("my-chat-member")
if event.myChatMember ne null then status check i.onMyChatMemberUpdated
if update.myChatMember ne null then i.onMyChatMemberUpdated
updateThreadName("chat-member")
if event.chatMember ne null then status check i.onChatMemberUpdated
if update.chatMember ne null then i.onChatMemberUpdated
updateThreadName("chat-join-request")
if event.chatJoinRequest ne null then status check i.onChatJoinRequest
if update.chatJoinRequest ne null then i.onChatJoinRequest
} catch case e => {
val errorMessage = StringBuilder()
errorMessage ++= "Event throws unexpected exception:\n"
Expand All @@ -77,8 +75,8 @@ class EventListenerManager (using coeur: MornyCoeur) extends UpdatesListener {
logger error errorMessage.toString
coeur.daemons.reporter.exception(e, "on event running")
}
if (status isOk) return
}
if env.isEventOk then boundary.break()
}}
}

}
Expand Down
38 changes: 28 additions & 10 deletions src/main/scala/cc/sukazyo/cono/morny/bot/command/Encryptor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cc.sukazyo.cono.morny.bot.command

import cc.sukazyo.cono.morny.Log.logger
import cc.sukazyo.cono.morny.MornyCoeur
import cc.sukazyo.cono.morny.bot.command.ICommandAlias.ListedAlias
import cc.sukazyo.cono.morny.data.TelegramStickers
import cc.sukazyo.cono.morny.util.tgapi.InputCommand
import cc.sukazyo.cono.morny.util.CommonEncrypt
Expand All @@ -13,14 +14,15 @@ import com.pengrad.telegrambot.model.request.ParseMode
import com.pengrad.telegrambot.request.{GetFile, SendDocument, SendMessage, SendSticker}

import java.io.IOException
import java.net.{URLDecoder, URLEncoder}
import java.util.Base64
import scala.language.postfixOps

/** Provides Telegram Command __`/encrypt`__. */
class Encryptor (using coeur: MornyCoeur) extends ITelegramCommand {

override val name: String = "encrypt"
override val aliases: Array[ICommandAlias] | Null = null
override val aliases: Array[ICommandAlias] | Null = Array(ListedAlias("enc"))
override val paramRule: String = "[algorithm|(l)] [(uppercase)]"
override val description: String = "通过指定算法加密回复的内容 (目前只支持文本)"

Expand Down Expand Up @@ -135,6 +137,12 @@ class Encryptor (using coeur: MornyCoeur) extends ITelegramCommand {
def genResult_hash (source: XEncryptable, processor: Array[Byte]=>Array[Byte]): EXHash =
val hashed = processor(source asByteArray) toHex;
EXHash(if mod_uppercase then hashed toUpperCase else hashed)
//noinspection UnitMethodIsParameterless
def echo_unsupported: Unit =
coeur.account exec SendSticker(
event.message.chat.id,
TelegramStickers ID_404
).replyToMessageId(event.message.messageId)
val result: EXHash|EXFile|EXText = args(0) match
case "base64" | "b64" | "base64url" | "base64u" | "b64u" =>
val _tool_b64 =
Expand All @@ -154,21 +162,27 @@ class Encryptor (using coeur: MornyCoeur) extends ITelegramCommand {
_tool_b64d.decode,
CommonEncrypt.lint_base64FileName
) } catch case _: IllegalArgumentException =>
coeur.account exec SendSticker(
event.message.chat.id,
TelegramStickers ID_404 // todo: is here better erro notify?
).replyToMessageId(event.message.messageId)
echo_unsupported
return
case "urlencoder" | "urlencode" | "urlenc" | "url" =>
input match
case x: XText =>
EXText(URLEncoder.encode(x.data, ENCRYPT_STANDARD_CHARSET))
case _: XFile => echo_unsupported; return;
case "urldecoder" | "urldecode" | "urldec" | "urld" =>
input match
case _: XFile => echo_unsupported; return;
case x: XText =>
try { EXText(URLDecoder.decode(x.data, ENCRYPT_STANDARD_CHARSET)) }
catch case _: IllegalArgumentException =>
echo_unsupported
return
case "md5" => genResult_hash(input, MD5)
case "sha1" => genResult_hash(input, SHA1)
case "sha256" => genResult_hash(input, SHA256)
case "sha512" => genResult_hash(input, SHA512)
case _ =>
coeur.account exec SendSticker(
event.message.chat.id,
TelegramStickers ID_404
).replyToMessageId(event.message.messageId)
return;
echo_unsupported; return;
// END BLOCK: encrypt

// output
Expand Down Expand Up @@ -203,6 +217,8 @@ class Encryptor (using coeur: MornyCoeur) extends ITelegramCommand {
* '''__base64url__''', base64u, b64u<br>
* '''__base64decode__''', base64d, b64d<br>
* '''__base64url-decode__''', base64ud, b64ud<br>
* '''urlencode''', urlencode, urlenc, url<br>
* '''__urldecoder__''', urldecode, urldec, urld<br>
* '''__sha1__'''<br>
* '''__sha256__'''<br>
* '''__sha512__'''<br>
Expand All @@ -218,6 +234,8 @@ class Encryptor (using coeur: MornyCoeur) extends ITelegramCommand {
|<b><u>base64url</u></b>, base64u, b64u
|<b><u>base64decode</u></b>, base64d, b64d
|<b><u>base64url-decode</u></b>, base64ud, b64ud
|<b><u>urlencoder</u></b>, urlencode, urlenc, url
|<b><u>urldecoder</u></b>, urldecode, urldec, urld
|<b><u>sha1</u></b>
|<b><u>sha256</u></b>
|<b><u>sha512</u></b>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,14 @@ class MornyCommands (using coeur: MornyCoeur) {
val listing = commands_toTelegramList
automaticTGListRemove()
coeur.account exec SetMyCommands(listing:_*)
logger info
logger notice
s"""automatic updated telegram command list :
|${commandsTelegramList_toString(listing)}""".stripMargin
}

def automaticTGListRemove (): Unit = {
coeur.account exec DeleteMyCommands()
logger info "cleaned up command list"
logger notice "cleaned up command list"
}

private def commandsTelegramList_toString (list: Array[BotCommand]): String =
Expand Down
Loading

0 comments on commit 69e9459

Please sign in to comment.