diff --git a/src/main/scala/cc/sukazyo/cono/morny/bot/command/Testing.scala b/src/main/scala/cc/sukazyo/cono/morny/bot/command/Testing.scala index c18c611..949fa83 100644 --- a/src/main/scala/cc/sukazyo/cono/morny/bot/command/Testing.scala +++ b/src/main/scala/cc/sukazyo/cono/morny/bot/command/Testing.scala @@ -1,15 +1,11 @@ package cc.sukazyo.cono.morny.bot.command import cc.sukazyo.cono.morny.MornyCoeur -import cc.sukazyo.cono.morny.extra.BilibiliForms -import cc.sukazyo.cono.morny.extra.bilibili.XWebAPI import cc.sukazyo.cono.morny.util.tgapi.InputCommand import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec import com.pengrad.telegrambot.model.Update import com.pengrad.telegrambot.model.request.ParseMode -import com.pengrad.telegrambot.request.{SendMessage, SendPhoto} - -import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h +import com.pengrad.telegrambot.request.SendMessage import scala.language.postfixOps @@ -20,20 +16,6 @@ class Testing (using coeur: MornyCoeur) extends ISimpleCommand { override def execute (using command: InputCommand, event: Update): Unit = { - val video = BilibiliForms.parse_videoUrl(command.args.mkString(" ")) - val video_info = XWebAPI.get_view(video) - - coeur.account exec new SendPhoto( - event.message.chat.id, - video_info.data.pic - ).replyToMessageId(event.message.messageId) - .caption( - // language=html - s"""${h(video_info.data.title)} - | @${h(video_info.data.owner.name)} - |${h(video_info.data.desc)}""".stripMargin - ).parseMode(ParseMode.HTML) - coeur.account exec new SendMessage( event.message.chat.id, // language=html 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 ba1c095..807da28 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 @@ -4,14 +4,16 @@ import cc.sukazyo.cono.morny.MornyCoeur import cc.sukazyo.cono.morny.bot.api.{EventEnv, EventListener} import cc.sukazyo.cono.morny.bot.event.OnGetSocial.tryFetchSocial import cc.sukazyo.cono.morny.data.TelegramStickers -import cc.sukazyo.cono.morny.extra.{twitter, weibo} +import cc.sukazyo.cono.morny.extra.{twitter, weibo, BilibiliForms} import cc.sukazyo.cono.morny.util.tgapi.TelegramExtensions.Bot.exec import cc.sukazyo.cono.morny.Log.{exceptionLog, logger} 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 com.pengrad.telegrambot.model.Chat import com.pengrad.telegrambot.model.request.ParseMode -import com.pengrad.telegrambot.request.{SendMessage, SendSticker} +import com.pengrad.telegrambot.request.{SendMessage, SendPhoto, SendSticker} class OnGetSocial (using coeur: MornyCoeur) extends EventListener { @@ -69,10 +71,43 @@ object OnGetSocial { succeed += 1 tryFetchSocialOfWeibo(f) }) + + { + val bilibiliVideos: List[BiliVideoId] = text match + case Left(texts) => + BiliVideoId.searchIn(texts) ::: BiliB23.searchIn(texts).map(_.toVideoId) + case Right(url) => + try BilibiliForms.parse_videoUrl(url) :: Nil + catch case _: IllegalArgumentException => + try BiliVideoId.matchUrl(BilibiliForms.destructB23Url(url)) :: Nil + catch case _: Exception => Nil + bilibiliVideos.foreach( video => + succeed += 1 + tryFetchSocialOfBilibili(video) + ) + } + succeed > 0 } + private def tryFetchSocialOfBilibili (video: BiliVideoId)(using replyChat: Long, replyToMessage: Int)(using coeur: MornyCoeur) = { + import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h + + val video_info = XWebAPI.get_view(video) + coeur.account exec new SendPhoto( + replyChat, + video_info.data.pic + ).replyToMessageId(replyToMessage) + .caption( + // language=html + s"""${h(video_info.data.title)} + | @${h(video_info.data.owner.name)} + |${h(video_info.data.desc)}""".stripMargin + ).parseMode(ParseMode.HTML) + + } + private def tryFetchSocialOfTweet (url: twitter.TweetUrlInformation)(using replyChat: Long, replyToMessage: Int)(using coeur: MornyCoeur) = import io.circe.{DecodingFailure, ParsingFailure} import sttp.client3.SttpClientException diff --git a/src/main/scala/cc/sukazyo/cono/morny/bot/query/ShareToolBilibili.scala b/src/main/scala/cc/sukazyo/cono/morny/bot/query/ShareToolBilibili.scala index d6446eb..45bd15f 100644 --- a/src/main/scala/cc/sukazyo/cono/morny/bot/query/ShareToolBilibili.scala +++ b/src/main/scala/cc/sukazyo/cono/morny/bot/query/ShareToolBilibili.scala @@ -8,8 +8,6 @@ import scala.language.postfixOps class ShareToolBilibili extends ITelegramQuery { - private val TITLE_BILI_AV = "[bilibili] Share video / av" - private val TITLE_BILI_BV = "[bilibili] Share video / BV" private val ID_PREFIX_BILI_AV = "[morny/share/bili/av]" private val ID_PREFIX_BILI_BV = "[morny/share/bili/bv]" private val SHARE_FORMAT_HTML = "%s" @@ -30,13 +28,17 @@ class ShareToolBilibili extends ITelegramQuery { List( InlineQueryUnit(InlineQueryResultArticle( inlineQueryId(ID_PREFIX_BILI_AV + it.av), - TITLE_BILI_AV + it.av, + s"[Bilibili] Video av${it.av}", InputTextMessageContent(formatShareHTML(it.avLink, it.toAvString)).parseMode(ParseMode HTML) + ).description( + s"Video URL only. Aka BV${it.bv}" )), InlineQueryUnit(InlineQueryResultArticle( inlineQueryId(ID_PREFIX_BILI_BV + it.bv), - TITLE_BILI_BV + it.bv, + s"[Bilibili] Video BV${it.bv}", InputTextMessageContent(formatShareHTML(it.bvLink, it.toBvString)).parseMode(ParseMode HTML) + ).description( + s"Video URL only. Aka av${it.av}" )) ) ) 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 6c2ca9c..6e20066 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 @@ -4,7 +4,11 @@ import cc.sukazyo.cono.morny.data.social.{SocialTwitterParser, SocialWeiboParser import cc.sukazyo.cono.morny.extra.{twitter, weibo} import cc.sukazyo.cono.morny.extra.twitter.FXApi 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 com.pengrad.telegrambot.model.Update +import com.pengrad.telegrambot.model.request.{InlineQueryResultPhoto, ParseMode} class ShareToolSocialContent extends ITelegramQuery { @@ -13,7 +17,33 @@ class ShareToolSocialContent extends ITelegramQuery { val query = event.inlineQuery.query if query == null then return null - twitterTweets(query) ::: weiboStatus(query) + twitterTweets(query) ::: weiboStatus(query) ::: bilibiliVideos(query) + + } + + private def bilibiliVideos (query: String): List[InlineQueryUnit[_]] = { + + val results: List[(String, BiliVideoId)] = + BiliVideoId.searchIn(query).map(x => (x.toString, x)) ++ + BiliB23.searchIn(query).map(x => (x.toString, x.toVideoId)) + + results.map { (_, video) => + val video_info = XWebAPI.get_view(video) + InlineQueryUnit(InlineQueryResultPhoto( + "[morny/share/bilibili/video/preview]" + video.av + "/" + video.bv, + video_info.data.pic, + video_info.data.pic + ).title( + s"[Bilibili] ${video_info.data.title}" + ).description( + s"av${video.av} / BV${video.bv} - Preview" + ).caption( + // language=html + s"""${h(video_info.data.title)} + | @${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/ShareToolTwitter.scala b/src/main/scala/cc/sukazyo/cono/morny/bot/query/ShareToolTwitter.scala index e3afdc7..a950f86 100644 --- a/src/main/scala/cc/sukazyo/cono/morny/bot/query/ShareToolTwitter.scala +++ b/src/main/scala/cc/sukazyo/cono/morny/bot/query/ShareToolTwitter.scala @@ -9,9 +9,9 @@ import scala.language.postfixOps class ShareToolTwitter extends ITelegramQuery { - private val TITLE_VX = "[tweet] Share as VxTwitter" + private val TITLE_VX = "[Twitter/X][VxTwitter]" private val ID_PREFIX_VX = "[morny/share/twitter/vx_url]" - private val TITLE_FX = "[tweet] Share as Fix-Tweet" + private val TITLE_FX = "[Twitter/X][Fix-Tweet]" private val ID_PREFIX_FX = "[morny/share/twitter/fx_url]" override def query (event: Update): List[InlineQueryUnit[_]] | Null = { @@ -21,7 +21,7 @@ class ShareToolTwitter extends ITelegramQuery { def getQueryTweetId (prefix: String, tweet: TweetUrlInformation): String = prefix + tweet.hashCode def getTweetName (title_prefix: String, tweet: TweetUrlInformation): String = - s"$title_prefix ${tweet.screenName}.${tweet.statusId}" + s"$title_prefix ${tweet.screenName}/${tweet.statusId}" twitter.guessTweetUrl(event.inlineQuery.query).flatMap(tweet => List( diff --git a/src/main/scala/cc/sukazyo/cono/morny/bot/query/ShareToolXhs.scala b/src/main/scala/cc/sukazyo/cono/morny/bot/query/ShareToolXhs.scala index 3c3dab4..a91ea76 100644 --- a/src/main/scala/cc/sukazyo/cono/morny/bot/query/ShareToolXhs.scala +++ b/src/main/scala/cc/sukazyo/cono/morny/bot/query/ShareToolXhs.scala @@ -5,7 +5,7 @@ import com.pengrad.telegrambot.model.request.InlineQueryResultArticle class ShareToolXhs extends ITelegramQuery { - private val TITLE = "[Xiaohongshu] Share Link" + private val TITLE = "[Xiaohongshu] Note" private val ID = "[morny/share/xhs/link]" override def query (event: Update): List[InlineQueryUnit[_]] | Null = { @@ -15,22 +15,24 @@ class ShareToolXhs extends ITelegramQuery { val content = inlineQuery.query def getTitle (xhsLink: XHSLink): String = { - s"$TITLE [${xhsLink.exploreId}]" + s"$TITLE ${xhsLink.exploreId}" } - val xhsLinks: List[(String, XHSLink)] = { + val xhsLinks: List[(String, XHSLink, Option[String])] = { XHSLink.searchUrls(content).map { - case xhsLink: XHSLink => (xhsLink.toString, xhsLink) + case xhsLink: XHSLink => (xhsLink.toString, xhsLink, None) case shareLink: XHSLink.ShareLink => - (shareLink.toString, shareLink.getXhsLink) + (shareLink.toString, shareLink.getXhsLink, Some(shareLink.link)) } } - xhsLinks.map((uniqueId, xhsLink) => + xhsLinks.map((uniqueId, xhsLink, maybeFromShare) => InlineQueryUnit(InlineQueryResultArticle( ID+uniqueId, getTitle(xhsLink), xhsLink.link + ).description( + "URL only." + (if maybeFromShare.nonEmpty then s" from $maybeFromShare" else "") )) )