♻️: better handle of quotes and media embedded into quotes

This commit is contained in:
VC
2025-12-01 11:37:58 +01:00
parent 79ac915347
commit 7334fb3d09
5 changed files with 119 additions and 86 deletions

View File

@@ -1,4 +1,4 @@
use crate::config::BlueskyConfig;
use crate::{config::BlueskyConfig, OolatoocsError};
use atrium_api::{
app::bsky::feed::post::RecordData, com::atproto::repo::upload_blob::Output,
types::string::Datetime, types::string::Language, types::string::RecordKey,
@@ -148,18 +148,16 @@ async fn get_record(
Ok(record)
}
/// Generate an quote embed record into Bsky
/// Generate an quote embed record
/// it is encapsulated in Option to prevent this function from failing
pub async fn generate_quote_records(
config: &BlueskyConfig,
quote_id: &str,
) -> Option<atrium_api::types::Union<atrium_api::app::bsky::feed::post::RecordEmbedRefs>> {
) -> Result<atrium_api::app::bsky::feed::post::RecordEmbedRefs, Box<dyn Error>> {
// if we cant match the quote_id, simply return None
let quote_record = match get_record(&config.handle, &rkey(quote_id)).await {
Ok(a) => a,
Err(_) => return None,
};
let quote_record = get_record(&config.handle, &rkey(quote_id)).await?;
Some(atrium_api::types::Union::Refs(
Ok(
atrium_api::app::bsky::feed::post::RecordEmbedRefs::AppBskyEmbedRecordMain(Box::new(
atrium_api::app::bsky::embed::record::MainData {
record: atrium_api::com::atproto::repo::strong_ref::MainData {
@@ -170,24 +168,18 @@ pub async fn generate_quote_records(
}
.into(),
)),
))
)
}
/// Generate an embed card record into Bsky
/// Generate an embed webcard record into Bsky
/// If the preview image does not exist or fails to upload, it is simply ignored
pub async fn generate_embed_records(
pub async fn generate_webcard_records(
bsky: &BskyAgent,
card: &Card,
) -> Option<atrium_api::types::Union<atrium_api::app::bsky::feed::post::RecordEmbedRefs>> {
// uploads the image card, if it fails, simply ignore everything
let blob = if let Some(url) = &card.image {
if let Ok(image_blob) = upload_media(true, bsky, url).await {
Some(image_blob.blob.clone())
} else {
None
}
} else {
None
) -> Result<atrium_api::app::bsky::feed::post::RecordEmbedRefs, Box<dyn Error + Send + Sync>> {
let blob = match &card.image {
Some(url) => upload_media(true, bsky, url).await?.blob.clone().into(),
None => None,
};
let record_card = atrium_api::app::bsky::embed::external::ExternalData {
@@ -197,14 +189,14 @@ pub async fn generate_embed_records(
uri: card.url.clone(),
};
Some(atrium_api::types::Union::Refs(
Ok(
atrium_api::app::bsky::feed::post::RecordEmbedRefs::AppBskyEmbedExternalMain(Box::new(
atrium_api::app::bsky::embed::external::MainData {
external: record_card.into(),
}
.into(),
)),
))
)
}
/// Generate an array of Bsky media records
@@ -213,11 +205,7 @@ pub async fn generate_embed_records(
pub async fn generate_media_records(
bsky: &BskyAgent,
media_attach: &[Attachment],
) -> Option<atrium_api::types::Union<atrium_api::app::bsky::feed::post::RecordEmbedRefs>> {
let mut embed: Option<
atrium_api::types::Union<atrium_api::app::bsky::feed::post::RecordEmbedRefs>,
> = None;
) -> Result<atrium_api::app::bsky::feed::post::RecordEmbedRefs, Box<dyn Error + Send + Sync>> {
let image_media_attach: Vec<_> = media_attach
.iter()
.filter(|x| x.r#type == AttachmentType::Image)
@@ -233,9 +221,9 @@ pub async fn generate_media_records(
if !video_media_attach.is_empty() {
// treat only the very first video, ignore the rest
let media = &video_media_attach[0];
let blob = upload_media(false, bsky, &media.url).await.unwrap();
let blob = upload_media(false, bsky, &media.url).await?;
embed = Some(atrium_api::types::Union::Refs(
return Ok(
atrium_api::app::bsky::feed::post::RecordEmbedRefs::AppBskyEmbedVideoMain(Box::new(
atrium_api::app::bsky::embed::video::MainData {
alt: media.description.clone(),
@@ -245,12 +233,10 @@ pub async fn generate_media_records(
}
.into(),
)),
));
// returns immediately, we dont want to treat the other medias
return embed;
);
}
// It wasnt a video, then its an image or a gallery of 4 images
let mut stream = stream::iter(image_media_attach)
.map(|media| {
let bsky = bsky.clone();
@@ -281,14 +267,14 @@ pub async fn generate_media_records(
}
if !images.is_empty() {
embed = Some(atrium_api::types::Union::Refs(
return Ok(
atrium_api::app::bsky::feed::post::RecordEmbedRefs::AppBskyEmbedImagesMain(Box::new(
atrium_api::app::bsky::embed::images::MainData { images }.into(),
)),
));
);
}
embed
Err(OolatoocsError::new("Cannot embed media").into())
}
async fn upload_media(