213 lines
8.3 KiB
Rust
213 lines
8.3 KiB
Rust
|
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<Album, Error> {
|
||
|
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<Album, Error> {
|
||
|
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<Album, Error>) -> (u16, Vec<u8>) {
|
||
|
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 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; }");
|
||
|
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 show_details = match err {
|
||
|
Error::APIErrors(ref err)
|
||
|
if err.errors.len() == 1 && err.errors[0].code == "404" =>
|
||
|
{
|
||
|
false
|
||
|
}
|
||
|
_ => true,
|
||
|
};
|
||
|
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())
|
||
|
}
|