diff --git a/gradle.properties b/gradle.properties index 712262a..fd7b79b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ 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.4.0-beta.1 +VERSION = 1.4.0-beta.2 USE_DELTA = false VERSION_DELTA = diff --git a/src/main/scala/cc/sukazyo/cono/morny/bot/event/OnGetSocial.scala b/src/main/scala/cc/sukazyo/cono/morny/bot/event/OnGetSocial.scala index 7463a46..ce69f34 100644 --- a/src/main/scala/cc/sukazyo/cono/morny/bot/event/OnGetSocial.scala +++ b/src/main/scala/cc/sukazyo/cono/morny/bot/event/OnGetSocial.scala @@ -11,10 +11,13 @@ import cc.sukazyo.cono.morny.data.social.{SocialTwitterParser, SocialWeiboParser import cc.sukazyo.cono.morny.extra.BilibiliForms.{BiliB23, BiliVideoId} import cc.sukazyo.cono.morny.extra.bilibili.XWebAPI import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Message.entitiesSafe +import cc.sukazyo.cono.morny.util.CommonFormat.formatDurationTimers import com.pengrad.telegrambot.model.Chat import com.pengrad.telegrambot.model.request.ParseMode import com.pengrad.telegrambot.request.{SendMessage, SendPhoto, SendSticker} +import java.time.Duration + class OnGetSocial (using coeur: MornyCoeur) extends EventListener { override def onMessage (using event: EventEnv): Unit = { @@ -102,7 +105,8 @@ object OnGetSocial { .caption( // language=html s"""${h(video_info.data.title)} - | @${h(video_info.data.owner.name)} + | ${formatDurationTimers(Duration.ofSeconds(video_info.data.duration))} @${h(video_info.data.owner.name)} + | |${h(video_info.data.desc)}""".stripMargin ).parseMode(ParseMode.HTML) diff --git a/src/main/scala/cc/sukazyo/cono/morny/bot/query/ShareToolSocialContent.scala b/src/main/scala/cc/sukazyo/cono/morny/bot/query/ShareToolSocialContent.scala index 3006c65..3d123ba 100644 --- a/src/main/scala/cc/sukazyo/cono/morny/bot/query/ShareToolSocialContent.scala +++ b/src/main/scala/cc/sukazyo/cono/morny/bot/query/ShareToolSocialContent.scala @@ -7,9 +7,12 @@ import cc.sukazyo.cono.morny.extra.weibo.MApi import cc.sukazyo.cono.morny.extra.BilibiliForms.{BiliB23, BiliVideoId} import cc.sukazyo.cono.morny.extra.bilibili.XWebAPI import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h +import cc.sukazyo.cono.morny.util.CommonFormat.formatDurationTimers import com.pengrad.telegrambot.model.Update import com.pengrad.telegrambot.model.request.{InlineQueryResultPhoto, ParseMode} +import java.time.Duration + class ShareToolSocialContent extends ITelegramQuery { override def query (event: Update): List[InlineQueryUnit[_]] | Null = { @@ -40,7 +43,8 @@ class ShareToolSocialContent extends ITelegramQuery { ).caption( // language=html s"""${h(video_info.data.title)} - | @${h(video_info.data.owner.name)} + | ${formatDurationTimers(Duration.ofSeconds(video_info.data.duration))} @${h(video_info.data.owner.name)} + | |${h(video_info.data.desc)}""".stripMargin ).parseMode(ParseMode.HTML)) } diff --git a/src/main/scala/cc/sukazyo/cono/morny/data/social/SocialContent.scala b/src/main/scala/cc/sukazyo/cono/morny/data/social/SocialContent.scala index 3858c7e..55b9bb9 100644 --- a/src/main/scala/cc/sukazyo/cono/morny/data/social/SocialContent.scala +++ b/src/main/scala/cc/sukazyo/cono/morny/data/social/SocialContent.scala @@ -5,7 +5,6 @@ import cc.sukazyo.cono.morny.data.social.SocialContent.SocialMediaType.{Photo, V import cc.sukazyo.cono.morny.MornyCoeur import cc.sukazyo.cono.morny.bot.query.InlineQueryUnit import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec -import cc.sukazyo.cono.morny.util.tgapi.formatting.NamingUtils.inlineQueryId import com.pengrad.telegrambot.model.request.* import com.pengrad.telegrambot.request.{SendMediaGroup, SendMessage} diff --git a/src/main/scala/cc/sukazyo/cono/morny/extra/bilibili/XWebView.scala b/src/main/scala/cc/sukazyo/cono/morny/extra/bilibili/XWebView.scala index ea8875d..a9cdd1f 100644 --- a/src/main/scala/cc/sukazyo/cono/morny/extra/bilibili/XWebView.scala +++ b/src/main/scala/cc/sukazyo/cono/morny/extra/bilibili/XWebView.scala @@ -26,7 +26,7 @@ case class XWebView ( owner: XWebView.User, stat: Ignore, dynamic: String, - cid: Int, + cid: Long, dimension: Ignore, premiere: Ignore, teenage_mode: Int, diff --git a/src/main/scala/cc/sukazyo/cono/morny/util/CommonFormat.scala b/src/main/scala/cc/sukazyo/cono/morny/util/CommonFormat.scala index d562d58..3510879 100644 --- a/src/main/scala/cc/sukazyo/cono/morny/util/CommonFormat.scala +++ b/src/main/scala/cc/sukazyo/cono/morny/util/CommonFormat.scala @@ -2,8 +2,9 @@ package cc.sukazyo.cono.morny.util import cc.sukazyo.cono.morny.util.EpochDateTime.{DurationMillis, EpochMillis} -import java.time.{Instant, LocalDateTime, ZoneId, ZoneOffset} +import java.time.{Duration, Instant, LocalDateTime, ZoneId, ZoneOffset} import java.time.format.DateTimeFormatter +import java.time.temporal.ChronoUnit /** Some formatting (convert some data to some standard output type) * methods normalized based on Morny's usage @@ -35,9 +36,9 @@ object CommonFormat { * * for example, timestamp [[0]] describes 1970-1-1 00:00:00 in * UTC+0, so, use the `timestamp` `0` and `utfOffset` `0` will - * returns `"1970-1-1 00:00:00:000"`; however, at the same time, + * return `"1970-1-1 00:00:00:000"`; however, at the same time, * in UTC+8, the local time is 1970-1-1 08:00:00:000, so use - * the `timestamp` `0` and the `utcOffset` `8` will returns + * the `timestamp` `0` and the `utcOffset` `8` will return * `"1970-1-1 08:00:00:000"` * * @return the time-zone local date-time-millis [[String]] describes the timestamp. @@ -63,7 +64,7 @@ object CommonFormat { ) ) - /** human readable [[String]] that describes the millis duration. + /** human-readable [[String]] that describes the millis duration. * * {{{ * scala> formatDuration(10) @@ -88,4 +89,49 @@ object CommonFormat { sb ++= (duration % 1000).toString ++= "ms" sb toString + def formatDuration (duration: Duration, minUnit: ChronoUnit = ChronoUnit.MILLIS): String = + List[(Long, String, ChronoUnit)]( + (duration.toNanosPart % 1_000_000, "ns", ChronoUnit.NANOS), + (duration.toMillisPart, "ms", ChronoUnit.MILLIS), + (duration.toSecondsPart, "s", ChronoUnit.SECONDS), + (duration.toMinutesPart, "min", ChronoUnit.MINUTES), + (duration.toHoursPart, "h", ChronoUnit.HOURS), + (duration.toDaysPart, "d", ChronoUnit.DAYS) + ).filter((_, _, level) => level.ordinal() >= minUnit.ordinal()) + .map((value, unit, _) => (value, unit)) + .map((value, unit) => if value != 0 then Right(s"$value$unit") else Left(s"$value$unit")) + .reverse.dropWhile(_.isLeft) + .map { + case Left(value) => value + case Right(value) => value + }.mkString(" ") + + def formatDurationTimers (duration: Duration, minUnit: ChronoUnit = ChronoUnit.SECONDS): String = + val result = List[(Long, Int, String, ChronoUnit)]( // define each levels parameter + (duration.toNanosPart % 1_000, 3, "", ChronoUnit.NANOS), + (duration.toNanosPart / 1000 % 1_000, 3, ".", ChronoUnit.MICROS), + (duration.toMillisPart, 3, ".", ChronoUnit.MILLIS), + (duration.toSecondsPart, 2, ":", ChronoUnit.SECONDS), + (duration.toMinutesPart, 2, ":", ChronoUnit.MINUTES), + (duration.toHoursPart, 2, ":", ChronoUnit.HOURS), + (duration.toDaysPart, 0, "!", ChronoUnit.DAYS) + ).filter((_, _, _, level) => level.ordinal() >= minUnit.ordinal()) // filter out smaller than minUnit levels + .map { (value, minWidth, prefixed, level) => // stringify the duration number, and fill to left if it is 0 + val stringed = value.toString.reverse.padTo(minWidth, '0').reverse + val data = (prefixed, stringed) + if value != 0 then (Right(data), level) else (Left(data), level) + }.reverse.dropWhile{ (value, level) => // filter out units with 0 value, on larger units side + value.isLeft && (level.ordinal() > ChronoUnit.SECONDS.ordinal()) // but do not filter out units smaller than seconds + }.map((value, _) => value).map { // just fold data + case Left(data) => data + case Right(data) => data + }.map((prefixed, value) => prefixed + value) + .mkString("") // make it as a string + .drop(1) // drop unnecessary prefixed unit-prefix + if result.startsWith("00.") then // when the max unit is already 0 second, return with 0 seconds + result.drop(1) + else if result.contains(":") || result.contains(".") then // when there contains more than one unit + result.dropWhile(_=='0') // drop the prefixed 0 on the largest unit + else "0:" + result // when the max unit is smaller than seconds, add the 0-minute parts + } diff --git a/src/test/scala/cc/sukazyo/cono/morny/MornyCLI.scala b/src/test/scala/cc/sukazyo/cono/morny/MornyCLI.scala index a5c01f8..78cd519 100644 --- a/src/test/scala/cc/sukazyo/cono/morny/MornyCLI.scala +++ b/src/test/scala/cc/sukazyo/cono/morny/MornyCLI.scala @@ -1,12 +1,22 @@ package cc.sukazyo.cono.morny -import cc.sukazyo.cono.morny.util.UniversalCommand +import cc.sukazyo.cono.morny.util.CommonFormat -import scala.io.StdIn +import java.time.Duration +import java.time.temporal.ChronoUnit @main def MornyCLI (): Unit = { - print("$ java -jar morny-coeur-\"+MornySystem.VERSION_FULL+\".jar ") - ServerMain main UniversalCommand(StdIn readLine) + val duration = Duration.ZERO +// .plusDays(2) +// .plusHours(21) +// .plusMinutes(2) +// .plusSeconds(5) + .plusMillis(123) + .plusNanos(876548) + + val echo = CommonFormat.formatDurationTimers(duration, ChronoUnit.SECONDS) + + println(echo) }