use anyhow::Result; use chrono::Local; use html2md::parse_html; use megalodon::{ entities::{Account, Attachment, Status}, response::Response, Megalodon, }; use rustyline::DefaultEditor; use url::Url; use url_open::UrlOpen; pub(super) async fn format_status( client: &Box, account: &Account, status: &Status, ) -> Result { let ancestor = format!( "{} > {}{}", status.created_at.with_timezone(&Local).format("%H:%M"), parse_html(&status.content).trim(), format_attachments(1, &status.media_attachments) ); let Response { json, .. } = client.get_status_context(status.id.clone(), None).await?; let thread = json .descendants .into_iter() .filter(|s| { s.in_reply_to_account_id == Some(account.id.clone()) && s.account.id == account.id }) .map(|status| { format!( "> > {} >> {}{}", status.created_at.with_timezone(&Local).format("%H:%M"), parse_html(&status.content).trim(), format_attachments(2, &status.media_attachments) ) }) .collect::>() .join("\n"); Ok(format!( "{}{}", ancestor, if !thread.is_empty() { format!("\n{}", thread) } else { String::default() } )) } fn format_attachments(depth: usize, attachments: &[Attachment]) -> String { let prefix = vec![">"; depth].join(""); if attachments.is_empty() { String::default() } else { format!( "\n{}", attachments .iter() .map(|a| { Url::parse(&a.url).unwrap().open(); let mut editor = DefaultEditor::new().unwrap(); let src = if let Ok(line) = editor.readline("Filename: ") { line } else { a.url.clone() }; format!("{} ", prefix, src) }) .collect::>() .join("\n") ) } }