diff --git a/gradle.properties b/gradle.properties index c61b7ab..20156e4 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.3.0-dev13 +VERSION = 1.3.0-dev14 USE_DELTA = false VERSION_DELTA = 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 84bcf80..e7766bc 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 @@ -17,6 +17,9 @@ import com.pengrad.telegrambot.request.{SendMediaGroup, SendMessage} * @param text_html Formatted HTML output of the status that can be output * directly to Telegram. Normally will contains metadata * like status' author or like count etc. + * @param text_withPicPlaceholder same with [[text_html]], but contains more + * placeholder texts of medias. can be used + * when medias cannot be output. * @param medias Status attachment medias. * @param medias_mosaic Mosaic version of status medias. Will be used when * the output API doesn't support multiple medias like @@ -28,6 +31,7 @@ import com.pengrad.telegrambot.request.{SendMediaGroup, SendMessage} */ case class SocialContent ( text_html: String, + text_withPicPlaceholder: String, medias: List[SocialMedia], medias_mosaic: Option[SocialMedia] = None, thumbnail: Option[SocialMedia] = None @@ -56,22 +60,30 @@ case class SocialContent ( def genInlineQueryResults (using id_head: String, id_param: Any, name: String): List[InlineQueryUnit[?]] = { ( - if (this.medias.length == 1) && (this.medias.head.t == Photo) && this.medias.head.isInstanceOf[SocialMediaWithUrl] then - InlineQueryUnit(InlineQueryResultPhoto( - inlineQueryId(s"[$id_head/photo/0]$id_param"), - this.medias.head.asInstanceOf[SocialMediaWithUrl].url, - thumbnailOrElse(this.medias.head.asInstanceOf[SocialMediaWithUrl].url) - ).title(s"$name").caption(text_html).parseMode(ParseMode.HTML)) :: Nil - else if (this.medias_mosaic nonEmpty) && (medias_mosaic.get.t == Photo) && medias_mosaic.get.isInstanceOf[SocialMediaWithUrl] then + if (medias_mosaic nonEmpty) && (medias_mosaic.get.t == Photo) && medias_mosaic.get.isInstanceOf[SocialMediaWithUrl] then InlineQueryUnit(InlineQueryResultPhoto( inlineQueryId(s"[$id_head/photo/mosaic]$id_param"), medias_mosaic.get.asInstanceOf[SocialMediaWithUrl].url, thumbnailOrElse(medias_mosaic.get.asInstanceOf[SocialMediaWithUrl].url) ).title(s"$name").caption(text_html).parseMode(ParseMode.HTML)) :: Nil + else if (medias nonEmpty) && (medias.head.t == Photo) then + val media = medias.head + media match + case media_url: SocialMediaWithUrl => + InlineQueryUnit(InlineQueryResultPhoto( + inlineQueryId(s"[$id_head/photo/0]$id_param"), + media_url.url, + thumbnailOrElse(media_url.url) + ).title(s"$name").caption(text_html).parseMode(ParseMode.HTML)) :: Nil + case _ => + InlineQueryUnit(InlineQueryResultArticle( + inlineQueryId(s"[$id_head/text_only]$id_param"), s"$name (text only)", + InputTextMessageContent(text_withPicPlaceholder).parseMode(ParseMode.HTML) + )) :: Nil else InlineQueryUnit(InlineQueryResultArticle( inlineQueryId(s"[$id_head/text]$id_param"), s"$name", - InputTextMessageContent(this.text_html).parseMode(ParseMode.HTML) + InputTextMessageContent(text_html).parseMode(ParseMode.HTML) )) :: Nil ) ::: Nil } diff --git a/src/main/scala/cc/sukazyo/cono/morny/data/social/SocialTwitterParser.scala b/src/main/scala/cc/sukazyo/cono/morny/data/social/SocialTwitterParser.scala index 21e2da9..b8cef11 100644 --- a/src/main/scala/cc/sukazyo/cono/morny/data/social/SocialTwitterParser.scala +++ b/src/main/scala/cc/sukazyo/cono/morny/data/social/SocialTwitterParser.scala @@ -2,20 +2,26 @@ package cc.sukazyo.cono.morny.data.social import cc.sukazyo.cono.morny.data.social.SocialContent.{SocialMedia, SocialMediaWithUrl} import cc.sukazyo.cono.morny.data.social.SocialContent.SocialMediaType.{Photo, Video} -import cc.sukazyo.cono.morny.extra.twitter.FXApi +import cc.sukazyo.cono.morny.extra.twitter.{FXApi, FXTweet} import cc.sukazyo.cono.morny.util.tgapi.formatting.TelegramParseEscape.escapeHtml as h object SocialTwitterParser { + def parseFXTweet_forMediaPlaceholderInContent (tweet: FXTweet): String = + tweet.media match + case None => "" + case Some(media) => + "\n" + (media.photos.getOrElse(Nil).map(* => "🖼️") ::: media.videos.getOrElse(Nil).map(* => "🎞️")) + .mkString(" ") + def parseFXTweet (api: FXApi): SocialContent = { api.tweet match case None => - SocialContent( + val content = // language=html s"""❌ Fix-Tweet ${api.code} - |${h(api.message)}""".stripMargin, - Nil - ) + |${h(api.message)}""".stripMargin + SocialContent(content, content, Nil) case Some(tweet) => val content: String = // language=html @@ -25,9 +31,17 @@ object SocialTwitterParser { | |💬${tweet.replies} 🔗${tweet.retweets} ❤️${tweet.likes} |${h(tweet.created_at)}""".stripMargin + val content_withMediasPlaceholder: String = + // language=html + s"""⚪️ ${h(tweet.author.name)} @${h(tweet.author.screen_name)} + | + |${h(tweet.text)}${parseFXTweet_forMediaPlaceholderInContent(tweet)} + | + |💬${tweet.replies} 🔗${tweet.retweets} ❤️${tweet.likes} + |${h(tweet.created_at)}""".stripMargin tweet.media match case None => - SocialContent(content, Nil) + SocialContent(content, content_withMediasPlaceholder, Nil) case Some(media) => val mediaGroup: List[SocialMedia] = ( @@ -46,7 +60,7 @@ object SocialTwitterParser { val mediaMosaic = media.mosaic match case Some(mosaic) => Some(SocialMediaWithUrl(mosaic.formats.jpeg)(Photo)) case None => None - SocialContent(content, mediaGroup, mediaMosaic, thumbnail) + SocialContent(content, content_withMediasPlaceholder, mediaGroup, mediaMosaic, thumbnail) } } diff --git a/src/main/scala/cc/sukazyo/cono/morny/data/social/SocialWeiboParser.scala b/src/main/scala/cc/sukazyo/cono/morny/data/social/SocialWeiboParser.scala index 9fac0d7..7acaa08 100644 --- a/src/main/scala/cc/sukazyo/cono/morny/data/social/SocialWeiboParser.scala +++ b/src/main/scala/cc/sukazyo/cono/morny/data/social/SocialWeiboParser.scala @@ -9,32 +9,42 @@ import sttp.client3.{HttpError, SttpClientException} object SocialWeiboParser { + def parseMStatus_forPicPreview (status: MStatus): String = + if status.pic_ids.isEmpty then "" else + "\n" + (for (pic <- status.pic_ids) yield "🖼️").mkString(" ") + + def parseMStatus_forRetweeted (originalStatus: MStatus): String = + originalStatus.retweeted_status match + case Some(status) => + // language=html + s""" + |//${h(status.user.screen_name)}: + |${ch(status.text)}${parseMStatus_forPicPreview(status)} + |""".stripMargin + case None => "" + @throws[HttpError[?] | SttpClientException | ParsingFailure | DecodingFailure] def parseMStatus (api: MApi[MStatus]): SocialContent = { - def retweetedMessage (retweetedStatus: Option[MStatus]): String = - retweetedStatus match - case Some(status) => - val pic_preview = if status.pic_ids.isEmpty then "" else - "\n" + (for (pic <- status.pic_ids) yield "🖼️").mkString(" ") - // language=html - s""" - |//${h(status.user.screen_name)}: - |${ch(status.text)}$pic_preview - |""".stripMargin - case None => "" val content = - // language=html + // language=html s"""🔸${h(api.data.user.screen_name)} | |${ch(api.data.text)} - |${retweetedMessage(api.data.retweeted_status)} + |${parseMStatus_forRetweeted(api.data)} + |${h(api.data.created_at)}""".stripMargin + val content_withPicPlaceholder = + // language=html + s"""🔸${h(api.data.user.screen_name)} + | + |${ch(api.data.text)}${parseMStatus_forPicPreview(api.data)} + |${parseMStatus_forRetweeted(api.data)} |${h(api.data.created_at)}""".stripMargin api.data.pics match case None => - SocialContent(content, Nil) + SocialContent(content, content_withPicPlaceholder, Nil) case Some(pics) => val mediaGroup = pics.map(f => SocialMediaWithBytesData(MApi.Fetch.pic(f.large.url))(Photo)) - SocialContent(content, mediaGroup) + SocialContent(content, content_withPicPlaceholder, mediaGroup) } }