diff --git a/src/notify/platform/qq/mod.rs b/src/notify/platform/qq/mod.rs index 6ac7cc8..0b8b858 100644 --- a/src/notify/platform/qq/mod.rs +++ b/src/notify/platform/qq/mod.rs @@ -239,7 +239,7 @@ impl Notifier { } let images = post - .attachments_recursive() + .attachments_recursive(true) .into_iter() .filter_map(|attachment| match attachment { PostAttachment::Image(image) => Some(image.media_url.as_str()), diff --git a/src/notify/platform/telegram/mod.rs b/src/notify/platform/telegram/mod.rs index 0dd30fc..3d601e9 100644 --- a/src/notify/platform/telegram/mod.rs +++ b/src/notify/platform/telegram/mod.rs @@ -464,7 +464,7 @@ impl Notifier { const DISABLE_NOTIFICATION: bool = true; // TODO: Make it configurable - let attachments = post.attachments_recursive(); + let attachments = post.attachments_recursive(true); let num_attachments = attachments.len(); let resp = match num_attachments { diff --git a/src/notify/platform/telegram/request.rs b/src/notify/platform/telegram/request.rs index 7b26176..e94242c 100644 --- a/src/notify/platform/telegram/request.rs +++ b/src/notify/platform/telegram/request.rs @@ -823,6 +823,9 @@ impl<'a> Text<'a> { content.parts().for_each(|part| match part { PostContentPart::Plain(text) => self.push_plain(text), PostContentPart::Link { display, url } => self.push_link(display, url), + PostContentPart::InlineAttachment(_) => { + // Ignore, we handle it in post.attachments + } }); } diff --git a/src/source/content.rs b/src/source/content.rs index 280b5b0..eafcf5a 100644 --- a/src/source/content.rs +++ b/src/source/content.rs @@ -1,3 +1,5 @@ +use super::PostAttachment; + #[derive(Clone, Debug, PartialEq)] pub struct PostContent(Vec); @@ -16,6 +18,10 @@ impl PostContent { .map(|part| match part { PostContentPart::Plain(text) => text.as_str(), PostContentPart::Link { url, .. } => url.as_str(), + PostContentPart::InlineAttachment(attachment) => match attachment { + PostAttachment::Image(attachment) => attachment.media_url.as_str(), + PostAttachment::Video(attachment) => attachment.media_url.as_str(), + }, }) .collect::() } @@ -65,4 +71,5 @@ impl PostContent { pub enum PostContentPart { Plain(String), Link { display: String, url: String }, + InlineAttachment(PostAttachment), } diff --git a/src/source/mod.rs b/src/source/mod.rs index 69c5355..3736c07 100644 --- a/src/source/mod.rs +++ b/src/source/mod.rs @@ -253,11 +253,21 @@ pub enum RepostFrom { } impl Post { - pub fn attachments_recursive(&self) -> Vec<&PostAttachment> { + pub fn attachments_recursive(&self, include_inlined: bool) -> Vec<&PostAttachment> { if let Some(RepostFrom::Recursion(repost_from)) = &self.repost_from { self.attachments .iter() - .chain(repost_from.attachments_recursive()) + .chain(self.content.parts().filter_map(|content| { + if !include_inlined { + return None; + } + if let PostContentPart::InlineAttachment(attachment) = content { + Some(attachment) + } else { + None + } + })) + .chain(repost_from.attachments_recursive(include_inlined)) .collect() } else { self.attachments.iter().collect() diff --git a/src/source/platform/bilibili/space.rs b/src/source/platform/bilibili/space.rs index 6a786fc..1c27f60 100644 --- a/src/source/platform/bilibili/space.rs +++ b/src/source/platform/bilibili/space.rs @@ -298,6 +298,22 @@ mod data { display: node.text.clone(), url: format!("https://www.bilibili.com/video/{rid}"), }, + RichTextNodeKind::ViewPicture { pics, .. } => { + if pics.len() != 1 { + warn!( + "bilibili rich text view-pic node has pics.len() = {}", + pics.len() + ); + PostContentPart::Plain(node.orig_text.clone()) + } else { + PostContentPart::InlineAttachment(PostAttachment::Image( + PostAttachmentImage { + media_url: pics.first().unwrap().src.clone(), + has_spoiler: false, + }, + )) + } + } // We treat these nodes as plain text RichTextNodeKind::Emoji { .. } | RichTextNodeKind::Lottery { .. } => { PostContentPart::Plain(node.orig_text.clone()) @@ -335,6 +351,12 @@ mod data { Lottery { rid: String }, #[serde(rename = "RICH_TEXT_NODE_TYPE_BV")] Bv { jump_url: String, rid: String }, + #[serde(rename = "RICH_TEXT_NODE_TYPE_VIEW_PICTURE")] + ViewPicture { + jump_url: String, + pics: Vec, + rid: String, + }, #[serde(untagged)] Unknown(json::Value), } @@ -346,6 +368,14 @@ mod data { // pub size: u64 // pub type: u64 } + + #[derive(Debug, Deserialize)] + pub struct RichTextNodeViewPicturePic { + pub src: String, + // pub height: u64 + // pub width: u64 + // pub size: u64 + } } pub struct Fetcher { diff --git a/src/source/platform/twitter/mod.rs b/src/source/platform/twitter/mod.rs index 8d01b03..84a5435 100644 --- a/src/source/platform/twitter/mod.rs +++ b/src/source/platform/twitter/mod.rs @@ -565,7 +565,7 @@ fn parse_tweet(tweet: data::Tweet) -> Post { .filter(|attachment| { if let Some(RepostFrom::Recursion(repost_from)) = &repost_from { let is_contained_in_repost = repost_from - .attachments_recursive() + .attachments_recursive(true) .iter() .any(|sub_attachment| *sub_attachment == attachment); !is_contained_in_repost