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)
}