use crate::structs::{Album, Error}; use quick_xml::events::{BytesEnd, BytesStart, BytesText, Event}; use quick_xml::Writer; use reqwest::Client; use std::io::Cursor; extern crate serde_json; pub async fn get_album(client: Client, id: &str) -> Result { let resp = client .get(&format!( "https://api.imgur.com/post/v1/albums/{}?client_id=546c25a59c58ad7&include=media", id )) .send() .await?; let status = resp.status(); let text = resp.text().await?; if status == 200 { Ok(serde_json::from_str(&text)?) } else { Err(Error::APIErrors(serde_json::from_str(&text)?)) } } pub async fn get_media(client: Client, id: &str) -> Result { let resp = client .get(&format!( "https://api.imgur.com/post/v1/media/{}?client_id=546c25a59c58ad7&include=media", id )) .send() .await?; let status = resp.status(); let text = resp.text().await?; if status == 200 { Ok(serde_json::from_str(&text)?) } else { Err(Error::APIErrors(serde_json::from_str(&text)?)) } } pub fn generate_html(album: Result) -> (u16, Vec) { let mut writer = Writer::new(Cursor::new(vec![])); let elem = BytesStart::owned(b"html".to_vec(), 4); writer.write_event(Event::Start(elem)).unwrap(); let elem = BytesStart::owned(b"head".to_vec(), 4); writer.write_event(Event::Start(elem)).unwrap(); let (show_details, title) = match album { Ok(ref album) if !album.title.is_empty() => (false, Some(album.title.clone())), Err(Error::APIErrors(ref err)) if err.errors.len() == 1 && err.errors[0].code == "404" => { (false, Some(format!("404: {}", &err.errors[0].detail))) } _ => (true, None), }; if let Some(title) = title { let elem = BytesStart::owned(b"title".to_vec(), 5); writer.write_event(Event::Start(elem)).unwrap(); let elem = BytesText::from_plain_str(&title); writer.write_event(Event::Text(elem)).unwrap(); let elem = BytesEnd::owned(b"title".to_vec()); writer.write_event(Event::End(elem)).unwrap(); } let elem = BytesStart::owned(b"style".to_vec(), 5); writer.write_event(Event::Start(elem)).unwrap(); let elem = BytesText::from_plain_str("body { background-color: black; color: white; text-align: center; }\ndiv { border: 1px solid #fcc; background: #fee; padding: 0.5em 1em 0.5em 1em; color: black; }\nimg, video { max-width: 100%; height: auto; object-fit: contain; }"); writer.write_event(Event::Text(elem)).unwrap(); let elem = BytesEnd::owned(b"style".to_vec()); writer.write_event(Event::End(elem)).unwrap(); let elem = BytesEnd::owned(b"head".to_vec()); writer.write_event(Event::End(elem)).unwrap(); let elem = BytesStart::owned(b"body".to_vec(), 4); writer.write_event(Event::Start(elem)).unwrap(); let status_code = match album { Ok(album) => { if album.is_mature { let elem = BytesStart::owned(b"div".to_vec(), 3); writer.write_event(Event::Start(elem)).unwrap(); let elem = BytesStart::owned(b"b".to_vec(), 1); writer.write_event(Event::Start(elem)).unwrap(); let elem = BytesText::from_plain_str("Marked as NSFW"); writer.write_event(Event::Text(elem)).unwrap(); let elem = BytesEnd::owned(b"b".to_vec()); writer.write_event(Event::End(elem)).unwrap(); let elem = BytesEnd::owned(b"div".to_vec()); writer.write_event(Event::End(elem)).unwrap(); } if !album.title.is_empty() { let elem = BytesStart::owned(b"h1".to_vec(), 2); writer.write_event(Event::Start(elem)).unwrap(); let elem = BytesText::from_plain_str(&album.title); writer.write_event(Event::Text(elem)).unwrap(); let elem = BytesEnd::owned(b"h1".to_vec()); writer.write_event(Event::End(elem)).unwrap(); } for media in &album.media { if media.r#type == "image" { let mut elem = BytesStart::owned(b"img".to_vec(), 3); elem.push_attribute(("width", media.width.to_string().as_str())); elem.push_attribute(("height", media.height.to_string().as_str())); elem.push_attribute(("src", media.url.as_str())); writer.write_event(Event::Start(elem)).unwrap(); let elem = BytesEnd::owned(b"img".to_vec()); writer.write_event(Event::End(elem)).unwrap(); } else if media.r#type == "video" { let mut elem = BytesStart::owned(b"video".to_vec(), 5); elem.push_attribute(("controls", "1")); elem.push_attribute(("width", media.width.to_string().as_str())); elem.push_attribute(("height", media.height.to_string().as_str())); elem.push_attribute(("src", media.url.as_str())); writer.write_event(Event::Start(elem)).unwrap(); let elem = BytesEnd::owned(b"video".to_vec()); writer.write_event(Event::End(elem)).unwrap(); } else { let elem = BytesStart::owned(b"div".to_vec(), 3); writer.write_event(Event::Start(elem)).unwrap(); let elem = BytesStart::owned(b"b".to_vec(), 1); writer.write_event(Event::Start(elem)).unwrap(); let text = format!("Unknown media type {}, URL is ", &media.r#type); let elem = BytesText::from_plain_str(&text); writer.write_event(Event::Text(elem)).unwrap(); let mut elem = BytesStart::owned(b"a".to_vec(), 1); elem.push_attribute(("href", media.url.as_str())); writer.write_event(Event::Start(elem)).unwrap(); let elem = BytesText::from_plain_str(&media.url); writer.write_event(Event::Text(elem)).unwrap(); let elem = BytesEnd::owned(b"a".to_vec()); writer.write_event(Event::End(elem)).unwrap(); let elem = BytesEnd::owned(b"b".to_vec()); writer.write_event(Event::End(elem)).unwrap(); let elem = BytesEnd::owned(b"div".to_vec()); writer.write_event(Event::End(elem)).unwrap(); } if !media.metadata.description.is_empty() { let elem = BytesStart::owned(b"p".to_vec(), 1); writer.write_event(Event::Start(elem)).unwrap(); let elem = BytesText::from_plain_str(&media.metadata.description); writer.write_event(Event::Text(elem)).unwrap(); let elem = BytesEnd::owned(b"a".to_vec()); writer.write_event(Event::End(elem)).unwrap(); } } 200 } Err(err) => { let mut elem = BytesStart::owned(b"div".to_vec(), 3); if show_details { elem.push_attribute(("style", "text-align: left;")); } writer.write_event(Event::Start(elem)).unwrap(); let elem = BytesStart::owned(b"b".to_vec(), 1); writer.write_event(Event::Start(elem)).unwrap(); let to_return = match err { Error::APIErrors(err) if !show_details => { let text = format!("404: {}", err.errors[0].detail); let elem = BytesText::from_plain_str(&text); writer.write_event(Event::Text(elem)).unwrap(); 404 } _ => { let elem = BytesStart::owned(b"pre".to_vec(), 3); writer.write_event(Event::Start(elem)).unwrap(); let text = format!("{:#?}", err); let elem = BytesText::from_plain_str(&text); writer.write_event(Event::Text(elem)).unwrap(); let elem = BytesEnd::owned(b"pre".to_vec()); writer.write_event(Event::End(elem)).unwrap(); 500 } }; let elem = BytesEnd::owned(b"b".to_vec()); writer.write_event(Event::End(elem)).unwrap(); let elem = BytesEnd::owned(b"div".to_vec()); writer.write_event(Event::End(elem)).unwrap(); to_return } }; let elem = BytesEnd::owned(b"body".to_vec()); writer.write_event(Event::End(elem)).unwrap(); let elem = BytesEnd::owned(b"html".to_vec()); writer.write_event(Event::End(elem)).unwrap(); (status_code, writer.into_inner().into_inner()) }