diff --git a/Cargo.lock b/Cargo.lock index 463e438..13fcd14 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -198,8 +198,9 @@ checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" [[package]] name = "holocal" -version = "0.1.0" +version = "0.1.2" dependencies = [ + "quick-xml", "reqwest", "tokio", ] @@ -562,6 +563,15 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "quick-xml" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26aab6b48e2590e4a64d1ed808749ba06257882b461d01ca71baeb747074a6dd" +dependencies = [ + "memchr", +] + [[package]] name = "quote" version = "1.0.8" diff --git a/Cargo.toml b/Cargo.toml index 9d9b665..25e446b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "holocal" -version = "0.1.1" +version = "0.1.2" authors = ["blank X "] edition = "2018" @@ -12,3 +12,4 @@ lto = true [dependencies] reqwest = { version = "0.10.10", features = ["default-tls"] } tokio = { version = "0.2.22", features = ["rt-core"] } +quick-xml = "0.20" diff --git a/src/main.rs b/src/main.rs index dfd5c18..d41cefc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,8 @@ use std::io::{stdin, BufRead}; use std::process::{exit, Command}; use std::os::unix::process::CommandExt; use reqwest::Client; +use quick_xml::Reader; +use quick_xml::events::Event; extern crate tokio; fn main() { @@ -68,25 +70,92 @@ fn main() { let text = tokio::runtime::Runtime::new() .unwrap() .block_on(get_feed_text(nitter_instance, &account)); - match &text.splitn(4, "").nth(2) { - Some(title) => println!("{}", &title.splitn(2, "").nth(0).unwrap()), - None => { - eprintln!("Cannot find tweet"); - exit(1); - } - }; - let image_url = text.splitn(3, " = None; + let mut url: Option = None; + let mut reader = Reader::from_str(&text); + let mut buf = Vec::new(); + loop { + match reader.read_event(&mut buf) { + Ok(Event::Start(ref e)) => { + match String::from_utf8(e.name().to_vec()).unwrap().as_str() { + "item" => { + is_inside_item = true; + title = None; + url = None; + }, + "title" => is_inside_title = true, + "description" => is_inside_description = true, + _ => () + }; + }, + Ok(Event::Text(e)) => { + if is_inside_item && is_inside_title { + title = Some(e.unescape_and_decode(&reader).unwrap()); + } + }, + Ok(Event::CData(e)) => { + if is_inside_item && is_inside_description { + let description_text = e.unescape_and_decode(&reader).unwrap(); + let mut description_reader = Reader::from_str(&description_text); + let mut description_buf = Vec::new(); + loop { + match description_reader.read_event(&mut description_buf) { + Ok(Event::Empty(ref e)) => { + if String::from_utf8(e.name().to_vec()).unwrap().as_str() == "img" { + url = Some(e.attributes() + .find(|attribute| String::from_utf8(attribute.as_ref().unwrap().key.to_vec()).unwrap().as_str() == "src") + .unwrap() + .unwrap() + .unescape_and_decode_value(&description_reader) + .unwrap()); + } + }, + Err(err) => panic!("Error at position {}: {:?}", description_reader.buffer_position(), err), + Ok(Event::Eof) => break, + _ => () + } + } + } + }, + Ok(Event::End(ref e)) => { + match String::from_utf8(e.name().to_vec()).unwrap().as_str() { + "item" => { + is_inside_item = false; + if title.is_some() && url.is_some() { + break; + } + }, + "description" => { + is_inside_description = false; + if title.is_some() && url.is_some() { + break; + } + }, + "title" => is_inside_title = false, + _ => () + }; + }, + Err(err) => panic!("Error at position {}: {:?}", reader.buffer_position(), err), + Ok(Event::Eof) => { + if title.is_none() || url.is_none() { + eprintln!("Cannot find tweet"); + exit(1); + } + break; + }, + _ => () + }; + buf.clear(); + } + println!("{}", title.unwrap()); + let mut args = view_image_command.to_vec().split_off(1); + let url = url.unwrap(); + for i in 0..args.len() { + if args[i] == "{}" { + args[i] = url.as_str(); } } Command::new(&view_image_command[0])